2018-09-18 11:14:11 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
|
|
|
|
#include <libxml/parser.h>
|
|
|
|
|
#include "tango_cache_xml.h"
|
|
|
|
|
|
|
|
|
|
bool parse_uploadID_xml(const char *content, int len, char **uploadID)
|
|
|
|
|
{
|
|
|
|
|
xmlDoc *pdoc;
|
|
|
|
|
xmlNode *pcur;
|
|
|
|
|
|
|
|
|
|
if((pdoc = xmlParseMemory(content, len)) == NULL)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if((pcur = xmlDocGetRootElement(pdoc)) == NULL)
|
|
|
|
|
{
|
|
|
|
|
xmlFreeDoc(pdoc);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while(pcur->type != XML_ELEMENT_NODE)
|
|
|
|
|
pcur = pcur->next;
|
|
|
|
|
if(xmlStrcmp(pcur->name, (const xmlChar *)"InitiateMultipartUploadResult"))
|
|
|
|
|
{
|
|
|
|
|
xmlFreeDoc(pdoc);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
pcur = pcur->children;
|
|
|
|
|
while(pcur != NULL)
|
|
|
|
|
{
|
|
|
|
|
if(pcur->type != XML_ELEMENT_NODE || xmlStrcmp(pcur->name, (const xmlChar *)"UploadId"))
|
|
|
|
|
{
|
|
|
|
|
pcur = pcur->next;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
*uploadID = (char *)xmlNodeGetContent(pcur);
|
|
|
|
|
xmlFreeDoc(pdoc);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xmlFreeDoc(pdoc);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-11 16:35:13 +08:00
|
|
|
void construct_complete_xml(struct tango_cache_ctx *ctx, char **xml, int *len)
|
2018-09-18 11:14:11 +08:00
|
|
|
{
|
2018-09-21 14:50:41 +08:00
|
|
|
struct multipart_etag_list *etag;
|
2018-09-18 11:14:11 +08:00
|
|
|
xmlDoc *pdoc;
|
|
|
|
|
xmlNode *root, *child;
|
|
|
|
|
char number[20];
|
|
|
|
|
|
|
|
|
|
pdoc = xmlNewDoc((const xmlChar *)"1.0");
|
|
|
|
|
root = xmlNewNode(NULL, (const xmlChar *)"CompleteMultipartUpload");
|
|
|
|
|
xmlNewProp(root, (const xmlChar *)"xmlns",(const xmlChar *)"http://s3.amazonaws.com/doc/2006-03-01/");
|
|
|
|
|
xmlDocSetRootElement(pdoc, root);
|
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
TAILQ_FOREACH(etag, &ctx->put.etag_head, node)
|
2018-09-18 11:14:11 +08:00
|
|
|
{
|
2018-09-21 14:50:41 +08:00
|
|
|
sprintf(number, "%u", etag->part_number);
|
2018-09-18 11:14:11 +08:00
|
|
|
child = xmlNewChild(root, NULL, (const xmlChar*)"Part", NULL);
|
2018-09-21 14:50:41 +08:00
|
|
|
xmlNewChild(child, NULL, (const xmlChar*)"ETag", (const xmlChar*)etag->etag);
|
2018-09-18 11:14:11 +08:00
|
|
|
xmlNewChild(child, NULL, (const xmlChar*)"PartNumber", (const xmlChar*)number);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xmlDocDumpFormatMemory(pdoc, (xmlChar **)xml, len, 1);
|
|
|
|
|
xmlFreeDoc(pdoc);
|
2018-10-11 16:35:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void fill_multidelete_xml_errcode(xmlNode *error, char *out, int size)
|
|
|
|
|
{
|
|
|
|
|
xmlChar *errcode;
|
|
|
|
|
xmlNode *child = error->children;
|
|
|
|
|
|
|
|
|
|
while(child != NULL)
|
|
|
|
|
{
|
|
|
|
|
if(child->type != XML_ELEMENT_NODE || xmlStrcmp(child->name, (const xmlChar *)"Message"))
|
|
|
|
|
{
|
|
|
|
|
child = child->next;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
errcode = xmlNodeGetContent(child);
|
|
|
|
|
snprintf(out, size, "%s", (char *)errcode);
|
|
|
|
|
xmlFree(errcode);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool parse_multidelete_xml(const char *xml, int len, u_int32_t *errnum, char *errstr, int size)
|
|
|
|
|
{
|
|
|
|
|
xmlDoc *pdoc;
|
|
|
|
|
xmlNode *pcur;
|
|
|
|
|
int errornum=0;
|
|
|
|
|
|
|
|
|
|
if((pdoc = xmlParseMemory(xml, len)) == NULL)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if((pcur = xmlDocGetRootElement(pdoc)) == NULL)
|
|
|
|
|
{
|
|
|
|
|
xmlFreeDoc(pdoc);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while(pcur->type != XML_ELEMENT_NODE)
|
|
|
|
|
pcur = pcur->next;
|
|
|
|
|
if(xmlStrcmp(pcur->name, (const xmlChar *)"DeleteResult"))
|
|
|
|
|
{
|
|
|
|
|
xmlFreeDoc(pdoc);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
pcur = pcur->children;
|
|
|
|
|
while(pcur != NULL)
|
|
|
|
|
{
|
|
|
|
|
if(pcur->type != XML_ELEMENT_NODE || xmlStrcmp(pcur->name, (const xmlChar *)"Error"))
|
|
|
|
|
{
|
|
|
|
|
pcur = pcur->next;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if(errornum == 0)
|
|
|
|
|
{
|
|
|
|
|
fill_multidelete_xml_errcode(pcur, errstr, size);
|
|
|
|
|
}
|
|
|
|
|
errornum++;
|
|
|
|
|
pcur = pcur->next;
|
|
|
|
|
}
|
|
|
|
|
*errnum = errornum;
|
|
|
|
|
|
|
|
|
|
xmlFreeDoc(pdoc);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void construct_multiple_delete_xml(const char *bucket, char *key[], u_int32_t num, int is_hash, char **xml, size_t *len)
|
|
|
|
|
{
|
|
|
|
|
xmlDoc *pdoc;
|
|
|
|
|
xmlNode *root, *child;
|
|
|
|
|
int xmllen;
|
|
|
|
|
|
|
|
|
|
pdoc = xmlNewDoc((const xmlChar *)"1.0");
|
|
|
|
|
root = xmlNewNode(NULL, (const xmlChar *)"Delete");
|
|
|
|
|
xmlDocSetRootElement(pdoc, root);
|
|
|
|
|
|
|
|
|
|
xmlNewChild(root, NULL, (const xmlChar*)"Quiet", (const xmlChar*)"true");
|
|
|
|
|
|
|
|
|
|
if(is_hash)
|
|
|
|
|
{
|
|
|
|
|
char hashkey[72], sha256[72];
|
|
|
|
|
for(u_int32_t i=0; i<num; i++)
|
|
|
|
|
{
|
|
|
|
|
child = xmlNewChild(root, NULL, (const xmlChar*)"Object", NULL);
|
|
|
|
|
caculate_sha256(key[i], strlen(key[i]), sha256, 72);
|
|
|
|
|
snprintf(hashkey, 256, "%c%c/%c%c/%s", sha256[0], sha256[1], sha256[2], sha256[3], sha256+4);
|
|
|
|
|
xmlNewChild(child, NULL, (const xmlChar*)"Key", (const xmlChar*)hashkey);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for(u_int32_t i=0; i<num; i++)
|
|
|
|
|
{
|
|
|
|
|
child = xmlNewChild(root, NULL, (const xmlChar*)"Object", NULL);
|
|
|
|
|
xmlNewChild(child, NULL, (const xmlChar*)"Key", (const xmlChar*)key[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
xmlDocDumpFormatMemoryEnc(pdoc, (xmlChar **)xml, &xmllen, "UTF-8", 1);
|
|
|
|
|
xmlFreeDoc(pdoc);
|
|
|
|
|
*len = xmllen;
|
2018-09-18 11:14:11 +08:00
|
|
|
}
|
|
|
|
|
|