fixed fallback to sigv2 for bucket create and GCS

This commit is contained in:
Takeshi Nakatani 2015-06-20 04:34:32 +00:00
parent 4d49ace06b
commit 966d229787

View File

@ -804,7 +804,20 @@ static int do_create_bucket(void)
headers_t meta; headers_t meta;
S3fsCurl s3fscurl(true); S3fsCurl s3fscurl(true);
return s3fscurl.PutRequest("/", meta, -1); // fd=-1 means for creating zero byte object. long res = s3fscurl.PutRequest("/", meta, -1);
if(res < 0){ // fd=-1 means for creating zero byte object.
long responseCode = s3fscurl.GetLastResponseCode();
if((responseCode == 400 || responseCode == 403) && S3fsCurl::IsSignatureV4()){
LOWSYSLOGPRINT(LOG_ERR, "Could not connect, so retry to connect by signature version 2.");
FPRN("Could not connect, so retry to connect by signature version 2.");
S3fsCurl::SetSignatureV4(false);
// retry to check
s3fscurl.DestroyCurlHandle();
res = s3fscurl.PutRequest("/", meta, -1);
}
}
return res;
} }
// common function for creation of a plain object // common function for creation of a plain object
@ -3561,25 +3574,14 @@ static int s3fs_check_service(void)
} }
S3fsCurl s3fscurl; S3fsCurl s3fscurl;
if(-1 == s3fscurl.CheckBucket()){ int res;
fprintf(stderr, "%s: Failed to access bucket.\n", program_name.c_str()); if(0 > (res = s3fscurl.CheckBucket())){
return EXIT_FAILURE; // get response code
}
long responseCode = s3fscurl.GetLastResponseCode(); long responseCode = s3fscurl.GetLastResponseCode();
if(responseCode == 400){ // check wrong endpoint, and automatically switch endpoint
if(!S3fsCurl::IsSignatureV4()){ if(responseCode == 400 && !is_specified_endpoint){
// signature version 2 // check region error
fprintf(stderr, "%s: Bad Request\n", program_name.c_str());
return EXIT_FAILURE;
}
if(is_specified_endpoint){
// if specifies endpoint, do not retry to connect.
fprintf(stderr, "%s: Bad Request\n", program_name.c_str());
return EXIT_FAILURE;
}
// check region error for signature version 4
BodyData* body = s3fscurl.GetBodyData(); BodyData* body = s3fscurl.GetBodyData();
string expectregion; string expectregion;
if(check_region_error(body->str(), expectregion)){ if(check_region_error(body->str(), expectregion)){
@ -3587,42 +3589,40 @@ static int s3fs_check_service(void)
LOWSYSLOGPRINT(LOG_ERR, "Could not connect wrong region %s, so retry to connect region %s.", endpoint.c_str(), expectregion.c_str()); LOWSYSLOGPRINT(LOG_ERR, "Could not connect wrong region %s, so retry to connect region %s.", endpoint.c_str(), expectregion.c_str());
FPRN("Could not connect wrong region %s, so retry to connect region %s.", endpoint.c_str(), expectregion.c_str()); FPRN("Could not connect wrong region %s, so retry to connect region %s.", endpoint.c_str(), expectregion.c_str());
endpoint = expectregion; endpoint = expectregion;
if (S3fsCurl::IsSignatureV4()) { if(S3fsCurl::IsSignatureV4()){
if (host == "http://s3.amazonaws.com") { if(host == "http://s3.amazonaws.com"){
host = "http://s3-" + endpoint + ".amazonaws.com"; host = "http://s3-" + endpoint + ".amazonaws.com";
} else if (host == "https://s3.amazonaws.com") { }else if(host == "https://s3.amazonaws.com"){
host = "https://s3-" + endpoint + ".amazonaws.com"; host = "https://s3-" + endpoint + ".amazonaws.com";
} }
} }
// retry to check // retry to check with new endpoint
s3fscurl.DestroyCurlHandle(); s3fscurl.DestroyCurlHandle();
if(-1 == s3fscurl.CheckBucket()){ res = s3fscurl.CheckBucket();
fprintf(stderr, "%s: Failed to access bucket.\n", program_name.c_str());
return EXIT_FAILURE;
}
responseCode = s3fscurl.GetLastResponseCode(); responseCode = s3fscurl.GetLastResponseCode();
} }
}
if(responseCode == 400){ // try signature v2
// retry to use sigv2 if(0 > res && (responseCode == 400 || responseCode == 403) && S3fsCurl::IsSignatureV4()){
// switch sigv2
LOWSYSLOGPRINT(LOG_ERR, "Could not connect, so retry to connect by signature version 2."); LOWSYSLOGPRINT(LOG_ERR, "Could not connect, so retry to connect by signature version 2.");
FPRN("Could not connect, so retry to connect by signature version 2."); FPRN("Could not connect, so retry to connect by signature version 2.");
S3fsCurl::SetSignatureV4(false); S3fsCurl::SetSignatureV4(false);
// retry to check // retry to check with sigv2
s3fscurl.DestroyCurlHandle(); s3fscurl.DestroyCurlHandle();
if(-1 == s3fscurl.CheckBucket()){ res = s3fscurl.CheckBucket();
fprintf(stderr, "%s: Failed to access bucket.\n", program_name.c_str());
return EXIT_FAILURE;
}
responseCode = s3fscurl.GetLastResponseCode(); responseCode = s3fscurl.GetLastResponseCode();
}
// check errors(after retrying)
if(0 > res && responseCode != 200 && responseCode != 301){
if(responseCode == 400){ if(responseCode == 400){
fprintf(stderr, "%s: Bad Request\n", program_name.c_str()); fprintf(stderr, "%s: Bad Request\n", program_name.c_str());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
}
}
if(responseCode == 403){ if(responseCode == 403){
fprintf(stderr, "%s: invalid credentials\n", program_name.c_str()); fprintf(stderr, "%s: invalid credentials\n", program_name.c_str());
return EXIT_FAILURE; return EXIT_FAILURE;
@ -3633,12 +3633,15 @@ static int s3fs_check_service(void)
} }
// unable to connect // unable to connect
if(responseCode == CURLE_OPERATION_TIMEDOUT){ if(responseCode == CURLE_OPERATION_TIMEDOUT){
return EXIT_SUCCESS; fprintf(stderr, "%s: unable to connect bucket and timeout\n", program_name.c_str());
return EXIT_FAILURE;
} }
if(responseCode != 200 && responseCode != 301){
// another error
fprintf(stderr, "%s: unable to connect\n", program_name.c_str()); fprintf(stderr, "%s: unable to connect\n", program_name.c_str());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
}
// make sure remote mountpath exists and is a directory // make sure remote mountpath exists and is a directory
if(mount_prefix.size() > 0){ if(mount_prefix.size() > 0){