Changeset 2504 for box/trunk/test


Ignore:
Timestamp:
13/04/2009 19:40:50 (3 years ago)
Author:
chris
Message:

Move S3Simulator into its own class, like S3Client, for reuse elsewhere.

Location:
box/trunk/test/httpserver
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • box/trunk/test/httpserver/testfiles/s3simulator.conf

    r926 r2504  
    1  
     1AccessKey = 0PN5J17HBGZHT7JJ3X82 
     2SecretKey = uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o 
     3StoreDirectory = testfiles 
    24AddressPrefix = http://localhost:1080 
    35 
    46Server 
    57{ 
    6         PidFile = testfiles/httpserver.pid 
     8        PidFile = testfiles/s3simulator.pid 
    79        ListenAddresses = inet:localhost:1080 
    810} 
  • box/trunk/test/httpserver/testhttpserver.cpp

    r2502 r2504  
    2727#include "IOStreamGetLine.h" 
    2828#include "S3Client.h" 
     29#include "S3Simulator.h" 
    2930#include "ServerControl.h" 
    3031#include "Test.h" 
     
    126127TestWebServer::~TestWebServer() {} 
    127128 
    128 class S3Simulator : public HTTPServer 
    129 { 
    130 public: 
    131         S3Simulator() { } 
    132         ~S3Simulator() { } 
    133  
    134         virtual void Handle(HTTPRequest &rRequest, HTTPResponse &rResponse); 
    135         virtual void HandleGet(HTTPRequest &rRequest, HTTPResponse &rResponse); 
    136         virtual void HandlePut(HTTPRequest &rRequest, HTTPResponse &rResponse); 
    137 }; 
    138  
    139 void S3Simulator::Handle(HTTPRequest &rRequest, HTTPResponse &rResponse) 
    140 { 
    141         // if anything goes wrong, return a 500 error 
    142         rResponse.SetResponseCode(HTTPResponse::Code_InternalServerError); 
    143         rResponse.SetContentType("text/plain"); 
    144  
    145         try 
    146         { 
    147                 // http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAuthentication.html 
    148                 std::string access_key = "0PN5J17HBGZHT7JJ3X82"; 
    149                 std::string secret_key = "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o"; 
    150                  
    151                 std::string md5, date, bucket; 
    152                 rRequest.GetHeader("Content-MD5", &md5); 
    153                 rRequest.GetHeader("Date", &date); 
    154                  
    155                 std::string host = rRequest.GetHostName(); 
    156                 std::string s3suffix = ".s3.amazonaws.com"; 
    157                 if (host.size() > s3suffix.size()) 
    158                 { 
    159                         std::string suffix = host.substr(host.size() - 
    160                                 s3suffix.size(), s3suffix.size()); 
    161                         if (suffix == s3suffix) 
    162                         { 
    163                                 bucket = host.substr(0, host.size() - 
    164                                         s3suffix.size()); 
    165                         } 
    166                 } 
    167                  
    168                 std::ostringstream data; 
    169                 data << rRequest.GetVerb() << "\n"; 
    170                 data << md5 << "\n"; 
    171                 data << rRequest.GetContentType() << "\n"; 
    172                 data << date << "\n"; 
    173                  
    174                 std::vector<HTTPRequest::Header> headers = rRequest.GetHeaders(); 
    175                  
    176                 for (std::vector<HTTPRequest::Header>::iterator 
    177                         i = headers.begin(); i != headers.end(); i++) 
    178                 { 
    179                         std::string& rHeaderName = i->first; 
    180                          
    181                         for (std::string::iterator c = rHeaderName.begin(); 
    182                                 c != rHeaderName.end() && *c != ':'; c++) 
    183                         { 
    184                                 *c = tolower(*c); 
    185                         } 
    186                 } 
    187                  
    188                 sort(headers.begin(), headers.end()); 
    189                  
    190                 for (std::vector<HTTPRequest::Header>::iterator 
    191                         i = headers.begin(); i != headers.end(); i++) 
    192                 { 
    193                         if (i->first.substr(0, 5) == "x-amz") 
    194                         { 
    195                                 data << i->first << ":" << i->second << "\n"; 
    196                         } 
    197                 }                
    198                  
    199                 if (! bucket.empty()) 
    200                 { 
    201                         data << "/" << bucket; 
    202                 } 
    203                  
    204                 data << rRequest.GetRequestURI(); 
    205                 std::string data_string = data.str(); 
    206  
    207                 unsigned char digest_buffer[EVP_MAX_MD_SIZE]; 
    208                 unsigned int digest_size = sizeof(digest_buffer); 
    209                 /* unsigned char* mac = */ HMAC(EVP_sha1(), 
    210                         secret_key.c_str(), secret_key.size(), 
    211                         (const unsigned char*)data_string.c_str(), 
    212                         data_string.size(), digest_buffer, &digest_size); 
    213                 std::string digest((const char *)digest_buffer, digest_size); 
    214                  
    215                 base64::encoder encoder; 
    216                 std::string expectedAuth = "AWS " + access_key + ":" + 
    217                         encoder.encode(digest); 
    218                  
    219                 if (expectedAuth[expectedAuth.size() - 1] == '\n') 
    220                 { 
    221                         expectedAuth = expectedAuth.substr(0, 
    222                                 expectedAuth.size() - 1); 
    223                 } 
    224                  
    225                 std::string actualAuth; 
    226                 if (!rRequest.GetHeader("Authorization", &actualAuth) || 
    227                         actualAuth != expectedAuth) 
    228                 { 
    229                         rResponse.SetResponseCode(HTTPResponse::Code_Unauthorized); 
    230                 }        
    231                 else if (rRequest.GetMethod() == HTTPRequest::Method_GET) 
    232                 { 
    233                         HandleGet(rRequest, rResponse); 
    234                 } 
    235                 else if (rRequest.GetMethod() == HTTPRequest::Method_PUT) 
    236                 { 
    237                         HandlePut(rRequest, rResponse); 
    238                 } 
    239                 else 
    240                 { 
    241                         rResponse.SetResponseCode(HTTPResponse::Code_MethodNotAllowed); 
    242                 } 
    243         } 
    244         catch (CommonException &ce) 
    245         { 
    246                 rResponse.IOStream::Write(ce.what()); 
    247         } 
    248         catch (std::exception &e) 
    249         { 
    250                 rResponse.IOStream::Write(e.what()); 
    251         } 
    252         catch (...) 
    253         { 
    254                 rResponse.IOStream::Write("Unknown error"); 
    255         } 
    256          
    257         return; 
    258 } 
    259  
    260 void S3Simulator::HandleGet(HTTPRequest &rRequest, HTTPResponse &rResponse) 
    261 { 
    262         std::string path = "testfiles"; 
    263         path += rRequest.GetRequestURI(); 
    264         std::auto_ptr<FileStream> apFile; 
    265  
    266         try 
    267         { 
    268                 apFile.reset(new FileStream(path)); 
    269         } 
    270         catch (CommonException &ce) 
    271         { 
    272                 if (ce.GetSubType() == CommonException::OSFileOpenError) 
    273                 { 
    274                         rResponse.SetResponseCode(HTTPResponse::Code_NotFound); 
    275                 } 
    276                 else if (ce.GetSubType() == CommonException::AccessDenied) 
    277                 { 
    278                         rResponse.SetResponseCode(HTTPResponse::Code_Forbidden); 
    279                 } 
    280                 throw; 
    281         } 
    282  
    283         // http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingRESTOperations.html 
    284         apFile->CopyStreamTo(rResponse); 
    285         rResponse.AddHeader("x-amz-id-2", "qBmKRcEWBBhH6XAqsKU/eg24V3jf/kWKN9dJip1L/FpbYr9FDy7wWFurfdQOEMcY"); 
    286         rResponse.AddHeader("x-amz-request-id", "F2A8CCCA26B4B26D"); 
    287         rResponse.AddHeader("Date", "Wed, 01 Mar  2006 12:00:00 GMT"); 
    288         rResponse.AddHeader("Last-Modified", "Sun, 1 Jan 2006 12:00:00 GMT"); 
    289         rResponse.AddHeader("ETag", "\"828ef3fdfa96f00ad9f27c383fc9ac7f\""); 
    290         rResponse.AddHeader("Server", "AmazonS3"); 
    291         rResponse.SetResponseCode(HTTPResponse::Code_OK); 
    292 } 
    293  
    294 void S3Simulator::HandlePut(HTTPRequest &rRequest, HTTPResponse &rResponse) 
    295 { 
    296         std::string path = "testfiles"; 
    297         path += rRequest.GetRequestURI(); 
    298         std::auto_ptr<FileStream> apFile; 
    299  
    300         try 
    301         { 
    302                 apFile.reset(new FileStream(path, O_CREAT | O_WRONLY)); 
    303         } 
    304         catch (CommonException &ce) 
    305         { 
    306                 if (ce.GetSubType() == CommonException::OSFileOpenError) 
    307                 { 
    308                         rResponse.SetResponseCode(HTTPResponse::Code_NotFound); 
    309                 } 
    310                 else if (ce.GetSubType() == CommonException::AccessDenied) 
    311                 { 
    312                         rResponse.SetResponseCode(HTTPResponse::Code_Forbidden); 
    313                 } 
    314                 throw; 
    315         } 
    316  
    317         if (rRequest.IsExpectingContinue()) 
    318         { 
    319                 rResponse.SendContinue(); 
    320         } 
    321  
    322         rRequest.ReadContent(*apFile); 
    323  
    324         // http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTObjectPUT.html 
    325         rResponse.AddHeader("x-amz-id-2", "LriYPLdmOdAiIfgSm/F1YsViT1LW94/xUQxMsF7xiEb1a0wiIOIxl+zbwZ163pt7"); 
    326         rResponse.AddHeader("x-amz-request-id", "F2A8CCCA26B4B26D"); 
    327         rResponse.AddHeader("Date", "Wed, 01 Mar  2006 12:00:00 GMT"); 
    328         rResponse.AddHeader("Last-Modified", "Sun, 1 Jan 2006 12:00:00 GMT"); 
    329         rResponse.AddHeader("ETag", "\"828ef3fdfa96f00ad9f27c383fc9ac7f\""); 
    330         rResponse.SetContentType(""); 
    331         rResponse.AddHeader("Server", "AmazonS3"); 
    332         rResponse.SetResponseCode(HTTPResponse::Code_OK); 
    333 } 
    334  
    335129int test(int argc, const char *argv[]) 
    336130{ 
     
    447241        TestRemoteProcessMemLeaks("generic-httpserver.memleaks"); 
    448242 
    449         // correct, official signature should succeed 
     243        // correct, official signature should succeed, with lower-case header 
    450244        { 
    451245                // http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAuthentication.html 
    452246                HTTPRequest request(HTTPRequest::Method_GET, "/photos/puppy.jpg"); 
    453247                request.SetHostName("johnsmith.s3.amazonaws.com"); 
    454                 request.AddHeader("Date", "Tue, 27 Mar 2007 19:36:42 +0000"); 
    455                 request.AddHeader("Authorization", 
     248                request.AddHeader("date", "Tue, 27 Mar 2007 19:36:42 +0000"); 
     249                request.AddHeader("authorization", 
    456250                        "AWS 0PN5J17HBGZHT7JJ3X82:xXjDGYUmKxnwqr5KXNPGldn5LbA="); 
    457251                 
    458252                S3Simulator simulator; 
     253                simulator.Configure("testfiles/s3simulator.conf"); 
    459254                 
    460255                CollectInBufferStream response_buffer; 
     
    474269                HTTPRequest request(HTTPRequest::Method_GET, "/photos/puppy.jpg"); 
    475270                request.SetHostName("johnsmith.s3.amazonaws.com"); 
    476                 request.AddHeader("Date", "Tue, 27 Mar 2007 19:36:42 +0000"); 
    477                 request.AddHeader("Authorization", 
     271                request.AddHeader("date", "Tue, 27 Mar 2007 19:36:42 +0000"); 
     272                request.AddHeader("authorization", 
    478273                        "AWS 0PN5J17HBGZHT7JJ3X82:xXjDGYUmKxnwqr5KXNPGldn5LbB="); 
    479274                 
    480275                S3Simulator simulator; 
     276                simulator.Configure("testfiles/s3simulator.conf"); 
    481277                 
    482278                CollectInBufferStream response_buffer; 
     
    488284                std::string response_data((const char *)response.GetBuffer(), 
    489285                        response.GetSize()); 
    490                 TEST_EQUAL("", response_data); 
     286                TEST_EQUAL("<html><head>" 
     287                        "<title>Internal Server Error</title></head>\n" 
     288                        "<h1>Internal Server Error</h1>\n" 
     289                        "<p>An error, type Authentication Failed occured " 
     290                        "when processing the request.</p>" 
     291                        "<p>Please try again later.</p></body>\n" 
     292                        "</html>\n", response_data); 
    491293        } 
    492294 
     
    494296        { 
    495297                S3Simulator simulator; 
     298                simulator.Configure("testfiles/s3simulator.conf"); 
    496299                S3Client client(&simulator, "johnsmith.s3.amazonaws.com", 
    497300                        "0PN5J17HBGZHT7JJ3X82", 
     
    528331                        "/newfile"); 
    529332                request.SetHostName("quotes.s3.amazonaws.com"); 
    530                 request.AddHeader("Date", "Wed, 01 Mar  2006 12:00:00 GMT"); 
    531                 request.AddHeader("Authorization", "AWS 0PN5J17HBGZHT7JJ3X82:XtMYZf0hdOo4TdPYQknZk0Lz7rw="); 
     333                request.AddHeader("date", "Wed, 01 Mar  2006 12:00:00 GMT"); 
     334                request.AddHeader("authorization", "AWS 0PN5J17HBGZHT7JJ3X82:XtMYZf0hdOo4TdPYQknZk0Lz7rw="); 
    532335                request.AddHeader("Content-Type", "text/plain"); 
    533336                 
     
    540343                 
    541344                S3Simulator simulator; 
     345                simulator.Configure("testfiles/s3simulator.conf"); 
    542346                simulator.Handle(request, response); 
    543347                 
     
    559363 
    560364        // Start the S3Simulator server 
    561         pid = LaunchServer("./test s3server testfiles/httpserver.conf", 
    562                 "testfiles/httpserver.pid"); 
     365        pid = LaunchServer("./test s3server testfiles/s3simulator.conf", 
     366                "testfiles/s3simulator.pid"); 
    563367        TEST_THAT(pid != -1 && pid != 0); 
    564368        if(pid <= 0) 
Note: See TracChangeset for help on using the changeset viewer.