summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2009-01-09 11:50:10 +0000
committerChris Wilson <chris+github@qwirx.com>2009-01-09 11:50:10 +0000
commitf44cc2b954fcacb662317f22da1dc1b08b96e2f6 (patch)
treee892cb656f87482e9fe16ef3b18caf47adb171d8 /test
parent0b999ceba3550774ef00dc0170c6995b353bb791 (diff)
Move S3Client class into its own files for public access.
Diffstat (limited to 'test')
-rw-r--r--test/httpserver/testhttpserver.cpp198
1 files changed, 1 insertions, 197 deletions
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<SocketStream> 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)