#include "aos_string.h" #include "aos_list.h" #include "aos_buf.h" #include "aos_util.h" #include "aos_log.h" #include "aos_status.h" #include "oss_util.h" #include "oss_auth.h" #include "oss_xml.h" #include "oss_define.h" static int get_truncated_from_xml(aos_pool_t *p, mxml_node_t *xml_node, const char *truncated_xml_path); int get_truncated_from_xml(aos_pool_t *p, mxml_node_t *xml_node, const char *truncated_xml_path) { char *is_truncated; int truncated = 0; is_truncated = get_xmlnode_value(p, xml_node, truncated_xml_path); if (is_truncated) { truncated = strcasecmp(is_truncated, "false") == 0 ? 0 : 1; } return truncated; } static char* new_xml_buff(mxml_node_t *doc); char* new_xml_buff(mxml_node_t *doc) { int bytes; char buffer[8192]; char *s; bytes = mxmlSaveString(doc, buffer, sizeof(buffer), MXML_NO_CALLBACK); if (bytes <= 0) { return (NULL); } if (bytes < (int)(sizeof(buffer) - 1)) { return (strdup(buffer)); } if ((s = malloc(bytes + 1)) == NULL) { return (NULL); } mxmlSaveString(doc, s, bytes + 1, MXML_NO_CALLBACK); return (s); } int get_xmldoc(aos_list_t *bc, mxml_node_t **root) { int res; if (aos_list_empty(bc)) { return AOSE_XML_PARSE_ERROR; } if ((res = aos_parse_xml_body(bc, root)) != AOSE_OK) { return AOSE_XML_PARSE_ERROR; } return AOSE_OK; } char *get_xmlnode_value(aos_pool_t *p, mxml_node_t *xml_node, const char *xml_path) { char *value = NULL; mxml_node_t *node; char *node_content; node = mxmlFindElement(xml_node, xml_node, xml_path, NULL, NULL, MXML_DESCEND); if (NULL != node && node->child != NULL) { node_content = node->child->value.opaque; value = apr_pstrdup(p, (char *)node_content); } return value; } int oss_acl_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_string_t *oss_acl) { int res; mxml_node_t *doc = NULL; const char xml_path[] = "Grant"; char *acl; res = get_xmldoc(bc, &doc); if (res == AOSE_OK) { acl = get_xmlnode_value(p, doc, xml_path); if (acl) { aos_str_set(oss_acl, acl); } mxmlDelete(doc); } return res; } void oss_list_objects_owner_parse(aos_pool_t *p, mxml_node_t *xml_node, oss_list_object_content_t *content) { mxml_node_t *node; char *node_content; char *owner_id; char *owner_display_name; node = mxmlFindElement(xml_node, xml_node, "ID",NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; owner_id = apr_pstrdup(p, node_content); aos_str_set(&content->owner_id, owner_id); } node = mxmlFindElement(xml_node, xml_node, "DisplayName", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; owner_display_name = apr_pstrdup(p, node_content); aos_str_set(&content->owner_display_name, owner_display_name); } } void oss_list_objects_content_parse(aos_pool_t *p, mxml_node_t *xml_node, oss_list_object_content_t *content) { char *key; char *last_modified; char *etag; char *size; char *node_content; mxml_node_t *node; node = mxmlFindElement(xml_node, xml_node, "Key", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; key = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->key, key); } node = mxmlFindElement(xml_node, xml_node, "LastModified", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; last_modified = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->last_modified, last_modified); } node = mxmlFindElement(xml_node, xml_node, "ETag", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; etag = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->etag, etag); } node = mxmlFindElement(xml_node, xml_node, "Size", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; size = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->size, size); } node = mxmlFindElement(xml_node, xml_node, "Owner", NULL, NULL, MXML_DESCEND); if (NULL != node) { oss_list_objects_owner_parse(p, node, content); } } void oss_list_objects_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path, aos_list_t *object_list) { mxml_node_t *content_node; oss_list_object_content_t *content; content_node = mxmlFindElement(root, root, xml_path, NULL, NULL, MXML_DESCEND); for ( ; content_node != NULL; ) { content = oss_create_list_object_content(p); oss_list_objects_content_parse(p, content_node, content); aos_list_add_tail(&content->node, object_list); content_node = mxmlFindElement(content_node, root, xml_path, NULL, NULL, MXML_DESCEND); } } void oss_list_objects_prefix_parse(aos_pool_t *p, mxml_node_t *xml_node, oss_list_object_common_prefix_t *common_prefix) { char *prefix; mxml_node_t *node; char *node_content; node = mxmlFindElement(xml_node, xml_node, "Prefix", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; prefix = apr_pstrdup(p, (char *)node_content); aos_str_set(&common_prefix->prefix, prefix); } } void oss_list_objects_common_prefix_parse(aos_pool_t *p, mxml_node_t *xml_node, const char *xml_path, aos_list_t *common_prefix_list) { mxml_node_t *node; oss_list_object_common_prefix_t *common_prefix; node = mxmlFindElement(xml_node, xml_node, xml_path, NULL, NULL, MXML_DESCEND); for ( ; node != NULL; ) { common_prefix = oss_create_list_object_common_prefix(p); oss_list_objects_prefix_parse(p, node, common_prefix); aos_list_add_tail(&common_prefix->node, common_prefix_list); node = mxmlFindElement(node, xml_node, xml_path, NULL, NULL, MXML_DESCEND); } } int oss_list_objects_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_list_t *object_list, aos_list_t *common_prefix_list, aos_string_t *marker, int *truncated) { int res; mxml_node_t *root; const char next_marker_xml_path[] = "NextMarker"; const char truncated_xml_path[] = "IsTruncated"; const char buckets_xml_path[] = "Contents"; const char common_prefix_xml_path[] = "CommonPrefixes"; char* next_marker; res = get_xmldoc(bc, &root); if (res == AOSE_OK) { next_marker = get_xmlnode_value(p, root, next_marker_xml_path); if (next_marker) { aos_str_set(marker, next_marker); } *truncated = get_truncated_from_xml(p, root, truncated_xml_path); oss_list_objects_contents_parse(p, root, buckets_xml_path, object_list); oss_list_objects_common_prefix_parse(p, root, common_prefix_xml_path, common_prefix_list); mxmlDelete(root); } return res; } int oss_upload_id_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_string_t *upload_id) { int res; mxml_node_t *root; const char xml_path[] = "UploadId"; char *id; res = get_xmldoc(bc, &root); if (res == AOSE_OK) { id = get_xmlnode_value(p, root, xml_path); if (id) { aos_str_set(upload_id, id); } mxmlDelete(root); } return res; } void oss_list_parts_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path, aos_list_t *part_list) { mxml_node_t *content_node; oss_list_part_content_t *content; content_node = mxmlFindElement(root, root, xml_path, NULL, NULL, MXML_DESCEND); for ( ; content_node != NULL; ) { content = oss_create_list_part_content(p); oss_list_parts_content_parse(p, content_node, content); aos_list_add_tail(&content->node, part_list); content_node = mxmlFindElement(content_node, root, xml_path, NULL, NULL, MXML_DESCEND); } } void oss_list_parts_content_parse(aos_pool_t *p, mxml_node_t *xml_node, oss_list_part_content_t *content) { char *part_number; char *last_modified; char *etag; char *size; char *node_content; mxml_node_t *node; node = mxmlFindElement(xml_node, xml_node, "PartNumber", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; part_number = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->part_number, part_number); } node = mxmlFindElement(xml_node, xml_node, "LastModified", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; last_modified = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->last_modified, last_modified); } node = mxmlFindElement(xml_node, xml_node, "ETag", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; etag = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->etag, etag); } node = mxmlFindElement(xml_node, xml_node, "Size", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; size = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->size, size); } } int oss_list_parts_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_list_t *part_list, aos_string_t *partnumber_marker, int *truncated) { int res; mxml_node_t *root; const char next_partnumber_marker_xml_path[] = "NextPartNumberMarker"; const char truncated_xml_path[] = "IsTruncated"; const char parts_xml_path[] = "Part"; char *next_partnumber_marker; res = get_xmldoc(bc, &root); if (res == AOSE_OK) { next_partnumber_marker = get_xmlnode_value(p, root, next_partnumber_marker_xml_path); if (next_partnumber_marker) { aos_str_set(partnumber_marker, next_partnumber_marker); } *truncated = get_truncated_from_xml(p, root, truncated_xml_path); oss_list_parts_contents_parse(p, root, parts_xml_path, part_list); mxmlDelete(root); } return res; } void oss_list_multipart_uploads_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path, aos_list_t *upload_list) { mxml_node_t *content_node; oss_list_multipart_upload_content_t *content; content_node = mxmlFindElement(root, root, xml_path, NULL, NULL, MXML_DESCEND); for ( ; content_node != NULL; ) { content = oss_create_list_multipart_upload_content(p); oss_list_multipart_uploads_content_parse(p, content_node, content); aos_list_add_tail(&content->node, upload_list); content_node = mxmlFindElement(content_node, root, xml_path, NULL, NULL, MXML_DESCEND); } } void oss_list_multipart_uploads_content_parse(aos_pool_t *p, mxml_node_t *xml_node, oss_list_multipart_upload_content_t *content) { char *key; char *upload_id; char *initiated; char *node_content; mxml_node_t *node; node = mxmlFindElement(xml_node, xml_node, "Key",NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; key = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->key, key); } node = mxmlFindElement(xml_node, xml_node, "UploadId",NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; upload_id = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->upload_id, upload_id); } node = mxmlFindElement(xml_node, xml_node, "Initiated",NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; initiated = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->initiated, initiated); } } int oss_list_multipart_uploads_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_list_t *upload_list, aos_string_t *key_marker, aos_string_t *upload_id_marker, int *truncated) { int res; mxml_node_t *root; const char next_key_marker_xml_path[] = "NextKeyMarker"; const char next_upload_id_marker_xml_path[] = "NextUploadIdMarker"; const char truncated_xml_path[] = "IsTruncated"; const char uploads_xml_path[] = "Upload"; char *next_key_marker; char *next_upload_id_marker; res = get_xmldoc(bc, &root); if (res == AOSE_OK) { next_key_marker = get_xmlnode_value(p, root, next_key_marker_xml_path); if (next_key_marker) { aos_str_set(key_marker, next_key_marker); } next_upload_id_marker = get_xmlnode_value(p, root, next_upload_id_marker_xml_path); if (next_upload_id_marker) { aos_str_set(upload_id_marker, next_upload_id_marker); } *truncated = get_truncated_from_xml(p, root, truncated_xml_path); oss_list_multipart_uploads_contents_parse(p, root, uploads_xml_path, upload_list); mxmlDelete(root); } return res; } char *build_complete_multipart_upload_xml(aos_pool_t *p, aos_list_t *bc) { char *xml_buff; char *complete_part_xml; aos_string_t xml_doc; mxml_node_t *doc; mxml_node_t *root_node; oss_complete_part_content_t *content; doc = mxmlNewXML("1.0"); root_node = mxmlNewElement(doc, "CompleteMultipartUpload"); aos_list_for_each_entry(oss_complete_part_content_t, content, bc, node) { mxml_node_t *part_node = mxmlNewElement(root_node, "Part"); mxml_node_t *part_number_node = mxmlNewElement(part_node, "PartNumber"); mxml_node_t *etag_node = mxmlNewElement(part_node, "ETag"); mxmlNewText(part_number_node, 0, content->part_number.data); mxmlNewText(etag_node, 0, content->etag.data); } xml_buff = new_xml_buff(doc); if (xml_buff == NULL) { return NULL; } aos_str_set(&xml_doc, xml_buff); complete_part_xml = aos_pstrdup(p, &xml_doc); free(xml_buff); mxmlDelete(doc); return complete_part_xml; } void build_complete_multipart_upload_body(aos_pool_t *p, aos_list_t *part_list, aos_list_t *body) { char *complete_multipart_upload_xml; aos_buf_t *b; complete_multipart_upload_xml = build_complete_multipart_upload_xml(p, part_list); aos_list_init(body); b = aos_buf_pack(p, complete_multipart_upload_xml, strlen(complete_multipart_upload_xml)); aos_list_add_tail(&b->node, body); } char *build_lifecycle_xml(aos_pool_t *p, aos_list_t *lifecycle_rule_list) { char *lifecycle_xml; char *xml_buff; aos_string_t xml_doc; mxml_node_t *doc; mxml_node_t *root_node; oss_lifecycle_rule_content_t *content; doc = mxmlNewXML("1.0"); root_node = mxmlNewElement(doc, "LifecycleConfiguration"); aos_list_for_each_entry(oss_lifecycle_rule_content_t, content, lifecycle_rule_list, node) { mxml_node_t *rule_node = mxmlNewElement(root_node, "Rule"); mxml_node_t *id_node = mxmlNewElement(rule_node, "ID"); mxml_node_t *prefix_node = mxmlNewElement(rule_node, "Prefix"); mxml_node_t *status_node = mxmlNewElement(rule_node, "Status"); mxml_node_t *expire_node = mxmlNewElement(rule_node, "Expiration"); mxmlNewText(id_node, 0, content->id.data); mxmlNewText(prefix_node, 0, content->prefix.data); mxmlNewText(status_node, 0, content->status.data); if (content->days != INT_MAX) { char value_str[64]; mxml_node_t *days_node = mxmlNewElement(expire_node, "Days"); apr_snprintf(value_str, sizeof(value_str), "%d", content->days); mxmlNewText(days_node, 0, value_str); } else if (content->date.len != 0 && strcmp(content->date.data, "") != 0) { mxml_node_t *date_node = mxmlNewElement(expire_node, "Date"); mxmlNewText(date_node, 0, content->date.data); } } xml_buff = new_xml_buff(doc); if (xml_buff == NULL) { return NULL; } aos_str_set(&xml_doc, xml_buff); lifecycle_xml = aos_pstrdup(p, &xml_doc); free(xml_buff); mxmlDelete(doc); return lifecycle_xml; } void build_lifecycle_body(aos_pool_t *p, aos_list_t *lifecycle_rule_list, aos_list_t *body) { char *lifecycle_xml; aos_buf_t *b; lifecycle_xml = build_lifecycle_xml(p, lifecycle_rule_list); aos_list_init(body); b = aos_buf_pack(p, lifecycle_xml, strlen(lifecycle_xml)); aos_list_add_tail(&b->node, body); } int oss_lifecycle_rules_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_list_t *lifecycle_rule_list) { int res; mxml_node_t *root = NULL; const char rule_xml_path[] = "Rule"; res = get_xmldoc(bc, &root); if (res == AOSE_OK) { oss_lifecycle_rule_contents_parse(p, root, rule_xml_path, lifecycle_rule_list); mxmlDelete(root); } return res; } void oss_lifecycle_rule_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path, aos_list_t *lifecycle_rule_list) { mxml_node_t *node; oss_lifecycle_rule_content_t *content; node = mxmlFindElement(root, root, xml_path, NULL, NULL, MXML_DESCEND); for ( ; node != NULL; ) { content = oss_create_lifecycle_rule_content(p); oss_lifecycle_rule_content_parse(p, node, content); aos_list_add_tail(&content->node, lifecycle_rule_list); node = mxmlFindElement(node, root, xml_path, NULL, NULL, MXML_DESCEND); } } void oss_lifecycle_rule_content_parse(aos_pool_t *p, mxml_node_t * xml_node, oss_lifecycle_rule_content_t *content) { char *id; char *prefix; char *status; char *node_content; mxml_node_t *node; node = mxmlFindElement(xml_node, xml_node, "ID",NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; id = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->id, id); } node = mxmlFindElement(xml_node, xml_node, "Prefix",NULL, NULL,MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; prefix = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->prefix, prefix); } node = mxmlFindElement(xml_node, xml_node, "Status",NULL, NULL,MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; status = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->status, status); } node = mxmlFindElement(xml_node, xml_node, "Expiration",NULL, NULL,MXML_DESCEND); if (NULL != node) { oss_lifecycle_rule_expire_parse(p, node, content); } } void oss_lifecycle_rule_expire_parse(aos_pool_t *p, mxml_node_t * xml_node, oss_lifecycle_rule_content_t *content) { char* days; char *date; mxml_node_t *node; char *node_content; node = mxmlFindElement(xml_node, xml_node, "Days", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; days = apr_pstrdup(p, (char *)node_content); content->days = atoi(days); } node = mxmlFindElement(xml_node, xml_node, "Date", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; date = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->date, date); } } void oss_delete_objects_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path, aos_list_t *object_list) { mxml_node_t *node; node = mxmlFindElement(root, root, xml_path, NULL, NULL, MXML_DESCEND); for ( ; node != NULL; ) { oss_object_key_t *content = oss_create_oss_object_key(p); oss_object_key_parse(p, node, content); aos_list_add_tail(&content->node, object_list); node = mxmlFindElement(node, root, xml_path, NULL, NULL, MXML_DESCEND); } } void oss_object_key_parse(aos_pool_t *p, mxml_node_t * xml_node, oss_object_key_t *content) { char *key; char *encoded_key; char *node_content; mxml_node_t *node; node = mxmlFindElement(xml_node, xml_node, "Key",NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; encoded_key = (char*)node_content; key = (char *) aos_palloc(p, strlen(encoded_key)); aos_url_decode(encoded_key, key); aos_str_set(&content->key, key); } } int oss_delete_objects_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_list_t *object_list) { int res; mxml_node_t *root = NULL; const char deleted_xml_path[] = "Deleted"; res = get_xmldoc(bc, &root); if (res == AOSE_OK) { oss_delete_objects_contents_parse(p, root, deleted_xml_path, object_list); mxmlDelete(root); } return res; } void oss_publish_url_parse(aos_pool_t *p, mxml_node_t *node, oss_live_channel_publish_url_t *content) { char *url; char *node_content; if (NULL != node) { node_content = node->child->value.opaque; url = apr_pstrdup(p, node_content); aos_str_set(&content->publish_url, url); } } void oss_play_url_parse(aos_pool_t *p, mxml_node_t *node, oss_live_channel_play_url_t *content) { char *url; char *node_content; if (NULL != node) { node_content = node->child->value.opaque; url = apr_pstrdup(p, node_content); aos_str_set(&content->play_url, url); } } void oss_publish_urls_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path, aos_list_t *publish_xml_list) { mxml_node_t *node; node = mxmlFindElement(root, root, xml_path, NULL, NULL, MXML_DESCEND); for ( ; node != NULL; ) { oss_live_channel_publish_url_t *content = oss_create_live_channel_publish_url(p); oss_publish_url_parse(p, node, content); aos_list_add_tail(&content->node, publish_xml_list); node = mxmlFindElement(node, root, xml_path, NULL, NULL, MXML_DESCEND); } } void oss_play_urls_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path, aos_list_t *play_xml_list) { mxml_node_t *node; node = mxmlFindElement(root, root, xml_path, NULL, NULL, MXML_DESCEND); for ( ; node != NULL; ) { oss_live_channel_play_url_t *content = oss_create_live_channel_play_url(p); oss_play_url_parse(p, node, content); aos_list_add_tail(&content->node, play_xml_list); node = mxmlFindElement(node, root, xml_path, NULL, NULL, MXML_DESCEND); } } void oss_create_live_channel_content_parse(aos_pool_t *p, mxml_node_t *root, const char *publish_xml_path, aos_list_t *publish_url_list, const char *play_xml_path, aos_list_t *play_url_list) { mxml_node_t *node; const char url_xml_path[] = "Url"; node = mxmlFindElement(root, root, publish_xml_path, NULL, NULL, MXML_DESCEND); if (NULL != node) { oss_publish_urls_contents_parse(p, node, url_xml_path, publish_url_list); } node = mxmlFindElement(root, root, play_xml_path, NULL, NULL, MXML_DESCEND); if (NULL != node) { oss_play_urls_contents_parse(p, node, url_xml_path, play_url_list); } } int oss_create_live_channel_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_list_t *publish_url_list, aos_list_t *play_url_list) { int res; mxml_node_t *root = NULL; const char publish_urls_xml_path[] = "PublishUrls"; const char play_urls_xml_path[] = "PlayUrls"; res = get_xmldoc(bc, &root); if (res == AOSE_OK) { oss_create_live_channel_content_parse(p, root, publish_urls_xml_path, publish_url_list, play_urls_xml_path, play_url_list); mxmlDelete(root); } return res; } char *build_create_live_channel_xml(aos_pool_t *p, oss_live_channel_configuration_t *config) { char *xml_buff; char *complete_part_xml; aos_string_t xml_doc; mxml_node_t *doc; mxml_node_t *root_node; char value_str[64]; mxml_node_t *description_node; mxml_node_t *status_node; mxml_node_t *target_node; mxml_node_t *type_node; mxml_node_t *frag_duration_node; mxml_node_t *frag_count_node; mxml_node_t *play_list_node; doc = mxmlNewXML("1.0"); root_node = mxmlNewElement(doc, "LiveChannelConfiguration"); description_node = mxmlNewElement(root_node, "Description"); mxmlNewText(description_node, 0, config->description.data); status_node = mxmlNewElement(root_node, "Status"); mxmlNewText(status_node, 0, config->status.data); // target target_node = mxmlNewElement(root_node, "Target"); type_node = mxmlNewElement(target_node, "Type"); mxmlNewText(type_node, 0, config->target.type.data); apr_snprintf(value_str, sizeof(value_str), "%d", config->target.frag_duration); frag_duration_node = mxmlNewElement(target_node, "FragDuration"); mxmlNewText(frag_duration_node, 0, value_str); apr_snprintf(value_str, sizeof(value_str), "%d", config->target.frag_count); frag_count_node = mxmlNewElement(target_node, "FragCount"); mxmlNewText(frag_count_node, 0, value_str); play_list_node = mxmlNewElement(target_node, "PlaylistName"); mxmlNewText(play_list_node, 0, config->target.play_list_name.data); // dump xml_buff = new_xml_buff(doc); if (xml_buff == NULL) { return NULL; } aos_str_set(&xml_doc, xml_buff); complete_part_xml = aos_pstrdup(p, &xml_doc); free(xml_buff); mxmlDelete(doc); return complete_part_xml; } void build_create_live_channel_body(aos_pool_t *p, oss_live_channel_configuration_t *config, aos_list_t *body) { char *live_channel_xml; aos_buf_t *b; live_channel_xml = build_create_live_channel_xml(p, config); aos_list_init(body); b = aos_buf_pack(p, live_channel_xml, strlen(live_channel_xml)); aos_list_add_tail(&b->node, body); } void oss_live_channel_info_target_content_parse(aos_pool_t *p, mxml_node_t *xml_node, oss_live_channel_target_t *target) { char *type; char *frag_duration; char *frag_count; char *play_list; char *node_content; mxml_node_t *node; node = mxmlFindElement(xml_node, xml_node, "Type", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; type = apr_pstrdup(p, node_content); aos_str_set(&target->type, type); } node = mxmlFindElement(xml_node, xml_node, "FragDuration", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; frag_duration = apr_pstrdup(p, node_content); target->frag_duration = atoi(frag_duration); } node = mxmlFindElement(xml_node, xml_node, "FragCount", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; frag_count = apr_pstrdup(p, node_content); target->frag_count = atoi(frag_count); } node = mxmlFindElement(xml_node, xml_node, "PlaylistName",NULL, NULL,MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; play_list = apr_pstrdup(p, node_content); aos_str_set(&target->play_list_name, play_list); } } void oss_live_channel_info_content_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path, oss_live_channel_configuration_t *info) { mxml_node_t *cofig_node; mxml_node_t *target_node; cofig_node = mxmlFindElement(root, root, xml_path, NULL, NULL, MXML_DESCEND); if (NULL != cofig_node) { char *description; char *status; char *node_content; mxml_node_t *node; node = mxmlFindElement(cofig_node, cofig_node, "Description", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; description = apr_pstrdup(p, node_content); aos_str_set(&info->description, description); } node = mxmlFindElement(cofig_node, cofig_node, "Status", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; status = apr_pstrdup(p, node_content); aos_str_set(&info->status, status); } target_node = mxmlFindElement(cofig_node, cofig_node, "Target", NULL, NULL, MXML_DESCEND); if (NULL != target_node) { oss_live_channel_info_target_content_parse(p, target_node, &info->target); } } } int oss_live_channel_info_parse_from_body(aos_pool_t *p, aos_list_t *bc, oss_live_channel_configuration_t *info) { int res; mxml_node_t *root; const char xml_path[] = "LiveChannelConfiguration"; res = get_xmldoc(bc, &root); if (res == AOSE_OK) { oss_live_channel_info_content_parse(p, root, xml_path, info); mxmlDelete(root); } return res; } void oss_live_channel_stat_video_content_parse(aos_pool_t *p, mxml_node_t *xml_node, oss_video_stat_t *video_stat) { char *width; char *height; char *frame_rate; char *band_width; char *codec; char *node_content; mxml_node_t *node; node = mxmlFindElement(xml_node, xml_node, "Width", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; width = apr_pstrdup(p, node_content); video_stat->width = atoi(width); } node = mxmlFindElement(xml_node, xml_node, "Height", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; height = apr_pstrdup(p, node_content); video_stat->height = atoi(height); } node = mxmlFindElement(xml_node, xml_node, "FrameRate", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; frame_rate = apr_pstrdup(p, node_content); video_stat->frame_rate = atoi(frame_rate); } node = mxmlFindElement(xml_node, xml_node, "Bandwidth", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; band_width = apr_pstrdup(p, node_content); video_stat->band_width = atoi(band_width); } node = mxmlFindElement(xml_node, xml_node, "Codec", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; codec = apr_pstrdup(p, node_content); aos_str_set(&video_stat->codec, codec); } } void oss_live_channel_stat_audio_content_parse(aos_pool_t *p, mxml_node_t *xml_node, oss_audio_stat_t *audio_stat) { char *band_width; char *sample_rate; char *codec; char *node_content; mxml_node_t *node; node = mxmlFindElement(xml_node, xml_node, "Bandwidth", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; band_width = apr_pstrdup(p, node_content); audio_stat->band_width = atoi(band_width); } node = mxmlFindElement(xml_node, xml_node, "SampleRate", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; sample_rate = apr_pstrdup(p, node_content); audio_stat->sample_rate = atoi(sample_rate); } node = mxmlFindElement(xml_node, xml_node, "Codec", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; codec = apr_pstrdup(p, node_content); aos_str_set(&audio_stat->codec, codec); } } void oss_live_channel_stat_content_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path, oss_live_channel_stat_t *stat) { mxml_node_t *stat_node; stat_node = mxmlFindElement(root, root, xml_path, NULL, NULL, MXML_DESCEND); if (NULL != stat_node) { char *status; char *connected_time; char *remote_addr; char *node_content; mxml_node_t *node; node = mxmlFindElement(stat_node, stat_node, "Status", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; status = apr_pstrdup(p, (char *)node_content); aos_str_set(&stat->pushflow_status, status); } node = mxmlFindElement(stat_node, stat_node, "ConnectedTime", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; connected_time = apr_pstrdup(p, (char *)node_content); aos_str_set(&stat->connected_time, connected_time); } node = mxmlFindElement(stat_node, stat_node, "RemoteAddr", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; remote_addr = apr_pstrdup(p, (char *)node_content); aos_str_set(&stat->remote_addr, remote_addr); } node = mxmlFindElement(stat_node, stat_node, "Video", NULL, NULL, MXML_DESCEND); if (NULL != node) { oss_live_channel_stat_video_content_parse(p, node, &stat->video_stat); } node = mxmlFindElement(stat_node, stat_node, "Audio", NULL, NULL, MXML_DESCEND); if (NULL != node) { oss_live_channel_stat_audio_content_parse(p, node, &stat->audio_stat); } } } int oss_live_channel_stat_parse_from_body(aos_pool_t *p, aos_list_t *bc, oss_live_channel_stat_t *stat) { int res; mxml_node_t *root; const char xml_path[] = "LiveChannelStat"; res = get_xmldoc(bc, &root); if (res == AOSE_OK) { oss_live_channel_stat_content_parse(p, root, xml_path, stat); mxmlDelete(root); } return res; } void oss_list_live_channel_content_parse(aos_pool_t *p, mxml_node_t *xml_node, oss_live_channel_content_t *content) { char *name; char *description; char *status; char *last_modified; char *node_content; mxml_node_t *node; node = mxmlFindElement(xml_node, xml_node, "Name", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; name = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->name, name); } node = mxmlFindElement(xml_node, xml_node, "Description", NULL, NULL, MXML_DESCEND); if (NULL != node) { if (NULL != node->child) { node_content = node->child->value.opaque; description = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->description, description); } else { aos_str_set(&content->description, ""); } } node = mxmlFindElement(xml_node, xml_node, "Status", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; status = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->status, status); } node = mxmlFindElement(xml_node, xml_node, "LastModified", NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; last_modified = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->last_modified, last_modified); } node = mxmlFindElement(xml_node, xml_node, "PublishUrls", NULL, NULL, MXML_DESCEND); if (NULL != node) { oss_publish_urls_contents_parse(p, node, "Url", &content->publish_url_list); } node = mxmlFindElement(xml_node, xml_node, "PlayUrls", NULL, NULL, MXML_DESCEND); if (NULL != node) { oss_play_urls_contents_parse(p, node, "Url", &content->play_url_list); } } void oss_list_live_channel_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path, aos_list_t *live_channel_list) { mxml_node_t *content_node; oss_live_channel_content_t *content; content_node = mxmlFindElement(root, root, xml_path, NULL, NULL, MXML_DESCEND); for ( ; content_node != NULL; ) { content = oss_create_list_live_channel_content(p); oss_list_live_channel_content_parse(p, content_node, content); aos_list_add_tail(&content->node, live_channel_list); content_node = mxmlFindElement(content_node, root, xml_path, NULL, NULL, MXML_DESCEND); } } int oss_list_live_channel_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_list_t *live_channel_list, aos_string_t *next_marker, int *truncated) { int res; mxml_node_t *root; const char next_marker_xml_path[] = "NextMarker"; const char truncated_xml_path[] = "IsTruncated"; const char live_channel_xml_path[] = "LiveChannel"; char *next_partnumber_marker; res = get_xmldoc(bc, &root); if (res == AOSE_OK) { next_partnumber_marker = get_xmlnode_value(p, root, next_marker_xml_path); if (next_partnumber_marker) { aos_str_set(next_marker, next_partnumber_marker); } *truncated = get_truncated_from_xml(p, root, truncated_xml_path); oss_list_live_channel_contents_parse(p, root, live_channel_xml_path, live_channel_list); mxmlDelete(root); } return res; } void oss_live_channel_history_content_parse(aos_pool_t *p, mxml_node_t * xml_node, oss_live_record_content_t *content) { char *start_time; char *end_time; char *remote_addr; char *node_content; mxml_node_t *node; node = mxmlFindElement(xml_node, xml_node, "StartTime",NULL, NULL, MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; start_time = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->start_time, start_time); } node = mxmlFindElement(xml_node, xml_node, "EndTime",NULL, NULL,MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; end_time = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->end_time, end_time); } node = mxmlFindElement(xml_node, xml_node, "RemoteAddr",NULL, NULL,MXML_DESCEND); if (NULL != node) { node_content = node->child->value.opaque; remote_addr = apr_pstrdup(p, (char *)node_content); aos_str_set(&content->remote_addr, remote_addr); } } void oss_live_channel_history_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path, aos_list_t *live_record_list) { mxml_node_t *node; oss_live_record_content_t *content; node = mxmlFindElement(root, root, xml_path, NULL, NULL, MXML_DESCEND); for ( ; node != NULL; ) { content = oss_create_live_record_content(p); oss_live_channel_history_content_parse(p, node, content); aos_list_add_tail(&content->node, live_record_list); node = mxmlFindElement(node, root, xml_path, NULL, NULL, MXML_DESCEND); } } int oss_live_channel_history_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_list_t *live_record_list) { int res; mxml_node_t *root = NULL; const char rule_xml_path[] = "LiveRecord"; res = get_xmldoc(bc, &root); if (res == AOSE_OK) { oss_live_channel_history_contents_parse(p, root, rule_xml_path, live_record_list); mxmlDelete(root); } return res; } char *build_objects_xml(aos_pool_t *p, aos_list_t *object_list, const char *quiet) { char *object_xml; char *xml_buff; aos_string_t xml_doc; mxml_node_t *doc; mxml_node_t *root_node; oss_object_key_t *content; mxml_node_t *quiet_node; doc = mxmlNewXML("1.0"); root_node = mxmlNewElement(doc, "Delete"); quiet_node = mxmlNewElement(root_node, "Quiet"); mxmlNewText(quiet_node, 0, quiet); aos_list_for_each_entry(oss_object_key_t, content, object_list, node) { mxml_node_t *object_node = mxmlNewElement(root_node, "Object"); mxml_node_t *key_node = mxmlNewElement(object_node, "Key"); mxmlNewText(key_node, 0, content->key.data); } xml_buff = new_xml_buff(doc); if (xml_buff == NULL) { return NULL; } aos_str_set(&xml_doc, xml_buff); object_xml = aos_pstrdup(p, &xml_doc); free(xml_buff); mxmlDelete(doc); return object_xml; } void build_delete_objects_body(aos_pool_t *p, aos_list_t *object_list, int is_quiet, aos_list_t *body) { char *objects_xml; aos_buf_t *b; char *quiet; quiet = is_quiet > 0 ? "true": "false"; objects_xml = build_objects_xml(p, object_list, quiet); aos_list_init(body); b = aos_buf_pack(p, objects_xml, strlen(objects_xml)); aos_list_add_tail(&b->node, body); } mxml_node_t *set_xmlnode_value_str(mxml_node_t *parent, const char *name, const aos_string_t *value) { mxml_node_t *node; char buff[AOS_MAX_XML_NODE_VALUE_LEN]; node = mxmlNewElement(parent, name); apr_snprintf(buff, AOS_MAX_XML_NODE_VALUE_LEN, "%.*s", value->len, value->data); return mxmlNewText(node, 0, buff); } mxml_node_t *set_xmlnode_value_int(mxml_node_t *parent, const char *name, int value) { mxml_node_t *node; char buff[AOS_MAX_INT64_STRING_LEN]; node = mxmlNewElement(parent, name); apr_snprintf(buff, AOS_MAX_INT64_STRING_LEN, "%d", value); return mxmlNewText(node, 0, buff); } mxml_node_t *set_xmlnode_value_int64(mxml_node_t *parent, const char *name, int64_t value) { mxml_node_t *node; char buff[AOS_MAX_INT64_STRING_LEN]; node = mxmlNewElement(parent, name); apr_snprintf(buff, AOS_MAX_INT64_STRING_LEN, "%" APR_INT64_T_FMT, value); return mxmlNewText(node, 0, buff); } int get_xmlnode_value_str(aos_pool_t *p, mxml_node_t *xml_node, const char *xml_path, aos_string_t *value) { char *node_content; node_content = get_xmlnode_value(p, xml_node, xml_path); if (NULL == node_content) { return AOS_FALSE; } aos_str_set(value, node_content); return AOS_TRUE; } int get_xmlnode_value_int(aos_pool_t *p, mxml_node_t *xml_node, const char *xml_path, int *value) { char *node_content; node_content = get_xmlnode_value(p, xml_node, xml_path); if (NULL == node_content) { return AOS_FALSE; } *value = atoi(node_content); return AOS_TRUE; } int get_xmlnode_value_int64(aos_pool_t *p, mxml_node_t *xml_node, const char *xml_path, int64_t *value) { char *node_content; node_content = get_xmlnode_value(p, xml_node, xml_path); if (NULL == node_content) { return AOS_FALSE; } *value = aos_atoi64(node_content); return AOS_TRUE; } char *oss_build_checkpoint_xml(aos_pool_t *p, const oss_checkpoint_t *checkpoint) { char *checkpoint_xml; char *xml_buff; aos_string_t xml_doc; mxml_node_t *doc; mxml_node_t *root_node; mxml_node_t *local_node; mxml_node_t *object_node; mxml_node_t *cpparts_node; mxml_node_t *parts_node; int i = 0; doc = mxmlNewXML("1.0"); root_node = mxmlNewElement(doc, "Checkpoint"); // MD5 set_xmlnode_value_str(root_node, "MD5", &checkpoint->md5); // Type set_xmlnode_value_int(root_node, "Type", checkpoint->cp_type); // LocalFile local_node = mxmlNewElement(root_node, "LocalFile"); // LocalFile.Path set_xmlnode_value_str(local_node, "Path", &checkpoint->file_path); // LocalFile.Size set_xmlnode_value_int64(local_node, "Size", checkpoint->file_size); // LocalFile.LastModified set_xmlnode_value_int64(local_node, "LastModified", checkpoint->file_last_modified); // LocalFile.MD5 set_xmlnode_value_str(local_node, "MD5", &checkpoint->file_md5); // Object object_node = mxmlNewElement(root_node, "Object"); // Object.Key set_xmlnode_value_str(object_node, "Key", &checkpoint->object_name); // Object.Size set_xmlnode_value_int64(object_node, "Size", checkpoint->object_size); // Object.LastModified set_xmlnode_value_str(object_node, "LastModified", &checkpoint->object_last_modified); // Object.ETag set_xmlnode_value_str(object_node, "ETag", &checkpoint->object_etag); // UploadId set_xmlnode_value_str(root_node, "UploadId", &checkpoint->upload_id); // CpParts cpparts_node = mxmlNewElement(root_node, "CPParts"); // CpParts.Number set_xmlnode_value_int(cpparts_node, "Number", checkpoint->part_num); // CpParts.Size set_xmlnode_value_int64(cpparts_node, "Size", checkpoint->part_size); // CpParts.Parts parts_node = mxmlNewElement(cpparts_node, "Parts"); for (i = 0; i < checkpoint->part_num; i++) { mxml_node_t *part_node = mxmlNewElement(parts_node, "Part"); set_xmlnode_value_int(part_node, "Index", checkpoint->parts[i].index); set_xmlnode_value_int64(part_node, "Offset", checkpoint->parts[i].offset); set_xmlnode_value_int64(part_node, "Size", checkpoint->parts[i].size); set_xmlnode_value_int(part_node, "Completed", checkpoint->parts[i].completed); set_xmlnode_value_str(part_node, "ETag", &checkpoint->parts[i].etag); } // dump xml_buff = new_xml_buff(doc); if (xml_buff == NULL) { return NULL; } aos_str_set(&xml_doc, xml_buff); checkpoint_xml = aos_pstrdup(p, &xml_doc); free(xml_buff); mxmlDelete(doc); return checkpoint_xml; } int oss_checkpoint_parse_from_body(aos_pool_t *p, const char *xml_body, oss_checkpoint_t *checkpoint) { mxml_node_t *root; mxml_node_t *local_node; mxml_node_t *object_node; mxml_node_t *cpparts_node; mxml_node_t *parts_node; mxml_node_t *node; int index = 0; root = mxmlLoadString(NULL, xml_body, MXML_OPAQUE_CALLBACK); if (NULL == root) { return AOSE_XML_PARSE_ERROR; } // MD5 get_xmlnode_value_str(p, root, "MD5", &checkpoint->md5); // Type get_xmlnode_value_int(p, root, "Type", &checkpoint->cp_type); // LocalFile local_node = mxmlFindElement(root, root, "LocalFile", NULL, NULL, MXML_DESCEND); // LocalFile.Path get_xmlnode_value_str(p, local_node, "Path", &checkpoint->file_path); // LocalFile.Size get_xmlnode_value_int64(p, local_node, "Size", &checkpoint->file_size); // LocalFile.LastModified get_xmlnode_value_int64(p, local_node, "LastModified", &checkpoint->file_last_modified); // LocalFile.MD5 get_xmlnode_value_str(p, local_node, "MD5", &checkpoint->file_md5); // Object object_node = mxmlFindElement(root, root, "Object", NULL, NULL, MXML_DESCEND); // Object.Key get_xmlnode_value_str(p, object_node, "Key", &checkpoint->object_name); // Object.Size get_xmlnode_value_int64(p, object_node, "Size", &checkpoint->object_size); // Object.LastModified get_xmlnode_value_str(p, object_node, "LastModified", &checkpoint->object_last_modified); // Object.ETag get_xmlnode_value_str(p, object_node, "ETag", &checkpoint->object_etag); // UploadId get_xmlnode_value_str(p, root, "UploadId", &checkpoint->upload_id); // CpParts cpparts_node = mxmlFindElement(root, root, "CPParts", NULL, NULL, MXML_DESCEND); // CpParts.Number get_xmlnode_value_int(p, cpparts_node, "Number", &checkpoint->part_num); // CpParts.Size get_xmlnode_value_int64(p, cpparts_node, "Size", &checkpoint->part_size); // CpParts.Parts parts_node = mxmlFindElement(cpparts_node, cpparts_node, "Parts", NULL, NULL, MXML_DESCEND); node = mxmlFindElement(parts_node, parts_node, "Part", NULL, NULL, MXML_DESCEND); for ( ; node != NULL; ) { get_xmlnode_value_int(p, node, "Index", &index); checkpoint->parts[index].index = index; get_xmlnode_value_int64(p, node, "Offset", &checkpoint->parts[index].offset); get_xmlnode_value_int64(p, node, "Size", &checkpoint->parts[index].size); get_xmlnode_value_int(p, node, "Completed", &checkpoint->parts[index].completed); get_xmlnode_value_str(p, node, "ETag", &checkpoint->parts[index].etag); node = mxmlFindElement(node, parts_node, "Part", NULL, NULL, MXML_DESCEND); } mxmlDelete(root); return AOSE_OK; }