mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2024-12-23 17:28:56 +00:00
Add simple XML parsing wrapper
Also simplify check_region_error.
This commit is contained in:
parent
21321a9d96
commit
b8ff6a647e
75
src/curl.cpp
75
src/curl.cpp
@ -31,9 +31,6 @@
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
#include <curl/curl.h>
|
||||
#include <libxml/xpath.h>
|
||||
#include <libxml/xpathInternals.h>
|
||||
#include <libxml/tree.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
@ -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<const char *>(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<const char*>(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<const char *>(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;
|
||||
}
|
||||
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<const char*>(cur_node->name);
|
||||
if(cur_node->children){
|
||||
if(XML_TEXT_NODE == cur_node->children->type){
|
||||
if(elementName == "ETag") {
|
||||
string etag = reinterpret_cast<const char *>(cur_node->children->content);
|
||||
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));
|
||||
}
|
||||
partdata.etaglist->at(partdata.etagpos).assign(etag);
|
||||
partdata.uploaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
S3FS_XMLFREEDOC(doc);
|
||||
|
||||
delete bodydata;
|
||||
bodydata = NULL;
|
||||
|
@ -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);
|
||||
|
37
src/s3fs.cpp
37
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.
|
||||
// "<Error><Code>AuthorizationHeaderMalformed</Code><Message>The authorization header is
|
||||
// malformed; the region 'us-east-1' is wrong; expecting 'ap-northeast-1'</Message>
|
||||
// <Region>ap-northeast-1</Region><RequestId>...</RequestId><HostId>...</HostId>
|
||||
// "<Error>
|
||||
// <Code>AuthorizationHeaderMalformed</Code>
|
||||
// <Message>The authorization header is malformed; the region 'us-east-1' is wrong; expecting 'ap-northeast-1'</Message>
|
||||
// <Region>ap-northeast-1</Region>
|
||||
// <RequestId>...</RequestId>
|
||||
// <HostId>...</HostId>
|
||||
// </Error>"
|
||||
//
|
||||
// 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, "<Message>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
|
||||
|
@ -31,6 +31,9 @@
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <libxml/xpath.h>
|
||||
#include <libxml/xpathInternals.h>
|
||||
#include <libxml/tree.h>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
@ -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<const char *>(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<const char*>(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<const char *>(cur_node->children->content);
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
S3FS_XMLFREEDOC(doc);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Help
|
||||
//-------------------------------------------------------------------
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user