diff --git a/lib/common/BoxException.h b/lib/common/BoxException.h index 361f04e89..6b284b0cc 100644 --- a/lib/common/BoxException.h +++ b/lib/common/BoxException.h @@ -29,11 +29,17 @@ class BoxException : public std::exception virtual unsigned int GetType() const throw() = 0; virtual unsigned int GetSubType() const throw() = 0; + bool IsType(unsigned int Type, unsigned int SubType) + { + return GetType() == Type && GetSubType() == SubType; + } virtual const std::string& GetMessage() const = 0; private: }; +#define EXCEPTION_IS_TYPE(exception_obj, type, subtype) \ + exception_obj.IsType(type::ExceptionType, type::subtype) #endif // BOXEXCEPTION__H diff --git a/lib/httpserver/S3Simulator.cpp b/lib/httpserver/S3Simulator.cpp index c400e93dc..3acb1a210 100644 --- a/lib/httpserver/S3Simulator.cpp +++ b/lib/httpserver/S3Simulator.cpp @@ -167,9 +167,8 @@ void S3Simulator::Handle(HTTPRequest &rRequest, HTTPResponse &rResponse) if (!rRequest.GetHeader("authorization", &actualAuth) || actualAuth != expectedAuth) { - rResponse.SetResponseCode(HTTPResponse::Code_Unauthorized); - SendInternalErrorResponse("Authentication Failed", - rResponse); + THROW_EXCEPTION_MESSAGE(HTTPException, AuthenticationFailed, + "Authentication code mismatch"); } else if (rRequest.GetMethod() == HTTPRequest::Method_GET) { @@ -181,14 +180,27 @@ void S3Simulator::Handle(HTTPRequest &rRequest, HTTPResponse &rResponse) } else { - rResponse.SetResponseCode(HTTPResponse::Code_BadRequest); - SendInternalErrorResponse("Unsupported Method", - rResponse); + THROW_EXCEPTION_MESSAGE(HTTPException, BadRequest, + "Unsupported Amazon S3 Method"); } } - catch (CommonException &ce) + catch (BoxException &ce) { SendInternalErrorResponse(ce.what(), rResponse); + + // Override the default status code 500 for a few specific exceptions. + if(EXCEPTION_IS_TYPE(ce, CommonException, OSFileOpenError)) + { + rResponse.SetResponseCode(HTTPResponse::Code_NotFound); + } + else if(EXCEPTION_IS_TYPE(ce, CommonException, AccessDenied)) + { + rResponse.SetResponseCode(HTTPResponse::Code_Forbidden); + } + else if(EXCEPTION_IS_TYPE(ce, HTTPException, AuthenticationFailed)) + { + rResponse.SetResponseCode(HTTPResponse::Code_Unauthorized); + } } catch (std::exception &e) { @@ -231,22 +243,7 @@ void S3Simulator::HandleGet(HTTPRequest &rRequest, HTTPResponse &rResponse) path += rRequest.GetRequestURI(); std::auto_ptr apFile; - try - { - apFile.reset(new FileStream(path)); - } - catch (CommonException &ce) - { - if (ce.GetSubType() == CommonException::OSFileOpenError) - { - rResponse.SetResponseCode(HTTPResponse::Code_NotFound); - } - else if (ce.GetSubType() == CommonException::AccessDenied) - { - rResponse.SetResponseCode(HTTPResponse::Code_Forbidden); - } - throw; - } + apFile.reset(new FileStream(path)); // http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingRESTOperations.html apFile->CopyStreamTo(rResponse);