mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
add proper POST support and more methods
GET params are always added plain POST is added to the GET arguments Uploads are handled by separate handler
This commit is contained in:
parent
e6bb6b3a0d
commit
a924ba1336
@ -43,6 +43,26 @@ MDNSResponder mdns;
|
|||||||
ESP8266WebServer server(80);
|
ESP8266WebServer server(80);
|
||||||
|
|
||||||
static bool hasSD = false;
|
static bool hasSD = false;
|
||||||
|
File uploadFile;
|
||||||
|
|
||||||
|
void handleFileUpload(){
|
||||||
|
if(server.uri() != "/upload") return;
|
||||||
|
HTTPUpload upload = server.upload();
|
||||||
|
if(upload.status == UPLOAD_FILE_START){
|
||||||
|
Serial.print("Upload: START, filename:");
|
||||||
|
Serial.println(upload.filename);
|
||||||
|
if(SD.exists((char *)upload.filename.c_str())) SD.remove((char *)upload.filename.c_str());
|
||||||
|
uploadFile = SD.open(upload.filename.c_str(), FILE_WRITE);
|
||||||
|
} else if(upload.status == UPLOAD_FILE_WRITE){
|
||||||
|
Serial.print("Upload: WRITE, Bytes:");
|
||||||
|
Serial.println(upload.buflen);
|
||||||
|
if(uploadFile) uploadFile.write(upload.buf, upload.buflen);
|
||||||
|
} else if(upload.status == UPLOAD_FILE_END){
|
||||||
|
Serial.print("Upload: END, Size:");
|
||||||
|
Serial.println(upload.size);
|
||||||
|
if(uploadFile) uploadFile.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool loadFromSdCard(String path){
|
bool loadFromSdCard(String path){
|
||||||
String dataType = "text/plain";
|
String dataType = "text/plain";
|
||||||
@ -152,6 +172,19 @@ void setup(void){
|
|||||||
//Attach handler
|
//Attach handler
|
||||||
server.onNotFound(tryLoadFromSdCard);
|
server.onNotFound(tryLoadFromSdCard);
|
||||||
|
|
||||||
|
//Attach Upload handler
|
||||||
|
server.onFileUpload(handleFileUpload);
|
||||||
|
|
||||||
|
//Attach handler for the Upload location
|
||||||
|
server.on("/upload", HTTP_POST, [](){
|
||||||
|
WiFiClient client = server.client();
|
||||||
|
String message = "HTTP/1.1 200 OK\r\n";
|
||||||
|
message += "Content-Type: text/plain\r\n";
|
||||||
|
message += "Access-Control-Allow-Origin: *\r\n";
|
||||||
|
message += "\r\n";
|
||||||
|
client.print(message);
|
||||||
|
});
|
||||||
|
|
||||||
//start server
|
//start server
|
||||||
server.begin();
|
server.begin();
|
||||||
Serial.println("HTTP server started");
|
Serial.println("HTTP server started");
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
You should have received a copy of the GNU Lesser General Public
|
You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this library; if not, write to the Free Software
|
License along with this library; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -25,7 +26,8 @@
|
|||||||
#include "WiFiClient.h"
|
#include "WiFiClient.h"
|
||||||
#include "ESP8266WebServer.h"
|
#include "ESP8266WebServer.h"
|
||||||
|
|
||||||
// #define DEBUG
|
//#define DEBUG
|
||||||
|
#define DEBUG_OUTPUT Serial1
|
||||||
|
|
||||||
struct ESP8266WebServer::RequestHandler {
|
struct ESP8266WebServer::RequestHandler {
|
||||||
RequestHandler(ESP8266WebServer::THandlerFunction fn, const char* uri, HTTPMethod method)
|
RequestHandler(ESP8266WebServer::THandlerFunction fn, const char* uri, HTTPMethod method)
|
||||||
@ -95,7 +97,7 @@ void ESP8266WebServer::handleClient()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Serial.println("New client");
|
DEBUG_OUTPUT.println("New client");
|
||||||
#endif
|
#endif
|
||||||
// Wait for data from client to become available
|
// Wait for data from client to become available
|
||||||
while(client.connected() && !client.available()){
|
while(client.connected() && !client.available()){
|
||||||
@ -106,86 +108,101 @@ void ESP8266WebServer::handleClient()
|
|||||||
String req = client.readStringUntil('\r');
|
String req = client.readStringUntil('\r');
|
||||||
client.readStringUntil('\n');
|
client.readStringUntil('\n');
|
||||||
|
|
||||||
HTTPMethod method = HTTP_GET;
|
|
||||||
if (req.startsWith("POST")) {
|
|
||||||
method = HTTP_POST;
|
|
||||||
}
|
|
||||||
|
|
||||||
// First line of HTTP request looks like "GET /path HTTP/1.1"
|
// First line of HTTP request looks like "GET /path HTTP/1.1"
|
||||||
// Retrieve the "/path" part by finding the spaces
|
// Retrieve the "/path" part by finding the spaces
|
||||||
int addr_start = req.indexOf(' ');
|
int addr_start = req.indexOf(' ');
|
||||||
int addr_end = req.indexOf(' ', addr_start + 1);
|
int addr_end = req.indexOf(' ', addr_start + 1);
|
||||||
if (addr_start == -1 || addr_end == -1) {
|
if (addr_start == -1 || addr_end == -1) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Serial.print("Invalid request: ");
|
DEBUG_OUTPUT.print("Invalid request: ");
|
||||||
Serial.println(req);
|
DEBUG_OUTPUT.println(req);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
req = req.substring(addr_start + 1, addr_end);
|
String methodStr = req.substring(0, addr_start);
|
||||||
|
String url = req.substring(addr_start + 1, addr_end);
|
||||||
|
String searchStr = "";
|
||||||
|
int hasSearch = url.indexOf('?');
|
||||||
|
if(hasSearch != -1){
|
||||||
|
searchStr = url.substring(hasSearch + 1);
|
||||||
|
url = url.substring(0, hasSearch);
|
||||||
|
}
|
||||||
|
_currentUri = url;
|
||||||
|
|
||||||
|
HTTPMethod method = HTTP_GET;
|
||||||
|
if (methodStr == "POST") {
|
||||||
|
method = HTTP_POST;
|
||||||
|
} else if (methodStr == "DELETE") {
|
||||||
|
method = HTTP_DELETE;
|
||||||
|
} else if (methodStr == "PUT") {
|
||||||
|
method = HTTP_PUT;
|
||||||
|
} else if (methodStr == "PATCH") {
|
||||||
|
method = HTTP_PATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
DEBUG_OUTPUT.print("method: ");
|
||||||
|
DEBUG_OUTPUT.print(methodStr);
|
||||||
|
DEBUG_OUTPUT.print(" url: ");
|
||||||
|
DEBUG_OUTPUT.print(url);
|
||||||
|
DEBUG_OUTPUT.print(" search: ");
|
||||||
|
DEBUG_OUTPUT.println(searchStr);
|
||||||
|
#endif
|
||||||
|
|
||||||
String formData;
|
String formData;
|
||||||
if (method == HTTP_POST) {
|
//bellow is needed only when POST type request
|
||||||
int contentLength = -1;
|
if(method == HTTP_POST || method == HTTP_PUT || method == HTTP_PATCH){
|
||||||
int headerCount = 0;
|
String boundaryStr;
|
||||||
while(headerCount < 1024) { // there shouldn't be that much really
|
String headerName;
|
||||||
String line = client.readStringUntil('\r');
|
String headerValue;
|
||||||
|
bool isForm = false;
|
||||||
|
uint32_t contentLength = 0;
|
||||||
|
//parse headers
|
||||||
|
while(1){
|
||||||
|
req = client.readStringUntil('\r');
|
||||||
client.readStringUntil('\n');
|
client.readStringUntil('\n');
|
||||||
|
if(req == "") break;//no moar headers
|
||||||
if (line.length() > 0) { // this is a header
|
int headerDiv = req.indexOf(':');
|
||||||
++headerCount;
|
if(headerDiv == -1){
|
||||||
if (contentLength < 0 && line.startsWith("Content-Length")) {
|
|
||||||
// get content length from the header
|
|
||||||
int valuePos = line.indexOf(' ', 14);
|
|
||||||
if (valuePos > 0) {
|
|
||||||
String valueStr = line.substring(valuePos+1);
|
|
||||||
contentLength = valueStr.toInt();
|
|
||||||
#ifdef DEBUG
|
|
||||||
Serial.print("Content-Length: ");
|
|
||||||
Serial.println(contentLength);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
headerName = req.substring(0, headerDiv);
|
||||||
|
headerValue = req.substring(headerDiv + 2);
|
||||||
|
if(headerName == "Content-Type"){
|
||||||
|
if(headerValue.startsWith("text/plain")){
|
||||||
|
isForm = false;
|
||||||
|
} else if(headerValue.startsWith("multipart/form-data")){
|
||||||
|
boundaryStr = headerValue.substring(headerValue.indexOf('=')+1);
|
||||||
|
isForm = true;
|
||||||
|
}
|
||||||
|
} else if(headerName == "Content-Length"){
|
||||||
|
contentLength = headerValue.toInt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
|
||||||
Serial.print("headerCount=");
|
|
||||||
Serial.println(headerCount);
|
|
||||||
#endif
|
|
||||||
if (contentLength >= 0) {
|
|
||||||
formData = "";
|
|
||||||
int n = 0; // timeout counter
|
|
||||||
while (formData.length() < contentLength && ++n < 3)
|
|
||||||
formData += client.readString();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
formData = client.readStringUntil('\r'); // will return after timing out once
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (method == HTTP_GET) {
|
|
||||||
int args_start = req.indexOf('?');
|
|
||||||
if (args_start != -1) {
|
|
||||||
formData = req.substring(args_start + 1);
|
|
||||||
req = req.substring(0, args_start);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(!isForm){
|
||||||
|
if(searchStr != "") searchStr += '&';
|
||||||
|
searchStr += client.readStringUntil('\r');
|
||||||
|
client.readStringUntil('\n');
|
||||||
|
}
|
||||||
|
_parseArguments(searchStr);
|
||||||
|
if(isForm){
|
||||||
|
_parseForm(client, boundaryStr, contentLength);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_parseArguments(searchStr);
|
||||||
|
}
|
||||||
client.flush();
|
client.flush();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Serial.print("Request: ");
|
DEBUG_OUTPUT.print("Request: ");
|
||||||
Serial.println(req);
|
DEBUG_OUTPUT.println(url);
|
||||||
Serial.print("Args: ");
|
DEBUG_OUTPUT.print(" Arguments: ");
|
||||||
Serial.println(formData);
|
DEBUG_OUTPUT.println(searchStr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_parseArguments(formData);
|
_handleRequest(client, url, method);
|
||||||
_handleRequest(client, req, method);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESP8266WebServer::send(int code, const char* content_type, String content) {
|
void ESP8266WebServer::send(int code, const char* content_type, String content) {
|
||||||
@ -237,6 +254,10 @@ bool ESP8266WebServer::hasArg(const char* name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ESP8266WebServer::_parseArguments(String data) {
|
void ESP8266WebServer::_parseArguments(String data) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
DEBUG_OUTPUT.print("args: ");
|
||||||
|
DEBUG_OUTPUT.println(data);
|
||||||
|
#endif
|
||||||
if (_currentArgs)
|
if (_currentArgs)
|
||||||
delete[] _currentArgs;
|
delete[] _currentArgs;
|
||||||
_currentArgs = 0;
|
_currentArgs = 0;
|
||||||
@ -254,8 +275,8 @@ void ESP8266WebServer::_parseArguments(String data) {
|
|||||||
++_currentArgCount;
|
++_currentArgCount;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Serial.print("args count: ");
|
DEBUG_OUTPUT.print("args count: ");
|
||||||
Serial.println(_currentArgCount);
|
DEBUG_OUTPUT.println(_currentArgCount);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_currentArgs = new RequestArgument[_currentArgCount];
|
_currentArgs = new RequestArgument[_currentArgCount];
|
||||||
@ -265,17 +286,17 @@ void ESP8266WebServer::_parseArguments(String data) {
|
|||||||
int equal_sign_index = data.indexOf('=', pos);
|
int equal_sign_index = data.indexOf('=', pos);
|
||||||
int next_arg_index = data.indexOf('&', pos);
|
int next_arg_index = data.indexOf('&', pos);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Serial.print("pos ");
|
DEBUG_OUTPUT.print("pos ");
|
||||||
Serial.print(pos);
|
DEBUG_OUTPUT.print(pos);
|
||||||
Serial.print("=@ ");
|
DEBUG_OUTPUT.print("=@ ");
|
||||||
Serial.print(equal_sign_index);
|
DEBUG_OUTPUT.print(equal_sign_index);
|
||||||
Serial.print(" &@ ");
|
DEBUG_OUTPUT.print(" &@ ");
|
||||||
Serial.println(next_arg_index);
|
DEBUG_OUTPUT.println(next_arg_index);
|
||||||
#endif
|
#endif
|
||||||
if ((equal_sign_index == -1) || ((equal_sign_index > next_arg_index) && (next_arg_index != -1))) {
|
if ((equal_sign_index == -1) || ((equal_sign_index > next_arg_index) && (next_arg_index != -1))) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Serial.print("arg missing value: ");
|
DEBUG_OUTPUT.print("arg missing value: ");
|
||||||
Serial.println(iarg);
|
DEBUG_OUTPUT.println(iarg);
|
||||||
#endif
|
#endif
|
||||||
if (next_arg_index == -1)
|
if (next_arg_index == -1)
|
||||||
break;
|
break;
|
||||||
@ -286,12 +307,12 @@ void ESP8266WebServer::_parseArguments(String data) {
|
|||||||
arg.key = data.substring(pos, equal_sign_index);
|
arg.key = data.substring(pos, equal_sign_index);
|
||||||
arg.value = data.substring(equal_sign_index + 1, next_arg_index);
|
arg.value = data.substring(equal_sign_index + 1, next_arg_index);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Serial.print("arg ");
|
DEBUG_OUTPUT.print("arg ");
|
||||||
Serial.print(iarg);
|
DEBUG_OUTPUT.print(iarg);
|
||||||
Serial.print(" key: ");
|
DEBUG_OUTPUT.print(" key: ");
|
||||||
Serial.print(arg.key);
|
DEBUG_OUTPUT.print(arg.key);
|
||||||
Serial.print(" value: ");
|
DEBUG_OUTPUT.print(" value: ");
|
||||||
Serial.println(arg.value);
|
DEBUG_OUTPUT.println(arg.value);
|
||||||
#endif
|
#endif
|
||||||
++iarg;
|
++iarg;
|
||||||
if (next_arg_index == -1)
|
if (next_arg_index == -1)
|
||||||
@ -300,12 +321,213 @@ void ESP8266WebServer::_parseArguments(String data) {
|
|||||||
}
|
}
|
||||||
_currentArgCount = iarg;
|
_currentArgCount = iarg;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Serial.print("args count: ");
|
DEBUG_OUTPUT.print("args count: ");
|
||||||
Serial.println(_currentArgCount);
|
DEBUG_OUTPUT.println(_currentArgCount);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ESP8266WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t len){
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
DEBUG_OUTPUT.print("Parse Form: Boundary: ");
|
||||||
|
DEBUG_OUTPUT.print(boundary);
|
||||||
|
DEBUG_OUTPUT.print("Length: ");
|
||||||
|
DEBUG_OUTPUT.println(len);
|
||||||
|
#endif
|
||||||
|
String line;
|
||||||
|
line = client.readStringUntil('\r');
|
||||||
|
client.readStringUntil('\n');
|
||||||
|
//start reading the form
|
||||||
|
if(line == ("--"+boundary)){
|
||||||
|
RequestArgument* postArgs = new RequestArgument[32];
|
||||||
|
int postArgsLen = 0;
|
||||||
|
while(1){
|
||||||
|
String argName;
|
||||||
|
String argValue;
|
||||||
|
String argType;
|
||||||
|
String argFilename;
|
||||||
|
bool argIsFile = false;
|
||||||
|
|
||||||
|
line = client.readStringUntil('\r');
|
||||||
|
client.readStringUntil('\n');
|
||||||
|
if(line.startsWith("Content-Disposition")){
|
||||||
|
int nameStart = line.indexOf('=');
|
||||||
|
if(nameStart != -1){
|
||||||
|
argName = line.substring(nameStart+2);
|
||||||
|
nameStart = argName.indexOf('=');
|
||||||
|
if(nameStart == -1){
|
||||||
|
argName = argName.substring(0, argName.length() - 1);
|
||||||
|
} else {
|
||||||
|
argFilename = argName.substring(nameStart+2, argName.length() - 1);
|
||||||
|
argName = argName.substring(0, argName.indexOf('"'));
|
||||||
|
argIsFile = true;
|
||||||
|
#ifdef DEBUG
|
||||||
|
DEBUG_OUTPUT.print("PostArg FileName: ");
|
||||||
|
DEBUG_OUTPUT.println(argFilename);
|
||||||
|
#endif
|
||||||
|
//use GET to set the filename if uploading using blob
|
||||||
|
if(argFilename == "blob" && hasArg("filename")) argFilename = arg("filename");
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
DEBUG_OUTPUT.print("PostArg Name: ");
|
||||||
|
DEBUG_OUTPUT.println(argName);
|
||||||
|
#endif
|
||||||
|
argType = "text/plain";
|
||||||
|
line = client.readStringUntil('\r');
|
||||||
|
client.readStringUntil('\n');
|
||||||
|
if(line.startsWith("Content-Type")){
|
||||||
|
argType = line.substring(line.indexOf(':')+2);
|
||||||
|
//skip next line
|
||||||
|
client.readStringUntil('\r');
|
||||||
|
client.readStringUntil('\n');
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
DEBUG_OUTPUT.print("PostArg Type: ");
|
||||||
|
DEBUG_OUTPUT.println(argType);
|
||||||
|
#endif
|
||||||
|
if(!argIsFile){
|
||||||
|
while(1){
|
||||||
|
line = client.readStringUntil('\r');
|
||||||
|
client.readStringUntil('\n');
|
||||||
|
if(line.startsWith("--"+boundary)) break;
|
||||||
|
argValue += line+"\n";
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
DEBUG_OUTPUT.print("PostArg Value: ");
|
||||||
|
DEBUG_OUTPUT.println(argValue);
|
||||||
|
DEBUG_OUTPUT.println();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RequestArgument& arg = postArgs[postArgsLen++];
|
||||||
|
arg.key = argName;
|
||||||
|
arg.value = argValue;
|
||||||
|
|
||||||
|
if(line == ("--"+boundary+"--")){
|
||||||
|
#ifdef DEBUG
|
||||||
|
DEBUG_OUTPUT.println("Done Parsing POST");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_currentUpload.status = UPLOAD_FILE_START;
|
||||||
|
_currentUpload.name = argName;
|
||||||
|
_currentUpload.filename = argFilename;
|
||||||
|
_currentUpload.type = argType;
|
||||||
|
_currentUpload.size = 0;
|
||||||
|
_currentUpload.buflen = 0;
|
||||||
|
#ifdef DEBUG
|
||||||
|
DEBUG_OUTPUT.print("Start File: ");
|
||||||
|
DEBUG_OUTPUT.print(_currentUpload.filename);
|
||||||
|
DEBUG_OUTPUT.print(" Type: ");
|
||||||
|
DEBUG_OUTPUT.println(_currentUpload.type);
|
||||||
|
#endif
|
||||||
|
if(_fileUploadHandler) _fileUploadHandler();
|
||||||
|
_currentUpload.status = UPLOAD_FILE_WRITE;
|
||||||
|
uint8_t argByte = client.read();
|
||||||
|
readfile:
|
||||||
|
while(argByte != 0x0D){
|
||||||
|
_currentUpload.buf[_currentUpload.buflen++] = argByte;
|
||||||
|
if(_currentUpload.buflen == 1460){
|
||||||
|
#ifdef DEBUG
|
||||||
|
DEBUG_OUTPUT.println("Write File: 1460");
|
||||||
|
#endif
|
||||||
|
if(_fileUploadHandler) _fileUploadHandler();
|
||||||
|
_currentUpload.size += _currentUpload.buflen;
|
||||||
|
_currentUpload.buflen = 0;
|
||||||
|
}
|
||||||
|
argByte = client.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
argByte = client.read();
|
||||||
|
if(argByte == 0x0A){
|
||||||
|
line = client.readStringUntil(0x0D);
|
||||||
|
client.readStringUntil(0x0A);
|
||||||
|
#ifdef DEBUG
|
||||||
|
DEBUG_OUTPUT.print("Write File: ");
|
||||||
|
DEBUG_OUTPUT.println(_currentUpload.buflen);
|
||||||
|
#endif
|
||||||
|
if(_fileUploadHandler) _fileUploadHandler();
|
||||||
|
_currentUpload.size += _currentUpload.buflen;
|
||||||
|
_currentUpload.buflen = 0;
|
||||||
|
if(line.startsWith("--"+boundary)){
|
||||||
|
_currentUpload.status = UPLOAD_FILE_END;
|
||||||
|
#ifdef DEBUG
|
||||||
|
DEBUG_OUTPUT.print("End File: ");
|
||||||
|
DEBUG_OUTPUT.print(_currentUpload.filename);
|
||||||
|
DEBUG_OUTPUT.print(" Type: ");
|
||||||
|
DEBUG_OUTPUT.print(_currentUpload.type);
|
||||||
|
DEBUG_OUTPUT.print(" Size: ");
|
||||||
|
DEBUG_OUTPUT.println(_currentUpload.size);
|
||||||
|
#endif
|
||||||
|
if(_fileUploadHandler) _fileUploadHandler();
|
||||||
|
if(line == ("--"+boundary+"--")){
|
||||||
|
#ifdef DEBUG
|
||||||
|
DEBUG_OUTPUT.println("Done Parsing POST");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
_currentUpload.buf[_currentUpload.buflen++] = 0x0D;
|
||||||
|
_currentUpload.buf[_currentUpload.buflen++] = 0x0A;
|
||||||
|
const char * lineChars = line.c_str();
|
||||||
|
uint32_t i = 0;
|
||||||
|
while(i < os_strlen(lineChars)){
|
||||||
|
_currentUpload.buf[_currentUpload.buflen++] = lineChars[i++];
|
||||||
|
if(_currentUpload.buflen == 1460){
|
||||||
|
#ifdef DEBUG
|
||||||
|
DEBUG_OUTPUT.println("Write File: 1460");
|
||||||
|
#endif
|
||||||
|
if(_fileUploadHandler) _fileUploadHandler();
|
||||||
|
_currentUpload.size += _currentUpload.buflen;
|
||||||
|
_currentUpload.buflen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argByte = client.read();
|
||||||
|
goto readfile;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_currentUpload.buf[_currentUpload.buflen++] = 0x0D;
|
||||||
|
if(_currentUpload.buflen == 1460){
|
||||||
|
#ifdef DEBUG
|
||||||
|
DEBUG_OUTPUT.println("Write File: 1460");
|
||||||
|
#endif
|
||||||
|
if(_fileUploadHandler) _fileUploadHandler();
|
||||||
|
_currentUpload.size += _currentUpload.buflen;
|
||||||
|
_currentUpload.buflen = 0;
|
||||||
|
}
|
||||||
|
goto readfile;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int iarg;
|
||||||
|
int totalArgs = ((32 - postArgsLen) < _currentArgCount)?(32 - 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;
|
||||||
|
_currentArgs = new RequestArgument[postArgsLen];
|
||||||
|
for (iarg = 0; iarg < postArgsLen; iarg++){
|
||||||
|
RequestArgument& arg = _currentArgs[iarg];
|
||||||
|
arg.key = postArgs[iarg].key;
|
||||||
|
arg.value = postArgs[iarg].value;
|
||||||
|
}
|
||||||
|
_currentArgCount = iarg;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESP8266WebServer::onFileUpload(THandlerFunction fn) {
|
||||||
|
_fileUploadHandler = fn;
|
||||||
|
}
|
||||||
|
|
||||||
void ESP8266WebServer::onNotFound(THandlerFunction fn) {
|
void ESP8266WebServer::onNotFound(THandlerFunction fn) {
|
||||||
_notFoundHandler = fn;
|
_notFoundHandler = fn;
|
||||||
}
|
}
|
||||||
@ -330,7 +552,7 @@ void ESP8266WebServer::_handleRequest(WiFiClient& client, String uri, HTTPMethod
|
|||||||
|
|
||||||
if (!handler){
|
if (!handler){
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Serial.println("request handler not found");
|
DEBUG_OUTPUT.println("request handler not found");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(_notFoundHandler) {
|
if(_notFoundHandler) {
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
You should have received a copy of the GNU Lesser General Public
|
You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this library; if not, write to the Free Software
|
License along with this library; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -25,8 +26,18 @@
|
|||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_POST };
|
enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE };
|
||||||
|
enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END };
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
HTTPUploadStatus status;
|
||||||
|
String filename;
|
||||||
|
String name;
|
||||||
|
String type;
|
||||||
|
size_t size;
|
||||||
|
size_t buflen;
|
||||||
|
uint8_t buf[1460];
|
||||||
|
} HTTPUpload;
|
||||||
|
|
||||||
class ESP8266WebServer
|
class ESP8266WebServer
|
||||||
{
|
{
|
||||||
@ -42,10 +53,12 @@ public:
|
|||||||
void on(const char* uri, THandlerFunction handler);
|
void on(const char* uri, THandlerFunction handler);
|
||||||
void on(const char* uri, HTTPMethod method, THandlerFunction fn);
|
void on(const char* uri, HTTPMethod method, THandlerFunction fn);
|
||||||
void onNotFound(THandlerFunction fn); //called when handler is not assigned
|
void onNotFound(THandlerFunction fn); //called when handler is not assigned
|
||||||
|
void onFileUpload(THandlerFunction fn); //handle file uploads
|
||||||
|
|
||||||
String uri() { return _currentUri; }
|
String uri() { return _currentUri; }
|
||||||
HTTPMethod method() { return _currentMethod; }
|
HTTPMethod method() { return _currentMethod; }
|
||||||
WiFiClient client() { return _currentClient; }
|
WiFiClient client() { return _currentClient; }
|
||||||
|
HTTPUpload upload() { return _currentUpload; }
|
||||||
|
|
||||||
String arg(const char* name); // get request argument value by name
|
String arg(const char* name); // get request argument value by name
|
||||||
String arg(int i); // get request argument value by number
|
String arg(int i); // get request argument value by number
|
||||||
@ -64,6 +77,7 @@ protected:
|
|||||||
void _parseArguments(String data);
|
void _parseArguments(String data);
|
||||||
static const char* _responseCodeToString(int code);
|
static const char* _responseCodeToString(int code);
|
||||||
static void _appendHeader(String& response, const char* name, const char* value);
|
static void _appendHeader(String& response, const char* name, const char* value);
|
||||||
|
void _parseForm(WiFiClient& client, String boundary, uint32_t len);
|
||||||
|
|
||||||
struct RequestHandler;
|
struct RequestHandler;
|
||||||
struct RequestArgument {
|
struct RequestArgument {
|
||||||
@ -79,10 +93,12 @@ protected:
|
|||||||
|
|
||||||
size_t _currentArgCount;
|
size_t _currentArgCount;
|
||||||
RequestArgument* _currentArgs;
|
RequestArgument* _currentArgs;
|
||||||
|
HTTPUpload _currentUpload;
|
||||||
|
|
||||||
RequestHandler* _firstHandler;
|
RequestHandler* _firstHandler;
|
||||||
RequestHandler* _lastHandler;
|
RequestHandler* _lastHandler;
|
||||||
THandlerFunction _notFoundHandler;
|
THandlerFunction _notFoundHandler;
|
||||||
|
THandlerFunction _fileUploadHandler;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user