Changeset 2444 for box/trunk/test
- Timestamp:
- 07/01/2009 17:31:04 (3 years ago)
- File:
-
- 1 edited
-
box/trunk/test/httpserver/testhttpserver.cpp (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
box/trunk/test/httpserver/testhttpserver.cpp
r2442 r2444 10 10 #include "Box.h" 11 11 12 #include <stdio.h> 13 #include <string.h> 12 #include <cstdio> 13 #include <cstring> 14 #include <ctime> 14 15 15 16 #include <openssl/hmac.h> 16 17 18 #include "autogen_HTTPException.h" 17 19 #include "HTTPRequest.h" 18 20 #include "HTTPResponse.h" … … 199 201 unsigned char digest_buffer[EVP_MAX_MD_SIZE]; 200 202 unsigned int digest_size = sizeof(digest_buffer); 201 unsigned char* mac =HMAC(EVP_sha1(),203 /* unsigned char* mac = */ HMAC(EVP_sha1(), 202 204 secret_key.c_str(), secret_key.size(), 203 205 (const unsigned char*)data_string.c_str(), … … 325 327 } 326 328 329 class S3Client 330 { 331 public: 332 S3Client(S3Simulator* pSimulator, const std::string& rHostName, 333 const std::string& rAccessKey, const std::string& rSecretKey) 334 : mpSimulator(pSimulator), 335 mHostName(rHostName), 336 mAccessKey(rAccessKey), 337 mSecretKey(rSecretKey) 338 { } 339 340 S3Client(std::string HostName, int Port, const std::string& rAccessKey, 341 const std::string& rSecretKey) 342 : mpSimulator(NULL), 343 mHostName(HostName), 344 mPort(Port), 345 mAccessKey(rAccessKey), 346 mSecretKey(rSecretKey) 347 { } 348 349 HTTPResponse GetObject(const std::string& rObjectURI); 350 351 private: 352 S3Simulator* mpSimulator; 353 std::string mHostName; 354 int mPort; 355 std::auto_ptr<SocketStream> mapClientSocket; 356 std::string mAccessKey, mSecretKey; 357 358 HTTPResponse FinishAndSendRequest(HTTPRequest::Method Method, 359 const std::string& rRequestURI, 360 IOStream* pStreamToSend = NULL, 361 const char* pStreamContentType = NULL); 362 HTTPResponse SendRequest(HTTPRequest& rRequest, 363 IOStream* pStreamToSend = NULL, 364 const char* pStreamContentType = NULL); 365 }; 366 367 HTTPResponse S3Client::GetObject(const std::string& rObjectURI) 368 { 369 return FinishAndSendRequest(HTTPRequest::Method_GET, rObjectURI); 370 } 371 372 HTTPResponse S3Client::FinishAndSendRequest(HTTPRequest::Method Method, 373 const std::string& rRequestURI, IOStream* pStreamToSend, 374 const char* pStreamContentType) 375 { 376 HTTPRequest request(Method, rRequestURI); 377 request.SetHostName(mHostName); 378 379 std::ostringstream date; 380 time_t tt = time(NULL); 381 struct tm *tp = gmtime(&tt); 382 if (!tp) 383 { 384 BOX_ERROR("Failed to get current time"); 385 THROW_EXCEPTION(HTTPException, Internal); 386 } 387 const char *dow[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; 388 date << dow[tp->tm_wday] << ", "; 389 const char *month[] = {"Jan","Feb","Mar","Apr","May","Jun", 390 "Jul","Aug","Sep","Oct","Nov","Dec"}; 391 date << std::internal << std::setfill('0') << 392 std::setw(2) << tp->tm_mday << " " << 393 month[tp->tm_mon] << " " << 394 (tp->tm_year + 1900) << " "; 395 date << std::setw(2) << tp->tm_hour << ":" << 396 std::setw(2) << tp->tm_min << ":" << 397 std::setw(2) << tp->tm_sec << " GMT"; 398 request.AddHeader("Date", date.str()); 399 400 if (pStreamContentType) 401 { 402 request.AddHeader("Content-Type", pStreamContentType); 403 } 404 405 std::string s3suffix = ".s3.amazonaws.com"; 406 std::string bucket; 407 if (mHostName.size() > s3suffix.size()) 408 { 409 std::string suffix = mHostName.substr(mHostName.size() - 410 s3suffix.size(), s3suffix.size()); 411 if (suffix == s3suffix) 412 { 413 bucket = mHostName.substr(0, mHostName.size() - 414 s3suffix.size()); 415 } 416 } 417 418 std::ostringstream data; 419 data << request.GetVerb() << "\n"; 420 data << "\n"; /* Content-MD5 */ 421 data << request.GetContentType() << "\n"; 422 data << date.str() << "\n"; 423 424 if (! bucket.empty()) 425 { 426 data << "/" << bucket; 427 } 428 429 data << request.GetRequestURI(); 430 std::string data_string = data.str(); 431 432 unsigned char digest_buffer[EVP_MAX_MD_SIZE]; 433 unsigned int digest_size = sizeof(digest_buffer); 434 /* unsigned char* mac = */ HMAC(EVP_sha1(), 435 mSecretKey.c_str(), mSecretKey.size(), 436 (const unsigned char*)data_string.c_str(), 437 data_string.size(), digest_buffer, &digest_size); 438 std::string digest((const char *)digest_buffer, digest_size); 439 440 base64::encoder encoder; 441 std::string auth_code = "AWS " + mAccessKey + ":" + 442 encoder.encode(digest); 443 444 if (auth_code[auth_code.size() - 1] == '\n') 445 { 446 auth_code = auth_code.substr(0, auth_code.size() - 1); 447 } 448 449 request.AddHeader("Authorization", auth_code); 450 451 if (mpSimulator) 452 { 453 if (pStreamToSend) 454 { 455 pStreamToSend->CopyStreamTo(request); 456 } 457 458 request.SetForReading(); 459 CollectInBufferStream response_buffer; 460 HTTPResponse response(&response_buffer); 461 462 mpSimulator->Handle(request, response); 463 return response; 464 } 465 else 466 { 467 try 468 { 469 if (!mapClientSocket.get()) 470 { 471 mapClientSocket.reset(new SocketStream()); 472 mapClientSocket->Open(Socket::TypeINET, 473 mHostName, mPort); 474 } 475 return SendRequest(request, pStreamToSend, 476 pStreamContentType); 477 } 478 catch (ConnectionException &ce) 479 { 480 if (ce.GetType() == ConnectionException::SocketWriteError) 481 { 482 // server may have disconnected us, 483 // try to reconnect, just once 484 mapClientSocket->Open(Socket::TypeINET, 485 mHostName, mPort); 486 return SendRequest(request, pStreamToSend, 487 pStreamContentType); 488 } 489 else 490 { 491 throw; 492 } 493 } 494 } 495 } 496 497 HTTPResponse S3Client::SendRequest(HTTPRequest& rRequest, 498 IOStream* pStreamToSend, const char* pStreamContentType) 499 { 500 HTTPResponse response; 501 502 if (pStreamToSend) 503 { 504 rRequest.SendWithStream(*mapClientSocket, 505 30000 /* milliseconds */, 506 pStreamToSend, response); 507 } 508 else 509 { 510 rRequest.Send(*mapClientSocket, 30000 /* milliseconds */); 511 response.Receive(*mapClientSocket, 30000 /* milliseconds */); 512 } 513 514 return response; 515 } 516 327 517 int test(int argc, const char *argv[]) 328 518 { … … 437 627 TestRemoteProcessMemLeaks("generic-httpserver.memleaks"); 438 628 629 // correct, official signature should succeed 439 630 { 440 631 // http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAuthentication.html … … 458 649 } 459 650 651 // modified signature should fail 460 652 { 461 653 // http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAuthentication.html … … 479 671 } 480 672 481 { 482 HTTPRequest request(HTTPRequest::Method_GET, "/nonexist"); 483 request.SetHostName("quotes.s3.amazonaws.com"); 484 request.AddHeader("Date", "Wed, 01 Mar 2006 12:00:00 GMT"); 485 request.AddHeader("Authorization", "AWS 0PN5J17HBGZHT7JJ3X82:0cSX/YPdtXua1aFFpYmH1tc0ajA="); 486 673 // S3Client tests 674 { 487 675 S3Simulator simulator; 488 489 CollectInBufferStream response_buffer; 490 HTTPResponse response(&response_buffer); 491 492 simulator.Handle(request, response); 676 S3Client client(&simulator, "johnsmith.s3.amazonaws.com", 677 "0PN5J17HBGZHT7JJ3X82", 678 "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o"); 679 680 HTTPResponse response = client.GetObject("/photos/puppy.jpg"); 681 TEST_EQUAL(200, response.GetResponseCode()); 682 std::string response_data((const char *)response.GetBuffer(), 683 response.GetSize()); 684 TEST_EQUAL("omgpuppies!\n", response_data); 685 686 response = client.GetObject("/nonexist"); 493 687 TEST_EQUAL(404, response.GetResponseCode()); 494 688 }
Note: See TracChangeset
for help on using the changeset viewer.
