22#include "../../Defines.h"
24#include "WiFiServer.h"
25#include "WiFiClient.h"
30#define DEBUG_OUTPUT DEBUG_ESP_PORT
32#define DEBUG_OUTPUT Serial
35static char* readBytesWithTimeout(WiFiClient& client,
size_t maxLength,
size_t& dataLength,
int timeout_ms)
39 while (dataLength < maxLength) {
40 int tries = timeout_ms;
42 while (!(newLength = client.available()) && tries--) delay(1);
47 buf = (
char *) malloc(newLength + 1);
53 char* newBuf = (
char *) realloc(buf, dataLength + newLength + 1);
60 client.readBytes(buf + dataLength, newLength);
61 dataLength += newLength;
62 buf[dataLength] =
'\0';
69 String req =
client.readStringUntil(
'\r');
70 client.readStringUntil(
'\n');
78 int addr_start = req.indexOf(
' ');
79 int addr_end = req.indexOf(
' ', addr_start + 1);
80 if (addr_start == -1 || addr_end == -1) {
81#ifdef DEBUG_ESP_HTTP_SERVER
88 String methodStr = req.substring(0, addr_start);
89 String url = req.substring(addr_start + 1, addr_end);
90 String versionEnd = req.substring(addr_end + 8);
92 String searchStr =
"";
93 int hasSearch = url.indexOf(
'?');
95 searchStr =
urlDecode(url.substring(hasSearch + 1));
96 url = url.substring(0, hasSearch);
102 if (methodStr ==
"POST") {
104 }
else if (methodStr ==
"DELETE") {
106 }
else if (methodStr ==
"OPTIONS") {
108 }
else if (methodStr ==
"PUT") {
110 }
else if (methodStr ==
"PATCH") {
115#ifdef DEBUG_ESP_HTTP_SERVER
139 bool isEncoded =
false;
140 uint32_t contentLength = 0;
143 req =
client.readStringUntil(
'\r');
144 client.readStringUntil(
'\n');
145 if (req ==
"")
break;
146 int headerDiv = req.indexOf(
':');
147 if (headerDiv == -1){
151 headerValue = req.substring(headerDiv + 1);
155 #ifdef DEBUG_ESP_HTTP_SERVER
162 if (
headerName.equalsIgnoreCase(
"Content-Type")){
163 if (headerValue.startsWith(
"text/plain")){
165 }
else if (headerValue.startsWith(
"application/x-www-form-urlencoded")){
168 }
else if (headerValue.startsWith(
"multipart/")){
169 boundaryStr = headerValue.substring(headerValue.indexOf(
'=')+1);
172 }
else if (
headerName.equalsIgnoreCase(
"Content-Length")){
173 contentLength = headerValue.toInt();
174 }
else if (
headerName.equalsIgnoreCase(
"Host")){
182 if (plainLength < contentLength) {
186 if (contentLength > 0) {
187 if (searchStr !=
"") searchStr +=
'&';
191 size_t decodedLen = decoded.length();
192 memcpy(plainBuf, decoded.c_str(), decodedLen);
193 plainBuf[decodedLen] = 0;
194 searchStr += plainBuf;
201 arg.value = String(plainBuf);
204 #ifdef DEBUG_ESP_HTTP_SERVER
223 req =
client.readStringUntil(
'\r');
224 client.readStringUntil(
'\n');
225 if (req ==
"")
break;
226 int headerDiv = req.indexOf(
':');
227 if (headerDiv == -1){
231 headerValue = req.substring(headerDiv + 2);
234 #ifdef DEBUG_ESP_HTTP_SERVER
249#ifdef DEBUG_ESP_HTTP_SERVER
270#ifdef DEBUG_ESP_HTTP_SERVER
277 if (data.length() == 0) {
284 for (
int i = 0; i < (int)data.length(); ) {
285 i = data.indexOf(
'&', i);
291#ifdef DEBUG_ESP_HTTP_SERVER
300 int equal_sign_index = data.indexOf(
'=', pos);
301 int next_arg_index = data.indexOf(
'&', pos);
302#ifdef DEBUG_ESP_HTTP_SERVER
310 if ((equal_sign_index == -1) || ((equal_sign_index > next_arg_index) && (next_arg_index != -1))) {
311#ifdef DEBUG_ESP_HTTP_SERVER
315 if (next_arg_index == -1)
317 pos = next_arg_index + 1;
321 arg.key = data.substring(pos, equal_sign_index);
322 arg.value = data.substring(equal_sign_index + 1, next_arg_index);
323#ifdef DEBUG_ESP_HTTP_SERVER
332 if (next_arg_index == -1)
334 pos = next_arg_index + 1;
337#ifdef DEBUG_ESP_HTTP_SERVER
366#ifdef DEBUG_ESP_HTTP_SERVER
375 line =
client.readStringUntil(
'\r');
377 }
while (line.length() == 0 && retry < 3);
379 client.readStringUntil(
'\n');
381 if (line == (
"--"+boundary)){
389 bool argIsFile =
false;
391 line =
client.readStringUntil(
'\r');
392 client.readStringUntil(
'\n');
393 if (line.length() > 19 && line.substring(0, 19).equalsIgnoreCase(
"Content-Disposition")){
394 int nameStart = line.indexOf(
'=');
395 if (nameStart != -1){
396 argName = line.substring(nameStart+2);
397 nameStart =
argName.indexOf(
'=');
398 if (nameStart == -1){
401 argFilename =
argName.substring(nameStart+2,
argName.length() - 1);
404#ifdef DEBUG_ESP_HTTP_SERVER
409 if (argFilename ==
"blob" &&
hasArg(
"filename")) argFilename =
arg(
"filename");
411#ifdef DEBUG_ESP_HTTP_SERVER
415 argType =
"text/plain";
416 line =
client.readStringUntil(
'\r');
417 client.readStringUntil(
'\n');
418 if (line.length() > 12 && line.substring(0, 12).equalsIgnoreCase(
"Content-Type")){
419 argType = line.substring(line.indexOf(
':')+2);
421 client.readStringUntil(
'\r');
422 client.readStringUntil(
'\n');
424#ifdef DEBUG_ESP_HTTP_SERVER
430 line =
client.readStringUntil(
'\r');
431 client.readStringUntil(
'\n');
432 if (line.startsWith(
"--"+boundary))
break;
433 if (argValue.length() > 0) argValue +=
"\n";
436#ifdef DEBUG_ESP_HTTP_SERVER
444 arg.value = argValue;
446 if (line == (
"--"+boundary+
"--")){
447#ifdef DEBUG_ESP_HTTP_SERVER
459#ifdef DEBUG_ESP_HTTP_SERVER
470 while(argByte != 0x0D){
478 if (argByte == 0x0A){
481 if ((
char)argByte !=
'-'){
489 if ((
char)argByte !=
'-'){
498 uint8_t endBuf[boundary.length()];
499 client.readBytes(endBuf, boundary.length());
501 if (strstr((
const char*)endBuf, boundary.c_str()) != NULL){
508#ifdef DEBUG_ESP_HTTP_SERVER
516 line =
client.readStringUntil(0x0D);
517 client.readStringUntil(0x0A);
519#ifdef DEBUG_ESP_HTTP_SERVER
531 while(i < boundary.length()){
549 for (iarg = 0; iarg < totalArgs; iarg++){
556 for (iarg = 0; iarg < postArgsLen; iarg++){
558 arg.key = postArgs[iarg].
key;
562 if (postArgs)
delete[] postArgs;
565#ifdef DEBUG_ESP_HTTP_SERVER
575 char temp[] =
"0x00";
576 unsigned int len = text.length();
581 char encodedChar = text.charAt(i++);
582 if ((encodedChar ==
'%') && (i + 1 < len))
584 temp[2] = text.charAt(i++);
585 temp[3] = text.charAt(i++);
587 decodedChar = strtol(temp, NULL, 16);
590 if (encodedChar ==
'+')
595 decodedChar = encodedChar;
598 decoded += decodedChar;
#define HTTP_MAX_POST_WAIT
#define HTTP_UPLOAD_BUFLEN
virtual void upload(WebServer &server, String requestUri, HTTPUpload &upload)
virtual bool canUpload(String uri)
virtual bool canHandle(HTTPMethod method, String uri)
static String urlDecode(const String &text)
RequestHandler * _currentHandler
RequestArgument * _currentArgs
void _parseArguments(String data)
HTTPMethod _currentMethod
RequestHandler * _firstHandler
bool _parseRequest(WiFiClient &client)
RequestArgument * _currentHeaders
bool _collectHeader(const char *headerName, const char *headerValue)
HTTPUpload _currentUpload
bool _parseFormUploadAborted()
bool _parseForm(WiFiClient &client, String boundary, uint32_t len)
uint8_t _uploadReadByte(WiFiClient &client)
void _uploadWriteByte(uint8_t b)
uint8_t buf[HTTP_UPLOAD_BUFLEN]