mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-22 21:23:07 +03:00
ESP8266WebServer: serve static files from FS
This commit is contained in:
parent
b5d9db91aa
commit
e8b27912d7
@ -25,25 +25,10 @@
|
||||
#include "WiFiServer.h"
|
||||
#include "WiFiClient.h"
|
||||
#include "ESP8266WebServer.h"
|
||||
|
||||
#include "detail/RequestHandler.h"
|
||||
// #define DEBUG
|
||||
#define DEBUG_OUTPUT Serial
|
||||
|
||||
struct ESP8266WebServer::RequestHandler {
|
||||
RequestHandler(ESP8266WebServer::THandlerFunction fn, const char* uri, HTTPMethod method)
|
||||
: fn(fn)
|
||||
, uri(uri)
|
||||
, method(method)
|
||||
, next(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
ESP8266WebServer::THandlerFunction fn;
|
||||
String uri;
|
||||
HTTPMethod method;
|
||||
RequestHandler* next;
|
||||
|
||||
};
|
||||
|
||||
ESP8266WebServer::ESP8266WebServer(int port)
|
||||
: _server(port)
|
||||
@ -78,7 +63,10 @@ void ESP8266WebServer::on(const char* uri, ESP8266WebServer::THandlerFunction ha
|
||||
|
||||
void ESP8266WebServer::on(const char* uri, HTTPMethod method, ESP8266WebServer::THandlerFunction fn)
|
||||
{
|
||||
RequestHandler* handler = new RequestHandler(fn, uri, method);
|
||||
_addRequestHandler(new FunctionRequestHandler(fn, uri, method));
|
||||
}
|
||||
|
||||
void ESP8266WebServer::_addRequestHandler(RequestHandler* handler) {
|
||||
if (!_lastHandler) {
|
||||
_firstHandler = handler;
|
||||
_lastHandler = handler;
|
||||
@ -89,6 +77,10 @@ void ESP8266WebServer::on(const char* uri, HTTPMethod method, ESP8266WebServer::
|
||||
}
|
||||
}
|
||||
|
||||
void ESP8266WebServer::serveStatic(const char* uri, FS fs, const char* path) {
|
||||
_addRequestHandler(new StaticRequestHandler(fs, uri));
|
||||
}
|
||||
|
||||
void ESP8266WebServer::handleClient()
|
||||
{
|
||||
WiFiClient client = _server.available();
|
||||
@ -269,15 +261,8 @@ void ESP8266WebServer::onNotFound(THandlerFunction fn) {
|
||||
|
||||
void ESP8266WebServer::_handleRequest() {
|
||||
RequestHandler* handler;
|
||||
for (handler = _firstHandler; handler; handler = handler->next)
|
||||
{
|
||||
if (handler->method != HTTP_ANY && handler->method != _currentMethod)
|
||||
continue;
|
||||
|
||||
if (handler->uri != _currentUri)
|
||||
continue;
|
||||
|
||||
handler->fn();
|
||||
for (handler = _firstHandler; handler; handler = handler->next) {
|
||||
if (handler->handle(*this, _currentMethod, _currentUri))
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#define ESP8266WEBSERVER_H
|
||||
|
||||
#include <functional>
|
||||
#include <FS.h>
|
||||
|
||||
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 };
|
||||
@ -37,6 +38,8 @@ enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END };
|
||||
#define CONTENT_LENGTH_UNKNOWN ((size_t) -1)
|
||||
#define CONTENT_LENGTH_NOT_SET ((size_t) -2)
|
||||
|
||||
class RequestHandler;
|
||||
|
||||
typedef struct {
|
||||
HTTPUploadStatus status;
|
||||
String filename;
|
||||
@ -59,6 +62,7 @@ public:
|
||||
typedef std::function<void(void)> THandlerFunction;
|
||||
void on(const char* uri, THandlerFunction handler);
|
||||
void on(const char* uri, HTTPMethod method, THandlerFunction fn);
|
||||
void serveStatic(const char* uri, FS fs, const char* path);
|
||||
void onNotFound(THandlerFunction fn); //called when handler is not assigned
|
||||
void onFileUpload(THandlerFunction fn); //handle file uploads
|
||||
|
||||
@ -99,6 +103,7 @@ template<typename T> size_t streamFile(T &file, const String& contentType){
|
||||
}
|
||||
|
||||
protected:
|
||||
void _addRequestHandler(RequestHandler* handler);
|
||||
void _handleRequest();
|
||||
bool _parseRequest(WiFiClient& client);
|
||||
void _parseArguments(String data);
|
||||
@ -108,7 +113,6 @@ protected:
|
||||
uint8_t _uploadReadByte(WiFiClient& client);
|
||||
void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength);
|
||||
|
||||
struct RequestHandler;
|
||||
struct RequestArgument {
|
||||
String key;
|
||||
String value;
|
||||
|
96
libraries/ESP8266WebServer/src/detail/RequestHandler.h
Normal file
96
libraries/ESP8266WebServer/src/detail/RequestHandler.h
Normal file
@ -0,0 +1,96 @@
|
||||
#ifndef REQUESTHANDLER_H
|
||||
#define REQUESTHANDLER_H
|
||||
|
||||
class RequestHandler {
|
||||
public:
|
||||
RequestHandler(const char* uri, HTTPMethod method)
|
||||
: uri(uri)
|
||||
, method(method)
|
||||
, next(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) = 0;
|
||||
|
||||
RequestHandler* next;
|
||||
|
||||
protected:
|
||||
String uri;
|
||||
HTTPMethod method;
|
||||
};
|
||||
|
||||
|
||||
class FunctionRequestHandler : public RequestHandler {
|
||||
typedef RequestHandler base;
|
||||
|
||||
public:
|
||||
FunctionRequestHandler(ESP8266WebServer::THandlerFunction fn, const char* uri, HTTPMethod method)
|
||||
: fn(fn)
|
||||
, base(uri, method)
|
||||
{
|
||||
}
|
||||
|
||||
bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override {
|
||||
if (method != HTTP_ANY && method != requestMethod)
|
||||
return false;
|
||||
|
||||
if (requestUri != uri)
|
||||
return false;
|
||||
|
||||
fn();
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
ESP8266WebServer::THandlerFunction fn;
|
||||
};
|
||||
|
||||
class StaticRequestHandler : public RequestHandler {
|
||||
typedef RequestHandler base;
|
||||
|
||||
public:
|
||||
StaticRequestHandler(FS& fs, const char* uri)
|
||||
: fs(fs)
|
||||
, base(uri, HTTP_GET)
|
||||
{
|
||||
}
|
||||
|
||||
bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override {
|
||||
if (requestMethod != method)
|
||||
return false;
|
||||
DEBUGV("StaticRequestHandler::handle: %s\r\n", requestUri.c_str());
|
||||
if (!requestUri.startsWith(uri))
|
||||
return false;
|
||||
|
||||
auto prefixLength = uri.length() - 1;
|
||||
String path = requestUri.substring(prefixLength);
|
||||
DEBUGV("StaticRequestHandler::handle: %d %s\r\n", prefixLength, path.c_str());
|
||||
File f = fs.open(path, "r");
|
||||
if (!f)
|
||||
return false;
|
||||
|
||||
server.streamFile(f, getContentType(path));
|
||||
return true;
|
||||
}
|
||||
|
||||
static String getContentType(const String& path) {
|
||||
if (path.endsWith(".html")) return "text/html";
|
||||
else if (path.endsWith(".htm")) return "text/html";
|
||||
else if (path.endsWith(".css")) return "text/css";
|
||||
else if (path.endsWith(".txt")) return "text/plain";
|
||||
else if (path.endsWith(".js")) return "application/javascript";
|
||||
else if (path.endsWith(".png")) return "image/png";
|
||||
else if (path.endsWith(".gif")) return "image/gif";
|
||||
else if (path.endsWith(".jpg")) return "image/jpeg";
|
||||
else if (path.endsWith(".ico")) return "image/x-icon";
|
||||
else if (path.endsWith(".xml")) return "text/xml";
|
||||
else if (path.endsWith(".pdf")) return "application/pdf";
|
||||
else if (path.endsWith(".zip")) return "application/zip";
|
||||
return "text/plain";
|
||||
}
|
||||
|
||||
protected:
|
||||
FS fs;
|
||||
};
|
||||
|
||||
#endif //REQUESTHANDLER_H
|
Loading…
x
Reference in New Issue
Block a user