mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
Merge branch 'dev' into dev2
This commit is contained in:
@@ -63,7 +63,7 @@ class AsyncJsonResponse : public AsyncAbstractResponse {
|
||||
|
||||
~AsyncJsonResponse() {
|
||||
}
|
||||
JsonVariant & getRoot() {
|
||||
JsonVariant getRoot() {
|
||||
return _root;
|
||||
}
|
||||
bool _sourceValid() const {
|
||||
@@ -108,7 +108,7 @@ class PrettyAsyncJsonResponse : public AsyncJsonResponse {
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::function<void(AsyncWebServerRequest * request, JsonVariant & json)> ArJsonRequestHandlerFunction;
|
||||
typedef std::function<void(AsyncWebServerRequest * request, JsonVariant json)> ArJsonRequestHandlerFunction;
|
||||
|
||||
class AsyncCallbackJsonWebHandler : public AsyncWebHandler {
|
||||
private:
|
||||
@@ -142,13 +142,15 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler {
|
||||
if (!_onRequest)
|
||||
return false;
|
||||
|
||||
if (!(_method & request->method()))
|
||||
WebRequestMethodComposite request_method = request->method();
|
||||
|
||||
if (!(_method & request_method))
|
||||
return false;
|
||||
|
||||
if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/")))
|
||||
return false;
|
||||
|
||||
if (!request->contentType().equalsIgnoreCase(JSON_MIMETYPE))
|
||||
if (request_method != HTTP_GET && !request->contentType().equalsIgnoreCase(JSON_MIMETYPE))
|
||||
return false;
|
||||
|
||||
request->addInterestingHeader("ANY");
|
||||
@@ -156,18 +158,23 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler {
|
||||
}
|
||||
|
||||
virtual void handleRequest(AsyncWebServerRequest * request) override final {
|
||||
if ((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str()))
|
||||
return request->requestAuthentication();
|
||||
if (_onRequest) {
|
||||
JsonVariant json; // empty variant
|
||||
if (request->_tempObject != NULL) {
|
||||
if (request->method() == HTTP_GET) {
|
||||
JsonVariant json;
|
||||
_onRequest(request, json);
|
||||
return;
|
||||
} else if (request->_tempObject != NULL) {
|
||||
JsonDocument jsonBuffer;
|
||||
DeserializationError error = deserializeJson(jsonBuffer, (uint8_t *)(request->_tempObject));
|
||||
if (!error) {
|
||||
json = jsonBuffer.as<JsonVariant>();
|
||||
JsonVariant json = jsonBuffer.as<JsonVariant>();
|
||||
_onRequest(request, json);
|
||||
return;
|
||||
}
|
||||
}
|
||||
_onRequest(request, json);
|
||||
request->send(_contentLength > _maxContentLength ? 413 : 400);
|
||||
} else {
|
||||
request->send(500);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <vector>
|
||||
#include "FS.h"
|
||||
|
||||
#include <ArduinoJson.h> // added by proddy
|
||||
|
||||
#include "StringArray.h"
|
||||
|
||||
#ifdef ESP32
|
||||
@@ -65,26 +67,26 @@ class AsyncResponseStream;
|
||||
|
||||
#ifndef WEBSERVER_H
|
||||
typedef enum {
|
||||
HTTP_GET = 0b00000001,
|
||||
HTTP_POST = 0b00000010,
|
||||
HTTP_DELETE = 0b00000100,
|
||||
HTTP_PUT = 0b00001000,
|
||||
HTTP_PATCH = 0b00010000,
|
||||
HTTP_HEAD = 0b00100000,
|
||||
HTTP_OPTIONS = 0b01000000,
|
||||
HTTP_ANY = 0b01111111,
|
||||
HTTP_GET = 0b00000001,
|
||||
HTTP_POST = 0b00000010,
|
||||
HTTP_DELETE = 0b00000100,
|
||||
HTTP_PUT = 0b00001000,
|
||||
HTTP_PATCH = 0b00010000,
|
||||
HTTP_HEAD = 0b00100000,
|
||||
HTTP_OPTIONS = 0b01000000,
|
||||
HTTP_ANY = 0b01111111,
|
||||
} WebRequestMethod;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FS_FILE_OPEN_MODE
|
||||
namespace fs {
|
||||
class FileOpenMode {
|
||||
public:
|
||||
static const char *read;
|
||||
static const char *write;
|
||||
static const char *append;
|
||||
};
|
||||
class FileOpenMode {
|
||||
public:
|
||||
static const char * read;
|
||||
static const char * write;
|
||||
static const char * append;
|
||||
};
|
||||
}; // namespace fs
|
||||
#else
|
||||
#include "FileOpenMode.h"
|
||||
#endif
|
||||
@@ -92,7 +94,7 @@ namespace fs {
|
||||
//if this value is returned when asked for data, packet will not be sent and you will be asked for data again
|
||||
#define RESPONSE_TRY_AGAIN 0xFFFFFFFF
|
||||
|
||||
typedef uint8_t WebRequestMethodComposite;
|
||||
typedef uint8_t WebRequestMethodComposite;
|
||||
typedef std::function<void(void)> ArDisconnectHandler;
|
||||
|
||||
/*
|
||||
@@ -104,17 +106,32 @@ class AsyncWebParameter {
|
||||
String _name;
|
||||
String _value;
|
||||
size_t _size;
|
||||
bool _isForm;
|
||||
bool _isFile;
|
||||
bool _isForm;
|
||||
bool _isFile;
|
||||
|
||||
public:
|
||||
|
||||
AsyncWebParameter(const String& name, const String& value, bool form=false, bool file=false, size_t size=0): _name(name), _value(value), _size(size), _isForm(form), _isFile(file){}
|
||||
const String& name() const { return _name; }
|
||||
const String& value() const { return _value; }
|
||||
size_t size() const { return _size; }
|
||||
bool isPost() const { return _isForm; }
|
||||
bool isFile() const { return _isFile; }
|
||||
AsyncWebParameter(const String & name, const String & value, bool form = false, bool file = false, size_t size = 0)
|
||||
: _name(name)
|
||||
, _value(value)
|
||||
, _size(size)
|
||||
, _isForm(form)
|
||||
, _isFile(file) {
|
||||
}
|
||||
const String & name() const {
|
||||
return _name;
|
||||
}
|
||||
const String & value() const {
|
||||
return _value;
|
||||
}
|
||||
size_t size() const {
|
||||
return _size;
|
||||
}
|
||||
bool isPost() const {
|
||||
return _isForm;
|
||||
}
|
||||
bool isFile() const {
|
||||
return _isFile;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -127,23 +144,36 @@ class AsyncWebHeader {
|
||||
String _value;
|
||||
|
||||
public:
|
||||
AsyncWebHeader() = default;
|
||||
AsyncWebHeader() = default;
|
||||
AsyncWebHeader(const AsyncWebHeader &) = default;
|
||||
|
||||
AsyncWebHeader(const String& name, const String& value): _name(name), _value(value){}
|
||||
AsyncWebHeader(const String& data): _name(), _value(){
|
||||
if(!data) return;
|
||||
int index = data.indexOf(':');
|
||||
if (index < 0) return;
|
||||
_name = data.substring(0, index);
|
||||
_value = data.substring(index + 2);
|
||||
AsyncWebHeader(const String & name, const String & value)
|
||||
: _name(name)
|
||||
, _value(value) {
|
||||
}
|
||||
AsyncWebHeader(const String & data)
|
||||
: _name()
|
||||
, _value() {
|
||||
if (!data)
|
||||
return;
|
||||
int index = data.indexOf(':');
|
||||
if (index < 0)
|
||||
return;
|
||||
_name = data.substring(0, index);
|
||||
_value = data.substring(index + 2);
|
||||
}
|
||||
|
||||
AsyncWebHeader &operator=(const AsyncWebHeader &) = default;
|
||||
AsyncWebHeader & operator=(const AsyncWebHeader &) = default;
|
||||
|
||||
const String& name() const { return _name; }
|
||||
const String& value() const { return _value; }
|
||||
String toString() const { return _name + F(": ") + _value + F("\r\n"); }
|
||||
const String & name() const {
|
||||
return _name;
|
||||
}
|
||||
const String & value() const {
|
||||
return _value;
|
||||
}
|
||||
String toString() const {
|
||||
return _name + F(": ") + _value + F("\r\n");
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -152,98 +182,117 @@ class AsyncWebHeader {
|
||||
|
||||
typedef enum { RCT_NOT_USED = -1, RCT_DEFAULT = 0, RCT_HTTP, RCT_WS, RCT_EVENT, RCT_MAX } RequestedConnectionType;
|
||||
|
||||
typedef std::function<size_t(uint8_t*, size_t, size_t)> AwsResponseFiller;
|
||||
typedef std::function<String(const String&)> AwsTemplateProcessor;
|
||||
typedef std::function<size_t(uint8_t *, size_t, size_t)> AwsResponseFiller;
|
||||
typedef std::function<String(const String &)> AwsTemplateProcessor;
|
||||
|
||||
class AsyncWebServerRequest {
|
||||
using File = fs::File;
|
||||
using FS = fs::FS;
|
||||
friend class AsyncWebServer;
|
||||
friend class AsyncCallbackWebHandler;
|
||||
private:
|
||||
AsyncClient* _client;
|
||||
AsyncWebServer* _server;
|
||||
AsyncWebHandler* _handler;
|
||||
AsyncWebServerResponse* _response;
|
||||
std::vector<String> _interestingHeaders;
|
||||
ArDisconnectHandler _onDisconnectfn;
|
||||
using File = fs::File;
|
||||
using FS = fs::FS;
|
||||
friend class AsyncWebServer;
|
||||
friend class AsyncCallbackWebHandler;
|
||||
|
||||
String _temp;
|
||||
private:
|
||||
AsyncClient * _client;
|
||||
AsyncWebServer * _server;
|
||||
AsyncWebHandler * _handler;
|
||||
AsyncWebServerResponse * _response;
|
||||
std::vector<String> _interestingHeaders;
|
||||
ArDisconnectHandler _onDisconnectfn;
|
||||
|
||||
String _temp;
|
||||
uint8_t _parseState;
|
||||
|
||||
uint8_t _version;
|
||||
uint8_t _version;
|
||||
WebRequestMethodComposite _method;
|
||||
String _url;
|
||||
String _host;
|
||||
String _contentType;
|
||||
String _boundary;
|
||||
String _authorization;
|
||||
RequestedConnectionType _reqconntype;
|
||||
void _removeNotInterestingHeaders();
|
||||
bool _isDigest;
|
||||
bool _isMultipart;
|
||||
bool _isPlainPost;
|
||||
bool _expectingContinue;
|
||||
size_t _contentLength;
|
||||
size_t _parsedLength;
|
||||
String _url;
|
||||
String _host;
|
||||
String _contentType;
|
||||
String _boundary;
|
||||
String _authorization;
|
||||
RequestedConnectionType _reqconntype;
|
||||
void _removeNotInterestingHeaders();
|
||||
bool _isDigest;
|
||||
bool _isMultipart;
|
||||
bool _isPlainPost;
|
||||
bool _expectingContinue;
|
||||
size_t _contentLength;
|
||||
size_t _parsedLength;
|
||||
|
||||
std::list<AsyncWebHeader> _headers;
|
||||
std::list<AsyncWebHeader> _headers;
|
||||
LinkedList<AsyncWebParameter *> _params;
|
||||
std::vector<String> _pathParams;
|
||||
std::vector<String> _pathParams;
|
||||
|
||||
uint8_t _multiParseState;
|
||||
uint8_t _boundaryPosition;
|
||||
size_t _itemStartIndex;
|
||||
size_t _itemSize;
|
||||
String _itemName;
|
||||
String _itemFilename;
|
||||
String _itemType;
|
||||
String _itemValue;
|
||||
uint8_t *_itemBuffer;
|
||||
size_t _itemBufferIndex;
|
||||
bool _itemIsFile;
|
||||
uint8_t _multiParseState;
|
||||
uint8_t _boundaryPosition;
|
||||
size_t _itemStartIndex;
|
||||
size_t _itemSize;
|
||||
String _itemName;
|
||||
String _itemFilename;
|
||||
String _itemType;
|
||||
String _itemValue;
|
||||
uint8_t * _itemBuffer;
|
||||
size_t _itemBufferIndex;
|
||||
bool _itemIsFile;
|
||||
|
||||
void _onPoll();
|
||||
void _onAck(size_t len, uint32_t time);
|
||||
void _onError(int8_t error);
|
||||
void _onTimeout(uint32_t time);
|
||||
void _onDisconnect();
|
||||
void _onData(void *buf, size_t len);
|
||||
void _onData(void * buf, size_t len);
|
||||
|
||||
void _addParam(AsyncWebParameter*);
|
||||
void _addPathParam(const char *param);
|
||||
void _addParam(AsyncWebParameter *);
|
||||
void _addPathParam(const char * param);
|
||||
|
||||
bool _parseReqHead();
|
||||
bool _parseReqHeader();
|
||||
void _parseLine();
|
||||
void _parsePlainPostChar(uint8_t data);
|
||||
void _parseMultipartPostByte(uint8_t data, bool last);
|
||||
void _addGetParams(const String& params);
|
||||
void _addGetParams(const String & params);
|
||||
|
||||
void _handleUploadStart();
|
||||
void _handleUploadByte(uint8_t data, bool last);
|
||||
void _handleUploadEnd();
|
||||
|
||||
public:
|
||||
File _tempFile;
|
||||
void *_tempObject;
|
||||
File _tempFile;
|
||||
void * _tempObject;
|
||||
|
||||
AsyncWebServerRequest(AsyncWebServer*, AsyncClient*);
|
||||
AsyncWebServerRequest(AsyncWebServer *, AsyncClient *);
|
||||
~AsyncWebServerRequest();
|
||||
|
||||
AsyncClient* client(){ return _client; }
|
||||
uint8_t version() const { return _version; }
|
||||
WebRequestMethodComposite method() const { return _method; }
|
||||
const String& url() const { return _url; }
|
||||
const String& host() const { return _host; }
|
||||
const String& contentType() const { return _contentType; }
|
||||
size_t contentLength() const { return _contentLength; }
|
||||
bool multipart() const { return _isMultipart; }
|
||||
const __FlashStringHelper *methodToString() const;
|
||||
const __FlashStringHelper *requestedConnTypeToString() const;
|
||||
RequestedConnectionType requestedConnType() const { return _reqconntype; }
|
||||
AsyncClient * client() {
|
||||
return _client;
|
||||
}
|
||||
uint8_t version() const {
|
||||
return _version;
|
||||
}
|
||||
WebRequestMethodComposite method() const {
|
||||
return _method;
|
||||
}
|
||||
const String & url() const {
|
||||
return _url;
|
||||
}
|
||||
const String & host() const {
|
||||
return _host;
|
||||
}
|
||||
const String & contentType() const {
|
||||
return _contentType;
|
||||
}
|
||||
size_t contentLength() const {
|
||||
return _contentLength;
|
||||
}
|
||||
bool multipart() const {
|
||||
return _isMultipart;
|
||||
}
|
||||
const __FlashStringHelper * methodToString() const;
|
||||
const __FlashStringHelper * requestedConnTypeToString() const;
|
||||
RequestedConnectionType requestedConnType() const {
|
||||
return _reqconntype;
|
||||
}
|
||||
bool isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2 = RCT_NOT_USED, RequestedConnectionType erct3 = RCT_NOT_USED);
|
||||
void onDisconnect (ArDisconnectHandler fn);
|
||||
void onDisconnect(ArDisconnectHandler fn);
|
||||
|
||||
//hash is the string representation of:
|
||||
// base64(user:pass) for basic or
|
||||
@@ -252,76 +301,85 @@ class AsyncWebServerRequest {
|
||||
bool authenticate(const char * username, const char * password, const char * realm = NULL, bool passwordIsHash = false);
|
||||
void requestAuthentication(const char * realm = NULL, bool isDigest = true);
|
||||
|
||||
void setHandler(AsyncWebHandler *handler){ _handler = handler; }
|
||||
void addInterestingHeader(const String& name);
|
||||
void setHandler(AsyncWebHandler * handler) {
|
||||
_handler = handler;
|
||||
}
|
||||
void addInterestingHeader(const String & name);
|
||||
|
||||
void redirect(const String& url);
|
||||
void redirect(const String & url);
|
||||
|
||||
void send(AsyncWebServerResponse *response);
|
||||
void send(int code, const String& contentType=String(), const String& content=String());
|
||||
void send(FS &fs, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr);
|
||||
void send(File content, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr);
|
||||
void send(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback=nullptr);
|
||||
void send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr);
|
||||
void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr);
|
||||
void send_P(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback=nullptr);
|
||||
void send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback=nullptr);
|
||||
void send(AsyncWebServerResponse * response);
|
||||
void send(int code, const String & contentType = String(), const String & content = String());
|
||||
void send(FS & fs, const String & path, const String & contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr);
|
||||
void send(File content, const String & path, const String & contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr);
|
||||
void send(Stream & stream, const String & contentType, size_t len, AwsTemplateProcessor callback = nullptr);
|
||||
void send(const String & contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr);
|
||||
void sendChunked(const String & contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr);
|
||||
void send_P(int code, const String & contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback = nullptr);
|
||||
void send_P(int code, const String & contentType, PGM_P content, AwsTemplateProcessor callback = nullptr);
|
||||
|
||||
AsyncWebServerResponse *beginResponse(int code, const String& contentType=String(), const String& content=String());
|
||||
AsyncWebServerResponse *beginResponse(FS &fs, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr);
|
||||
AsyncWebServerResponse *beginResponse(File content, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr);
|
||||
AsyncWebServerResponse *beginResponse(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback=nullptr);
|
||||
AsyncWebServerResponse *beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr);
|
||||
AsyncWebServerResponse *beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr);
|
||||
AsyncResponseStream *beginResponseStream(const String& contentType, size_t bufferSize=1460);
|
||||
AsyncWebServerResponse *beginResponse_P(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback=nullptr);
|
||||
AsyncWebServerResponse *beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback=nullptr);
|
||||
AsyncWebServerResponse * beginResponse(int code, const String & contentType = String(), const String & content = String());
|
||||
AsyncWebServerResponse *
|
||||
beginResponse(FS & fs, const String & path, const String & contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr);
|
||||
AsyncWebServerResponse *
|
||||
beginResponse(File content, const String & path, const String & contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr);
|
||||
AsyncWebServerResponse * beginResponse(Stream & stream, const String & contentType, size_t len, AwsTemplateProcessor callback = nullptr);
|
||||
AsyncWebServerResponse * beginResponse(const String & contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr);
|
||||
AsyncWebServerResponse * beginChunkedResponse(const String & contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr);
|
||||
AsyncResponseStream * beginResponseStream(const String & contentType, size_t bufferSize = 1460);
|
||||
AsyncWebServerResponse * beginResponse_P(int code, const String & contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback = nullptr);
|
||||
AsyncWebServerResponse * beginResponse_P(int code, const String & contentType, PGM_P content, AwsTemplateProcessor callback = nullptr);
|
||||
|
||||
size_t headers() const; // get header count
|
||||
bool hasHeader(const String& name) const; // check if header exists
|
||||
bool hasHeader(const __FlashStringHelper * data) const; // check if header exists
|
||||
// added by proddy
|
||||
AsyncWebServerResponse * beginResponse(const String & contentType, const uint8_t * content, size_t len);
|
||||
|
||||
AsyncWebHeader* getHeader(const String& name);
|
||||
const AsyncWebHeader* getHeader(const String& name) const;
|
||||
AsyncWebHeader* getHeader(const __FlashStringHelper * data);
|
||||
const AsyncWebHeader* getHeader(const __FlashStringHelper * data) const;
|
||||
AsyncWebHeader* getHeader(size_t num);
|
||||
const AsyncWebHeader* getHeader(size_t num) const;
|
||||
size_t headers() const; // get header count
|
||||
bool hasHeader(const String & name) const; // check if header exists
|
||||
bool hasHeader(const __FlashStringHelper * data) const; // check if header exists
|
||||
|
||||
size_t params() const; // get arguments count
|
||||
bool hasParam(const String& name, bool post=false, bool file=false) const;
|
||||
bool hasParam(const __FlashStringHelper * data, bool post=false, bool file=false) const;
|
||||
AsyncWebHeader * getHeader(const String & name);
|
||||
const AsyncWebHeader * getHeader(const String & name) const;
|
||||
AsyncWebHeader * getHeader(const __FlashStringHelper * data);
|
||||
const AsyncWebHeader * getHeader(const __FlashStringHelper * data) const;
|
||||
AsyncWebHeader * getHeader(size_t num);
|
||||
const AsyncWebHeader * getHeader(size_t num) const;
|
||||
|
||||
AsyncWebParameter* getParam(const String& name, bool post=false, bool file=false) const;
|
||||
AsyncWebParameter* getParam(const __FlashStringHelper * data, bool post, bool file) const;
|
||||
AsyncWebParameter* getParam(size_t num) const;
|
||||
size_t params() const; // get arguments count
|
||||
bool hasParam(const String & name, bool post = false, bool file = false) const;
|
||||
bool hasParam(const __FlashStringHelper * data, bool post = false, bool file = false) const;
|
||||
|
||||
size_t args() const { return params(); } // get arguments count
|
||||
const String& arg(const String& name) const; // get request argument value by name
|
||||
const String& arg(const __FlashStringHelper * data) const; // get request argument value by F(name)
|
||||
const String& arg(size_t i) const; // get request argument value by number
|
||||
const String& argName(size_t i) const; // get request argument name by number
|
||||
bool hasArg(const char* name) const; // check if argument exists
|
||||
bool hasArg(const __FlashStringHelper * data) const; // check if F(argument) exists
|
||||
AsyncWebParameter * getParam(const String & name, bool post = false, bool file = false) const;
|
||||
AsyncWebParameter * getParam(const __FlashStringHelper * data, bool post, bool file) const;
|
||||
AsyncWebParameter * getParam(size_t num) const;
|
||||
|
||||
const String& ASYNCWEBSERVER_REGEX_ATTRIBUTE pathArg(size_t i) const;
|
||||
size_t args() const {
|
||||
return params();
|
||||
} // get arguments count
|
||||
const String & arg(const String & name) const; // get request argument value by name
|
||||
const String & arg(const __FlashStringHelper * data) const; // get request argument value by F(name)
|
||||
const String & arg(size_t i) const; // get request argument value by number
|
||||
const String & argName(size_t i) const; // get request argument name by number
|
||||
bool hasArg(const char * name) const; // check if argument exists
|
||||
bool hasArg(const __FlashStringHelper * data) const; // check if F(argument) exists
|
||||
|
||||
const String& header(const char* name) const;// get request header value by name
|
||||
const String& header(const __FlashStringHelper * data) const;// get request header value by F(name)
|
||||
const String& header(size_t i) const; // get request header value by number
|
||||
const String& headerName(size_t i) const; // get request header name by number
|
||||
String urlDecode(const String& text) const;
|
||||
const String & ASYNCWEBSERVER_REGEX_ATTRIBUTE pathArg(size_t i) const;
|
||||
|
||||
const String & header(const char * name) const; // get request header value by name
|
||||
const String & header(const __FlashStringHelper * data) const; // get request header value by F(name)
|
||||
const String & header(size_t i) const; // get request header value by number
|
||||
const String & headerName(size_t i) const; // get request header name by number
|
||||
String urlDecode(const String & text) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* FILTER :: Callback to filter AsyncWebRewrite and AsyncWebHandler (done by the Server)
|
||||
* */
|
||||
|
||||
typedef std::function<bool(AsyncWebServerRequest *request)> ArRequestFilterFunction;
|
||||
typedef std::function<bool(AsyncWebServerRequest * request)> ArRequestFilterFunction;
|
||||
|
||||
bool ON_STA_FILTER(AsyncWebServerRequest *request);
|
||||
bool ON_STA_FILTER(AsyncWebServerRequest * request);
|
||||
|
||||
bool ON_AP_FILTER(AsyncWebServerRequest *request);
|
||||
bool ON_AP_FILTER(AsyncWebServerRequest * request);
|
||||
|
||||
/*
|
||||
* REWRITE :: One instance can be handle any Request (done by the Server)
|
||||
@@ -329,25 +387,44 @@ bool ON_AP_FILTER(AsyncWebServerRequest *request);
|
||||
|
||||
class AsyncWebRewrite {
|
||||
protected:
|
||||
String _from;
|
||||
String _toUrl;
|
||||
String _params;
|
||||
String _from;
|
||||
String _toUrl;
|
||||
String _params;
|
||||
ArRequestFilterFunction _filter;
|
||||
|
||||
public:
|
||||
AsyncWebRewrite(const char* from, const char* to): _from(from), _toUrl(to), _params(String()), _filter(NULL){
|
||||
int index = _toUrl.indexOf('?');
|
||||
if (index > 0) {
|
||||
_params = _toUrl.substring(index +1);
|
||||
_toUrl = _toUrl.substring(0, index);
|
||||
}
|
||||
AsyncWebRewrite(const char * from, const char * to)
|
||||
: _from(from)
|
||||
, _toUrl(to)
|
||||
, _params(String())
|
||||
, _filter(NULL) {
|
||||
int index = _toUrl.indexOf('?');
|
||||
if (index > 0) {
|
||||
_params = _toUrl.substring(index + 1);
|
||||
_toUrl = _toUrl.substring(0, index);
|
||||
}
|
||||
}
|
||||
virtual ~AsyncWebRewrite() {
|
||||
}
|
||||
AsyncWebRewrite & setFilter(ArRequestFilterFunction fn) {
|
||||
_filter = fn;
|
||||
return *this;
|
||||
}
|
||||
bool filter(AsyncWebServerRequest * request) const {
|
||||
return _filter == NULL || _filter(request);
|
||||
}
|
||||
const String & from(void) const {
|
||||
return _from;
|
||||
}
|
||||
const String & toUrl(void) const {
|
||||
return _toUrl;
|
||||
}
|
||||
const String & params(void) const {
|
||||
return _params;
|
||||
}
|
||||
virtual bool match(AsyncWebServerRequest * request) {
|
||||
return from() == request->url() && filter(request);
|
||||
}
|
||||
virtual ~AsyncWebRewrite(){}
|
||||
AsyncWebRewrite& setFilter(ArRequestFilterFunction fn) { _filter = fn; return *this; }
|
||||
bool filter(AsyncWebServerRequest *request) const { return _filter == NULL || _filter(request); }
|
||||
const String& from(void) const { return _from; }
|
||||
const String& toUrl(void) const { return _toUrl; }
|
||||
const String& params(void) const { return _params; }
|
||||
virtual bool match(AsyncWebServerRequest *request) { return from() == request->url() && filter(request); }
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -357,78 +434,107 @@ class AsyncWebRewrite {
|
||||
class AsyncWebHandler {
|
||||
protected:
|
||||
ArRequestFilterFunction _filter;
|
||||
String _username;
|
||||
String _password;
|
||||
String _username;
|
||||
String _password;
|
||||
|
||||
public:
|
||||
AsyncWebHandler():_username(""), _password(""){}
|
||||
AsyncWebHandler& setFilter(ArRequestFilterFunction fn) { _filter = fn; return *this; }
|
||||
AsyncWebHandler& setAuthentication(const char *username, const char *password){ _username = String(username);_password = String(password); return *this; };
|
||||
bool filter(AsyncWebServerRequest *request){ return _filter == NULL || _filter(request); }
|
||||
virtual ~AsyncWebHandler(){}
|
||||
virtual bool canHandle(AsyncWebServerRequest *request __attribute__((unused))){
|
||||
return false;
|
||||
AsyncWebHandler()
|
||||
: _username("")
|
||||
, _password("") {
|
||||
}
|
||||
AsyncWebHandler & setFilter(ArRequestFilterFunction fn) {
|
||||
_filter = fn;
|
||||
return *this;
|
||||
}
|
||||
AsyncWebHandler & setAuthentication(const char * username, const char * password) {
|
||||
_username = String(username);
|
||||
_password = String(password);
|
||||
return *this;
|
||||
};
|
||||
bool filter(AsyncWebServerRequest * request) {
|
||||
return _filter == NULL || _filter(request);
|
||||
}
|
||||
virtual ~AsyncWebHandler() {
|
||||
}
|
||||
virtual bool canHandle(AsyncWebServerRequest * request __attribute__((unused))) {
|
||||
return false;
|
||||
}
|
||||
virtual void handleRequest(AsyncWebServerRequest * request __attribute__((unused))) {
|
||||
}
|
||||
virtual void handleUpload(AsyncWebServerRequest * request __attribute__((unused)),
|
||||
const String & filename __attribute__((unused)),
|
||||
size_t index __attribute__((unused)),
|
||||
uint8_t * data __attribute__((unused)),
|
||||
size_t len __attribute__((unused)),
|
||||
bool final __attribute__((unused))) {
|
||||
}
|
||||
virtual void handleBody(AsyncWebServerRequest * request __attribute__((unused)),
|
||||
uint8_t * data __attribute__((unused)),
|
||||
size_t len __attribute__((unused)),
|
||||
size_t index __attribute__((unused)),
|
||||
size_t total __attribute__((unused))) {
|
||||
}
|
||||
virtual bool isRequestHandlerTrivial() {
|
||||
return true;
|
||||
}
|
||||
virtual void handleRequest(AsyncWebServerRequest *request __attribute__((unused))){}
|
||||
virtual void handleUpload(AsyncWebServerRequest *request __attribute__((unused)), const String& filename __attribute__((unused)), size_t index __attribute__((unused)), uint8_t *data __attribute__((unused)), size_t len __attribute__((unused)), bool final __attribute__((unused))){}
|
||||
virtual void handleBody(AsyncWebServerRequest *request __attribute__((unused)), uint8_t *data __attribute__((unused)), size_t len __attribute__((unused)), size_t index __attribute__((unused)), size_t total __attribute__((unused))){}
|
||||
virtual bool isRequestHandlerTrivial(){return true;}
|
||||
};
|
||||
|
||||
/*
|
||||
* RESPONSE :: One instance is created for each Request (attached by the Handler)
|
||||
* */
|
||||
|
||||
typedef enum {
|
||||
RESPONSE_SETUP, RESPONSE_HEADERS, RESPONSE_CONTENT, RESPONSE_WAIT_ACK, RESPONSE_END, RESPONSE_FAILED
|
||||
} WebResponseState;
|
||||
typedef enum { RESPONSE_SETUP, RESPONSE_HEADERS, RESPONSE_CONTENT, RESPONSE_WAIT_ACK, RESPONSE_END, RESPONSE_FAILED } WebResponseState;
|
||||
|
||||
class AsyncWebServerResponse {
|
||||
protected:
|
||||
int _code;
|
||||
int _code;
|
||||
std::list<AsyncWebHeader> _headers;
|
||||
String _contentType;
|
||||
size_t _contentLength;
|
||||
bool _sendContentLength;
|
||||
bool _chunked;
|
||||
size_t _headLength;
|
||||
size_t _sentLength;
|
||||
size_t _ackedLength;
|
||||
size_t _writtenLength;
|
||||
WebResponseState _state;
|
||||
const char* _responseCodeToString(int code);
|
||||
public:
|
||||
static const __FlashStringHelper *responseCodeToString(int code);
|
||||
String _contentType;
|
||||
size_t _contentLength;
|
||||
bool _sendContentLength;
|
||||
bool _chunked;
|
||||
size_t _headLength;
|
||||
size_t _sentLength;
|
||||
size_t _ackedLength;
|
||||
size_t _writtenLength;
|
||||
WebResponseState _state;
|
||||
const char * _responseCodeToString(int code);
|
||||
|
||||
public:
|
||||
static const __FlashStringHelper * responseCodeToString(int code);
|
||||
|
||||
public:
|
||||
AsyncWebServerResponse();
|
||||
virtual ~AsyncWebServerResponse();
|
||||
virtual void setCode(int code);
|
||||
virtual void setContentLength(size_t len);
|
||||
virtual void setContentType(const String& type);
|
||||
virtual void addHeader(const String& name, const String& value);
|
||||
virtual void setCode(int code);
|
||||
virtual void setContentLength(size_t len);
|
||||
virtual void setContentType(const String & type);
|
||||
virtual void addHeader(const String & name, const String & value);
|
||||
virtual String _assembleHead(uint8_t version);
|
||||
virtual bool _started() const;
|
||||
virtual bool _finished() const;
|
||||
virtual bool _failed() const;
|
||||
virtual bool _sourceValid() const;
|
||||
virtual void _respond(AsyncWebServerRequest *request);
|
||||
virtual size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
|
||||
virtual bool _started() const;
|
||||
virtual bool _finished() const;
|
||||
virtual bool _failed() const;
|
||||
virtual bool _sourceValid() const;
|
||||
virtual void _respond(AsyncWebServerRequest * request);
|
||||
virtual size_t _ack(AsyncWebServerRequest * request, size_t len, uint32_t time);
|
||||
};
|
||||
|
||||
/*
|
||||
* SERVER :: One instance
|
||||
* */
|
||||
|
||||
typedef std::function<void(AsyncWebServerRequest *request)> ArRequestHandlerFunction;
|
||||
typedef std::function<void(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final)> ArUploadHandlerFunction;
|
||||
typedef std::function<void(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total)> ArBodyHandlerFunction;
|
||||
typedef std::function<void(AsyncWebServerRequest * request)> ArRequestHandlerFunction;
|
||||
typedef std::function<void(AsyncWebServerRequest * request, const String & filename, size_t index, uint8_t * data, size_t len, bool final)> ArUploadHandlerFunction;
|
||||
typedef std::function<void(AsyncWebServerRequest * request, uint8_t * data, size_t len, size_t index, size_t total)> ArBodyHandlerFunction;
|
||||
|
||||
typedef std::function<void(AsyncWebServerRequest * request, JsonVariant json)> ArJsonRequestHandlerFunction; // added by proddy
|
||||
|
||||
class AsyncWebServer {
|
||||
protected:
|
||||
AsyncServer _server;
|
||||
LinkedList<AsyncWebRewrite*> _rewrites;
|
||||
LinkedList<AsyncWebHandler*> _handlers;
|
||||
AsyncCallbackWebHandler* _catchAllHandler;
|
||||
AsyncServer _server;
|
||||
LinkedList<AsyncWebRewrite *> _rewrites;
|
||||
LinkedList<AsyncWebHandler *> _handlers;
|
||||
AsyncCallbackWebHandler * _catchAllHandler;
|
||||
|
||||
public:
|
||||
AsyncWebServer(uint16_t port);
|
||||
@@ -438,58 +544,65 @@ class AsyncWebServer {
|
||||
void end();
|
||||
|
||||
#if ASYNC_TCP_SSL_ENABLED
|
||||
void onSslFileRequest(AcSSlFileHandler cb, void* arg);
|
||||
void beginSecure(const char *cert, const char *private_key_file, const char *password);
|
||||
void onSslFileRequest(AcSSlFileHandler cb, void * arg);
|
||||
void beginSecure(const char * cert, const char * private_key_file, const char * password);
|
||||
#endif
|
||||
|
||||
AsyncWebRewrite& addRewrite(AsyncWebRewrite* rewrite);
|
||||
bool removeRewrite(AsyncWebRewrite* rewrite);
|
||||
AsyncWebRewrite& rewrite(const char* from, const char* to);
|
||||
AsyncWebRewrite & addRewrite(AsyncWebRewrite * rewrite);
|
||||
bool removeRewrite(AsyncWebRewrite * rewrite);
|
||||
AsyncWebRewrite & rewrite(const char * from, const char * to);
|
||||
|
||||
AsyncWebHandler& addHandler(AsyncWebHandler* handler);
|
||||
bool removeHandler(AsyncWebHandler* handler);
|
||||
AsyncWebHandler & addHandler(AsyncWebHandler * handler);
|
||||
bool removeHandler(AsyncWebHandler * handler);
|
||||
|
||||
AsyncCallbackWebHandler& on(const char* uri, ArRequestHandlerFunction onRequest);
|
||||
AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest);
|
||||
AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload);
|
||||
AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody);
|
||||
AsyncCallbackWebHandler & on(const char * uri, ArRequestHandlerFunction onRequest);
|
||||
AsyncCallbackWebHandler & on(const char * uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest);
|
||||
AsyncCallbackWebHandler & on(const char * uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload);
|
||||
AsyncCallbackWebHandler &
|
||||
on(const char * uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody);
|
||||
|
||||
AsyncStaticWebHandler& serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_control = NULL);
|
||||
void on(const char * uri, ArJsonRequestHandlerFunction onRequest); // added by proddy
|
||||
|
||||
AsyncStaticWebHandler & serveStatic(const char * uri, fs::FS & fs, const char * path, const char * cache_control = NULL);
|
||||
|
||||
void onNotFound(ArRequestHandlerFunction fn); //called when handler is not assigned
|
||||
void onFileUpload(ArUploadHandlerFunction fn); //handle file uploads
|
||||
void onRequestBody(ArBodyHandlerFunction fn); //handle posts with plain body content (JSON often transmitted this way as a request)
|
||||
void onRequestBody(ArBodyHandlerFunction fn); //handle posts with plain body content (JSON often transmitted this way as a request)
|
||||
|
||||
void reset(); //remove all writers and handlers, with onNotFound/onFileUpload/onRequestBody
|
||||
|
||||
void _handleDisconnect(AsyncWebServerRequest *request);
|
||||
void _attachHandler(AsyncWebServerRequest *request);
|
||||
void _rewriteRequest(AsyncWebServerRequest *request);
|
||||
void _handleDisconnect(AsyncWebServerRequest * request);
|
||||
void _attachHandler(AsyncWebServerRequest * request);
|
||||
void _rewriteRequest(AsyncWebServerRequest * request);
|
||||
};
|
||||
|
||||
class DefaultHeaders {
|
||||
using headers_t = std::list<AsyncWebHeader>;
|
||||
headers_t _headers;
|
||||
using headers_t = std::list<AsyncWebHeader>;
|
||||
headers_t _headers;
|
||||
|
||||
public:
|
||||
DefaultHeaders() = default;
|
||||
public:
|
||||
DefaultHeaders() = default;
|
||||
|
||||
using ConstIterator = headers_t::const_iterator;
|
||||
using ConstIterator = headers_t::const_iterator;
|
||||
|
||||
void addHeader(const String& name, const String& value){
|
||||
_headers.emplace_back(name, value);
|
||||
}
|
||||
void addHeader(const String & name, const String & value) {
|
||||
_headers.emplace_back(name, value);
|
||||
}
|
||||
|
||||
ConstIterator begin() const { return _headers.begin(); }
|
||||
ConstIterator end() const { return _headers.end(); }
|
||||
ConstIterator begin() const {
|
||||
return _headers.begin();
|
||||
}
|
||||
ConstIterator end() const {
|
||||
return _headers.end();
|
||||
}
|
||||
|
||||
DefaultHeaders(DefaultHeaders const &) = delete;
|
||||
DefaultHeaders &operator=(DefaultHeaders const &) = delete;
|
||||
DefaultHeaders(DefaultHeaders const &) = delete;
|
||||
DefaultHeaders & operator=(DefaultHeaders const &) = delete;
|
||||
|
||||
static DefaultHeaders &Instance() {
|
||||
static DefaultHeaders instance;
|
||||
return instance;
|
||||
}
|
||||
static DefaultHeaders & Instance() {
|
||||
static DefaultHeaders instance;
|
||||
return instance;
|
||||
}
|
||||
};
|
||||
|
||||
#include "WebResponseImpl.h"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,34 +31,43 @@
|
||||
|
||||
// It is possible to restore these defines, but one can use _min and _max instead. Or std::min, std::max.
|
||||
|
||||
class AsyncBasicResponse: public AsyncWebServerResponse {
|
||||
class AsyncBasicResponse : public AsyncWebServerResponse {
|
||||
private:
|
||||
String _content;
|
||||
|
||||
public:
|
||||
AsyncBasicResponse(int code, const String& contentType=String(), const String& content=String());
|
||||
void _respond(AsyncWebServerRequest *request);
|
||||
size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
|
||||
bool _sourceValid() const { return true; }
|
||||
AsyncBasicResponse(int code, const String & contentType = String(), const String & content = String());
|
||||
void _respond(AsyncWebServerRequest * request);
|
||||
size_t _ack(AsyncWebServerRequest * request, size_t len, uint32_t time);
|
||||
bool _sourceValid() const {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class AsyncAbstractResponse: public AsyncWebServerResponse {
|
||||
class AsyncAbstractResponse : public AsyncWebServerResponse {
|
||||
private:
|
||||
String _head;
|
||||
// Data is inserted into cache at begin().
|
||||
// This is inefficient with vector, but if we use some other container,
|
||||
// Data is inserted into cache at begin().
|
||||
// This is inefficient with vector, but if we use some other container,
|
||||
// we won't be able to access it as contiguous array of bytes when reading from it,
|
||||
// so by gaining performance in one place, we'll lose it in another.
|
||||
std::vector<uint8_t> _cache;
|
||||
size_t _readDataFromCacheOrContent(uint8_t* data, const size_t len);
|
||||
size_t _fillBufferAndProcessTemplates(uint8_t* buf, size_t maxLen);
|
||||
size_t _readDataFromCacheOrContent(uint8_t * data, const size_t len);
|
||||
size_t _fillBufferAndProcessTemplates(uint8_t * buf, size_t maxLen);
|
||||
|
||||
protected:
|
||||
AwsTemplateProcessor _callback;
|
||||
|
||||
public:
|
||||
AsyncAbstractResponse(AwsTemplateProcessor callback=nullptr);
|
||||
void _respond(AsyncWebServerRequest *request);
|
||||
size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
|
||||
bool _sourceValid() const { return false; }
|
||||
virtual size_t _fillBuffer(uint8_t *buf __attribute__((unused)), size_t maxLen __attribute__((unused))) { return 0; }
|
||||
AsyncAbstractResponse(AwsTemplateProcessor callback = nullptr);
|
||||
void _respond(AsyncWebServerRequest * request);
|
||||
size_t _ack(AsyncWebServerRequest * request, size_t len, uint32_t time);
|
||||
bool _sourceValid() const {
|
||||
return false;
|
||||
}
|
||||
virtual size_t _fillBuffer(uint8_t * buf __attribute__((unused)), size_t maxLen __attribute__((unused))) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef TEMPLATE_PLACEHOLDER
|
||||
@@ -66,72 +75,91 @@ class AsyncAbstractResponse: public AsyncWebServerResponse {
|
||||
#endif
|
||||
|
||||
#define TEMPLATE_PARAM_NAME_LENGTH 32
|
||||
class AsyncFileResponse: public AsyncAbstractResponse {
|
||||
using File = fs::File;
|
||||
using FS = fs::FS;
|
||||
class AsyncFileResponse : public AsyncAbstractResponse {
|
||||
using File = fs::File;
|
||||
using FS = fs::FS;
|
||||
|
||||
private:
|
||||
File _content;
|
||||
File _content;
|
||||
String _path;
|
||||
void _setContentType(const String& path);
|
||||
void _setContentType(const String & path);
|
||||
|
||||
public:
|
||||
AsyncFileResponse(FS &fs, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr);
|
||||
AsyncFileResponse(File content, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr);
|
||||
AsyncFileResponse(FS & fs, const String & path, const String & contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr);
|
||||
AsyncFileResponse(File content, const String & path, const String & contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr);
|
||||
~AsyncFileResponse();
|
||||
bool _sourceValid() const { return !!(_content); }
|
||||
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override;
|
||||
bool _sourceValid() const {
|
||||
return !!(_content);
|
||||
}
|
||||
virtual size_t _fillBuffer(uint8_t * buf, size_t maxLen) override;
|
||||
};
|
||||
|
||||
class AsyncStreamResponse: public AsyncAbstractResponse {
|
||||
class AsyncStreamResponse : public AsyncAbstractResponse {
|
||||
private:
|
||||
Stream *_content;
|
||||
Stream * _content;
|
||||
|
||||
public:
|
||||
AsyncStreamResponse(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback=nullptr);
|
||||
bool _sourceValid() const { return !!(_content); }
|
||||
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override;
|
||||
AsyncStreamResponse(Stream & stream, const String & contentType, size_t len, AwsTemplateProcessor callback = nullptr);
|
||||
bool _sourceValid() const {
|
||||
return !!(_content);
|
||||
}
|
||||
virtual size_t _fillBuffer(uint8_t * buf, size_t maxLen) override;
|
||||
};
|
||||
|
||||
class AsyncCallbackResponse: public AsyncAbstractResponse {
|
||||
class AsyncCallbackResponse : public AsyncAbstractResponse {
|
||||
private:
|
||||
AwsResponseFiller _content;
|
||||
size_t _filledLength;
|
||||
size_t _filledLength;
|
||||
|
||||
public:
|
||||
AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr);
|
||||
bool _sourceValid() const { return !!(_content); }
|
||||
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override;
|
||||
AsyncCallbackResponse(const String & contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr);
|
||||
bool _sourceValid() const {
|
||||
return !!(_content);
|
||||
}
|
||||
virtual size_t _fillBuffer(uint8_t * buf, size_t maxLen) override;
|
||||
};
|
||||
|
||||
class AsyncChunkedResponse: public AsyncAbstractResponse {
|
||||
class AsyncChunkedResponse : public AsyncAbstractResponse {
|
||||
private:
|
||||
AwsResponseFiller _content;
|
||||
size_t _filledLength;
|
||||
size_t _filledLength;
|
||||
|
||||
public:
|
||||
AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr);
|
||||
bool _sourceValid() const { return !!(_content); }
|
||||
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override;
|
||||
AsyncChunkedResponse(const String & contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr);
|
||||
bool _sourceValid() const {
|
||||
return !!(_content);
|
||||
}
|
||||
virtual size_t _fillBuffer(uint8_t * buf, size_t maxLen) override;
|
||||
};
|
||||
|
||||
class AsyncProgmemResponse: public AsyncAbstractResponse {
|
||||
class AsyncProgmemResponse : public AsyncAbstractResponse {
|
||||
private:
|
||||
const uint8_t * _content;
|
||||
size_t _readLength;
|
||||
size_t _readLength;
|
||||
|
||||
public:
|
||||
AsyncProgmemResponse(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback=nullptr);
|
||||
bool _sourceValid() const { return true; }
|
||||
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override;
|
||||
AsyncProgmemResponse(int code, const String & contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback = nullptr);
|
||||
bool _sourceValid() const {
|
||||
return true;
|
||||
}
|
||||
virtual size_t _fillBuffer(uint8_t * buf, size_t maxLen) override;
|
||||
};
|
||||
|
||||
class cbuf;
|
||||
|
||||
class AsyncResponseStream: public AsyncAbstractResponse, public Print {
|
||||
class AsyncResponseStream : public AsyncAbstractResponse, public Print {
|
||||
private:
|
||||
std::unique_ptr<cbuf> _content;
|
||||
|
||||
public:
|
||||
AsyncResponseStream(const String& contentType, size_t bufferSize);
|
||||
AsyncResponseStream(const String & contentType, size_t bufferSize);
|
||||
~AsyncResponseStream();
|
||||
bool _sourceValid() const { return (_state < RESPONSE_END); }
|
||||
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override;
|
||||
size_t write(const uint8_t *data, size_t len);
|
||||
size_t write(uint8_t data);
|
||||
bool _sourceValid() const {
|
||||
return (_state < RESPONSE_END);
|
||||
}
|
||||
virtual size_t _fillBuffer(uint8_t * buf, size_t maxLen) override;
|
||||
size_t write(const uint8_t * data, size_t len);
|
||||
size_t write(uint8_t data);
|
||||
using Print::write;
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,179 +20,192 @@
|
||||
*/
|
||||
#include "ESPAsyncWebServer.h"
|
||||
#include "WebHandlerImpl.h"
|
||||
#include "AsyncJson.h"
|
||||
|
||||
bool ON_STA_FILTER(AsyncWebServerRequest *request) {
|
||||
return WiFi.localIP() == request->client()->localIP();
|
||||
bool ON_STA_FILTER(AsyncWebServerRequest * request) {
|
||||
return WiFi.localIP() == request->client()->localIP();
|
||||
}
|
||||
|
||||
bool ON_AP_FILTER(AsyncWebServerRequest *request) {
|
||||
return WiFi.localIP() != request->client()->localIP();
|
||||
bool ON_AP_FILTER(AsyncWebServerRequest * request) {
|
||||
return WiFi.localIP() != request->client()->localIP();
|
||||
}
|
||||
|
||||
#ifndef HAVE_FS_FILE_OPEN_MODE
|
||||
const char *fs::FileOpenMode::read = "r";
|
||||
const char *fs::FileOpenMode::write = "w";
|
||||
const char *fs::FileOpenMode::append = "a";
|
||||
const char * fs::FileOpenMode::read = "r";
|
||||
const char * fs::FileOpenMode::write = "w";
|
||||
const char * fs::FileOpenMode::append = "a";
|
||||
#endif
|
||||
|
||||
AsyncWebServer::AsyncWebServer(uint16_t port)
|
||||
: _server(port)
|
||||
, _rewrites(LinkedList<AsyncWebRewrite*>([](AsyncWebRewrite* r){ delete r; }))
|
||||
, _handlers(LinkedList<AsyncWebHandler*>([](AsyncWebHandler* h){ delete h; }))
|
||||
{
|
||||
_catchAllHandler = new AsyncCallbackWebHandler();
|
||||
if(_catchAllHandler == NULL)
|
||||
return;
|
||||
_server.onClient([](void *s, AsyncClient* c){
|
||||
if(c == NULL)
|
||||
return;
|
||||
c->setRxTimeout(3);
|
||||
AsyncWebServerRequest *r = new AsyncWebServerRequest((AsyncWebServer*)s, c);
|
||||
if(r == NULL){
|
||||
c->close(true);
|
||||
c->free();
|
||||
delete c;
|
||||
}
|
||||
}, this);
|
||||
: _server(port)
|
||||
, _rewrites(LinkedList<AsyncWebRewrite *>([](AsyncWebRewrite * r) { delete r; }))
|
||||
, _handlers(LinkedList<AsyncWebHandler *>([](AsyncWebHandler * h) { delete h; })) {
|
||||
_catchAllHandler = new AsyncCallbackWebHandler();
|
||||
if (_catchAllHandler == NULL)
|
||||
return;
|
||||
_server.onClient(
|
||||
[](void * s, AsyncClient * c) {
|
||||
if (c == NULL)
|
||||
return;
|
||||
c->setRxTimeout(3);
|
||||
AsyncWebServerRequest * r = new AsyncWebServerRequest((AsyncWebServer *)s, c);
|
||||
if (r == NULL) {
|
||||
c->close(true);
|
||||
c->free();
|
||||
delete c;
|
||||
}
|
||||
},
|
||||
this);
|
||||
}
|
||||
|
||||
AsyncWebServer::~AsyncWebServer(){
|
||||
reset();
|
||||
end();
|
||||
if(_catchAllHandler) delete _catchAllHandler;
|
||||
AsyncWebServer::~AsyncWebServer() {
|
||||
reset();
|
||||
end();
|
||||
if (_catchAllHandler)
|
||||
delete _catchAllHandler;
|
||||
}
|
||||
|
||||
AsyncWebRewrite& AsyncWebServer::addRewrite(AsyncWebRewrite* rewrite){
|
||||
_rewrites.add(rewrite);
|
||||
return *rewrite;
|
||||
AsyncWebRewrite & AsyncWebServer::addRewrite(AsyncWebRewrite * rewrite) {
|
||||
_rewrites.add(rewrite);
|
||||
return *rewrite;
|
||||
}
|
||||
|
||||
bool AsyncWebServer::removeRewrite(AsyncWebRewrite *rewrite){
|
||||
return _rewrites.remove(rewrite);
|
||||
bool AsyncWebServer::removeRewrite(AsyncWebRewrite * rewrite) {
|
||||
return _rewrites.remove(rewrite);
|
||||
}
|
||||
|
||||
AsyncWebRewrite& AsyncWebServer::rewrite(const char* from, const char* to){
|
||||
return addRewrite(new AsyncWebRewrite(from, to));
|
||||
AsyncWebRewrite & AsyncWebServer::rewrite(const char * from, const char * to) {
|
||||
return addRewrite(new AsyncWebRewrite(from, to));
|
||||
}
|
||||
|
||||
AsyncWebHandler& AsyncWebServer::addHandler(AsyncWebHandler* handler){
|
||||
_handlers.add(handler);
|
||||
return *handler;
|
||||
AsyncWebHandler & AsyncWebServer::addHandler(AsyncWebHandler * handler) {
|
||||
_handlers.add(handler);
|
||||
return *handler;
|
||||
}
|
||||
|
||||
bool AsyncWebServer::removeHandler(AsyncWebHandler *handler){
|
||||
return _handlers.remove(handler);
|
||||
bool AsyncWebServer::removeHandler(AsyncWebHandler * handler) {
|
||||
return _handlers.remove(handler);
|
||||
}
|
||||
|
||||
void AsyncWebServer::begin(){
|
||||
_server.setNoDelay(true);
|
||||
_server.begin();
|
||||
void AsyncWebServer::begin() {
|
||||
_server.setNoDelay(true);
|
||||
_server.begin();
|
||||
}
|
||||
|
||||
void AsyncWebServer::end(){
|
||||
_server.end();
|
||||
void AsyncWebServer::end() {
|
||||
_server.end();
|
||||
}
|
||||
|
||||
#if ASYNC_TCP_SSL_ENABLED
|
||||
void AsyncWebServer::onSslFileRequest(AcSSlFileHandler cb, void* arg){
|
||||
_server.onSslFileRequest(cb, arg);
|
||||
void AsyncWebServer::onSslFileRequest(AcSSlFileHandler cb, void * arg) {
|
||||
_server.onSslFileRequest(cb, arg);
|
||||
}
|
||||
|
||||
void AsyncWebServer::beginSecure(const char *cert, const char *key, const char *password){
|
||||
_server.beginSecure(cert, key, password);
|
||||
void AsyncWebServer::beginSecure(const char * cert, const char * key, const char * password) {
|
||||
_server.beginSecure(cert, key, password);
|
||||
}
|
||||
#endif
|
||||
|
||||
void AsyncWebServer::_handleDisconnect(AsyncWebServerRequest *request){
|
||||
delete request;
|
||||
void AsyncWebServer::_handleDisconnect(AsyncWebServerRequest * request) {
|
||||
delete request;
|
||||
}
|
||||
|
||||
void AsyncWebServer::_rewriteRequest(AsyncWebServerRequest *request){
|
||||
for(const auto& r: _rewrites){
|
||||
if (r->match(request)){
|
||||
request->_url = r->toUrl();
|
||||
request->_addGetParams(r->params());
|
||||
void AsyncWebServer::_rewriteRequest(AsyncWebServerRequest * request) {
|
||||
for (const auto & r : _rewrites) {
|
||||
if (r->match(request)) {
|
||||
request->_url = r->toUrl();
|
||||
request->_addGetParams(r->params());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncWebServer::_attachHandler(AsyncWebServerRequest *request){
|
||||
for(const auto& h: _handlers){
|
||||
if (h->filter(request) && h->canHandle(request)){
|
||||
request->setHandler(h);
|
||||
return;
|
||||
void AsyncWebServer::_attachHandler(AsyncWebServerRequest * request) {
|
||||
for (const auto & h : _handlers) {
|
||||
if (h->filter(request) && h->canHandle(request)) {
|
||||
request->setHandler(h);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
request->addInterestingHeader(F("ANY"));
|
||||
request->setHandler(_catchAllHandler);
|
||||
request->addInterestingHeader(F("ANY"));
|
||||
request->setHandler(_catchAllHandler);
|
||||
}
|
||||
|
||||
|
||||
AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody){
|
||||
AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler();
|
||||
handler->setUri(uri);
|
||||
handler->setMethod(method);
|
||||
handler->onRequest(onRequest);
|
||||
handler->onUpload(onUpload);
|
||||
handler->onBody(onBody);
|
||||
addHandler(handler);
|
||||
return *handler;
|
||||
AsyncCallbackWebHandler & AsyncWebServer::on(const char * uri,
|
||||
WebRequestMethodComposite method,
|
||||
ArRequestHandlerFunction onRequest,
|
||||
ArUploadHandlerFunction onUpload,
|
||||
ArBodyHandlerFunction onBody) {
|
||||
AsyncCallbackWebHandler * handler = new AsyncCallbackWebHandler();
|
||||
handler->setUri(uri);
|
||||
handler->setMethod(method);
|
||||
handler->onRequest(onRequest);
|
||||
handler->onUpload(onUpload);
|
||||
handler->onBody(onBody);
|
||||
addHandler(handler);
|
||||
return *handler;
|
||||
}
|
||||
|
||||
AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload){
|
||||
AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler();
|
||||
handler->setUri(uri);
|
||||
handler->setMethod(method);
|
||||
handler->onRequest(onRequest);
|
||||
handler->onUpload(onUpload);
|
||||
addHandler(handler);
|
||||
return *handler;
|
||||
AsyncCallbackWebHandler &
|
||||
AsyncWebServer::on(const char * uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload) {
|
||||
AsyncCallbackWebHandler * handler = new AsyncCallbackWebHandler();
|
||||
handler->setUri(uri);
|
||||
handler->setMethod(method);
|
||||
handler->onRequest(onRequest);
|
||||
handler->onUpload(onUpload);
|
||||
addHandler(handler);
|
||||
return *handler;
|
||||
}
|
||||
|
||||
AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest){
|
||||
AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler();
|
||||
handler->setUri(uri);
|
||||
handler->setMethod(method);
|
||||
handler->onRequest(onRequest);
|
||||
addHandler(handler);
|
||||
return *handler;
|
||||
AsyncCallbackWebHandler & AsyncWebServer::on(const char * uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest) {
|
||||
AsyncCallbackWebHandler * handler = new AsyncCallbackWebHandler();
|
||||
handler->setUri(uri);
|
||||
handler->setMethod(method);
|
||||
handler->onRequest(onRequest);
|
||||
addHandler(handler);
|
||||
return *handler;
|
||||
}
|
||||
|
||||
AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, ArRequestHandlerFunction onRequest){
|
||||
AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler();
|
||||
handler->setUri(uri);
|
||||
handler->onRequest(onRequest);
|
||||
addHandler(handler);
|
||||
return *handler;
|
||||
AsyncCallbackWebHandler & AsyncWebServer::on(const char * uri, ArRequestHandlerFunction onRequest) {
|
||||
AsyncCallbackWebHandler * handler = new AsyncCallbackWebHandler();
|
||||
handler->setUri(uri);
|
||||
handler->onRequest(onRequest);
|
||||
addHandler(handler);
|
||||
return *handler;
|
||||
}
|
||||
|
||||
AsyncStaticWebHandler& AsyncWebServer::serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_control){
|
||||
AsyncStaticWebHandler* handler = new AsyncStaticWebHandler(uri, fs, path, cache_control);
|
||||
addHandler(handler);
|
||||
return *handler;
|
||||
// added by proddy
|
||||
void AsyncWebServer::on(const char * uri, ArJsonRequestHandlerFunction onRequest) {
|
||||
auto * handler = new AsyncCallbackJsonWebHandler(uri, onRequest);
|
||||
addHandler(handler);
|
||||
}
|
||||
|
||||
void AsyncWebServer::onNotFound(ArRequestHandlerFunction fn){
|
||||
_catchAllHandler->onRequest(fn);
|
||||
AsyncStaticWebHandler & AsyncWebServer::serveStatic(const char * uri, fs::FS & fs, const char * path, const char * cache_control) {
|
||||
AsyncStaticWebHandler * handler = new AsyncStaticWebHandler(uri, fs, path, cache_control);
|
||||
addHandler(handler);
|
||||
return *handler;
|
||||
}
|
||||
|
||||
void AsyncWebServer::onFileUpload(ArUploadHandlerFunction fn){
|
||||
_catchAllHandler->onUpload(fn);
|
||||
void AsyncWebServer::onNotFound(ArRequestHandlerFunction fn) {
|
||||
_catchAllHandler->onRequest(fn);
|
||||
}
|
||||
|
||||
void AsyncWebServer::onRequestBody(ArBodyHandlerFunction fn){
|
||||
_catchAllHandler->onBody(fn);
|
||||
void AsyncWebServer::onFileUpload(ArUploadHandlerFunction fn) {
|
||||
_catchAllHandler->onUpload(fn);
|
||||
}
|
||||
|
||||
void AsyncWebServer::reset(){
|
||||
_rewrites.free();
|
||||
_handlers.free();
|
||||
|
||||
if (_catchAllHandler != NULL){
|
||||
_catchAllHandler->onRequest(NULL);
|
||||
_catchAllHandler->onUpload(NULL);
|
||||
_catchAllHandler->onBody(NULL);
|
||||
}
|
||||
void AsyncWebServer::onRequestBody(ArBodyHandlerFunction fn) {
|
||||
_catchAllHandler->onBody(fn);
|
||||
}
|
||||
|
||||
void AsyncWebServer::reset() {
|
||||
_rewrites.free();
|
||||
_handlers.free();
|
||||
|
||||
if (_catchAllHandler != NULL) {
|
||||
_catchAllHandler->onRequest(NULL);
|
||||
_catchAllHandler->onUpload(NULL);
|
||||
_catchAllHandler->onBody(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user