diff --git a/libraries/WebServer/src/Parsing.cpp b/libraries/WebServer/src/Parsing.cpp index f0b6692bc0c..f3e9a7bcbef 100644 --- a/libraries/WebServer/src/Parsing.cpp +++ b/libraries/WebServer/src/Parsing.cpp @@ -31,8 +31,8 @@ #endif #define __STR(a) #a -#define _STR(a) __STR(a) -const char * _http_method_str[] = { +#define _STR(a) __STR(a) +static const char *_http_method_str[] = { #define XX(num, name, string) _STR(name), HTTP_METHOD_MAP(XX) #undef XX @@ -41,25 +41,25 @@ const char * _http_method_str[] = { static const char Content_Type[] PROGMEM = "Content-Type"; static const char filename[] PROGMEM = "filename"; -static char* readBytesWithTimeout(WiFiClient& client, size_t maxLength, size_t& dataLength, int timeout_ms) -{ +static char *readBytesWithTimeout(WiFiClient &client, size_t maxLength, size_t &dataLength, int timeout_ms) { char *buf = nullptr; dataLength = 0; while (dataLength < maxLength) { int tries = timeout_ms; size_t newLength; - while (!(newLength = client.available()) && tries--) delay(1); + while (!(newLength = client.available()) && tries--) { + delay(1); + } if (!newLength) { break; } if (!buf) { - buf = (char *) malloc(newLength + 1); + buf = (char *)malloc(newLength + 1); if (!buf) { return nullptr; } - } - else { - char* newBuf = (char *) realloc(buf, dataLength + newLength + 1); + } else { + char *newBuf = (char *)realloc(buf, dataLength + newLength + 1); if (!newBuf) { free(buf); return nullptr; @@ -73,13 +73,13 @@ static char* readBytesWithTimeout(WiFiClient& client, size_t maxLength, size_t& return buf; } -bool WebServer::_parseRequest(WiFiClient& client) { +bool WebServer::_parseRequest(WiFiClient &client) { // Read the first line of HTTP request String req = client.readStringUntil('\r'); client.readStringUntil('\n'); //reset header value for (int i = 0; i < _headerKeysCount; ++i) { - _currentHeaders[i].value =String(); + _currentHeaders[i].value = String(); } // First line of HTTP request looks like "GET /path HTTP/1.1" @@ -97,7 +97,7 @@ bool WebServer::_parseRequest(WiFiClient& client) { _currentVersion = atoi(versionEnd.c_str()); String searchStr = ""; int hasSearch = url.indexOf('?'); - if (hasSearch != -1){ + if (hasSearch != -1) { searchStr = url.substring(hasSearch + 1); url = url.substring(0, hasSearch); } @@ -107,7 +107,7 @@ bool WebServer::_parseRequest(WiFiClient& client) { HTTPMethod method = HTTP_ANY; size_t num_methods = sizeof(_http_method_str) / sizeof(const char *); - for (size_t i=0; inext()) { - if (handler->canHandle(_currentMethod, _currentUri)) + if (handler->canHandle(*this, _currentMethod, _currentUri)) { break; + } } _currentHandler = handler; String formData; // below is needed only when POST type request - if (method == HTTP_POST || method == HTTP_PUT || method == HTTP_PATCH || method == HTTP_DELETE){ + if (method == HTTP_POST || method == HTTP_PUT || method == HTTP_PATCH || method == HTTP_DELETE) { String boundaryStr; String headerName; String headerValue; bool isForm = false; bool isEncoded = false; //parse headers - while(1){ + while (1) { req = client.readStringUntil('\r'); client.readStringUntil('\n'); - if (req == "") break;//no moar headers + if (req == "") { + break; //no moar headers + } int headerDiv = req.indexOf(':'); - if (headerDiv == -1){ + if (headerDiv == -1) { break; } headerName = req.substring(0, headerDiv); headerValue = req.substring(headerDiv + 1); headerValue.trim(); - _collectHeader(headerName.c_str(),headerValue.c_str()); + _collectHeader(headerName.c_str(), headerValue.c_str()); log_v("headerName: %s", headerName.c_str()); log_v("headerValue: %s", headerValue.c_str()); - if (headerName.equalsIgnoreCase(FPSTR(Content_Type))){ + if (headerName.equalsIgnoreCase(FPSTR(Content_Type))) { using namespace mime; - if (headerValue.startsWith(FPSTR(mimeTable[txt].mimeType))){ + if (headerValue.startsWith(FPSTR(mimeTable[txt].mimeType))) { isForm = false; - } else if (headerValue.startsWith(F("application/x-www-form-urlencoded"))){ + } else if (headerValue.startsWith(F("application/x-www-form-urlencoded"))) { isForm = false; isEncoded = true; - } else if (headerValue.startsWith(F("multipart/"))){ + } else if (headerValue.startsWith(F("multipart/"))) { boundaryStr = headerValue.substring(headerValue.indexOf('=') + 1); - boundaryStr.replace("\"",""); + boundaryStr.replace("\"", ""); isForm = true; } - } else if (headerName.equalsIgnoreCase(F("Content-Length"))){ + } else if (headerName.equalsIgnoreCase(F("Content-Length"))) { _clientContentLength = headerValue.toInt(); - } else if (headerName.equalsIgnoreCase(F("Host"))){ + } else if (headerName.equalsIgnoreCase(F("Host"))) { _hostHeader = headerValue; } } - if (!isForm && _currentHandler && _currentHandler->canRaw(_currentUri)){ + if (!isForm && _currentHandler && _currentHandler->canRaw(*this, _currentUri)) { log_v("Parse raw"); _currentRaw.reset(new HTTPRaw()); _currentRaw->status = RAW_START; @@ -198,21 +201,23 @@ bool WebServer::_parseRequest(WiFiClient& client) { log_v("Finish Raw"); } else if (!isForm) { size_t plainLength; - char* plainBuf = readBytesWithTimeout(client, _clientContentLength, plainLength, HTTP_MAX_POST_WAIT); + char *plainBuf = readBytesWithTimeout(client, _clientContentLength, plainLength, HTTP_MAX_POST_WAIT); if (plainLength < _clientContentLength) { - free(plainBuf); - return false; + free(plainBuf); + return false; } if (_clientContentLength > 0) { - if(isEncoded){ + if (isEncoded) { //url encoded form - if (searchStr != "") searchStr += '&'; + if (searchStr != "") { + searchStr += '&'; + } searchStr += plainBuf; } _parseArguments(searchStr); - if(!isEncoded){ + if (!isEncoded) { //plain post json or other data - RequestArgument& arg = _currentArgs[_currentArgCount++]; + RequestArgument &arg = _currentArgs[_currentArgCount++]; arg.key = F("plain"); arg.value = String(plainBuf); } @@ -234,22 +239,24 @@ bool WebServer::_parseRequest(WiFiClient& client) { String headerName; String headerValue; //parse headers - while(1){ + while (1) { req = client.readStringUntil('\r'); client.readStringUntil('\n'); - if (req == "") break;//no moar headers + if (req == "") { + break; //no moar headers + } int headerDiv = req.indexOf(':'); - if (headerDiv == -1){ + if (headerDiv == -1) { break; } headerName = req.substring(0, headerDiv); headerValue = req.substring(headerDiv + 2); - _collectHeader(headerName.c_str(),headerValue.c_str()); + _collectHeader(headerName.c_str(), headerValue.c_str()); - log_v("headerName: %s", headerName.c_str()); - log_v("headerValue: %s", headerValue.c_str()); + log_v("headerName: %s", headerName.c_str()); + log_v("headerValue: %s", headerValue.c_str()); - if (headerName.equalsIgnoreCase("Host")){ + if (headerName.equalsIgnoreCase("Host")) { _hostHeader = headerValue; } } @@ -263,20 +270,21 @@ bool WebServer::_parseRequest(WiFiClient& client) { return true; } -bool WebServer::_collectHeader(const char* headerName, const char* headerValue) { +bool WebServer::_collectHeader(const char *headerName, const char *headerValue) { for (int i = 0; i < _headerKeysCount; i++) { if (_currentHeaders[i].key.equalsIgnoreCase(headerName)) { - _currentHeaders[i].value=headerValue; - return true; - } + _currentHeaders[i].value = headerValue; + return true; + } } return false; } void WebServer::_parseArguments(String data) { log_v("args: %s", data.c_str()); - if (_currentArgs) + if (_currentArgs) { delete[] _currentArgs; + } _currentArgs = 0; if (data.length() == 0) { _currentArgCount = 0; @@ -285,16 +293,17 @@ void WebServer::_parseArguments(String data) { } _currentArgCount = 1; - for (int i = 0; i < (int)data.length(); ) { + for (int i = 0; i < (int)data.length();) { i = data.indexOf('&', i); - if (i == -1) + if (i == -1) { break; + } ++i; ++_currentArgCount; } log_v("args count: %d", _currentArgCount); - _currentArgs = new RequestArgument[_currentArgCount+1]; + _currentArgs = new RequestArgument[_currentArgCount + 1]; int pos = 0; int iarg; for (iarg = 0; iarg < _currentArgCount;) { @@ -303,50 +312,83 @@ void WebServer::_parseArguments(String data) { log_v("pos %d =@%d &@%d", pos, equal_sign_index, next_arg_index); if ((equal_sign_index == -1) || ((equal_sign_index > next_arg_index) && (next_arg_index != -1))) { log_e("arg missing value: %d", iarg); - if (next_arg_index == -1) + if (next_arg_index == -1) { break; + } pos = next_arg_index + 1; continue; } - RequestArgument& arg = _currentArgs[iarg]; + RequestArgument &arg = _currentArgs[iarg]; arg.key = urlDecode(data.substring(pos, equal_sign_index)); arg.value = urlDecode(data.substring(equal_sign_index + 1, next_arg_index)); log_v("arg %d key: %s value: %s", iarg, arg.key.c_str(), arg.value.c_str()); ++iarg; - if (next_arg_index == -1) + if (next_arg_index == -1) { break; + } pos = next_arg_index + 1; } _currentArgCount = iarg; log_v("args count: %d", _currentArgCount); - } -void WebServer::_uploadWriteByte(uint8_t b){ - if (_currentUpload->currentSize == HTTP_UPLOAD_BUFLEN){ - if(_currentHandler && _currentHandler->canUpload(_currentUri)) +void WebServer::_uploadWriteByte(uint8_t b) { + if (_currentUpload->currentSize == HTTP_UPLOAD_BUFLEN) { + if (_currentHandler && _currentHandler->canUpload(*this, _currentUri)) { _currentHandler->upload(*this, _currentUri, *_currentUpload); + } _currentUpload->totalSize += _currentUpload->currentSize; _currentUpload->currentSize = 0; } _currentUpload->buf[_currentUpload->currentSize++] = b; } -int WebServer::_uploadReadByte(WiFiClient& client) { +int WebServer::_uploadReadByte(WiFiClient &client) { int res = client.read(); if (res < 0) { - while(!client.available() && client.connected()) - delay(2); + // keep trying until you either read a valid byte or timeout + const unsigned long startMillis = millis(); + const long timeoutIntervalMillis = client.getTimeout(); + bool timedOut = false; + for (;;) { + if (!client.connected()) { + return -1; + } + // loosely modeled after blinkWithoutDelay pattern + while (!timedOut && !client.available() && client.connected()) { + delay(2); + timedOut = (millis() - startMillis) >= timeoutIntervalMillis; + } - res = client.read(); + res = client.read(); + if (res >= 0) { + return res; // exit on a valid read + } + // NOTE: it is possible to get here and have all of the following + // assertions hold true + // + // -- client.available() > 0 + // -- client.connected == true + // -- res == -1 + // + // a simple retry strategy overcomes this which is to say the + // assertion is not permanent, but the reason that this works + // is elusive, and possibly indicative of a more subtle underlying + // issue + + timedOut = (millis() - startMillis) >= timeoutIntervalMillis; + if (timedOut) { + return res; // exit on a timeout + } + } } return res; } -bool WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t len){ - (void) len; +bool WebServer::_parseForm(WiFiClient &client, String boundary, uint32_t len) { + (void)len; log_v("Parse Form: Boundary: %s Length: %d", boundary.c_str(), len); String line; int retry = 0; @@ -357,11 +399,13 @@ bool WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t len){ client.readStringUntil('\n'); //start reading the form - if (line == ("--"+boundary)){ - if(_postArgs) delete[] _postArgs; + if (line == ("--" + boundary)) { + if (_postArgs) { + delete[] _postArgs; + } _postArgs = new RequestArgument[WEBSERVER_MAX_POST_ARGS]; _postArgsLen = 0; - while(1){ + while (1) { String argName; String argValue; String argType; @@ -370,49 +414,56 @@ bool WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t len){ line = client.readStringUntil('\r'); client.readStringUntil('\n'); - if (line.length() > 19 && line.substring(0, 19).equalsIgnoreCase(F("Content-Disposition"))){ + if (line.length() > 19 && line.substring(0, 19).equalsIgnoreCase(F("Content-Disposition"))) { int nameStart = line.indexOf('='); - if (nameStart != -1){ - argName = line.substring(nameStart+2); + if (nameStart != -1) { + argName = line.substring(nameStart + 2); nameStart = argName.indexOf('='); - if (nameStart == -1){ + if (nameStart == -1) { argName = argName.substring(0, argName.length() - 1); } else { - argFilename = argName.substring(nameStart+2, argName.length() - 1); + argFilename = argName.substring(nameStart + 2, argName.length() - 1); argName = argName.substring(0, argName.indexOf('"')); argIsFile = true; - log_v("PostArg FileName: %s",argFilename.c_str()); + log_v("PostArg FileName: %s", argFilename.c_str()); //use GET to set the filename if uploading using blob - if (argFilename == F("blob") && hasArg(FPSTR(filename))) + if (argFilename == F("blob") && hasArg(FPSTR(filename))) { argFilename = arg(FPSTR(filename)); + } } log_v("PostArg Name: %s", argName.c_str()); using namespace mime; argType = FPSTR(mimeTable[txt].mimeType); line = client.readStringUntil('\r'); client.readStringUntil('\n'); - if (line.length() > 12 && line.substring(0, 12).equalsIgnoreCase(FPSTR(Content_Type))){ - argType = line.substring(line.indexOf(':')+2); - //skip next line - client.readStringUntil('\r'); + while (line.length() > 0) { + if (line.length() > 12 && line.substring(0, 12).equalsIgnoreCase(FPSTR(Content_Type))) { + argType = line.substring(line.indexOf(':') + 2); + } + //skip over any other headers + line = client.readStringUntil('\r'); client.readStringUntil('\n'); } log_v("PostArg Type: %s", argType.c_str()); - if (!argIsFile){ - while(1){ + if (!argIsFile) { + while (1) { line = client.readStringUntil('\r'); client.readStringUntil('\n'); - if (line.startsWith("--"+boundary)) break; - if (argValue.length() > 0) argValue += "\n"; + if (line.startsWith("--" + boundary)) { + break; + } + if (argValue.length() > 0) { + argValue += "\n"; + } argValue += line; } log_v("PostArg Value: %s", argValue.c_str()); - RequestArgument& arg = _postArgs[_postArgsLen++]; + RequestArgument &arg = _postArgs[_postArgsLen++]; arg.key = argName; arg.value = argValue; - if (line == ("--"+boundary+"--")){ + if (line == ("--" + boundary + "--")) { log_v("Done Parsing POST"); break; } else if (_postArgsLen >= WEBSERVER_MAX_POST_ARGS) { @@ -428,60 +479,62 @@ bool WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t len){ _currentUpload->totalSize = 0; _currentUpload->currentSize = 0; log_v("Start File: %s Type: %s", _currentUpload->filename.c_str(), _currentUpload->type.c_str()); - if(_currentHandler && _currentHandler->canUpload(_currentUri)) + if (_currentHandler && _currentHandler->canUpload(*this, _currentUri)) { _currentHandler->upload(*this, _currentUri, *_currentUpload); + } _currentUpload->status = UPLOAD_FILE_WRITE; int fastBoundaryLen = 4 /* \r\n-- */ + boundary.length() + 1 /* \0 */; - char fastBoundary[ fastBoundaryLen ]; + char fastBoundary[fastBoundaryLen]; snprintf(fastBoundary, fastBoundaryLen, "\r\n--%s", boundary.c_str()); int boundaryPtr = 0; - while ( true ) { - int ret = _uploadReadByte(client); - if (ret < 0) { - // Unexpected, we should have had data available per above - return _parseFormUploadAborted(); + while (true) { + int ret = _uploadReadByte(client); + if (ret < 0) { + // Unexpected, we should have had data available per above + return _parseFormUploadAborted(); + } + char in = (char)ret; + if (in == fastBoundary[boundaryPtr]) { + // The input matched the current expected character, advance and possibly exit this file + boundaryPtr++; + if (boundaryPtr == fastBoundaryLen - 1) { + // We read the whole boundary line, we're done here! + break; + } + } else { + // The char doesn't match what we want, so dump whatever matches we had, the read in char, and reset ptr to start + for (int i = 0; i < boundaryPtr; i++) { + _uploadWriteByte(fastBoundary[i]); } - char in = (char) ret; - if (in == fastBoundary[ boundaryPtr ]) { - // The input matched the current expected character, advance and possibly exit this file - boundaryPtr++; - if (boundaryPtr == fastBoundaryLen - 1) { - // We read the whole boundary line, we're done here! - break; - } + if (in == fastBoundary[0]) { + // This could be the start of the real end, mark it so and don't emit/skip it + boundaryPtr = 1; } else { - // The char doesn't match what we want, so dump whatever matches we had, the read in char, and reset ptr to start - for (int i = 0; i < boundaryPtr; i++) { - _uploadWriteByte( fastBoundary[ i ] ); - } - if (in == fastBoundary[ 0 ]) { - // This could be the start of the real end, mark it so and don't emit/skip it - boundaryPtr = 1; - } else { - // Not the 1st char of our pattern, so emit and ignore - _uploadWriteByte( in ); - boundaryPtr = 0; - } + // Not the 1st char of our pattern, so emit and ignore + _uploadWriteByte(in); + boundaryPtr = 0; } + } } // Found the boundary string, finish processing this file upload - if (_currentHandler && _currentHandler->canUpload(_currentUri)) - _currentHandler->upload(*this, _currentUri, *_currentUpload); + if (_currentHandler && _currentHandler->canUpload(*this, _currentUri)) { + _currentHandler->upload(*this, _currentUri, *_currentUpload); + } _currentUpload->totalSize += _currentUpload->currentSize; _currentUpload->status = UPLOAD_FILE_END; - if (_currentHandler && _currentHandler->canUpload(_currentUri)) - _currentHandler->upload(*this, _currentUri, *_currentUpload); - log_v("End File: %s Type: %s Size: %d", - _currentUpload->filename.c_str(), - _currentUpload->type.c_str(), - (int)_currentUpload->totalSize); - if (!client.connected()) return _parseFormUploadAborted(); + if (_currentHandler && _currentHandler->canUpload(*this, _currentUri)) { + _currentHandler->upload(*this, _currentUri, *_currentUpload); + } + log_v("End File: %s Type: %s Size: %d", _currentUpload->filename.c_str(), _currentUpload->type.c_str(), (int)_currentUpload->totalSize); + if (!client.connected()) { + return _parseFormUploadAborted(); + } line = client.readStringUntil('\r'); client.readStringUntil('\n'); - if (line == "--") { // extra two dashes mean we reached the end of all form fields - log_v("Done Parsing POST"); - break; + if (line == "--") { // extra two dashes mean we reached the end of all form fields + log_v("Done Parsing POST"); + break; } continue; } @@ -490,23 +543,25 @@ bool WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t len){ } int iarg; - int totalArgs = ((WEBSERVER_MAX_POST_ARGS - _postArgsLen) < _currentArgCount)?(WEBSERVER_MAX_POST_ARGS - _postArgsLen):_currentArgCount; - for (iarg = 0; iarg < totalArgs; iarg++){ - RequestArgument& arg = _postArgs[_postArgsLen++]; + int totalArgs = ((WEBSERVER_MAX_POST_ARGS - _postArgsLen) < _currentArgCount) ? (WEBSERVER_MAX_POST_ARGS - _postArgsLen) : _currentArgCount; + for (iarg = 0; iarg < totalArgs; iarg++) { + RequestArgument &arg = _postArgs[_postArgsLen++]; arg.key = _currentArgs[iarg].key; arg.value = _currentArgs[iarg].value; } - if (_currentArgs) delete[] _currentArgs; + if (_currentArgs) { + delete[] _currentArgs; + } _currentArgs = new RequestArgument[_postArgsLen]; - for (iarg = 0; iarg < _postArgsLen; iarg++){ - RequestArgument& arg = _currentArgs[iarg]; + for (iarg = 0; iarg < _postArgsLen; iarg++) { + RequestArgument &arg = _currentArgs[iarg]; arg.key = _postArgs[iarg].key; arg.value = _postArgs[iarg].value; } _currentArgCount = iarg; if (_postArgs) { delete[] _postArgs; - _postArgs=nullptr; + _postArgs = nullptr; _postArgsLen = 0; } return true; @@ -515,40 +570,35 @@ bool WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t len){ return false; } -String WebServer::urlDecode(const String& text) -{ - String decoded = ""; - char temp[] = "0x00"; - unsigned int len = text.length(); - unsigned int i = 0; - while (i < len) - { - char decodedChar; - char encodedChar = text.charAt(i++); - if ((encodedChar == '%') && (i + 1 < len)) - { - temp[2] = text.charAt(i++); - temp[3] = text.charAt(i++); - - decodedChar = strtol(temp, NULL, 16); - } - else { - if (encodedChar == '+') - { - decodedChar = ' '; - } - else { - decodedChar = encodedChar; // normal ascii char - } - } - decoded += decodedChar; - } - return decoded; +String WebServer::urlDecode(const String &text) { + String decoded = ""; + char temp[] = "0x00"; + unsigned int len = text.length(); + unsigned int i = 0; + while (i < len) { + char decodedChar; + char encodedChar = text.charAt(i++); + if ((encodedChar == '%') && (i + 1 < len)) { + temp[2] = text.charAt(i++); + temp[3] = text.charAt(i++); + + decodedChar = strtol(temp, NULL, 16); + } else { + if (encodedChar == '+') { + decodedChar = ' '; + } else { + decodedChar = encodedChar; // normal ascii char + } + } + decoded += decodedChar; + } + return decoded; } -bool WebServer::_parseFormUploadAborted(){ +bool WebServer::_parseFormUploadAborted() { _currentUpload->status = UPLOAD_FILE_ABORTED; - if(_currentHandler && _currentHandler->canUpload(_currentUri)) + if (_currentHandler && _currentHandler->canUpload(*this, _currentUri)) { _currentHandler->upload(*this, _currentUri, *_currentUpload); + } return false; } diff --git a/libraries/WebServer/src/WebServer.cpp b/libraries/WebServer/src/WebServer.cpp index d296ce716b0..34fef297768 100644 --- a/libraries/WebServer/src/WebServer.cpp +++ b/libraries/WebServer/src/WebServer.cpp @@ -299,10 +299,10 @@ void WebServer::handleClient() { case HC_WAIT_READ: // Wait for data from client to become available if (_currentClient.available()) { + // because HTTP_MAX_SEND_WAIT is expressed in milliseconds, + // it must be divided by 1000 + currentClient.setTimeout(HTTP_MAX_SEND_WAIT / 1000); if (_parseRequest(_currentClient)) { - // because HTTP_MAX_SEND_WAIT is expressed in milliseconds, - // it must be divided by 1000 - _currentClient.setTimeout(HTTP_MAX_SEND_WAIT / 1000); _contentLength = CONTENT_LENGTH_NOT_SET; _handleRequest(); diff --git a/libraries/WebServer/src/WebServer.h b/libraries/WebServer/src/WebServer.h index d472d8d772e..d9bd32f27fa 100644 --- a/libraries/WebServer/src/WebServer.h +++ b/libraries/WebServer/src/WebServer.h @@ -49,7 +49,7 @@ enum HTTPAuthMethod { BASIC_AUTH, DIGEST_AUTH }; #define HTTP_MAX_DATA_WAIT 5000 //ms to wait for the client to send the request #define HTTP_MAX_POST_WAIT 5000 //ms to wait for POST data to arrive #define HTTP_MAX_SEND_WAIT 5000 //ms to wait for data chunk to be ACKed -#define HTTP_MAX_CLOSE_WAIT 2000 //ms to wait for the client to close the connection +#define HTTP_MAX_CLOSE_WAIT 5000 //ms to wait for the client to close the connection #define CONTENT_LENGTH_UNKNOWN ((size_t) -1) #define CONTENT_LENGTH_NOT_SET ((size_t) -2) @@ -71,7 +71,7 @@ typedef struct HTTPRawStatus status; size_t totalSize; // content size size_t currentSize; // size of data currently in buf - uint8_t buf[HTTP_UPLOAD_BUFLEN]; + uint8_t buf[HTTP_RAW_BUFLEN]; void *data; // additional data } HTTPRaw;