# HG changeset patch # User Sebastien Jodogne # Date 1367850747 -7200 # Node ID 1188cb0ddaa538be6b2e5a31d7d0b385a77589f3 # Parent d558fa565c42fc31dd978f3a6fde1294b0969027 http method faking diff -r d558fa565c42 -r 1188cb0ddaa5 CMakeLists.txt --- a/CMakeLists.txt Mon May 06 13:51:59 2013 +0200 +++ b/CMakeLists.txt Mon May 06 16:32:27 2013 +0200 @@ -150,6 +150,7 @@ Core/Lua/LuaFunctionCall.cpp OrthancCppClient/HttpClient.cpp + OrthancCppClient/HttpEnumerations.cpp OrthancCppClient/HttpException.cpp ) diff -r d558fa565c42 -r 1188cb0ddaa5 Core/HttpServer/MongooseServer.cpp --- a/Core/HttpServer/MongooseServer.cpp Mon May 06 13:51:59 2013 +0200 +++ b/Core/HttpServer/MongooseServer.cpp Mon May 06 16:32:27 2013 +0200 @@ -268,9 +268,9 @@ - static PostDataStatus ReadPostData(std::string& postData, - struct mg_connection *connection, - const HttpHandler::Arguments& headers) + static PostDataStatus ReadBody(std::string& postData, + struct mg_connection *connection, + const HttpHandler::Arguments& headers) { HttpHandler::Arguments::const_iterator cs = headers.find("content-length"); if (cs == headers.end()) @@ -322,7 +322,7 @@ std::string boundary = "--" + contentType.substr(multipartLength); std::string postData; - PostDataStatus status = ReadPostData(postData, connection, headers); + PostDataStatus status = ReadBody(postData, connection, headers); if (status != PostDataStatus_Success) { @@ -518,13 +518,17 @@ // A faking has been done within this request Toolbox::ToUpperCase(overriden); + LOG(INFO) << "HTTP method faking has been detected for " << overriden; + if (overriden == "PUT") { method = Orthanc_HttpMethod_Put; + return true; } else if (overriden == "DELETE") { method = Orthanc_HttpMethod_Delete; + return true; } else { @@ -568,7 +572,6 @@ MongooseServer* that = (MongooseServer*) (request->user_data); MongooseOutput output(connection); - // Check remote calls if (!that->IsRemoteAccessAllowed() && request->remote_ip != LOCALHOST) @@ -600,7 +603,7 @@ Orthanc_HttpMethod method; if (!ExtractMethod(method, request, headers, argumentsGET)) { - output.SendHeader(Orthanc_HttpStatus_405_MethodNotAllowed); + output.SendHeader(Orthanc_HttpStatus_400_BadRequest); return (void*) ""; } @@ -639,42 +642,44 @@ if (method == Orthanc_HttpMethod_Post || method == Orthanc_HttpMethod_Put) { + PostDataStatus status; + HttpHandler::Arguments::const_iterator ct = headers.find("content-type"); if (ct == headers.end()) { - output.SendHeader(Orthanc_HttpStatus_400_BadRequest); - return (void*) ""; - } - - PostDataStatus status; - - std::string contentType = ct->second; - if (contentType.size() >= multipartLength && - !memcmp(contentType.c_str(), multipart, multipartLength)) - { - status = ParseMultipartPost(body, connection, headers, contentType, that->GetChunkStore()); + // No content-type specified. Assume no multi-part content occurs at this point. + status = ReadBody(body, connection, headers); } else { - status = ReadPostData(body, connection, headers); + std::string contentType = ct->second; + if (contentType.size() >= multipartLength && + !memcmp(contentType.c_str(), multipart, multipartLength)) + { + status = ParseMultipartPost(body, connection, headers, contentType, that->GetChunkStore()); + } + else + { + status = ReadBody(body, connection, headers); + } } switch (status) { - case PostDataStatus_NoLength: - output.SendHeader(Orthanc_HttpStatus_411_LengthRequired); - return (void*) ""; + case PostDataStatus_NoLength: + output.SendHeader(Orthanc_HttpStatus_411_LengthRequired); + return (void*) ""; - case PostDataStatus_Failure: - output.SendHeader(Orthanc_HttpStatus_400_BadRequest); - return (void*) ""; + case PostDataStatus_Failure: + output.SendHeader(Orthanc_HttpStatus_400_BadRequest); + return (void*) ""; - case PostDataStatus_Pending: - output.AnswerBufferWithContentType(NULL, 0, ""); - return (void*) ""; + case PostDataStatus_Pending: + output.AnswerBufferWithContentType(NULL, 0, ""); + return (void*) ""; - default: - break; + default: + break; } } @@ -697,6 +702,7 @@ { try { + LOG(INFO) << Orthanc_HttpMethod_ToString(method) << " " << Toolbox::FlattenUri(uri); handler->Handle(output, method, uri, headers, argumentsGET, body); } catch (OrthancException& e) diff -r d558fa565c42 -r 1188cb0ddaa5 Core/RestApi/RestApi.cpp --- a/Core/RestApi/RestApi.cpp Mon May 06 13:51:59 2013 +0200 +++ b/Core/RestApi/RestApi.cpp Mon May 06 16:32:27 2013 +0200 @@ -198,7 +198,7 @@ { if (it->first->Match(components, trailing, uri)) { - LOG(INFO) << "REST GET call on: " << Toolbox::FlattenUri(uri); + //LOG(INFO) << "REST GET call on: " << Toolbox::FlattenUri(uri); ok = true; GetCall call; call.output_ = &restOutput; @@ -220,7 +220,7 @@ { if (it->first->Match(components, trailing, uri)) { - LOG(INFO) << "REST PUT call on: " << Toolbox::FlattenUri(uri); + //LOG(INFO) << "REST PUT call on: " << Toolbox::FlattenUri(uri); ok = true; PutCall call; call.output_ = &restOutput; @@ -242,7 +242,7 @@ { if (it->first->Match(components, trailing, uri)) { - LOG(INFO) << "REST POST call on: " << Toolbox::FlattenUri(uri); + //LOG(INFO) << "REST POST call on: " << Toolbox::FlattenUri(uri); ok = true; PostCall call; call.output_ = &restOutput; @@ -264,7 +264,7 @@ { if (it->first->Match(components, trailing, uri)) { - LOG(INFO) << "REST DELETE call on: " << Toolbox::FlattenUri(uri); + //LOG(INFO) << "REST DELETE call on: " << Toolbox::FlattenUri(uri); ok = true; DeleteCall call; call.output_ = &restOutput; @@ -280,7 +280,8 @@ if (!ok) { - LOG(INFO) << "REST method " << method << " not allowed on: " << Toolbox::FlattenUri(uri); + LOG(INFO) << "REST method " << Orthanc_HttpMethod_ToString(method) + << " not allowed on: " << Toolbox::FlattenUri(uri); output.SendMethodNotAllowedError(GetAcceptedMethods(uri)); } } diff -r d558fa565c42 -r 1188cb0ddaa5 NEWS --- a/NEWS Mon May 06 13:51:59 2013 +0200 +++ b/NEWS Mon May 06 16:32:27 2013 +0200 @@ -9,6 +9,7 @@ * Filtering of incoming HTTP requests (through Lua scripting) * Clearing of "/exports" and "/changes" * Check MD5 of third party downloads +* Faking of the HTTP methods PUT and DELETE Version 0.5.1 (2013/04/17) diff -r d558fa565c42 -r 1188cb0ddaa5 OrthancCppClient/HttpEnumerations.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancCppClient/HttpEnumerations.cpp Mon May 06 16:32:27 2013 +0200 @@ -0,0 +1,50 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2013 Medical Physics Department, CHU of Liege, + * Belgium + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + **/ + + +#include "HttpEnumerations.h" + +const char* Orthanc_HttpMethod_ToString(Orthanc_HttpMethod method) +{ + switch (method) + { + case Orthanc_HttpMethod_Get: + return "GET"; + + case Orthanc_HttpMethod_Post: + return "POST"; + + case Orthanc_HttpMethod_Delete: + return "DELETE"; + + case Orthanc_HttpMethod_Put: + return "PUT"; + + default: + return "?"; + } +} + diff -r d558fa565c42 -r 1188cb0ddaa5 OrthancCppClient/HttpEnumerations.h --- a/OrthancCppClient/HttpEnumerations.h Mon May 06 13:51:59 2013 +0200 +++ b/OrthancCppClient/HttpEnumerations.h Mon May 06 16:32:27 2013 +0200 @@ -111,3 +111,6 @@ Orthanc_HttpMethod_Delete = 2, Orthanc_HttpMethod_Put = 3 }; + + +const char* Orthanc_HttpMethod_ToString(Orthanc_HttpMethod method);