Skip to content

Http uploads #1055

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Nov 22, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,9 @@ void ESP8266HTTPUpdateServer::setup(ESP8266WebServer *server)
_server->sendHeader("Access-Control-Allow-Origin", "*");
_server->send(200, "text/plain", (Update.hasError())?"FAIL":"OK");
ESP.restart();
});

// handler for the file upload, get's the sketch bytes, and writes
// them through the Update object.
_server->onFileUpload([&](){
if(_server->uri() != "/update") return;
},[&](){
// handler for the file upload, get's the sketch bytes, and writes
// them through the Update object
HTTPUpload& upload = _server->upload();
if(upload.status == UPLOAD_FILE_START){
if (_serial_output)
Expand Down Expand Up @@ -70,6 +67,6 @@ void ESP8266HTTPUpdateServer::setup(ESP8266WebServer *server)
Update.end();
if (_serial_output) Serial.println("Update was aborted");
}
yield();
delay(0);
});
}
7 changes: 3 additions & 4 deletions libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser.ino
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,9 @@ void setup(void){
server.on("/edit", HTTP_PUT, handleFileCreate);
//delete file
server.on("/edit", HTTP_DELETE, handleFileDelete);
//called after file upload
server.on("/edit", HTTP_POST, [](){ server.send(200, "text/plain", ""); });
//called when a file is received inside POST data
server.onFileUpload(handleFileUpload);
//first callback is called after the request has ended with all parsed arguments
//second callback handles file uploads at that location
server.on("/edit", HTTP_POST, [](){ server.send(200, "text/plain", ""); }, handleFileUpload);

//called when the url is not defined here
//use it to load content from SPIFFS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,8 @@ void setup(void){
server.on("/list", HTTP_GET, printDirectory);
server.on("/edit", HTTP_DELETE, handleDelete);
server.on("/edit", HTTP_PUT, handleCreate);
server.on("/edit", HTTP_POST, [](){ returnOK(); });
server.on("/edit", HTTP_POST, [](){ returnOK(); }, handleFileUpload);
server.onNotFound(handleNotFound);
server.onFileUpload(handleFileUpload);

server.begin();
DBG_OUTPUT_PORT.println("HTTP server started");
Expand Down
14 changes: 6 additions & 8 deletions libraries/ESP8266WebServer/examples/WebUpdate/WebUpdate.ino
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ void setup(void){
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/html", serverIndex);
});
server.onFileUpload([](){
if(server.uri() != "/update") return;
server.on("/update", HTTP_POST, [](){
server.sendHeader("Connection", "close");
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", (Update.hasError())?"FAIL":"OK");
ESP.restart();
},[](){
HTTPUpload& upload = server.upload();
if(upload.status == UPLOAD_FILE_START){
Serial.setDebugOutput(true);
Expand All @@ -52,12 +56,6 @@ void setup(void){
}
yield();
});
server.on("/update", HTTP_POST, [](){
server.sendHeader("Connection", "close");
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", (Update.hasError())?"FAIL":"OK");
ESP.restart();
});
server.begin();
MDNS.addService("http", "tcp", 80);

Expand Down
18 changes: 10 additions & 8 deletions libraries/ESP8266WebServer/src/ESP8266WebServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

ESP8266WebServer::ESP8266WebServer(IPAddress addr, int port)
: _server(addr, port)
, _currentHandler(0)
, _firstHandler(0)
, _lastHandler(0)
, _currentArgCount(0)
Expand All @@ -44,6 +45,7 @@ ESP8266WebServer::ESP8266WebServer(IPAddress addr, int port)

ESP8266WebServer::ESP8266WebServer(int port)
: _server(port)
, _currentHandler(0)
, _firstHandler(0)
, _lastHandler(0)
, _currentArgCount(0)
Expand Down Expand Up @@ -74,7 +76,11 @@ void ESP8266WebServer::on(const char* uri, ESP8266WebServer::THandlerFunction ha
}

void ESP8266WebServer::on(const char* uri, HTTPMethod method, ESP8266WebServer::THandlerFunction fn) {
_addRequestHandler(new FunctionRequestHandler(fn, uri, method));
on(uri, method, fn, _fileUploadHandler);
}

void ESP8266WebServer::on(const char* uri, HTTPMethod method, ESP8266WebServer::THandlerFunction fn, ESP8266WebServer::THandlerFunction ufn) {
_addRequestHandler(new FunctionRequestHandler(fn, ufn, uri, method));
}

void ESP8266WebServer::addHandler(RequestHandler* handler) {
Expand Down Expand Up @@ -352,13 +358,7 @@ void ESP8266WebServer::onNotFound(THandlerFunction fn) {
}

void ESP8266WebServer::_handleRequest() {
RequestHandler* handler;
for (handler = _firstHandler; handler; handler = handler->next()) {
if (handler->handle(*this, _currentMethod, _currentUri))
break;
}

if (!handler){
if (!_currentHandler){
#ifdef DEBUG
DEBUG_OUTPUT.println("request handler not found");
#endif
Expand All @@ -369,6 +369,8 @@ void ESP8266WebServer::_handleRequest() {
else {
send(404, "text/plain", String("Not found: ") + _currentUri);
}
} else {
_currentHandler->handle(*this, _currentMethod, _currentUri);
}

uint16_t maxWait = HTTP_MAX_CLOSE_WAIT;
Expand Down
14 changes: 8 additions & 6 deletions libraries/ESP8266WebServer/src/ESP8266WebServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@ enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END,

class ESP8266WebServer;

#include "detail/RequestHandler.h"

namespace fs {
class FS;
}

typedef struct {
HTTPUploadStatus status;
String filename;
Expand All @@ -56,6 +50,12 @@ typedef struct {
uint8_t buf[HTTP_UPLOAD_BUFLEN];
} HTTPUpload;

#include "detail/RequestHandler.h"

namespace fs {
class FS;
}

class ESP8266WebServer
{
public:
Expand All @@ -69,6 +69,7 @@ class ESP8266WebServer
typedef std::function<void(void)> THandlerFunction;
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, THandlerFunction ufn);
void addHandler(RequestHandler* handler);
void serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_header = NULL );
void onNotFound(THandlerFunction fn); //called when handler is not assigned
Expand Down Expand Up @@ -155,6 +156,7 @@ template<typename T> size_t streamFile(T &file, const String& contentType){

String _hostHeader;

RequestHandler* _currentHandler;
RequestHandler* _firstHandler;
RequestHandler* _lastHandler;
THandlerFunction _notFoundHandler;
Expand Down
23 changes: 18 additions & 5 deletions libraries/ESP8266WebServer/src/Parsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
DEBUG_OUTPUT.println(searchStr);
#endif

//attach handler
RequestHandler* handler;
for (handler = _firstHandler; handler; handler = handler->next()) {
if (handler->canHandle(_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){
Expand Down Expand Up @@ -279,7 +287,8 @@ void ESP8266WebServer::_parseArguments(String data) {

void ESP8266WebServer::_uploadWriteByte(uint8_t b){
if (_currentUpload.currentSize == HTTP_UPLOAD_BUFLEN){
if (_fileUploadHandler) _fileUploadHandler();
if(_currentHandler && _currentHandler->canUpload(_currentUri))
_currentHandler->upload(*this, _currentUri, _currentUpload);
_currentUpload.totalSize += _currentUpload.currentSize;
_currentUpload.currentSize = 0;
}
Expand Down Expand Up @@ -397,7 +406,8 @@ bool ESP8266WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t
DEBUG_OUTPUT.print(" Type: ");
DEBUG_OUTPUT.println(_currentUpload.type);
#endif
if (_fileUploadHandler) _fileUploadHandler();
if(_currentHandler && _currentHandler->canUpload(_currentUri))
_currentHandler->upload(*this, _currentUri, _currentUpload);
_currentUpload.status = UPLOAD_FILE_WRITE;
uint8_t argByte = _uploadReadByte(client);
readfile:
Expand Down Expand Up @@ -433,10 +443,12 @@ bool ESP8266WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t
client.readBytes(endBuf, boundary.length());

if (strstr((const char*)endBuf, boundary.c_str()) != NULL){
if (_fileUploadHandler) _fileUploadHandler();
if(_currentHandler && _currentHandler->canUpload(_currentUri))
_currentHandler->upload(*this, _currentUri, _currentUpload);
_currentUpload.totalSize += _currentUpload.currentSize;
_currentUpload.status = UPLOAD_FILE_END;
if (_fileUploadHandler) _fileUploadHandler();
if(_currentHandler && _currentHandler->canUpload(_currentUri))
_currentHandler->upload(*this, _currentUri, _currentUpload);
#ifdef DEBUG
DEBUG_OUTPUT.print("End File: ");
DEBUG_OUTPUT.print(_currentUpload.filename);
Expand Down Expand Up @@ -503,6 +515,7 @@ bool ESP8266WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t

bool ESP8266WebServer::_parseFormUploadAborted(){
_currentUpload.status = UPLOAD_FILE_ABORTED;
if (_fileUploadHandler) _fileUploadHandler();
if(_currentHandler && _currentHandler->canUpload(_currentUri))
_currentHandler->upload(*this, _currentUri, _currentUpload);
return false;
}
3 changes: 3 additions & 0 deletions libraries/ESP8266WebServer/src/detail/RequestHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

class RequestHandler {
public:
virtual bool canHandle(HTTPMethod method, String uri) { return false; }
virtual bool canUpload(String uri) { return false; }
virtual bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) { return false; }
virtual void upload(ESP8266WebServer& server, String requestUri, HTTPUpload& upload) {}

RequestHandler* next() { return _next; }
void next(RequestHandler* r) { _next = r; }
Expand Down
46 changes: 36 additions & 10 deletions libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,49 @@

class FunctionRequestHandler : public RequestHandler {
public:
FunctionRequestHandler(ESP8266WebServer::THandlerFunction fn, const char* uri, HTTPMethod method)
FunctionRequestHandler(ESP8266WebServer::THandlerFunction fn, ESP8266WebServer::THandlerFunction ufn, const char* uri, HTTPMethod method)
: _fn(fn)
, _ufn(ufn)
, _uri(uri)
, _method(method)
{
}

bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override {
bool canHandle(HTTPMethod requestMethod, String requestUri) override {
if (_method != HTTP_ANY && _method != requestMethod)
return false;

if (requestUri != _uri)
return false;

return true;
}

bool canUpload(String requestUri) override {
if (!_ufn || !canHandle(HTTP_POST, requestUri))
return false;

return true;
}

bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override {
if (!canHandle(requestMethod, requestUri))
return false;

_fn();
return true;
}

void upload(ESP8266WebServer& server, String requestUri, HTTPUpload& upload) override {
if (canUpload(requestUri))
_ufn();
}

protected:
String _uri;
HTTPMethod _method;
ESP8266WebServer::THandlerFunction _fn;
ESP8266WebServer::THandlerFunction _ufn;
};

class StaticRequestHandler : public RequestHandler {
Expand All @@ -41,12 +62,22 @@ class StaticRequestHandler : public RequestHandler {
DEBUGV("StaticRequestHandler: path=%s uri=%s isFile=%d, cache_header=%s\r\n", path, uri, _isFile, cache_header);
_baseUriLength = _uri.length();
}
bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override {

bool canHandle(HTTPMethod requestMethod, String requestUri) override {
if (requestMethod != HTTP_GET)
return false;
DEBUGV("StaticRequestHandler::handle: request=%s _uri=%s\r\n", requestUri.c_str(), _uri.c_str());
if (!requestUri.startsWith(_uri))

if (_isFile && requestUri != _uri || !requestUri.startsWith(_uri))
return false;

return true;
}

bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override {
if (!canHandle(requestMethod, requestUri))
return false;

DEBUGV("StaticRequestHandler::handle: request=%s _uri=%s\r\n", requestUri.c_str(), _uri.c_str());

String path(_path);

Expand All @@ -57,11 +88,6 @@ class StaticRequestHandler : public RequestHandler {
// URI in request to get the file path.
path += requestUri.substring(_baseUriLength);
}

else if (requestUri != _uri) {
// Base URI points to a file but request doesn't match this URI exactly
return false;
}
DEBUGV("StaticRequestHandler::handle: path=%s, isFile=%d\r\n", path.c_str(), _isFile);

String contentType = getContentType(path);
Expand Down