comparison Core/HttpServer/MongooseServer.cpp @ 416:1188cb0ddaa5

http method faking
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 06 May 2013 16:32:27 +0200
parents d558fa565c42
children 7441037663cd
comparison
equal deleted inserted replaced
415:d558fa565c42 416:1188cb0ddaa5
266 } 266 }
267 267
268 268
269 269
270 270
271 static PostDataStatus ReadPostData(std::string& postData, 271 static PostDataStatus ReadBody(std::string& postData,
272 struct mg_connection *connection, 272 struct mg_connection *connection,
273 const HttpHandler::Arguments& headers) 273 const HttpHandler::Arguments& headers)
274 { 274 {
275 HttpHandler::Arguments::const_iterator cs = headers.find("content-length"); 275 HttpHandler::Arguments::const_iterator cs = headers.find("content-length");
276 if (cs == headers.end()) 276 if (cs == headers.end())
277 { 277 {
278 return PostDataStatus_NoLength; 278 return PostDataStatus_NoLength;
320 ChunkStore& chunkStore) 320 ChunkStore& chunkStore)
321 { 321 {
322 std::string boundary = "--" + contentType.substr(multipartLength); 322 std::string boundary = "--" + contentType.substr(multipartLength);
323 323
324 std::string postData; 324 std::string postData;
325 PostDataStatus status = ReadPostData(postData, connection, headers); 325 PostDataStatus status = ReadBody(postData, connection, headers);
326 326
327 if (status != PostDataStatus_Success) 327 if (status != PostDataStatus_Success)
328 { 328 {
329 return status; 329 return status;
330 } 330 }
516 if (overriden.size() > 0) 516 if (overriden.size() > 0)
517 { 517 {
518 // A faking has been done within this request 518 // A faking has been done within this request
519 Toolbox::ToUpperCase(overriden); 519 Toolbox::ToUpperCase(overriden);
520 520
521 LOG(INFO) << "HTTP method faking has been detected for " << overriden;
522
521 if (overriden == "PUT") 523 if (overriden == "PUT")
522 { 524 {
523 method = Orthanc_HttpMethod_Put; 525 method = Orthanc_HttpMethod_Put;
526 return true;
524 } 527 }
525 else if (overriden == "DELETE") 528 else if (overriden == "DELETE")
526 { 529 {
527 method = Orthanc_HttpMethod_Delete; 530 method = Orthanc_HttpMethod_Delete;
531 return true;
528 } 532 }
529 else 533 else
530 { 534 {
531 return false; 535 return false;
532 } 536 }
566 if (event == MG_NEW_REQUEST) 570 if (event == MG_NEW_REQUEST)
567 { 571 {
568 MongooseServer* that = (MongooseServer*) (request->user_data); 572 MongooseServer* that = (MongooseServer*) (request->user_data);
569 MongooseOutput output(connection); 573 MongooseOutput output(connection);
570 574
571
572 // Check remote calls 575 // Check remote calls
573 if (!that->IsRemoteAccessAllowed() && 576 if (!that->IsRemoteAccessAllowed() &&
574 request->remote_ip != LOCALHOST) 577 request->remote_ip != LOCALHOST)
575 { 578 {
576 SendUnauthorized(output); 579 SendUnauthorized(output);
598 601
599 // Compute the HTTP method, taking method faking into consideration 602 // Compute the HTTP method, taking method faking into consideration
600 Orthanc_HttpMethod method; 603 Orthanc_HttpMethod method;
601 if (!ExtractMethod(method, request, headers, argumentsGET)) 604 if (!ExtractMethod(method, request, headers, argumentsGET))
602 { 605 {
603 output.SendHeader(Orthanc_HttpStatus_405_MethodNotAllowed); 606 output.SendHeader(Orthanc_HttpStatus_400_BadRequest);
604 return (void*) ""; 607 return (void*) "";
605 } 608 }
606 609
607 610
608 // Authenticate this connection 611 // Authenticate this connection
637 // Extract the body of the request for PUT and POST 640 // Extract the body of the request for PUT and POST
638 std::string body; 641 std::string body;
639 if (method == Orthanc_HttpMethod_Post || 642 if (method == Orthanc_HttpMethod_Post ||
640 method == Orthanc_HttpMethod_Put) 643 method == Orthanc_HttpMethod_Put)
641 { 644 {
645 PostDataStatus status;
646
642 HttpHandler::Arguments::const_iterator ct = headers.find("content-type"); 647 HttpHandler::Arguments::const_iterator ct = headers.find("content-type");
643 if (ct == headers.end()) 648 if (ct == headers.end())
644 { 649 {
645 output.SendHeader(Orthanc_HttpStatus_400_BadRequest); 650 // No content-type specified. Assume no multi-part content occurs at this point.
646 return (void*) ""; 651 status = ReadBody(body, connection, headers);
647 }
648
649 PostDataStatus status;
650
651 std::string contentType = ct->second;
652 if (contentType.size() >= multipartLength &&
653 !memcmp(contentType.c_str(), multipart, multipartLength))
654 {
655 status = ParseMultipartPost(body, connection, headers, contentType, that->GetChunkStore());
656 } 652 }
657 else 653 else
658 { 654 {
659 status = ReadPostData(body, connection, headers); 655 std::string contentType = ct->second;
656 if (contentType.size() >= multipartLength &&
657 !memcmp(contentType.c_str(), multipart, multipartLength))
658 {
659 status = ParseMultipartPost(body, connection, headers, contentType, that->GetChunkStore());
660 }
661 else
662 {
663 status = ReadBody(body, connection, headers);
664 }
660 } 665 }
661 666
662 switch (status) 667 switch (status)
663 { 668 {
664 case PostDataStatus_NoLength: 669 case PostDataStatus_NoLength:
665 output.SendHeader(Orthanc_HttpStatus_411_LengthRequired); 670 output.SendHeader(Orthanc_HttpStatus_411_LengthRequired);
666 return (void*) ""; 671 return (void*) "";
667 672
668 case PostDataStatus_Failure: 673 case PostDataStatus_Failure:
669 output.SendHeader(Orthanc_HttpStatus_400_BadRequest); 674 output.SendHeader(Orthanc_HttpStatus_400_BadRequest);
670 return (void*) ""; 675 return (void*) "";
671 676
672 case PostDataStatus_Pending: 677 case PostDataStatus_Pending:
673 output.AnswerBufferWithContentType(NULL, 0, ""); 678 output.AnswerBufferWithContentType(NULL, 0, "");
674 return (void*) ""; 679 return (void*) "";
675 680
676 default: 681 default:
677 break; 682 break;
678 } 683 }
679 } 684 }
680 685
681 686
682 // Call the proper handler for this URI 687 // Call the proper handler for this URI
695 HttpHandler* handler = that->FindHandler(uri); 700 HttpHandler* handler = that->FindHandler(uri);
696 if (handler) 701 if (handler)
697 { 702 {
698 try 703 try
699 { 704 {
705 LOG(INFO) << Orthanc_HttpMethod_ToString(method) << " " << Toolbox::FlattenUri(uri);
700 handler->Handle(output, method, uri, headers, argumentsGET, body); 706 handler->Handle(output, method, uri, headers, argumentsGET, body);
701 } 707 }
702 catch (OrthancException& e) 708 catch (OrthancException& e)
703 { 709 {
704 LOG(ERROR) << "MongooseServer Exception [" << e.What() << "]"; 710 LOG(ERROR) << "MongooseServer Exception [" << e.What() << "]";