Skip to content

Commit a14b256

Browse files
authored
Add files via upload
1 parent 6c56bb3 commit a14b256

File tree

2 files changed

+31
-15
lines changed

2 files changed

+31
-15
lines changed

src/AsyncWebServerRequest.cpp

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
#include <ESPAsyncWebServer.h>
22

3+
/**
4+
* @brief Sends a file from the filesystem to the client, with optional gzip compression and ETag-based caching.
5+
*
6+
* This method serves files over HTTP from the provided filesystem. If a compressed version of the file
7+
* (with a `.gz` extension) exists and the `download` flag is not set, it serves the compressed file.
8+
* It also handles ETag caching using the CRC32 value from the gzip trailer, responding with `304 Not Modified`
9+
* if the client's `If-None-Match` header matches the generated ETag.
10+
*
11+
* @param fs Reference to the filesystem (SPIFFS, LittleFS, etc.).
12+
* @param path Path to the file to be served.
13+
* @param contentType Optional MIME type of the file to be sent.
14+
* If contentType is "" it will be obtained from the file extension
15+
* @param download If true, forces the file to be sent as a download (disables gzip compression).
16+
* @param callback Optional template processor for dynamic content generation.
17+
* Templates will not be processed in compressed files.
18+
*
19+
* @note If neither the file nor its compressed version exists, responds with `404 Not Found`.
20+
*/
321
void AsyncWebServerRequest::send(FS &fs, const String &path, const char *contentType, bool download, AwsTemplateProcessor callback) {
422
const String gzPath = path + asyncsrv::T__gz;
523
const bool useCompressedVersion = !download && fs.exists(gzPath);
@@ -13,7 +31,7 @@
1331

1432
uint8_t crcFromGzipTrailer[4];
1533
if (file.read(crcFromGzipTrailer, sizeof(crcFromGzipTrailer)) == sizeof(crcFromGzipTrailer)) {
16-
char serverETag[11]; // " + 8 hex chars + " + '\0'
34+
char serverETag[9];
1735
_getEtag(crcFromGzipTrailer, serverETag);
1836

1937
// Compare with client's If-None-Match header
@@ -42,24 +60,22 @@
4260
* This function converts a 4-byte array into a hexadecimal ETag string enclosed in quotes.
4361
*
4462
* @param trailer[4] Input array of 4 bytes to convert to hexadecimal
45-
* @param serverETag Output buffer that must be at least 11 bytes long to store the ETag
46-
* Must be pre-allocated with minimum 11 bytes (8 hex + 2 quotes + 1 null terminator)
63+
* @param serverETag Output buffer to store the ETag
64+
* Must be pre-allocated with minimum 9 bytes (8 hex + 1 null terminator)
4765
*/
4866
void AsyncWebServerRequest::_getEtag(uint8_t trailer[4], char* serverETag) {
4967
static constexpr char hexChars[] = "0123456789ABCDEF";
5068

5169
uint32_t data;
5270
memcpy(&data, trailer, 4);
5371

54-
serverETag[0] = '"';
55-
serverETag[1] = hexChars[(data >> 4) & 0x0F];
56-
serverETag[2] = hexChars[data & 0x0F];
57-
serverETag[3] = hexChars[(data >> 12) & 0x0F];
58-
serverETag[4] = hexChars[(data >> 8) & 0x0F];
59-
serverETag[5] = hexChars[(data >> 20) & 0x0F];
60-
serverETag[6] = hexChars[(data >> 16) & 0x0F];
61-
serverETag[7] = hexChars[(data >> 28)];
62-
serverETag[8] = hexChars[(data >> 24) & 0x0F];
63-
serverETag[9] = '"';
64-
serverETag[10] = '\0';
72+
serverETag[0] = hexChars[(data >> 4) & 0x0F];
73+
serverETag[1] = hexChars[data & 0x0F];
74+
serverETag[2] = hexChars[(data >> 12) & 0x0F];
75+
serverETag[3] = hexChars[(data >> 8) & 0x0F];
76+
serverETag[4] = hexChars[(data >> 20) & 0x0F];
77+
serverETag[5] = hexChars[(data >> 16) & 0x0F];
78+
serverETag[6] = hexChars[(data >> 28)];
79+
serverETag[7] = hexChars[(data >> 24) & 0x0F];
80+
serverETag[8] = '\0';
6581
}

src/WebResponses.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ AsyncFileResponse::AsyncFileResponse(FS &fs, const String &path, const char *con
688688
_content.seek(_contentLength - 8);
689689
uint8_t crcInTrailer[4];
690690
if (_content.read(crcInTrailer, sizeof(crcInTrailer)) == sizeof(crcInTrailer)) {
691-
char serverETag[11];
691+
char serverETag[9];
692692
AsyncWebServerRequest::_getEtag(crcInTrailer, serverETag);
693693
addHeader(T_ETag, serverETag, false);
694694
addHeader(T_Cache_Control, T_no_cache, false);

0 commit comments

Comments
 (0)