mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +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 "WiFiServer.h"
|
||||||
#include "WiFiClient.h"
|
#include "WiFiClient.h"
|
||||||
#include "ESP8266WebServer.h"
|
#include "ESP8266WebServer.h"
|
||||||
|
#include "detail/RequestHandler.h"
|
||||||
// #define DEBUG
|
// #define DEBUG
|
||||||
#define DEBUG_OUTPUT Serial
|
#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)
|
ESP8266WebServer::ESP8266WebServer(int port)
|
||||||
: _server(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)
|
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) {
|
if (!_lastHandler) {
|
||||||
_firstHandler = handler;
|
_firstHandler = handler;
|
||||||
_lastHandler = 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()
|
void ESP8266WebServer::handleClient()
|
||||||
{
|
{
|
||||||
WiFiClient client = _server.available();
|
WiFiClient client = _server.available();
|
||||||
@ -269,15 +261,8 @@ void ESP8266WebServer::onNotFound(THandlerFunction fn) {
|
|||||||
|
|
||||||
void ESP8266WebServer::_handleRequest() {
|
void ESP8266WebServer::_handleRequest() {
|
||||||
RequestHandler* handler;
|
RequestHandler* handler;
|
||||||
for (handler = _firstHandler; handler; handler = handler->next)
|
for (handler = _firstHandler; handler; handler = handler->next) {
|
||||||
{
|
if (handler->handle(*this, _currentMethod, _currentUri))
|
||||||
if (handler->method != HTTP_ANY && handler->method != _currentMethod)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (handler->uri != _currentUri)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
handler->fn();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#define ESP8266WEBSERVER_H
|
#define ESP8266WEBSERVER_H
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <FS.h>
|
||||||
|
|
||||||
enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE };
|
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 };
|
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_UNKNOWN ((size_t) -1)
|
||||||
#define CONTENT_LENGTH_NOT_SET ((size_t) -2)
|
#define CONTENT_LENGTH_NOT_SET ((size_t) -2)
|
||||||
|
|
||||||
|
class RequestHandler;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
HTTPUploadStatus status;
|
HTTPUploadStatus status;
|
||||||
String filename;
|
String filename;
|
||||||
@ -59,6 +62,7 @@ public:
|
|||||||
typedef std::function<void(void)> THandlerFunction;
|
typedef std::function<void(void)> THandlerFunction;
|
||||||
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 serveStatic(const char* uri, FS fs, const char* path);
|
||||||
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
|
void onFileUpload(THandlerFunction fn); //handle file uploads
|
||||||
|
|
||||||
@ -99,6 +103,7 @@ template<typename T> size_t streamFile(T &file, const String& contentType){
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void _addRequestHandler(RequestHandler* handler);
|
||||||
void _handleRequest();
|
void _handleRequest();
|
||||||
bool _parseRequest(WiFiClient& client);
|
bool _parseRequest(WiFiClient& client);
|
||||||
void _parseArguments(String data);
|
void _parseArguments(String data);
|
||||||
@ -108,7 +113,6 @@ protected:
|
|||||||
uint8_t _uploadReadByte(WiFiClient& client);
|
uint8_t _uploadReadByte(WiFiClient& client);
|
||||||
void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength);
|
void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength);
|
||||||
|
|
||||||
struct RequestHandler;
|
|
||||||
struct RequestArgument {
|
struct RequestArgument {
|
||||||
String key;
|
String key;
|
||||||
String value;
|
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