From 2d7fdbb68affcce91fe34817fd86be7697ede461 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Thu, 27 Oct 2022 14:08:32 +0300 Subject: [PATCH 1/8] expose WebSocket makeBuffer() method to be piblically available --- src/AsyncWebSocket.cpp | 94 +++++++++++------------------------------- src/AsyncWebSocket.h | 78 +++++++++++++++++++++++++++-------- 2 files changed, 84 insertions(+), 88 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 12be5f83e..bb165144e 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -181,7 +181,7 @@ class AsyncWebSocketControl { */ -AsyncWebSocketMessage::AsyncWebSocketMessage(std::shared_ptr> buffer, uint8_t opcode, bool mask) : +AsyncWebSocketMessage::AsyncWebSocketMessage(AsyncWebSocketMessageBuffer buffer, uint8_t opcode, bool mask) : _WSbuffer{buffer}, _opcode(opcode & 0x07), _mask{mask}, @@ -643,39 +643,12 @@ size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) } #endif -namespace { -std::shared_ptr> makeBuffer(const uint8_t *message, size_t len) +AsyncWebSocketMessageBuffer AsyncWebSocketClient::makeBuffer(const uint8_t *message, size_t len) { auto buffer = std::make_shared>(len); std::memcpy(buffer->data(), message, len); return buffer; } -} - -void AsyncWebSocketClient::text(std::shared_ptr> buffer) -{ - _queueMessage(buffer); -} - -void AsyncWebSocketClient::text(const uint8_t *message, size_t len) -{ - text(makeBuffer(message, len)); -} - -void AsyncWebSocketClient::text(const char *message, size_t len) -{ - text((const uint8_t *)message, len); -} - -void AsyncWebSocketClient::text(const char *message) -{ - text(message, strlen(message)); -} - -void AsyncWebSocketClient::text(const String &message) -{ - text(message.c_str(), message.length()); -} void AsyncWebSocketClient::text(const __FlashStringHelper *data) { @@ -698,31 +671,6 @@ void AsyncWebSocketClient::text(const __FlashStringHelper *data) } } -void AsyncWebSocketClient::binary(std::shared_ptr> buffer) -{ - _queueMessage(buffer, WS_BINARY); -} - -void AsyncWebSocketClient::binary(const uint8_t *message, size_t len) -{ - binary(makeBuffer(message, len)); -} - -void AsyncWebSocketClient::binary(const char *message, size_t len) -{ - binary((const uint8_t *)message, len); -} - -void AsyncWebSocketClient::binary(const char *message) -{ - binary(message, strlen(message)); -} - -void AsyncWebSocketClient::binary(const String &message) -{ - binary(message.c_str(), message.length()); -} - void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len) { PGM_P p = reinterpret_cast(data); @@ -737,7 +685,7 @@ void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len) IPAddress AsyncWebSocketClient::remoteIP() const { if (!_client) - return IPAddress(0U); + return IPAddress((uint32_t)0); return _client->remoteIP(); } @@ -850,23 +798,15 @@ void AsyncWebSocket::pingAll(const uint8_t *data, size_t len) c.ping(data, len); } +void AsyncWebSocket::text(uint32_t id, AsyncWebSocketMessageBuffer message){ + if (AsyncWebSocketClient * c = client(id)) + c->message(message); +}; void AsyncWebSocket::text(uint32_t id, const uint8_t *message, size_t len) { if (AsyncWebSocketClient * c = client(id)) c->text(makeBuffer(message, len)); } -void AsyncWebSocket::text(uint32_t id, const char *message, size_t len) -{ - text(id, (const uint8_t *)message, len); -} -void AsyncWebSocket::text(uint32_t id, const char * message) -{ - text(id, message, strlen(message)); -} -void AsyncWebSocket::text(uint32_t id, const String &message) -{ - text(id, message.c_str(), message.length()); -} void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *data) { PGM_P p = reinterpret_cast(data); @@ -889,7 +829,7 @@ void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *data) } } -void AsyncWebSocket::textAll(std::shared_ptr> buffer) +void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer buffer) { for (auto &c : _clients) if (c.status() == WS_CONNECTED) @@ -932,6 +872,10 @@ void AsyncWebSocket::textAll(const __FlashStringHelper *data) } } +void AsyncWebSocket::binary(uint32_t id, AsyncWebSocketMessageBuffer message){ + if (AsyncWebSocketClient * c = client(id)) + c->binary(message); +}; void AsyncWebSocket::binary(uint32_t id, const uint8_t *message, size_t len) { if (AsyncWebSocketClient *c = client(id)) @@ -961,7 +905,7 @@ void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *data, size_t } } -void AsyncWebSocket::binaryAll(std::shared_ptr> buffer) +void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer buffer) { for (auto &c : _clients) if (c.status() == WS_CONNECTED) @@ -1022,7 +966,7 @@ size_t AsyncWebSocket::printfAll(const char *format, ...) va_end(arg); delete[] temp; - std::shared_ptr> buffer = std::make_shared>(len); + AsyncWebSocketMessageBuffer buffer = std::make_shared>(len); va_start(arg, format); vsnprintf( (char *)buffer->data(), len + 1, format, arg); @@ -1058,7 +1002,7 @@ size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) va_end(arg); delete[] temp; - std::shared_ptr> buffer = std::make_shared>(len + 1); + AsyncWebSocketMessageBuffer buffer = std::make_shared>(len + 1); va_start(arg, formatP); vsnprintf_P((char *)buffer->data(), len + 1, formatP, arg); @@ -1141,6 +1085,13 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request) request->send(response); } +AsyncWebSocketMessageBuffer AsyncWebSocket::makeBuffer(const uint8_t *message, size_t len) +{ + auto buffer = std::make_shared>(len); + std::memcpy(buffer->data(), message, len); + return buffer; +} + /* * Response to Web Socket request - sends the authorization and detaches the TCP Client from the web server * Authentication code from https://github.com/Links2004/arduinoWebSockets/blob/master/src/WebSockets.cpp#L480 @@ -1208,3 +1159,4 @@ size_t AsyncWebSocketResponse::_ack(AsyncWebServerRequest *request, size_t len, return 0; } + diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 9a0a3b45b..199c2c843 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -50,6 +50,8 @@ #define DEFAULT_MAX_WS_CLIENTS 4 #endif +using AsyncWebSocketMessageBuffer = std::shared_ptr>; + class AsyncWebSocket; class AsyncWebSocketResponse; class AsyncWebSocketClient; @@ -84,6 +86,7 @@ typedef enum { WS_CONTINUATION, WS_TEXT, WS_BINARY, WS_DISCONNECT = 0x08, WS_PIN typedef enum { WS_MSG_SENDING, WS_MSG_SENT, WS_MSG_ERROR } AwsMessageStatus; typedef enum { WS_EVT_CONNECT, WS_EVT_DISCONNECT, WS_EVT_PONG, WS_EVT_ERROR, WS_EVT_DATA } AwsEventType; + class AsyncWebSocketMessage { private: @@ -161,7 +164,26 @@ class AsyncWebSocketClient { } //data packets - void message(std::shared_ptr> buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); } + /** + * @brief allocate memory buffer owned by shared-pointer and copy provided data + * used to keep the data untill websocket send is complete for single/multiple clients + * + * @param message + * @param len + * @return AsyncWebSocketMessageBuffer + */ + AsyncWebSocketMessageBuffer makeBuffer(const uint8_t *message, size_t len); + + /** + * @brief allocate empty memory buffer owned by shared-pointer + * used to keep the data untill websocket send is complete for single/multiple clients + * + * @param len + * @return AsyncWebSocketMessageBuffer + */ + inline AsyncWebSocketMessageBuffer makeBuffer(size_t len){ return std::make_shared>(len); }; + + void message(AsyncWebSocketMessageBuffer buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); } bool queueIsFull() const; size_t queueLen() const; @@ -170,18 +192,18 @@ class AsyncWebSocketClient { size_t printf_P(PGM_P formatP, ...) __attribute__ ((format (printf, 2, 3))); #endif - void text(std::shared_ptr> buffer); - void text(const uint8_t *message, size_t len); - void text(const char *message, size_t len); - void text(const char *message); - void text(const String &message); + inline void text(AsyncWebSocketMessageBuffer buffer){ _queueMessage(buffer); }; + inline void text(const uint8_t *message, size_t len){ text(makeBuffer(message, len)); }; + inline void text(const char *message, size_t len){ text((const uint8_t *)message, len); }; + inline void text(const char *message){ text(message, strlen(message)); }; + inline void text(const String &message){ text(message.c_str(), message.length()); }; void text(const __FlashStringHelper *message); - void binary(std::shared_ptr> buffer); - void binary(const uint8_t *message, size_t len); - void binary(const char * message, size_t len); - void binary(const char * message); - void binary(const String &message); + inline void binary(AsyncWebSocketMessageBuffer buffer){ _queueMessage(buffer, WS_BINARY); }; + inline void binary(const uint8_t *message, size_t len){ binary(makeBuffer(message, len)); }; + inline void binary(const char * message, size_t len){ binary((const uint8_t *)message, len); }; + inline void binary(const char * message){ binary(message, strlen(message)); }; + inline void binary(const String &message){ binary(message.c_str(), message.length()); }; void binary(const __FlashStringHelper *message, size_t len); bool canSend() const; @@ -205,7 +227,7 @@ class AsyncWebSocket: public AsyncWebHandler { std::list _clients; uint32_t _cNextId; AwsEventHandler _eventHandler; - AwsHandshakeHandler _handshakeHandler; + AwsHandshakeHandler _handshakeHandler; bool _enabled; AsyncWebLock _lock; @@ -229,26 +251,48 @@ class AsyncWebSocket: public AsyncWebHandler { void ping(uint32_t id, const uint8_t *data=NULL, size_t len=0); void pingAll(const uint8_t *data=NULL, size_t len=0); // done + //data packets + /** + * @brief allocate memory buffer owned by shared-pointer and copy provided data + * used to keep the data untill websocket send is complete for single/multiple clients + * + * @param message + * @param len + * @return AsyncWebSocketMessageBuffer + */ + AsyncWebSocketMessageBuffer makeBuffer(const uint8_t *message, size_t len); + + /** + * @brief allocate empty memory buffer owned by shared-pointer + * used to keep the data untill websocket send is complete for single/multiple clients + * + * @param len + * @return AsyncWebSocketMessageBuffer + */ + inline AsyncWebSocketMessageBuffer makeBuffer(size_t len){ return std::make_shared>(len); }; + + void text(uint32_t id, AsyncWebSocketMessageBuffer message); void text(uint32_t id, const uint8_t * message, size_t len); - void text(uint32_t id, const char *message, size_t len); - void text(uint32_t id, const char *message); - void text(uint32_t id, const String &message); + inline void text(uint32_t id, const char *message, size_t len){ text(id, (const uint8_t *)message, len); }; + inline void text(uint32_t id, const char *message){ text(id, message, strlen(message)); }; + inline void text(uint32_t id, const String &message){ text(id, message.c_str(), message.length()); }; void text(uint32_t id, const __FlashStringHelper *message); - void textAll(std::shared_ptr> buffer); + void textAll(AsyncWebSocketMessageBuffer buffer); void textAll(const uint8_t *message, size_t len); void textAll(const char * message, size_t len); void textAll(const char * message); void textAll(const String &message); void textAll(const __FlashStringHelper *message); // need to convert + void binary(uint32_t id, AsyncWebSocketMessageBuffer message); void binary(uint32_t id, const uint8_t *message, size_t len); void binary(uint32_t id, const char *message, size_t len); void binary(uint32_t id, const char *message); void binary(uint32_t id, const String &message); void binary(uint32_t id, const __FlashStringHelper *message, size_t len); - void binaryAll(std::shared_ptr> buffer); + void binaryAll(AsyncWebSocketMessageBuffer buffer); void binaryAll(const uint8_t *message, size_t len); void binaryAll(const char *message, size_t len); void binaryAll(const char *message); From 68b21d258f68b1507681c8fde7f3b1ef917e7a78 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Tue, 31 Jan 2023 15:18:44 +0900 Subject: [PATCH 2/8] set real "Last-Modified" header based on file's LastWrite time Get file's LastWrite timestamp for file handlers (if supported by FS driver) and construct proper "Last-Modified" header. Works fine for LittleFS. If not supported by FS than fallback to previous implementation with manual value for "Last-Modified". Signed-off-by: Emil Muratov --- README.md | 7 +++++-- src/WebHandlers.cpp | 18 ++++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d6dd3206a..21c87914e 100644 --- a/README.md +++ b/README.md @@ -823,8 +823,11 @@ handler->setCacheControl("max-age=30"); ``` ### Specifying Date-Modified header -It is possible to specify Date-Modified header to enable the server to return Not-Modified (304) response for requests -with "If-Modified-Since" header with the same value, instead of responding with the actual file content. +Sever sets "Last-Modified" header automatically if FS driver supports file modification timestamps (LittleFS does). +Server returns "Not-Modified" (304) response for requests with "If-Modified-Since" header with _the same_ value as file's mod date, instead of responding with the actual file content. It does not perform date calculations checking if File's mod date is newer or later than in "If-Modified-Since" header. + +For FS not supporting file timestamps (like deprecated SPIFFS) it is possible to specify Date-Modified header manually. + ```cpp // Update the date modified string every time files are updated server.serveStatic("/", SPIFFS, "/www/").setLastModified("Mon, 20 Jun 2016 14:00:00 GMT"); diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 1f435e68a..daa7752a4 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -187,14 +187,28 @@ uint8_t AsyncStaticWebHandler::_countBits(const uint8_t value) const void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest *request) { // Get the filename from request->_tempObject and free it - String filename = String((char*)request->_tempObject); + String filename((char*)request->_tempObject); free(request->_tempObject); request->_tempObject = NULL; if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) return request->requestAuthentication(); if (request->_tempFile == true) { - String etag = String(request->_tempFile.size()); + time_t lw = request->_tempFile.getLastWrite(); // get last file mod time (if supported by FS) + if (lw) { + _last_modified.clear(); + _last_modified.reserve(30); // need 'Fri, 27 Jan 2023 15:50:27 GMT' + char *t = ctime(&lw); // ctime 'Thu Jan 26 17:42:48 2023' + _last_modified.concat(t, 3); // day of week + _last_modified.concat((char)0x2c); // comma + _last_modified.concat(t+7, 3); // day + _last_modified.concat(t+3, 4); // month + _last_modified.concat(t+19, 5); // year + _last_modified.concat(t+10, 9); // time + _last_modified.concat(" GMT"); + _last_modified.setCharAt(29, 0); // null terminate + } + String etag(request->_tempFile.size()); if (_last_modified.length() && _last_modified == request->header("If-Modified-Since")) { request->_tempFile.close(); request->send(304); // Not modified From ebde6d718f6b675f3091807a68308edc84f20460 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Tue, 31 Jan 2023 15:18:44 +0900 Subject: [PATCH 3/8] set real "Last-Modified" header based on file's LastWrite time Get file's LastWrite timestamp for file handlers (if supported by FS driver) and construct proper "Last-Modified" header. Works fine for LittleFS. If not supported by FS than fallback to previous implementation with manual value for "Last-Modified". Signed-off-by: Emil Muratov --- README.md | 7 +++++-- src/WebHandlers.cpp | 20 +++++++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d3d3cf91b..610f88f6c 100644 --- a/README.md +++ b/README.md @@ -876,8 +876,11 @@ handler->setCacheControl("max-age=30"); ``` ### Specifying Date-Modified header -It is possible to specify Date-Modified header to enable the server to return Not-Modified (304) response for requests -with "If-Modified-Since" header with the same value, instead of responding with the actual file content. +Sever sets "Last-Modified" header automatically if FS driver supports file modification timestamps (LittleFS does). +Server returns "Not-Modified" (304) response for requests with "If-Modified-Since" header with _the same_ value as file's mod date, instead of responding with the actual file content. It does not perform date calculations checking if File's mod date is newer or later than in "If-Modified-Since" header. + +For FS not supporting file timestamps (like deprecated SPIFFS) it is possible to specify Date-Modified header manually. + ```cpp // Update the date modified string every time files are updated server.serveStatic("/", SPIFFS, "/www/").setLastModified("Mon, 20 Jun 2016 14:00:00 GMT"); diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 8e87ff1cf..816529ba8 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -199,15 +199,29 @@ uint8_t AsyncStaticWebHandler::_countBits(const uint8_t value) const void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest *request) { // Get the filename from request->_tempObject and free it - String filename = String((char*)request->_tempObject); + String filename((char*)request->_tempObject); free(request->_tempObject); request->_tempObject = NULL; if((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())) return request->requestAuthentication(); if (request->_tempFile == true) { - String etag = String(request->_tempFile.size()); - if (_last_modified.length() && _last_modified == request->header(F("If-Modified-Since"))) { + time_t lw = request->_tempFile.getLastWrite(); // get last file mod time (if supported by FS) + if (lw) { + _last_modified.clear(); + _last_modified.reserve(30); // need 'Fri, 27 Jan 2023 15:50:27 GMT' + char *t = ctime(&lw); // ctime 'Thu Jan 26 17:42:48 2023' + _last_modified.concat(t, 3); // day of week + _last_modified.concat((char)0x2c); // comma + _last_modified.concat(t+7, 3); // day + _last_modified.concat(t+3, 4); // month + _last_modified.concat(t+19, 5); // year + _last_modified.concat(t+10, 9); // time + _last_modified.concat(" GMT"); + _last_modified.setCharAt(29, 0); // null terminate + } + String etag(request->_tempFile.size()); + if (_last_modified.length() && _last_modified == request->header("If-Modified-Since")) { request->_tempFile.close(); request->send(304); // Not modified } else if (_cache_control.length() && request->hasHeader(F("If-None-Match")) && request->header(F("If-None-Match")).equals(etag)) { From 481e092eee49a1876ade0200d2e634c2f48363e0 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Tue, 23 May 2023 01:45:59 +0900 Subject: [PATCH 4/8] set etag header's value to lastmod timestamp if available, otherwise to file size --- src/WebHandlers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index daa7752a4..3cdc07a91 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -208,7 +208,7 @@ void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest *request) _last_modified.concat(" GMT"); _last_modified.setCharAt(29, 0); // null terminate } - String etag(request->_tempFile.size()); + String etag(lw ? lw : request->_tempFile.size()); // set etag to lastmod timestamp if available, otherwise to size if (_last_modified.length() && _last_modified == request->header("If-Modified-Since")) { request->_tempFile.close(); request->send(304); // Not modified From d814400b49cf1f190c14e52abf7d8d0329ba4aae Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Tue, 8 Aug 2023 18:00:49 +0900 Subject: [PATCH 5/8] rewrite IMS timestap generation to use std::strftime --- src/WebHandlers.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 3cdc07a91..625b638b0 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -20,6 +20,7 @@ */ #include "ESPAsyncWebServer.h" #include "WebHandlerImpl.h" +#include AsyncStaticWebHandler::AsyncStaticWebHandler(const char* uri, FS& fs, const char* path, const char* cache_control) : _fs(fs), _uri(uri), _path(path), _default_file("index.htm"), _cache_control(cache_control), _last_modified(""), _callback(nullptr) @@ -196,17 +197,9 @@ void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest *request) if (request->_tempFile == true) { time_t lw = request->_tempFile.getLastWrite(); // get last file mod time (if supported by FS) if (lw) { - _last_modified.clear(); - _last_modified.reserve(30); // need 'Fri, 27 Jan 2023 15:50:27 GMT' - char *t = ctime(&lw); // ctime 'Thu Jan 26 17:42:48 2023' - _last_modified.concat(t, 3); // day of week - _last_modified.concat((char)0x2c); // comma - _last_modified.concat(t+7, 3); // day - _last_modified.concat(t+3, 4); // month - _last_modified.concat(t+19, 5); // year - _last_modified.concat(t+10, 9); // time - _last_modified.concat(" GMT"); - _last_modified.setCharAt(29, 0); // null terminate + char datetime[std::size("Fri, 27 Jan 2023 15:50:27 GMT")]; + std::strftime(std::data(datetime), std::size(datetime), "%a, %d %b %Y %H:%M:%S GMT", std::gmtime(&lw)); + _last_modified = datetime; } String etag(lw ? lw : request->_tempFile.size()); // set etag to lastmod timestamp if available, otherwise to size if (_last_modified.length() && _last_modified == request->header("If-Modified-Since")) { From 5d76a357ed53fe6a8ec5d838cf85dfee199fb61b Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Fri, 19 Jan 2024 11:03:55 +0900 Subject: [PATCH 6/8] update library.json - set AsyncTCPSock as dependency --- library.json | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/library.json b/library.json index 332c1c34b..7b8a47172 100644 --- a/library.json +++ b/library.json @@ -18,16 +18,9 @@ "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" + "owner": "yubox-node-org", + "name": "AsyncTCPSock", + "version": "https://github.com/yubox-node-org/AsyncTCPSock" }, { "name": "Hash", From 26b5769d21ea3c227114f25c1bd85617b37f5c3e Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Mon, 19 Feb 2024 20:51:50 +0900 Subject: [PATCH 7/8] switch dep to AsyncTCP-esphome --- library.json | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/library.json b/library.json index 7b8a47172..9ef4d1d8b 100644 --- a/library.json +++ b/library.json @@ -18,13 +18,10 @@ "platforms": ["espressif8266", "espressif32"], "dependencies": [ { - "owner": "yubox-node-org", - "name": "AsyncTCPSock", - "version": "https://github.com/yubox-node-org/AsyncTCPSock" - }, - { - "name": "Hash", - "platforms": "espressif8266" + "owner": "esphome", + "name": "AsyncTCP-esphome", + "version": "^2.1.1", + "platforms": "espressif32" } ] } From 7ff17c000996c28e3844160139a71dd07056a4a7 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Tue, 20 Feb 2024 01:43:24 +0900 Subject: [PATCH 8/8] set Etag header value to last modified timestamp --- src/WebHandlers.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 61681b5b5..464ab984c 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -208,12 +208,8 @@ void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest *request) if (request->_tempFile == true) { time_t lw = request->_tempFile.getLastWrite(); // get last file mod time (if supported by FS) - if (lw) { - char datetime[std::size("Fri, 27 Jan 2023 15:50:27 GMT")]; - std::strftime(std::data(datetime), std::size(datetime), "%a, %d %b %Y %H:%M:%S GMT", std::gmtime(&lw)); - _last_modified = datetime; - } - String etag(request->_tempFile.size()); + if (lw) setLastModified(std::gmtime(&lw)); + String etag(lw ? lw : request->_tempFile.size()); // set etag to lastmod timestamp if available, otherwise to size if (_last_modified.length() && _last_modified == request->header("If-Modified-Since")) { request->_tempFile.close(); request->send(304); // Not modified