Skip to content
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

feat: added global filter and global disconnect #4

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
22 changes: 11 additions & 11 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ jobs:
- name: Build Tests
run: bash ./.github/scripts/on-push.sh ${{ matrix.board }} 0 1

build-pio:
name: PlatformIO for ${{ matrix.board }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
board: [esp32, esp8266]
steps:
- uses: actions/checkout@v1
- name: Build Tests
run: bash ./.github/scripts/on-push.sh ${{ matrix.board }} 1 1
# build-pio:
# name: PlatformIO for ${{ matrix.board }} on ${{ matrix.os }}
# runs-on: ${{ matrix.os }}
# strategy:
# matrix:
# os: [ubuntu-latest, windows-latest, macOS-latest]
# board: [esp32, esp8266]
# steps:
# - uses: actions/checkout@v1
# - name: Build Tests
# run: bash ./.github/scripts/on-push.sh ${{ matrix.board }} 1 1
4 changes: 4 additions & 0 deletions library.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@
"platforms": ["espressif8266", "espressif32"],
"dependencies": [
{
"owner": "me-no-dev",
"name": "ESPAsyncTCP",
"version": "^1.2.2",
"platforms": "espressif8266"
},
{
"owner": "me-no-dev",
"name": "AsyncTCP",
"version": "^1.1.1",
"platforms": "espressif32"
},
{
Expand Down
16 changes: 12 additions & 4 deletions src/AsyncJson.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@
#if ARDUINOJSON_VERSION_MAJOR == 5
#define ARDUINOJSON_5_COMPATIBILITY
#else
#define DYNAMIC_JSON_DOCUMENT_SIZE 1024
#ifndef DYNAMIC_JSON_DOCUMENT_SIZE
#define DYNAMIC_JSON_DOCUMENT_SIZE 1024
#endif
#endif

constexpr const char* JSON_MIMETYPE = "application/json";
Expand Down Expand Up @@ -199,9 +201,15 @@ class AsyncCallbackJsonWebHandler: public AsyncWebHandler {

if(!(_method & request->method()))
return false;

if(_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri+"/")))
return false;

if (_uri.length() && _uri.endsWith("*")) {
String uriTemplate = String(_uri);
uriTemplate = uriTemplate.substring(0, uriTemplate.length() - 1);
if (!request->url().startsWith(uriTemplate))
return false;
} else
if(_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri+"/")))
return false;

if ( !request->contentType().equalsIgnoreCase(JSON_MIMETYPE) )
return false;
Expand Down
25 changes: 8 additions & 17 deletions src/AsyncWebSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,7 @@
#include <libb64/cencode.h>

#ifndef ESP8266
extern "C" {
typedef struct {
uint32_t state[5];
uint32_t count[2];
unsigned char buffer[64];
} SHA1_CTX;

void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]);
void SHA1Init(SHA1_CTX* context);
void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len);
void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
}
#include "mbedtls/sha1.h"
#else
#include <Hash.h>
#endif
Expand Down Expand Up @@ -911,7 +900,7 @@ void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer)

IPAddress AsyncWebSocketClient::remoteIP() {
if(!_client) {
return IPAddress(0U);
return IPAddress((uint32_t)0);
}
return _client->remoteIP();
}
Expand Down Expand Up @@ -1361,10 +1350,12 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket
sha1(key + WS_STR_UUID, hash);
#else
(String&)key += WS_STR_UUID;
SHA1_CTX ctx;
SHA1Init(&ctx);
SHA1Update(&ctx, (const unsigned char*)key.c_str(), key.length());
SHA1Final(hash, &ctx);
mbedtls_sha1_context ctx;
mbedtls_sha1_init(&ctx);
mbedtls_sha1_starts_ret(&ctx);
mbedtls_sha1_update_ret(&ctx, (const unsigned char*)key.c_str(), key.length());
mbedtls_sha1_finish_ret(&ctx, hash);
mbedtls_sha1_free(&ctx);
#endif
base64_encodestate _state;
base64_init_encodestate(&_state);
Expand Down
19 changes: 14 additions & 5 deletions src/ESPAsyncWebServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,18 +409,22 @@ typedef std::function<void(AsyncWebServerRequest *request)> ArRequestHandlerFunc
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)> ASDisconnectHandler;

class AsyncWebServer {
protected:
AsyncServer _server;
LinkedList<AsyncWebRewrite*> _rewrites;
LinkedList<AsyncWebHandler*> _handlers;
AsyncCallbackWebHandler* _catchAllHandler;
ASDisconnectHandler _onDisconnectfn;
ArRequestFilterFunction _filter;

public:
AsyncWebServer(uint16_t port);
~AsyncWebServer();

void begin();
int8_t begin();
void end();

#if ASYNC_TCP_SSL_ENABLED
Expand All @@ -435,16 +439,21 @@ class AsyncWebServer {
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);
// Filter returns true of request should be processed.
// In case of false is returned, filter must set own handler
AsyncWebServer& setFilter(ArRequestFilterFunction fn);

AsyncCallbackWebHandler& on(const String &uri, ArRequestHandlerFunction onRequest);
AsyncCallbackWebHandler& on(const String &uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest);
AsyncCallbackWebHandler& on(const String &uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload);
AsyncCallbackWebHandler& on(const String &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 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 onDisconnect (ASDisconnectHandler fn); // handle disconnect globally

void reset(); //remove all writers and handlers, with onNotFound/onFileUpload/onRequestBody

Expand Down
50 changes: 26 additions & 24 deletions src/SPIFFSEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "edit.htm.gz.h"
#endif

#ifdef ESP32
#ifdef ESP32
#define fullName(x) name(x)
#endif

Expand All @@ -33,13 +33,13 @@ static bool matchWild(const char *pattern, const char *testee) {
nxPat=pattern++; nxTst=testee;
continue;
}
if (nxPat){
if (nxPat){
pattern = nxPat+1; testee=++nxTst;
continue;
}
return false;
}
while (*pattern=='*'){pattern++;}
while (*pattern=='*'){pattern++;}
return (*pattern == 0);
}

Expand Down Expand Up @@ -200,7 +200,7 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){
#endif
String fname = entry.fullName();
if (fname.charAt(0) != '/') fname = "/" + fname;

if (isExcluded(_fs, fname.c_str())) {
#ifdef ESP32
entry = dir.openNextFile();
Expand Down Expand Up @@ -236,14 +236,16 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){
if (request->header(F("If-Modified-Since")).equals(buildTime)) {
request->send(304);
} else {
#ifdef EDFS
AsyncWebServerResponse *response = request->beginResponse(_fs, F("/edit_gz"), F("text/html"), false);
#ifdef EDFS
AsyncWebServerResponse *response = request->beginResponse(_fs, F("/edit.htm.gz"), F("text/html"), false);
#else
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), edit_htm_gz, edit_htm_gz_len);
#endif
response->addHeader(F("Content-Encoding"), F("gzip"));
response->addHeader(F("Last-Modified"), buildTime);
request->send(response);
if (response) {
response->addHeader(F("Content-Encoding"), F("gzip"));
response->addHeader(F("Last-Modified"), buildTime);
request->send(response);
}
}
}
} else if(request->method() == HTTP_DELETE){
Expand All @@ -252,45 +254,45 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){
#ifdef ESP32
_fs.rmdir(request->getParam(F("path"), true)->value()); // try rmdir for littlefs
#endif
}
}

request->send(200, "", String(F("DELETE: "))+request->getParam(F("path"), true)->value());
} else
request->send(404);
} else if(request->method() == HTTP_POST){
if(request->hasParam(F("data"), true, true) && _fs.exists(request->getParam(F("data"), true, true)->value()))
request->send(200, "", String(F("UPLOADED: "))+request->getParam(F("data"), true, true)->value());

else if(request->hasParam(F("rawname"), true) && request->hasParam(F("raw0"), true)){
String rawnam = request->getParam(F("rawname"), true)->value();

if (_fs.exists(rawnam)) _fs.remove(rawnam); // delete it to allow a mode

int k = 0;
uint16_t i = 0;
fs::File f = _fs.open(rawnam, "a");

while (request->hasParam(String(F("raw")) + String(k), true)) { //raw0 .. raw1
if(f){
i += f.print(request->getParam(String(F("raw")) + String(k), true)->value());
i += f.print(request->getParam(String(F("raw")) + String(k), true)->value());
}
k++;
}
f.close();
request->send(200, "", String(F("IPADWRITE: ")) + rawnam + ":" + String(i));

} else {
request->send(500);
}
}

} else if(request->method() == HTTP_PUT){
if(request->hasParam(F("path"), true)){
String filename = request->getParam(F("path"), true)->value();
if(_fs.exists(filename)){
request->send(200);
} else {
} else {
/*******************************************************/
#ifdef ESP32
#ifdef ESP32
if (strchr(filename.c_str(), '/')) {
// For file creation, silently make subdirs as needed. If any fail,
// it will be caught by the real file open later on
Expand All @@ -306,9 +308,9 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){
}
}
free(pathStr);
}
#endif
/*******************************************************/
}
#endif
/*******************************************************/
fs::File f = _fs.open(filename, "w");
if(f){
f.write((uint8_t)0x00);
Expand Down
6 changes: 3 additions & 3 deletions src/WebAuthentication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or mo
memset(_buf, 0x00, 16);
#ifdef ESP32
mbedtls_md5_init(&_ctx);
mbedtls_md5_starts(&_ctx);
mbedtls_md5_update(&_ctx, data, len);
mbedtls_md5_finish(&_ctx, _buf);
mbedtls_md5_starts_ret(&_ctx);
mbedtls_md5_update_ret(&_ctx, data, len);
mbedtls_md5_finish_ret(&_ctx, _buf);
#else
MD5Init(&_ctx);
MD5Update(&_ctx, data, len);
Expand Down
Loading