diff options
author | Bryan Ischo <bryan@ischo.com> | 2008-07-10 21:12:21 +0000 |
---|---|---|
committer | Bryan Ischo <bryan@ischo.com> | 2008-07-10 21:12:21 +0000 |
commit | c0535eabe25706904711f1453e724e659b93318c (patch) | |
tree | 55e2a2acc6fbc71e4c1a55489aaeed7f2cc919e2 /src/error_parser.c | |
parent | e9e38ab98e38b35725d85cbe6101bfbbd34d1418 (diff) | |
download | ceph-libs3-c0535eabe25706904711f1453e724e659b93318c.tar.gz |
* Work in progress - reorganized alot, completed list bucket, create bucket,
delete bucket, test bucket
Diffstat (limited to 'src/error_parser.c')
-rw-r--r-- | src/error_parser.c | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/src/error_parser.c b/src/error_parser.c new file mode 100644 index 0000000..d26bba8 --- /dev/null +++ b/src/error_parser.c @@ -0,0 +1,239 @@ +/** ************************************************************************** + * error_parser.c + * + * Copyright 2008 Bryan Ischo <bryan@ischo.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the + * + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + ************************************************************************** **/ + +#include <string.h> +#include "error_parser.h" + + +static S3Status errorXmlCallback(const char *elementPath, const char *data, + int dataLen, void *callbackData) +{ + // We ignore end of element callbacks because we don't care about them + if (!data) { + return S3StatusOK; + } + + ErrorParser *errorParser = (ErrorParser *) callbackData; + + int fit; + + if (!strcmp(elementPath, "Error")) { + // Ignore, this is the Error element itself, we only care about subs + } + else if (!strcmp(elementPath, "Error/Code")) { + string_buffer_append(errorParser->code, data, dataLen, fit); + } + else if (!strcmp(elementPath, "Error/Message")) { + string_buffer_append(errorParser->message, data, dataLen, fit); + errorParser->s3ErrorDetails.message = errorParser->message; + } + else if (!strcmp(elementPath, "Error/Resource")) { + string_buffer_append(errorParser->resource, data, dataLen, fit); + errorParser->s3ErrorDetails.resource = errorParser->resource; + } + else if (!strcmp(elementPath, "Error/FurtherDetails")) { + string_buffer_append(errorParser->furtherDetails, data, dataLen, fit); + errorParser->s3ErrorDetails.furtherDetails = + errorParser->furtherDetails; + } + else { + if (strncmp(elementPath, "Error/", sizeof("Error/") - 1)) { + // If for some weird reason it's not within the Error element, + // ignore it + return S3StatusOK; + } + // It's an unknown error element. See if it matches the most + // recent error element. + const char *elementName = &(elementPath[sizeof("Error/") - 1]); + if (errorParser->s3ErrorDetails.extraDetailsCount && + !strcmp(elementName, errorParser->s3ErrorDetails.extraDetails + [errorParser->s3ErrorDetails.extraDetailsCount - 1].name)) { + // Append the value + string_multibuffer_append(errorParser->extraDetailsNamesValues, + data, dataLen, fit); + // If it didn't fit, remove this extra + if (!fit) { + errorParser->s3ErrorDetails.extraDetailsCount--; + } + return S3StatusOK; + } + // OK, must add another unknown error element, if it will fit. + if (errorParser->s3ErrorDetails.extraDetailsCount == + sizeof(errorParser->extraDetails)) { + // Won't fit. Ignore this one. + return S3StatusOK; + } + // Copy in the name and value + char *name = string_multibuffer_current + (errorParser->extraDetailsNamesValues); + int nameLen = strlen(elementName); + string_multibuffer_add(errorParser->extraDetailsNamesValues, + elementName, nameLen, fit); + if (!fit) { + // Name didn't fit; ignore this one. + return S3StatusOK; + } + char *value = string_multibuffer_current + (errorParser->extraDetailsNamesValues); + string_multibuffer_add(errorParser->extraDetailsNamesValues, + data, dataLen, fit); + if (!fit) { + // Value didn't fit; ignore this one. + return S3StatusOK; + } + S3NameValue *nv = &(errorParser->extraDetails + [errorParser->s3ErrorDetails.extraDetailsCount++]); + nv->name = name; + nv->value = value; + } + + return S3StatusOK; +} + + +void error_parser_initialize(ErrorParser *errorParser) +{ + errorParser->s3ErrorDetails.message = 0; + errorParser->s3ErrorDetails.resource = 0; + errorParser->s3ErrorDetails.furtherDetails = 0; + errorParser->s3ErrorDetails.extraDetailsCount = 0; + errorParser->s3ErrorDetails.extraDetails = errorParser->extraDetails; + errorParser->errorXmlParserInitialized = 0; + string_buffer_initialize(errorParser->code); + string_buffer_initialize(errorParser->message); + string_buffer_initialize(errorParser->resource); + string_buffer_initialize(errorParser->furtherDetails); + string_multibuffer_initialize(errorParser->extraDetailsNamesValues); +} + + +S3Status error_parser_add(ErrorParser *errorParser, char *buffer, + int bufferSize) +{ + if (!errorParser->errorXmlParserInitialized) { + S3Status status = simplexml_initialize + (&(errorParser->errorXmlParser), &errorXmlCallback, errorParser); + if (status != S3StatusOK) { + return status; + } + errorParser->errorXmlParserInitialized = 1; + } + + return simplexml_add(&(errorParser->errorXmlParser), buffer, bufferSize); +} + + +void error_parser_convert_status(ErrorParser *errorParser, S3Status *status) +{ + // Convert the error status string into a code + if (!errorParser->codeLen) { + return; + } + +#define HANDLE_CODE(name) \ + do { \ + if (!strcmp(errorParser->code, #name)) { \ + *status = S3StatusError##name; \ + goto code_set; \ + } \ + } while (0) + + HANDLE_CODE(AccessDenied); + HANDLE_CODE(AccountProblem); + HANDLE_CODE(AmbiguousGrantByEmailAddress); + HANDLE_CODE(BadDigest); + HANDLE_CODE(BucketAlreadyExists); + HANDLE_CODE(BucketAlreadyOwnedByYou); + HANDLE_CODE(BucketNotEmpty); + HANDLE_CODE(CredentialsNotSupported); + HANDLE_CODE(CrossLocationLoggingProhibited); + HANDLE_CODE(EntityTooSmall); + HANDLE_CODE(EntityTooLarge); + HANDLE_CODE(ExpiredToken); + HANDLE_CODE(IncompleteBody); + HANDLE_CODE(IncorrectNumberOfFilesInPostRequest); + HANDLE_CODE(InlineDataTooLarge); + HANDLE_CODE(InternalError); + HANDLE_CODE(InvalidAccessKeyId); + HANDLE_CODE(InvalidAddressingHeader); + HANDLE_CODE(InvalidArgument); + HANDLE_CODE(InvalidBucketName); + HANDLE_CODE(InvalidDigest); + HANDLE_CODE(InvalidLocationConstraint); + HANDLE_CODE(InvalidPayer); + HANDLE_CODE(InvalidPolicyDocument); + HANDLE_CODE(InvalidRange); + HANDLE_CODE(InvalidSecurity); + HANDLE_CODE(InvalidSOAPRequest); + HANDLE_CODE(InvalidStorageClass); + HANDLE_CODE(InvalidTargetBucketForLogging); + HANDLE_CODE(InvalidToken); + HANDLE_CODE(InvalidURI); + HANDLE_CODE(KeyTooLong); + HANDLE_CODE(MalformedACLError); + HANDLE_CODE(MalformedXML); + HANDLE_CODE(MaxMessageLengthExceeded); + HANDLE_CODE(MaxPostPreDataLengthExceededError); + HANDLE_CODE(MetadataTooLarge); + HANDLE_CODE(MethodNotAllowed); + HANDLE_CODE(MissingAttachment); + HANDLE_CODE(MissingContentLength); + HANDLE_CODE(MissingSecurityElement); + HANDLE_CODE(MissingSecurityHeader); + HANDLE_CODE(NoLoggingStatusForKey); + HANDLE_CODE(NoSuchBucket); + HANDLE_CODE(NoSuchKey); + HANDLE_CODE(NotImplemented); + HANDLE_CODE(NotSignedUp); + HANDLE_CODE(OperationAborted); + HANDLE_CODE(PermanentRedirect); + HANDLE_CODE(PreconditionFailed); + HANDLE_CODE(Redirect); + HANDLE_CODE(RequestIsNotMultiPartContent); + HANDLE_CODE(RequestTimeout); + HANDLE_CODE(RequestTimeTooSkewed); + HANDLE_CODE(RequestTorrentOfBucketError); + HANDLE_CODE(SignatureDoesNotMatch); + HANDLE_CODE(SlowDown); + HANDLE_CODE(TemporaryRedirect); + HANDLE_CODE(TokenRefreshRequired); + HANDLE_CODE(TooManyBuckets); + HANDLE_CODE(UnexpectedContent); + HANDLE_CODE(UnresolvableGrantByEmailAddress); + HANDLE_CODE(UserKeyMustBeSpecified); + *status = S3StatusErrorUnknown; + + code_set: + + return; +} + + +// Always call this +void error_parser_deinitialize(ErrorParser *errorParser) +{ + if (errorParser->errorXmlParserInitialized) { + simplexml_deinitialize(&(errorParser->errorXmlParser)); + } +} |