Mercurial > hg > orthanc
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() << "]"; |