From 141cb51fc6b79fa2919644f71785af1876195548 Mon Sep 17 00:00:00 2001 From: Till Klocke Date: Tue, 8 Sep 2015 13:45:02 +0200 Subject: [PATCH 1/2] Added first attemp to access the raw body without parsing --- Sming/SmingCore/Network/HttpRequest.cpp | 87 ++++++++++++++----- Sming/SmingCore/Network/HttpRequest.h | 3 + .../Network/HttpServerConnection.cpp | 36 +++++--- 3 files changed, 89 insertions(+), 37 deletions(-) diff --git a/Sming/SmingCore/Network/HttpRequest.cpp b/Sming/SmingCore/Network/HttpRequest.cpp index 3b6d195412..decfd57719 100644 --- a/Sming/SmingCore/Network/HttpRequest.cpp +++ b/Sming/SmingCore/Network/HttpRequest.cpp @@ -19,6 +19,7 @@ HttpRequest::HttpRequest() cookies = NULL; postDataProcessed = 0; combinePostFrag = false; + bodyBuf = NULL; } HttpRequest::~HttpRequest() @@ -30,17 +31,19 @@ HttpRequest::~HttpRequest() postDataProcessed = 0; } -String HttpRequest::getQueryParameter(String parameterName, String defaultValue /* = "" */) +String HttpRequest::getQueryParameter(String parameterName, + String defaultValue /* = "" */) { if (requestGetParameters && requestGetParameters->contains(parameterName)) - return (*requestGetParameters)[parameterName]; + return (*requestGetParameters)[parameterName]; return defaultValue; } -String HttpRequest::getPostParameter(String parameterName, String defaultValue /* = "" */) +String HttpRequest::getPostParameter(String parameterName, + String defaultValue /* = "" */) { if (requestPostParameters && requestPostParameters->contains(parameterName)) - return (*requestPostParameters)[parameterName]; + return (*requestPostParameters)[parameterName]; return defaultValue; } @@ -64,7 +67,8 @@ String HttpRequest::getCookie(String name, String defaultValue /* = "" */) int HttpRequest::getContentLength() { String len = getHeader("Content-Length"); - if (len.length() == 0) return -1; + if (len.length() == 0) + return -1; return len.toInt(); } @@ -77,7 +81,8 @@ String HttpRequest::getContentType() HttpParseResult HttpRequest::parseHeader(HttpServer *server, pbuf* buf) { int headerEnd = NetUtils::pbufFindStr(buf, "\r\n\r\n"); - if (headerEnd == -1) return eHPR_Wait; + if (headerEnd == -1) + return eHPR_Wait; if (headerEnd > NETWORK_MAX_HTTP_PARSING_LEN) { debugf("NETWORK_MAX_HTTP_PARSING_LEN"); @@ -97,15 +102,17 @@ HttpParseResult HttpRequest::parseHeader(HttpServer *server, pbuf* buf) if (urlParamsStart != -1 && urlParamsStart < urlEnd) { path = NetUtils::pbufStrCopy(buf, urlStart, urlParamsStart - urlStart); - if (requestGetParameters == NULL) requestGetParameters = new HashMap(); - extractParsingItemsList(buf, urlParamsStart + 1, urlEnd, '&', ' ', requestGetParameters); + if (requestGetParameters == NULL) + requestGetParameters = new HashMap(); + extractParsingItemsList(buf, urlParamsStart + 1, urlEnd, '&', ' ', + requestGetParameters); } else path = NetUtils::pbufStrCopy(buf, urlStart, urlEnd - urlStart); debugf("path=%s", path.c_str()); int line, nextLine; - line = NetUtils::pbufFindStr(buf, "\r\n", urlEnd) + 2; + line = NetUtils::pbufFindStr(buf, "\r\n", urlEnd) + 2; do { nextLine = NetUtils::pbufFindStr(buf, "\r\n", line); @@ -119,14 +126,18 @@ HttpParseResult HttpRequest::parseHeader(HttpServer *server, pbuf* buf) { if (name == "Cookie") { - if (cookies == NULL) cookies = new HashMap(); - extractParsingItemsList(buf, delim + 1, nextLine, ';', '\r', cookies); + if (cookies == NULL) + cookies = new HashMap(); + extractParsingItemsList(buf, delim + 1, nextLine, ';', + '\r', cookies); } else { - String value = NetUtils::pbufStrCopy(buf, delim + 1, nextLine - (delim + 1)); + String value = NetUtils::pbufStrCopy(buf, delim + 1, + nextLine - (delim + 1)); value.trim(); - if (requestHeaders == NULL) requestHeaders = new HashMap(); + if (requestHeaders == NULL) + requestHeaders = new HashMap(); (*requestHeaders)[name] = value; debugf("%s === %s", name.c_str(), value.c_str()); } @@ -134,7 +145,7 @@ HttpParseResult HttpRequest::parseHeader(HttpServer *server, pbuf* buf) } } line = nextLine + 2; - } while(nextLine != -1); + } while (nextLine != -1); if (headerEnd != -1) { @@ -152,7 +163,8 @@ HttpParseResult HttpRequest::parsePostData(HttpServer *server, pbuf* buf) if (requestPostParameters == NULL) { int headerEnd = NetUtils::pbufFindStr(buf, "\r\n\r\n"); - if (headerEnd == -1) return eHPR_Failed; + if (headerEnd == -1) + return eHPR_Failed; if (headerEnd + getContentLength() > NETWORK_MAX_HTTP_PARSING_LEN) { debugf("NETWORK_MAX_HTTP_PARSING_LEN"); @@ -164,7 +176,8 @@ HttpParseResult HttpRequest::parsePostData(HttpServer *server, pbuf* buf) } else if (combinePostFrag) { - String cur = requestPostParameters->keyAt(requestPostParameters->count() - 1); + String cur = requestPostParameters->keyAt( + requestPostParameters->count() - 1); debugf("Continue POST frag %s", cur.c_str()); int delimItem = NetUtils::pbufFindChar(buf, '&', 0); if (delimItem == -1) @@ -181,7 +194,8 @@ HttpParseResult HttpRequest::parsePostData(HttpServer *server, pbuf* buf) postDataProcessed += start; } - bool notFinished = extractParsingItemsList(buf, start, buf->tot_len, '&', ' ', requestPostParameters); + bool notFinished = extractParsingItemsList(buf, start, buf->tot_len, '&', + ' ', requestPostParameters); if (notFinished) combinePostFrag = true; // continue reading this parameter value //TODO: continue for param name @@ -193,19 +207,21 @@ HttpParseResult HttpRequest::parsePostData(HttpServer *server, pbuf* buf) return eHPR_Wait; } -bool HttpRequest::extractParsingItemsList(pbuf* buf, int startPos, int endPos, char delimChar, char endChar, - HashMap* resultItems) +bool HttpRequest::extractParsingItemsList(pbuf* buf, int startPos, int endPos, + char delimChar, char endChar, HashMap* resultItems) { bool continued = false; int delimItem, nextItem, startItem = startPos; while (startItem < endPos) { delimItem = NetUtils::pbufFindStr(buf, "=", startItem); - if (delimItem == -1 || delimItem > endPos) break; + if (delimItem == -1 || delimItem > endPos) + break; nextItem = NetUtils::pbufFindChar(buf, delimChar, delimItem + 1); if (nextItem == -1) nextItem = NetUtils::pbufFindChar(buf, endChar, delimItem + 1); - if (nextItem > endPos) break; + if (nextItem > endPos) + break; if (nextItem == -1) { @@ -213,8 +229,10 @@ bool HttpRequest::extractParsingItemsList(pbuf* buf, int startPos, int endPos, c continued = true; } - String ItemName = NetUtils::pbufStrCopy(buf, startItem, delimItem - startItem); - String ItemValue = NetUtils::pbufStrCopy(buf, delimItem + 1, nextItem - delimItem - 1); + String ItemName = NetUtils::pbufStrCopy(buf, startItem, + delimItem - startItem); + String ItemValue = NetUtils::pbufStrCopy(buf, delimItem + 1, + nextItem - delimItem - 1); char* nam = uri_unescape(NULL, 0, ItemName.c_str(), -1); ItemName = nam; free(nam); @@ -222,7 +240,8 @@ bool HttpRequest::extractParsingItemsList(pbuf* buf, int startPos, int endPos, c ItemValue = val; free(val); ItemName.trim(); - if (!continued) ItemValue.trim(); + if (!continued) + ItemValue.trim(); debugf("Item: %s = %s", ItemName.c_str(), ItemValue.c_str()); (*resultItems)[ItemName] = ItemValue; startItem = nextItem + 1; @@ -230,6 +249,26 @@ bool HttpRequest::extractParsingItemsList(pbuf* buf, int startPos, int endPos, c return continued; } +void HttpRequest::parseRawData(HttpServer *server, pbuf* buf) +{ + if (!combinePostFrag) + { + bodyBuf = (char *) os_zalloc(sizeof(char) * buf->tot_len); + } + int headerEnd = NetUtils::pbufFindStr(buf, "\r\n\r\n"); + if (headerEnd + getContentLength() > NETWORK_MAX_HTTP_PARSING_LEN) + { + debugf("NETWORK_MAX_HTTP_PARSING_LEN"); + return; + } + pbuf_copy_partial(buf, bodyBuf, buf->tot_len, headerEnd + 4); +} + +char* HttpRequest::getBody() +{ + return bodyBuf; +} + bool HttpRequest::isAjax() { String req = getHeader("HTTP_X_REQUESTED_WITH"); diff --git a/Sming/SmingCore/Network/HttpRequest.h b/Sming/SmingCore/Network/HttpRequest.h index 9317522eba..ef444af857 100644 --- a/Sming/SmingCore/Network/HttpRequest.h +++ b/Sming/SmingCore/Network/HttpRequest.h @@ -42,6 +42,7 @@ class HttpRequest String getPostParameter(String parameterName, String defaultValue = ""); String getHeader(String headerName, String defaultValue = ""); String getCookie(String cookieName, String defaultValue = ""); + char* getBody(); public: HttpParseResult parseHeader(HttpServer *server, pbuf* buf); @@ -49,6 +50,7 @@ class HttpRequest bool extractParsingItemsList(pbuf* buf, int startPos, int endPos, char delimChar, char endChar, HashMap *resultItems); + void parseRawData(HttpServer *server, pbuf* buf); private: String method; @@ -59,6 +61,7 @@ class HttpRequest HashMap *cookies; int postDataProcessed; bool combinePostFrag; + char *bodyBuf; friend class TemplateFileStream; }; diff --git a/Sming/SmingCore/Network/HttpServerConnection.cpp b/Sming/SmingCore/Network/HttpServerConnection.cpp index 9a7261d423..ab64447bb1 100644 --- a/Sming/SmingCore/Network/HttpServerConnection.cpp +++ b/Sming/SmingCore/Network/HttpServerConnection.cpp @@ -11,8 +11,9 @@ #include "TcpServer.h" #include "../../Services/cWebsocket/websocket.h" -HttpServerConnection::HttpServerConnection(HttpServer *parentServer, tcp_pcb *clientTcp) - : TcpConnection(clientTcp, true), server(parentServer), state(eHCS_Ready) +HttpServerConnection::HttpServerConnection(HttpServer *parentServer, + tcp_pcb *clientTcp) : + TcpConnection(clientTcp, true), server(parentServer), state(eHCS_Ready) { TcpServer::totalConnections++; response.setHeader("Connection", "close"); @@ -32,13 +33,13 @@ err_t HttpServerConnection::onReceive(pbuf *buf) } /*{ - // split.buf.test - pbuf* dbghack = new pbuf(); - dbghack->payload = (char*)buf->payload + 100; - dbghack->len = buf->len - 100; - buf->len = 100; - buf->next = dbghack; - }*/ + // split.buf.test + pbuf* dbghack = new pbuf(); + dbghack->payload = (char*)buf->payload + 100; + dbghack->len = buf->len - 100; + buf->len = 100; + buf->next = dbghack; + }*/ if (state == eHCS_Ready) { @@ -54,11 +55,14 @@ err_t HttpServerConnection::onReceive(pbuf *buf) else if (res == eHPR_Successful) { debugf("Request: %s, %s", request.getRequestMethod().c_str(), - (request.getContentLength() > 0 ? (String(request.getContentLength()) + " bytes").c_str() : "nodata")); + (request.getContentLength() > 0 ? + (String(request.getContentLength()) + " bytes").c_str() : + "nodata")); String contType = request.getContentType(); contType.toLowerCase(); - if (request.getContentLength() > 0 && contType.indexOf(ContentType::FormUrlEncoded) != -1) + if (request.getContentLength() > 0 + && contType.indexOf(ContentType::FormUrlEncoded) != -1) state = eHCS_ParsePostData; else state = eHCS_ParsingCompleted; @@ -86,6 +90,10 @@ err_t HttpServerConnection::onReceive(pbuf *buf) state = eHCS_ParsingCompleted; } } + else if (state == eHCS_ParsingCompleted && request.getContentLength() > 0) + { + request.parseRawData(server, buf); + } // Fire callbacks TcpConnection::onReceive(buf); @@ -102,7 +110,8 @@ void HttpServerConnection::beginSendData() return; } - if (!response.hasBody() && (response.getStatusCode() < 100 || response.getStatusCode() > 399)) + if (!response.hasBody() + && (response.getStatusCode() < 100 || response.getStatusCode() > 399)) { // Show default error message sendError(); @@ -173,7 +182,8 @@ void HttpServerConnection::onError(err_t err) TcpConnection::onError(err); } -void HttpServerConnection::setDisconnectionHandler(HttpServerConnectionDelegate handler) +void HttpServerConnection::setDisconnectionHandler( + HttpServerConnectionDelegate handler) { disconnection = handler; } From b9dfc651a8d01bf066e98b3b643d1e22c9f66cd1 Mon Sep 17 00:00:00 2001 From: Till Klocke Date: Tue, 8 Sep 2015 13:53:06 +0200 Subject: [PATCH 2/2] bodyBuf is now freed in destructor of HttpRequest, but only if it was allocated first --- Sming/SmingCore/Network/HttpRequest.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Sming/SmingCore/Network/HttpRequest.cpp b/Sming/SmingCore/Network/HttpRequest.cpp index decfd57719..dab13faf27 100644 --- a/Sming/SmingCore/Network/HttpRequest.cpp +++ b/Sming/SmingCore/Network/HttpRequest.cpp @@ -29,6 +29,10 @@ HttpRequest::~HttpRequest() delete requestPostParameters; delete cookies; postDataProcessed = 0; + if (bodyBuf != NULL) + { + os_free(bodyBuf); + } } String HttpRequest::getQueryParameter(String parameterName, @@ -251,10 +255,7 @@ bool HttpRequest::extractParsingItemsList(pbuf* buf, int startPos, int endPos, void HttpRequest::parseRawData(HttpServer *server, pbuf* buf) { - if (!combinePostFrag) - { - bodyBuf = (char *) os_zalloc(sizeof(char) * buf->tot_len); - } + bodyBuf = (char *) os_zalloc(sizeof(char) * buf->tot_len); int headerEnd = NetUtils::pbufFindStr(buf, "\r\n\r\n"); if (headerEnd + getContentLength() > NETWORK_MAX_HTTP_PARSING_LEN) {