diff options
author | Bryan Ischo <bryan@ischo.com> | 2008-07-22 11:15:45 +0000 |
---|---|---|
committer | Bryan Ischo <bryan@ischo.com> | 2008-07-22 11:15:45 +0000 |
commit | 70ff9e5b4bafe769109386914ef5f85b17c2b009 (patch) | |
tree | e3959216687d541758edf85fab4c542506e58df4 /src | |
parent | d6998ae7a48171ea78d4c60c22818672f36750de (diff) | |
download | ceph-libs3-70ff9e5b4bafe769109386914ef5f85b17c2b009.tar.gz |
* Fixed some error handling
* Report HTTP errors when S3 doesn't supply error details
* Complete libs3.h header documentation
* Bumped version to 0.2
Diffstat (limited to 'src')
-rw-r--r-- | src/general.c | 6 | ||||
-rw-r--r-- | src/request.c | 79 | ||||
-rw-r--r-- | src/s3.c | 7 |
3 files changed, 78 insertions, 14 deletions
diff --git a/src/general.c b/src/general.c index f7aa034..1ef1e65 100644 --- a/src/general.c +++ b/src/general.c @@ -287,6 +287,12 @@ const char *S3_get_status_name(S3Status status) handlecase(ErrorUnresolvableGrantByEmailAddress); handlecase(ErrorUserKeyMustBeSpecified); handlecase(ErrorUnknown); + handlecase(HttpErrorMovedTemporarily); + handlecase(HttpErrorBadRequest); + handlecase(HttpErrorForbidden); + handlecase(HttpErrorNotFound); + handlecase(HttpErrorConflict); + handlecase(HttpErrorUnknown); } return "Unknown"; diff --git a/src/request.c b/src/request.c index 6cf7050..9813e21 100644 --- a/src/request.c +++ b/src/request.c @@ -119,10 +119,23 @@ static void request_headers_done(Request *request) request->propertiesCallbackMade = 1; + // Get the http response code + request->httpResponseCode = 0; + if (curl_easy_getinfo(request->curl, CURLINFO_RESPONSE_CODE, + &(request->httpResponseCode)) != CURLE_OK) { + // Not able to get the HTTP response code - error + request->status = S3StatusInternalError; + return; + } + response_headers_handler_done(&(request->responseHeadersHandler), request->curl); - if (request->propertiesCallback) { + // Only make the callback if it was a successful request; otherwise we're + // returning information about the error response itself + if (request->propertiesCallback && + (request->httpResponseCode >= 200) && + (request->httpResponseCode <= 299)) { request->status = (*(request->propertiesCallback)) (&(request->responseHeadersHandler.responseProperties), request->callbackData); @@ -187,15 +200,9 @@ static size_t curl_write_func(void *ptr, size_t size, size_t nmemb, return 0; } - // Get the http response code - int httpResponseCode = 0; - if (curl_easy_getinfo(request->curl, CURLINFO_RESPONSE_CODE, - &(httpResponseCode)) != CURLE_OK) { - // Not able to get the HTTP response code - error - request->status = S3StatusInternalError; - } // On HTTP error, we expect to parse an HTTP error response - else if ((httpResponseCode < 200) || (httpResponseCode > 299)) { + if ((request->httpResponseCode < 200) || + (request->httpResponseCode > 299)) { request->status = error_parser_add (&(request->errorParser), (char *) ptr, len); } @@ -1149,6 +1156,57 @@ void request_finish(Request *request) if (request->status == S3StatusOK) { error_parser_convert_status(&(request->errorParser), &(request->status)); + // If there still was no error recorded, then it is possible that + // there was in fact an error but that there was no error XML + // detailing the error + if ((request->status == S3StatusOK) && + ((request->httpResponseCode < 200) || + (request->httpResponseCode > 299))) { + switch (request->httpResponseCode) { + case 301: + request->status = S3StatusErrorPermanentRedirect; + break; + case 307: + request->status = S3StatusHttpErrorMovedTemporarily; + break; + case 400: + request->status = S3StatusHttpErrorBadRequest; + break; + case 403: + request->status = S3StatusHttpErrorForbidden; + break; + case 404: + request->status = S3StatusHttpErrorNotFound; + break; + case 405: + request->status = S3StatusErrorMethodNotAllowed; + break; + case 409: + request->status = S3StatusHttpErrorConflict; + break; + case 411: + request->status = S3StatusErrorMissingContentLength; + break; + case 412: + request->status = S3StatusErrorPreconditionFailed; + break; + case 416: + request->status = S3StatusErrorInvalidRange; + break; + case 500: + request->status = S3StatusErrorInternalError; + break; + case 501: + request->status = S3StatusErrorNotImplemented; + break; + case 503: + request->status = S3StatusErrorSlowDown; + break; + default: + request->status = S3StatusHttpErrorUnknown; + break; + } + } } (*(request->completeCallback)) @@ -1172,8 +1230,9 @@ S3Status request_curl_code_to_status(CURLcode code) case CURLE_WRITE_ERROR: case CURLE_OPERATION_TIMEDOUT: return S3StatusConnectionFailed; + case CURLE_PARTIAL_FILE: + return S3StatusOK; default: return S3StatusInternalError; } } - @@ -182,8 +182,7 @@ static void printError() fprintf(stderr, "\nERROR: %s\n", S3_get_status_name(statusG)); } else { - fprintf(stderr, "\nERROR: S3 returned an unexpected error:\n"); - fprintf(stderr, " %s\n", S3_get_status_name(statusG)); + fprintf(stderr, "\nERROR: %s\n", S3_get_status_name(statusG)); fprintf(stderr, "%s\n", errorDetailsG); } } @@ -227,7 +226,7 @@ static void usageExit(FILE *out) " head <bucket>/<key> [ifModifiedSince, ifNotmodifiedSince, ifMatch,\n" " ifNotMatch] (implies -s)\n" " delete <bucket>/<key>\n" -" getacl <bucket>/<key> [filename, allDetails]" +" getacl <bucket>/<key> [filename, allDetails]\n" " setacl <bucket>/<key> [filename]" "\n"); @@ -1804,7 +1803,7 @@ static void get_object(int argc, char **argv, int optind) ftruncate(fileno(outfile), ftell(outfile)); } } - else if (statusG != S3StatusErrorPreconditionFailed) { + else { printError(); } |