diff --git a/src/curl.cpp b/src/curl.cpp index 8960293..ae44151 100644 --- a/src/curl.cpp +++ b/src/curl.cpp @@ -31,9 +31,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -2531,50 +2528,6 @@ string S3fsCurl::CalcSignature(const string& method, const string& canonical_uri return Signature; } -// XML in BodyData has UploadId, Parse XML body for UploadId -bool S3fsCurl::GetUploadId(string& upload_id) -{ - bool result = false; - - if(!bodydata){ - return result; - } - upload_id.clear(); - - xmlDocPtr doc; - if(NULL == (doc = xmlReadMemory(bodydata->str(), bodydata->size(), "", NULL, 0))){ - return result; - } - if(NULL == doc->children){ - S3FS_XMLFREEDOC(doc); - return result; - } - for(xmlNodePtr cur_node = doc->children->children; NULL != cur_node; cur_node = cur_node->next){ - // For DEBUG - // string cur_node_name(reinterpret_cast(cur_node->name)); - // printf("cur_node_name: %s\n", cur_node_name.c_str()); - - if(XML_ELEMENT_NODE == cur_node->type){ - string elementName = reinterpret_cast(cur_node->name); - // For DEBUG - // printf("elementName: %s\n", elementName.c_str()); - - if(cur_node->children){ - if(XML_TEXT_NODE == cur_node->children->type){ - if(elementName == "UploadId") { - upload_id = reinterpret_cast(cur_node->children->content); - result = true; - break; - } - } - } - } - } - S3FS_XMLFREEDOC(doc); - - return result; -} - void S3fsCurl::insertV4Headers() { string server_path = type == REQTYPE_LISTBUCKET ? "/" : path; @@ -3449,8 +3402,7 @@ int S3fsCurl::PreMultipartPostRequest(const char* tpath, headers_t& meta, string return result; } - // Parse XML body for UploadId - if(!S3fsCurl::GetUploadId(upload_id)){ + if(!simple_parse_xml(bodydata->str(), bodydata->size(), "UploadId", upload_id)){ delete bodydata; bodydata = NULL; return -1; @@ -3793,33 +3745,12 @@ bool S3fsCurl::CopyMultipartPostCallback(S3fsCurl* s3fscurl) bool S3fsCurl::CopyMultipartPostComplete() { - // parse ETag from response - xmlDocPtr doc; - if(NULL == (doc = xmlReadMemory(bodydata->str(), bodydata->size(), "", NULL, 0))){ - return false; + std::string etag; + partdata.uploaded = simple_parse_xml(bodydata->str(), bodydata->size(), "ETag", etag); + if(etag.size() >= 2 && *etag.begin() == '"' && *etag.rbegin() == '"'){ + etag.assign(etag.substr(1, etag.size() - 2)); } - if(NULL == doc->children){ - S3FS_XMLFREEDOC(doc); - return false; - } - for(xmlNodePtr cur_node = doc->children->children; NULL != cur_node; cur_node = cur_node->next){ - if(XML_ELEMENT_NODE == cur_node->type){ - string elementName = reinterpret_cast(cur_node->name); - if(cur_node->children){ - if(XML_TEXT_NODE == cur_node->children->type){ - if(elementName == "ETag") { - string etag = reinterpret_cast(cur_node->children->content); - if(etag.size() >= 2 && *etag.begin() == '"' && *etag.rbegin() == '"'){ - etag.assign(etag.substr(1, etag.size() - 2)); - } - partdata.etaglist->at(partdata.etagpos).assign(etag); - partdata.uploaded = true; - } - } - } - } - } - S3FS_XMLFREEDOC(doc); + partdata.etaglist->at(partdata.etagpos).assign(etag); delete bodydata; bodydata = NULL; diff --git a/src/curl.h b/src/curl.h index 904dce3..25eb180 100644 --- a/src/curl.h +++ b/src/curl.h @@ -379,7 +379,6 @@ class S3fsCurl void insertAuthHeaders(); std::string CalcSignatureV2(const std::string& method, const std::string& strMD5, const std::string& content_type, const std::string& date, const std::string& resource); std::string CalcSignature(const std::string& method, const std::string& canonical_uri, const std::string& query_string, const std::string& strdate, const std::string& payload_hash, const std::string& date8601); - bool GetUploadId(std::string& upload_id); int GetIAMCredentials(void); int UploadMultipartPostSetup(const char* tpath, int part_num, const std::string& upload_id); diff --git a/src/s3fs.cpp b/src/s3fs.cpp index 13e4a16..dcccea7 100644 --- a/src/s3fs.cpp +++ b/src/s3fs.cpp @@ -3766,39 +3766,30 @@ static int s3fs_utility_processing(time_t abort_time) // // If calling with wrong region, s3fs gets following error body as 400 error code. -// "AuthorizationHeaderMalformedThe authorization header is -// malformed; the region 'us-east-1' is wrong; expecting 'ap-northeast-1' -// ap-northeast-1...... +// " +// AuthorizationHeaderMalformed +// The authorization header is malformed; the region 'us-east-1' is wrong; expecting 'ap-northeast-1' +// ap-northeast-1 +// ... +// ... // " // -// So this is cheep codes but s3fs should get correct region automatically. +// So this is cheap code but s3fs should get correct region automatically. // -static bool check_region_error(const char* pbody, const string& currentep, string& expectregion) +static bool check_region_error(const char* pbody, size_t len, string& expectregion) { if(!pbody){ return false; } - const char* region; - const char* regionend; - if(NULL == (region = strcasestr(pbody, "The authorization header is malformed; the region "))){ + + std::string code; + if(!simple_parse_xml(pbody, len, "Code", code) || code != "AuthorizationHeaderMalformed"){ return false; } - // check current endpoint region in body. - if(NULL == (region = strcasestr(region, currentep.c_str()))){ + + if(!simple_parse_xml(pbody, len, "Region", expectregion)){ return false; } - if(NULL == (region = strcasestr(region, "expecting \'"))){ - return false; - } - region += strlen("expecting \'"); - if(NULL == (regionend = strchr(region, '\''))){ - return false; - } - string strtmp(region, (regionend - region)); - if(0 == strtmp.length()){ - return false; - } - expectregion = strtmp; return true; } @@ -3825,7 +3816,7 @@ static int s3fs_check_service() // check region error(for putting message or retrying) BodyData* body = s3fscurl.GetBodyData(); string expectregion; - if(check_region_error(body->str(), endpoint, expectregion)){ + if(check_region_error(body->str(), body->size(), expectregion)){ // [NOTE] // If endpoint is not specified(using us-east-1 region) and // an error is encountered accessing a different region, we diff --git a/src/s3fs_util.cpp b/src/s3fs_util.cpp index 4c88ef3..273a144 100644 --- a/src/s3fs_util.cpp +++ b/src/s3fs_util.cpp @@ -31,6 +31,9 @@ #include #include #include +#include +#include +#include #include #include @@ -972,6 +975,50 @@ bool is_need_check_obj_detail(headers_t& meta) return true; } +bool simple_parse_xml(const char* data, size_t len, const char* key, std::string& value) +{ + bool result = false; + + if(!data || !key){ + return result; + } + value.clear(); + + xmlDocPtr doc; + if(NULL == (doc = xmlReadMemory(data, len, "", NULL, 0))){ + return result; + } + + if(NULL == doc->children){ + S3FS_XMLFREEDOC(doc); + return result; + } + for(xmlNodePtr cur_node = doc->children->children; NULL != cur_node; cur_node = cur_node->next){ + // For DEBUG + // string cur_node_name(reinterpret_cast(cur_node->name)); + // printf("cur_node_name: %s\n", cur_node_name.c_str()); + + if(XML_ELEMENT_NODE == cur_node->type){ + string elementName = reinterpret_cast(cur_node->name); + // For DEBUG + // printf("elementName: %s\n", elementName.c_str()); + + if(cur_node->children){ + if(XML_TEXT_NODE == cur_node->children->type){ + if(elementName == key) { + value = reinterpret_cast(cur_node->children->content); + result = true; + break; + } + } + } + } + } + S3FS_XMLFREEDOC(doc); + + return result; +} + //------------------------------------------------------------------- // Help //------------------------------------------------------------------- diff --git a/src/s3fs_util.h b/src/s3fs_util.h index 1d279e1..a70f000 100644 --- a/src/s3fs_util.h +++ b/src/s3fs_util.h @@ -133,6 +133,7 @@ time_t cvtIAMExpireStringToTime(const char* s); time_t get_lastmodified(const char* s); time_t get_lastmodified(headers_t& meta); bool is_need_check_obj_detail(headers_t& meta); +bool simple_parse_xml(const char* data, size_t len, const char* key, std::string& value); void show_usage(void); void show_help(void);