Loading src/http.cpp +39 −1 Original line number Diff line number Diff line Loading @@ -3163,6 +3163,24 @@ const std::vector<char> libhttppp::HttpClient::Delete(libhttppp::HttpRequest &nr return _doH1Request("DELETE", DELETEREQUEST, nreq, nullptr, maxTries, /*followRedirects=*/false); } const std::vector<char> libhttppp::HttpClient::Options(libhttppp::HttpRequest &nreq, size_t maxTries) { // No body, and a 3xx response to a CORS/capability preflight isn't meaningful to follow -- // same reasoning as Delete(). return _doH1Request("OPTIONS", OPTIONSREQUEST, nreq, nullptr, maxTries, /*followRedirects=*/false); } const std::vector<char> libhttppp::HttpClient::Head(libhttppp::HttpRequest &nreq, size_t maxTries) { return _doH1Request("HEAD", HEADREQUEST, nreq, nullptr, maxTries, /*followRedirects=*/true); } const std::vector<char> libhttppp::HttpClient::Patch(libhttppp::HttpRequest &nreq, const std::vector<char> &patch, size_t maxTries) { return _doH1Request("PATCH", PATCHREQUEST, nreq, &patch, maxTries, /*followRedirects=*/true); } const std::vector<char> libhttppp::HttpClient::Put(libhttppp::HttpRequest &nreq, const std::vector<char> &put, size_t maxTries) { Loading Loading @@ -4130,6 +4148,9 @@ size_t libhttppp::HttpRequest::parseH2(const std::vector<hpack::HeaderField> &he else if (method == "POST") _RequestType = POSTREQUEST; else if (method == "PUT") _RequestType = PUTREQUEST; else if (method == "DELETE") _RequestType = DELETEREQUEST; else if (method == "OPTIONS") _RequestType = OPTIONSREQUEST; else if (method == "HEAD") _RequestType = HEADREQUEST; else if (method == "PATCH") _RequestType = PATCHREQUEST; else _RequestType = GETREQUEST; auto *pathHd = getHeaderData(":path"); Loading Loading @@ -4198,6 +4219,9 @@ size_t libhttppp::HttpRequest::parseH3(const std::vector<qpack::HeaderField> &he else if (method == "POST") _RequestType = POSTREQUEST; else if (method == "PUT") _RequestType = PUTREQUEST; else if (method == "DELETE") _RequestType = DELETEREQUEST; else if (method == "OPTIONS") _RequestType = OPTIONSREQUEST; else if (method == "HEAD") _RequestType = HEADREQUEST; else if (method == "PATCH") _RequestType = PATCHREQUEST; else _RequestType = GETREQUEST; auto *pathHd = getHeaderData(":path"); Loading Loading @@ -4286,7 +4310,15 @@ size_t libhttppp::HttpRequest::parseH1() { else if (method == "POST") _RequestType = POSTREQUEST; else if (method == "PUT") _RequestType = PUTREQUEST; else if (method == "DELETE") _RequestType = DELETEREQUEST; else _RequestType = PARSEREQUEST; // or a dedicated enum for others else if (method == "OPTIONS") _RequestType = OPTIONSREQUEST; else if (method == "HEAD") _RequestType = HEADREQUEST; else if (method == "PATCH") _RequestType = PATCHREQUEST; // Anything else falling back to PARSEREQUEST was worse than just wrong labeling: the // REQUESTHANDLING switch in httpd.cpp only recognizes GET/POST/PUT/DELETE/PARSEREQUEST, // and PARSEREQUEST there means "re-invoke parse() on whatever's left in RecvData" -- for // an already-fully-parsed-but-unrecognized method that reparses the request body (or // nothing) as a fresh request line, never reaching RequestEvent at all. else _RequestType = GETREQUEST; // 6) Store pseudo-headers in _firstHeaderData (unified storage) { Loading Loading @@ -4417,6 +4449,12 @@ void libhttppp::HttpRequest::printHeader(std::string &buffer){ buffer="PUT "; else if(_RequestType==DELETEREQUEST) buffer="DELETE "; else if(_RequestType==OPTIONSREQUEST) buffer="OPTIONS "; else if(_RequestType==HEADREQUEST) buffer="HEAD "; else if(_RequestType==PATCHREQUEST) buffer="PATCH "; buffer.append(_cachedRequest); buffer.append(" "); Loading src/http.h +3 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,9 @@ namespace libhttppp { const std::vector<char> Post(HttpRequest &nreq,const std::vector<char> &post, size_t maxTries=0); const std::vector<char> Put(HttpRequest &nreq,const std::vector<char> &put, size_t maxTries=0); const std::vector<char> Delete(HttpRequest &nreq, size_t maxTries=0); const std::vector<char> Options(HttpRequest &nreq, size_t maxTries=0); const std::vector<char> Head(HttpRequest &nreq, size_t maxTries=0); const std::vector<char> Patch(HttpRequest &nreq,const std::vector<char> &patch, size_t maxTries=0); // Streaming API: send request, return parsed response headers only. // After this call, use readBodyChunk() to read body data incrementally. Loading src/httpd.cpp +12 −2 Original line number Diff line number Diff line Loading @@ -1909,7 +1909,16 @@ REQUESTHANDLING: RequestEvent(cureq,tid,args); cureq._RequestType=PARSEREQUEST; break; case PUTREQUEST: { case OPTIONSREQUEST: RequestEvent(cureq,tid,args); cureq._RequestType=PARSEREQUEST; break; case HEADREQUEST: RequestEvent(cureq,tid,args); cureq._RequestType=PARSEREQUEST; break; case PUTREQUEST: case PATCHREQUEST: { if(cureq.isChunkedRequest()){ int dr = cureq.decodeChunkedBody(); if(dr == 0) break; // body incomplete, wait for more Loading Loading @@ -2086,7 +2095,8 @@ void libhttppp::HttpEvent::ResponseEvent(netplus::con &curcon,const int tid,ULON // destroy parsed headers — including Content-Length — causing the // partially received body to be re-parsed as HTTP headers, which // leads to an endless loop for large/multi-file uploads). if (cureq.getRequestType() == POSTREQUEST || cureq.getRequestType() == PUTREQUEST) { if (cureq.getRequestType() == POSTREQUEST || cureq.getRequestType() == PUTREQUEST || cureq.getRequestType() == PATCHREQUEST) { return; } if (cureq.getRequestType() == PARSEREQUEST && cureq.getRequestURL().empty()) { Loading src/httpdefinitions.h +3 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define POSTREQUEST 2 #define DELETEREQUEST 3 #define PUTREQUEST 4 #define OPTIONSREQUEST 5 #define HEADREQUEST 6 #define PATCHREQUEST 7 //define http version Loading Loading
src/http.cpp +39 −1 Original line number Diff line number Diff line Loading @@ -3163,6 +3163,24 @@ const std::vector<char> libhttppp::HttpClient::Delete(libhttppp::HttpRequest &nr return _doH1Request("DELETE", DELETEREQUEST, nreq, nullptr, maxTries, /*followRedirects=*/false); } const std::vector<char> libhttppp::HttpClient::Options(libhttppp::HttpRequest &nreq, size_t maxTries) { // No body, and a 3xx response to a CORS/capability preflight isn't meaningful to follow -- // same reasoning as Delete(). return _doH1Request("OPTIONS", OPTIONSREQUEST, nreq, nullptr, maxTries, /*followRedirects=*/false); } const std::vector<char> libhttppp::HttpClient::Head(libhttppp::HttpRequest &nreq, size_t maxTries) { return _doH1Request("HEAD", HEADREQUEST, nreq, nullptr, maxTries, /*followRedirects=*/true); } const std::vector<char> libhttppp::HttpClient::Patch(libhttppp::HttpRequest &nreq, const std::vector<char> &patch, size_t maxTries) { return _doH1Request("PATCH", PATCHREQUEST, nreq, &patch, maxTries, /*followRedirects=*/true); } const std::vector<char> libhttppp::HttpClient::Put(libhttppp::HttpRequest &nreq, const std::vector<char> &put, size_t maxTries) { Loading Loading @@ -4130,6 +4148,9 @@ size_t libhttppp::HttpRequest::parseH2(const std::vector<hpack::HeaderField> &he else if (method == "POST") _RequestType = POSTREQUEST; else if (method == "PUT") _RequestType = PUTREQUEST; else if (method == "DELETE") _RequestType = DELETEREQUEST; else if (method == "OPTIONS") _RequestType = OPTIONSREQUEST; else if (method == "HEAD") _RequestType = HEADREQUEST; else if (method == "PATCH") _RequestType = PATCHREQUEST; else _RequestType = GETREQUEST; auto *pathHd = getHeaderData(":path"); Loading Loading @@ -4198,6 +4219,9 @@ size_t libhttppp::HttpRequest::parseH3(const std::vector<qpack::HeaderField> &he else if (method == "POST") _RequestType = POSTREQUEST; else if (method == "PUT") _RequestType = PUTREQUEST; else if (method == "DELETE") _RequestType = DELETEREQUEST; else if (method == "OPTIONS") _RequestType = OPTIONSREQUEST; else if (method == "HEAD") _RequestType = HEADREQUEST; else if (method == "PATCH") _RequestType = PATCHREQUEST; else _RequestType = GETREQUEST; auto *pathHd = getHeaderData(":path"); Loading Loading @@ -4286,7 +4310,15 @@ size_t libhttppp::HttpRequest::parseH1() { else if (method == "POST") _RequestType = POSTREQUEST; else if (method == "PUT") _RequestType = PUTREQUEST; else if (method == "DELETE") _RequestType = DELETEREQUEST; else _RequestType = PARSEREQUEST; // or a dedicated enum for others else if (method == "OPTIONS") _RequestType = OPTIONSREQUEST; else if (method == "HEAD") _RequestType = HEADREQUEST; else if (method == "PATCH") _RequestType = PATCHREQUEST; // Anything else falling back to PARSEREQUEST was worse than just wrong labeling: the // REQUESTHANDLING switch in httpd.cpp only recognizes GET/POST/PUT/DELETE/PARSEREQUEST, // and PARSEREQUEST there means "re-invoke parse() on whatever's left in RecvData" -- for // an already-fully-parsed-but-unrecognized method that reparses the request body (or // nothing) as a fresh request line, never reaching RequestEvent at all. else _RequestType = GETREQUEST; // 6) Store pseudo-headers in _firstHeaderData (unified storage) { Loading Loading @@ -4417,6 +4449,12 @@ void libhttppp::HttpRequest::printHeader(std::string &buffer){ buffer="PUT "; else if(_RequestType==DELETEREQUEST) buffer="DELETE "; else if(_RequestType==OPTIONSREQUEST) buffer="OPTIONS "; else if(_RequestType==HEADREQUEST) buffer="HEAD "; else if(_RequestType==PATCHREQUEST) buffer="PATCH "; buffer.append(_cachedRequest); buffer.append(" "); Loading
src/http.h +3 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,9 @@ namespace libhttppp { const std::vector<char> Post(HttpRequest &nreq,const std::vector<char> &post, size_t maxTries=0); const std::vector<char> Put(HttpRequest &nreq,const std::vector<char> &put, size_t maxTries=0); const std::vector<char> Delete(HttpRequest &nreq, size_t maxTries=0); const std::vector<char> Options(HttpRequest &nreq, size_t maxTries=0); const std::vector<char> Head(HttpRequest &nreq, size_t maxTries=0); const std::vector<char> Patch(HttpRequest &nreq,const std::vector<char> &patch, size_t maxTries=0); // Streaming API: send request, return parsed response headers only. // After this call, use readBodyChunk() to read body data incrementally. Loading
src/httpd.cpp +12 −2 Original line number Diff line number Diff line Loading @@ -1909,7 +1909,16 @@ REQUESTHANDLING: RequestEvent(cureq,tid,args); cureq._RequestType=PARSEREQUEST; break; case PUTREQUEST: { case OPTIONSREQUEST: RequestEvent(cureq,tid,args); cureq._RequestType=PARSEREQUEST; break; case HEADREQUEST: RequestEvent(cureq,tid,args); cureq._RequestType=PARSEREQUEST; break; case PUTREQUEST: case PATCHREQUEST: { if(cureq.isChunkedRequest()){ int dr = cureq.decodeChunkedBody(); if(dr == 0) break; // body incomplete, wait for more Loading Loading @@ -2086,7 +2095,8 @@ void libhttppp::HttpEvent::ResponseEvent(netplus::con &curcon,const int tid,ULON // destroy parsed headers — including Content-Length — causing the // partially received body to be re-parsed as HTTP headers, which // leads to an endless loop for large/multi-file uploads). if (cureq.getRequestType() == POSTREQUEST || cureq.getRequestType() == PUTREQUEST) { if (cureq.getRequestType() == POSTREQUEST || cureq.getRequestType() == PUTREQUEST || cureq.getRequestType() == PATCHREQUEST) { return; } if (cureq.getRequestType() == PARSEREQUEST && cureq.getRequestURL().empty()) { Loading
src/httpdefinitions.h +3 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define POSTREQUEST 2 #define DELETEREQUEST 3 #define PUTREQUEST 4 #define OPTIONSREQUEST 5 #define HEADREQUEST 6 #define PATCHREQUEST 7 //define http version Loading