@@ -70,12 +70,12 @@ AsyncStaticWebHandler& AsyncStaticWebHandler::setIsDir(bool isDir) {
7070}
7171
7272AsyncStaticWebHandler& AsyncStaticWebHandler::setDefaultFile (const char * filename) {
73- _default_file = String ( filename) ;
73+ _default_file = filename;
7474 return *this ;
7575}
7676
7777AsyncStaticWebHandler& AsyncStaticWebHandler::setCacheControl (const char * cache_control) {
78- _cache_control = String ( cache_control) ;
78+ _cache_control = cache_control;
7979 return *this ;
8080}
8181
@@ -85,16 +85,20 @@ AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(const char* last_m
8585}
8686
8787AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified (struct tm * last_modified) {
88- auto formatP = PSTR (" %a, %d %b %Y %H:%M:%S %Z" );
88+ char result[30 ];
89+ #ifdef ESP8266
90+ auto formatP = PSTR (" %a, %d %b %Y %H:%M:%S GMT" );
8991 char format[strlen_P (formatP) + 1 ];
9092 strcpy_P (format, formatP);
93+ #else
94+ static constexpr const char * format = " %a, %d %b %Y %H:%M:%S GMT" ;
95+ #endif
9196
92- char result[30 ];
9397 strftime (result, sizeof (result), format, last_modified);
94- return setLastModified ((const char *)result);
98+ _last_modified = result;
99+ return *this ;
95100}
96101
97- #ifdef ESP8266
98102AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified (time_t last_modified) {
99103 return setLastModified ((struct tm *)gmtime (&last_modified));
100104}
@@ -105,7 +109,7 @@ AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified() {
105109 return *this ;
106110 return setLastModified (last_modified);
107111}
108- # endif
112+
109113bool AsyncStaticWebHandler::canHandle (AsyncWebServerRequest* request) const {
110114 return request->isHTTP () && request->method () == HTTP_GET && request->url ().startsWith (_uri) && _getFile (request);
111115}
@@ -194,50 +198,59 @@ uint8_t AsyncStaticWebHandler::_countBits(const uint8_t value) const {
194198
195199void AsyncStaticWebHandler::handleRequest (AsyncWebServerRequest* request) {
196200 // Get the filename from request->_tempObject and free it
197- String filename = String ((char *)request->_tempObject );
201+ String filename ((char *)request->_tempObject );
198202 free (request->_tempObject );
199203 request->_tempObject = NULL ;
200204
201- if (request->_tempFile == true ) {
205+ if (request->_tempFile != true ){
206+ request->send (404 );
207+ return ;
208+ }
209+
202210 time_t lw = request->_tempFile .getLastWrite (); // get last file mod time (if supported by FS)
203211 // set etag to lastmod timestamp if available, otherwise to size
204212 String etag;
205213 if (lw) {
206- setLastModified (gmtime (&lw) );
214+ setLastModified (lw );
207215#if defined(TARGET_RP2040)
208216 // time_t == long long int
209- const size_t len = 1 + 8 * sizeof (time_t );
217+ constexpr size_t len = 1 + 8 * sizeof (time_t );
210218 char buf[len];
211- char * ret = lltoa (lw, buf, len, 10 );
219+ char * ret = lltoa (lw ^ request-> _tempFile . size () , buf, len, 10 );
212220 etag = ret ? String (ret) : String (request->_tempFile .size ());
213221#else
214- etag = String (lw);
222+ etag = lw ^ request-> _tempFile . size (); // etag combines file size and lastmod timestamp
215223#endif
216224 } else {
217- etag = String ( request->_tempFile .size () );
225+ etag = request->_tempFile .size ();
218226 }
219- if (_last_modified.length () && _last_modified == request->header (T_IMS)) {
220- request->_tempFile .close ();
221- request->send (304 ); // Not modified
222- } else if (_cache_control.length () && request->hasHeader (T_INM) && request->header (T_INM).equals (etag)) {
227+
228+ bool not_modified = false ;
229+
230+ // if-none-match has precedence over if-modified-since
231+ if (request->hasHeader (T_INM))
232+ not_modified = request->header (T_INM).equals (etag);
233+ else if (_last_modified.length ())
234+ not_modified = request->header (T_IMS).equals (_last_modified);
235+
236+ AsyncWebServerResponse* response;
237+
238+ if (not_modified){
223239 request->_tempFile .close ();
224- AsyncWebServerResponse* response = new AsyncBasicResponse (304 ); // Not modified
225- response->addHeader (T_Cache_Control, _cache_control.c_str ());
226- response->addHeader (T_ETag, etag.c_str ());
227- request->send (response);
240+ response = new AsyncBasicResponse (304 ); // Not modified
228241 } else {
229- AsyncWebServerResponse* response = new AsyncFileResponse (request->_tempFile , filename, String (), false , _callback);
230- if (_last_modified.length ())
231- response->addHeader (T_Last_Modified, _last_modified.c_str ());
232- if (_cache_control.length ()) {
233- response->addHeader (T_Cache_Control, _cache_control.c_str ());
234- response->addHeader (T_ETag, etag.c_str ());
235- }
236- request->send (response);
242+ response = new AsyncFileResponse (request->_tempFile , filename, emptyString, false , _callback);
237243 }
238- } else {
239- request->send (404 );
240- }
244+
245+ response->addHeader (T_ETag, etag.c_str ());
246+
247+ if (_last_modified.length ())
248+ response->addHeader (T_Last_Modified, _last_modified.c_str ());
249+ if (_cache_control.length ())
250+ response->addHeader (T_Cache_Control, _cache_control.c_str ());
251+
252+ request->send (response);
253+
241254}
242255
243256AsyncStaticWebHandler& AsyncStaticWebHandler::setTemplateProcessor (AwsTemplateProcessor newCallback) {
0 commit comments