diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..df30947 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ + +.idea/ diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 9fe4873..6800a82 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -81,10 +81,11 @@ class AsyncWebHeader { AsyncWebHeader(String name, String value): _name(name), _value(value), next(NULL){} AsyncWebHeader(String data): _name(), _value(), next(NULL){ - if(!data || !data.length() || data.indexOf(':') < 0) - return; - _name = data.substring(0, data.indexOf(':')); - _value = data.substring(data.indexOf(':') + 2); + if(!data) return; + int index = data.indexOf(':'); + if (index < 0) return; + _name = data.substring(0, index); + _value = data.substring(index + 2); } ~AsyncWebHeader(){} String name(){ return _name; } @@ -149,7 +150,6 @@ class AsyncWebServerRequest { bool _parseReqHead(); bool _parseReqHeader(); void _parseLine(); - void _parseByte(uint8_t data); void _parsePlainPostChar(uint8_t data); void _parseMultipartPostByte(uint8_t data, bool last); void _addGetParam(String param); diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index ee8efcd..617f8f1 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -102,12 +102,22 @@ AsyncWebServerRequest::~AsyncWebServerRequest(){ void AsyncWebServerRequest::_onData(void *buf, size_t len){ if(_parseState < PARSE_REQ_BODY){ - size_t i; - for(i=0; ihandleRequest(this); else send(501); - return; } } } @@ -201,16 +210,23 @@ void AsyncWebServerRequest::_addGetParam(String param){ param = urlDecode(param); String name = param; String value = ""; - if(param.indexOf('=') > 0){ - name = param.substring(0, param.indexOf('=')); - value = param.substring(param.indexOf('=') + 1); + int index = param.indexOf('='); + if(index > 0){ + name = param.substring(0, index); + value = param.substring(index + 1); } _addParam(new AsyncWebParameter(name, value)); } bool AsyncWebServerRequest::_parseReqHead(){ - String m = _temp.substring(0, _temp.indexOf(' ')); + // Split the head into method, url and version + int index = _temp.indexOf(' '); + String m = _temp.substring(0, index); + index = _temp.indexOf(' ', index+1); + String u = _temp.substring(m.length()+1, index); + _temp = _temp.substring(index+1); + if(m == "GET"){ _method = HTTP_GET; } else if(m == "POST"){ @@ -227,22 +243,22 @@ bool AsyncWebServerRequest::_parseReqHead(){ _method = HTTP_OPTIONS; } - _temp = _temp.substring(_temp.indexOf(' ')+1); - String u = _temp.substring(0, _temp.indexOf(' ')); u = urlDecode(u); String g = String(); - if(u.indexOf('?') > 0){ - g = u.substring(u.indexOf('?') + 1); - u = u.substring(0, u.indexOf('?')); + index = u.indexOf('?'); + if(index > 0){ + g = u.substring(index+1); + u = u.substring(0, index); } _url = u; if(g.length()){ while(true){ if(g.length() == 0) break; - if(g.indexOf('&') > 0){ - _addGetParam(g.substring(0, g.indexOf('&'))); - g = g.substring(g.indexOf('&') + 1); + index = g.indexOf('&'); + if(index > 0){ + _addGetParam(g.substring(0, index)); + g = g.substring(index+1); } else { _addGetParam(g); break; @@ -250,7 +266,6 @@ bool AsyncWebServerRequest::_parseReqHead(){ } } - _temp = _temp.substring(_temp.indexOf(' ')+1); if(_temp.startsWith("HTTP/1.1")) _version = 1; _temp = String(); @@ -258,36 +273,32 @@ bool AsyncWebServerRequest::_parseReqHead(){ } bool AsyncWebServerRequest::_parseReqHeader(){ - if(_temp.indexOf(':')){ - AsyncWebHeader *h = new AsyncWebHeader(_temp); - if(h == NULL) - return false; - if(h->name() == "Host"){ - _host = h->value(); - delete h; + int index = _temp.indexOf(':'); + if(index){ + String name = _temp.substring(0, index); + String value = _temp.substring(index + 2); + if(name == "Host"){ + _host = value; _server->_handleRequest(this); - } else if(h->name() == "Content-Type"){ - if (h->value().startsWith("multipart/")){ - _boundary = h->value().substring(h->value().indexOf('=')+1); - _contentType = h->value().substring(0, h->value().indexOf(';')); + } else if(name == "Content-Type"){ + if (value.startsWith("multipart/")){ + _boundary = value.substring(value.indexOf('=')+1); + _contentType = value.substring(0, value.indexOf(';')); _isMultipart = true; } else { - _contentType = h->value(); + _contentType = value; } - delete h; - } else if(h->name() == "Content-Length"){ - _contentLength = atoi(h->value().c_str()); - delete h; - } else if(h->name() == "Expect" && h->value() == "100-continue"){ + } else if(name == "Content-Length"){ + _contentLength = atoi(value.c_str()); + } else if(name == "Expect" && value == "100-continue"){ _expectingContinue = true; - delete h; - } else if(h->name() == "Authorization"){ - if(h->value().startsWith("Basic")){ - _authorization = h->value().substring(6); + } else if(name == "Authorization"){ + if(value.startsWith("Basic")){ + _authorization = value.substring(6); } - delete h; } else { - if(_interestingHeaders->contains(h->name()) || _interestingHeaders->contains("ANY")){ + if(_interestingHeaders->contains(name) || _interestingHeaders->contains("ANY")){ + AsyncWebHeader *h = new AsyncWebHeader(name, value); if(_headers == NULL) _headers = h; else { @@ -295,10 +306,8 @@ bool AsyncWebServerRequest::_parseReqHeader(){ while(hs->next != NULL) hs = hs->next; hs->next = h; } - } else - delete h; + } } - } _temp = String(); return true; @@ -532,14 +541,6 @@ void AsyncWebServerRequest::_parseLine(){ } } -void AsyncWebServerRequest::_parseByte(uint8_t data){ - if((char)data != '\r' && (char)data != '\n') - _temp += (char)data; - if((char)data == '\n') - _parseLine(); -} - - int AsyncWebServerRequest::headers(){ int i = 0; @@ -793,26 +794,24 @@ bool AsyncWebServerRequest::hasHeader(const char* name){ String AsyncWebServerRequest::urlDecode(const String& text){ - String decoded = ""; char temp[] = "0x00"; unsigned int len = text.length(); unsigned int i = 0; + String decoded = String(); + decoded.reserve(len); // Allocate the string internal buffer - never longer from source text 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 { - if (encodedChar == '+'){ - decodedChar = ' '; - } else { - decodedChar = encodedChar; // normal ascii char - } + decodedChar = encodedChar; // normal ascii char } - decoded += decodedChar; + decoded.concat(decodedChar); } return decoded; } diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index b1de8a6..5eead49 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -119,21 +119,31 @@ String AsyncWebServerResponse::_assembleHead(uint8_t version){ if(_chunked) addHeader("Transfer-Encoding","chunked"); } - String out = "HTTP/1." + String(version) + " " + String(_code) + " " + _responseCodeToString(_code) + "\r\n"; - if(_sendContentLength) - out += "Content-Length: " + String(_contentLength) + "\r\n"; + String out = String(); + int bufSize = 300; + char buf[bufSize]; - if(_contentType.length()) - out += "Content-Type: " + _contentType + "\r\n"; + snprintf(buf, bufSize, "HTTP/1.%d %d %s\r\n", version, _code, _responseCodeToString(_code)); + out.concat(buf); + + if(_sendContentLength) { + snprintf(buf, bufSize, "Content-Length: %d\r\n", _contentLength); + out.concat(buf); + } + if(_contentType.length()) { + snprintf(buf, bufSize, "Content-Type: %s\r\n", _contentType.c_str()); + out.concat(buf); + } AsyncWebHeader *h; while(_headers != NULL){ h = _headers; _headers = _headers->next; - out += h->toString(); + snprintf(buf, bufSize, "%s: %s\r\n", h->name().c_str(), h->value().c_str()); + out.concat(buf); delete h; } - out += "\r\n"; + out.concat("\r\n"); _headLength = out.length(); return out; }