From f44cc2b954fcacb662317f22da1dc1b08b96e2f6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 9 Jan 2009 11:50:10 +0000 Subject: Move S3Client class into its own files for public access. --- test/httpserver/testhttpserver.cpp | 198 +------------------------------------ 1 file changed, 1 insertion(+), 197 deletions(-) (limited to 'test') diff --git a/test/httpserver/testhttpserver.cpp b/test/httpserver/testhttpserver.cpp index 5b608591..421c9626 100644 --- a/test/httpserver/testhttpserver.cpp +++ b/test/httpserver/testhttpserver.cpp @@ -20,6 +20,7 @@ #include "HTTPResponse.h" #include "HTTPServer.h" #include "IOStreamGetLine.h" +#include "S3Client.h" #include "ServerControl.h" #include "Test.h" #include "decode.h" @@ -326,203 +327,6 @@ void S3Simulator::HandlePut(HTTPRequest &rRequest, HTTPResponse &rResponse) rResponse.SetResponseCode(HTTPResponse::Code_OK); } -class S3Client -{ - public: - S3Client(S3Simulator* pSimulator, const std::string& rHostName, - const std::string& rAccessKey, const std::string& rSecretKey) - : mpSimulator(pSimulator), - mHostName(rHostName), - mAccessKey(rAccessKey), - mSecretKey(rSecretKey) - { } - - S3Client(std::string HostName, int Port, const std::string& rAccessKey, - const std::string& rSecretKey) - : mpSimulator(NULL), - mHostName(HostName), - mPort(Port), - mAccessKey(rAccessKey), - mSecretKey(rSecretKey) - { } - - HTTPResponse GetObject(const std::string& rObjectURI); - HTTPResponse PutObject(const std::string& rObjectURI, - IOStream& rStreamToSend, const char* pContentType = NULL); - - private: - S3Simulator* mpSimulator; - std::string mHostName; - int mPort; - std::auto_ptr mapClientSocket; - std::string mAccessKey, mSecretKey; - - HTTPResponse FinishAndSendRequest(HTTPRequest::Method Method, - const std::string& rRequestURI, - IOStream* pStreamToSend = NULL, - const char* pStreamContentType = NULL); - HTTPResponse SendRequest(HTTPRequest& rRequest, - IOStream* pStreamToSend = NULL, - const char* pStreamContentType = NULL); -}; - -HTTPResponse S3Client::GetObject(const std::string& rObjectURI) -{ - return FinishAndSendRequest(HTTPRequest::Method_GET, rObjectURI); -} - -HTTPResponse S3Client::PutObject(const std::string& rObjectURI, - IOStream& rStreamToSend, const char* pContentType) -{ - return FinishAndSendRequest(HTTPRequest::Method_PUT, rObjectURI, - &rStreamToSend, pContentType); -} - -HTTPResponse S3Client::FinishAndSendRequest(HTTPRequest::Method Method, - const std::string& rRequestURI, IOStream* pStreamToSend, - const char* pStreamContentType) -{ - HTTPRequest request(Method, rRequestURI); - request.SetHostName(mHostName); - - std::ostringstream date; - time_t tt = time(NULL); - struct tm *tp = gmtime(&tt); - if (!tp) - { - BOX_ERROR("Failed to get current time"); - THROW_EXCEPTION(HTTPException, Internal); - } - const char *dow[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; - date << dow[tp->tm_wday] << ", "; - const char *month[] = {"Jan","Feb","Mar","Apr","May","Jun", - "Jul","Aug","Sep","Oct","Nov","Dec"}; - date << std::internal << std::setfill('0') << - std::setw(2) << tp->tm_mday << " " << - month[tp->tm_mon] << " " << - (tp->tm_year + 1900) << " "; - date << std::setw(2) << tp->tm_hour << ":" << - std::setw(2) << tp->tm_min << ":" << - std::setw(2) << tp->tm_sec << " GMT"; - request.AddHeader("Date", date.str()); - - if (pStreamContentType) - { - request.AddHeader("Content-Type", pStreamContentType); - } - - std::string s3suffix = ".s3.amazonaws.com"; - std::string bucket; - if (mHostName.size() > s3suffix.size()) - { - std::string suffix = mHostName.substr(mHostName.size() - - s3suffix.size(), s3suffix.size()); - if (suffix == s3suffix) - { - bucket = mHostName.substr(0, mHostName.size() - - s3suffix.size()); - } - } - - std::ostringstream data; - data << request.GetVerb() << "\n"; - data << "\n"; /* Content-MD5 */ - data << request.GetContentType() << "\n"; - data << date.str() << "\n"; - - if (! bucket.empty()) - { - data << "/" << bucket; - } - - data << request.GetRequestURI(); - std::string data_string = data.str(); - - unsigned char digest_buffer[EVP_MAX_MD_SIZE]; - unsigned int digest_size = sizeof(digest_buffer); - /* unsigned char* mac = */ HMAC(EVP_sha1(), - mSecretKey.c_str(), mSecretKey.size(), - (const unsigned char*)data_string.c_str(), - data_string.size(), digest_buffer, &digest_size); - std::string digest((const char *)digest_buffer, digest_size); - - base64::encoder encoder; - std::string auth_code = "AWS " + mAccessKey + ":" + - encoder.encode(digest); - - if (auth_code[auth_code.size() - 1] == '\n') - { - auth_code = auth_code.substr(0, auth_code.size() - 1); - } - - request.AddHeader("Authorization", auth_code); - - if (mpSimulator) - { - if (pStreamToSend) - { - pStreamToSend->CopyStreamTo(request); - } - - request.SetForReading(); - CollectInBufferStream response_buffer; - HTTPResponse response(&response_buffer); - - mpSimulator->Handle(request, response); - return response; - } - else - { - try - { - if (!mapClientSocket.get()) - { - mapClientSocket.reset(new SocketStream()); - mapClientSocket->Open(Socket::TypeINET, - mHostName, mPort); - } - return SendRequest(request, pStreamToSend, - pStreamContentType); - } - catch (ConnectionException &ce) - { - if (ce.GetType() == ConnectionException::SocketWriteError) - { - // server may have disconnected us, - // try to reconnect, just once - mapClientSocket->Open(Socket::TypeINET, - mHostName, mPort); - return SendRequest(request, pStreamToSend, - pStreamContentType); - } - else - { - throw; - } - } - } -} - -HTTPResponse S3Client::SendRequest(HTTPRequest& rRequest, - IOStream* pStreamToSend, const char* pStreamContentType) -{ - HTTPResponse response; - - if (pStreamToSend) - { - rRequest.SendWithStream(*mapClientSocket, - 30000 /* milliseconds */, - pStreamToSend, response); - } - else - { - rRequest.Send(*mapClientSocket, 30000 /* milliseconds */); - response.Receive(*mapClientSocket, 30000 /* milliseconds */); - } - - return response; -} - int test(int argc, const char *argv[]) { if(argc >= 2 && ::strcmp(argv[1], "server") == 0) -- cgit v1.2.3