summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBryan Ischo <bryan@ischo.com>2008-07-22 11:15:45 +0000
committerBryan Ischo <bryan@ischo.com>2008-07-22 11:15:45 +0000
commit70ff9e5b4bafe769109386914ef5f85b17c2b009 (patch)
treee3959216687d541758edf85fab4c542506e58df4 /src
parentd6998ae7a48171ea78d4c60c22818672f36750de (diff)
downloadceph-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.c6
-rw-r--r--src/request.c79
-rw-r--r--src/s3.c7
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;
}
}
-
diff --git a/src/s3.c b/src/s3.c
index e58c789..bc182ad 100644
--- a/src/s3.c
+++ b/src/s3.c
@@ -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();
}