diff --git a/code/espurna/static/index.all.html.ipp b/code/espurna/static/index.all.html.ipp index 47c1b6d4..4119c4d1 100644 --- a/code/espurna/static/index.all.html.ipp +++ b/code/espurna/static/index.all.html.ipp @@ -1,7 +1,8 @@ #pragma once #include #include -alignas(4) static constexpr char webui_content_encoding[] = "br"; +alignas(4) static constexpr char webui_last_modified[] PROGMEM = "Tue, 01 Apr 2025 00:16:24 GMT"; +alignas(4) static constexpr char webui_content_encoding[] PROGMEM = "br"; alignas(4) static constexpr uint8_t webui_data[] PROGMEM = { 0x5b,0x68,0xeb,0x52,0xc2,0x76,0x35,0xe6,0x76,0xb0,0xf1,0xc4,0x55,0x17,0x26,0xdb,0x86,0xbd,0xde,0xac, 0x02,0x4c,0xd4,0xdd,0x4f,0xb8,0xc0,0x3c,0x0b,0x3b,0xf4,0x66,0x15,0x9a,0x82,0x6e,0x1f,0xe7,0x01,0x55, diff --git a/code/espurna/static/index.curtain.html.ipp b/code/espurna/static/index.curtain.html.ipp index 26c7ffb8..dbff7909 100644 --- a/code/espurna/static/index.curtain.html.ipp +++ b/code/espurna/static/index.curtain.html.ipp @@ -1,7 +1,8 @@ #pragma once #include #include -alignas(4) static constexpr char webui_content_encoding[] = "br"; +alignas(4) static constexpr char webui_last_modified[] PROGMEM = "Tue, 01 Apr 2025 00:16:24 GMT"; +alignas(4) static constexpr char webui_content_encoding[] PROGMEM = "br"; alignas(4) static constexpr uint8_t webui_data[] PROGMEM = { 0x5b,0xea,0xe4,0x31,0xe1,0x8e,0x77,0x3b,0x48,0x08,0xa8,0x7a,0xa0,0x40,0xb9,0x7d,0x84,0xdb,0x01,0x8a, 0x48,0x74,0x37,0xa2,0x84,0x1d,0x7b,0x14,0xd0,0x1d,0x1a,0x0a,0x89,0x7c,0x1c,0x50,0x3d,0x27,0xd0,0x21, diff --git a/code/espurna/static/index.garland.html.ipp b/code/espurna/static/index.garland.html.ipp index d72fb30c..4b1e8589 100644 --- a/code/espurna/static/index.garland.html.ipp +++ b/code/espurna/static/index.garland.html.ipp @@ -1,7 +1,8 @@ #pragma once #include #include -alignas(4) static constexpr char webui_content_encoding[] = "br"; +alignas(4) static constexpr char webui_last_modified[] PROGMEM = "Tue, 01 Apr 2025 00:16:24 GMT"; +alignas(4) static constexpr char webui_content_encoding[] PROGMEM = "br"; alignas(4) static constexpr uint8_t webui_data[] PROGMEM = { 0x5b,0xb6,0xdb,0x31,0x3b,0xd0,0xc2,0xc6,0x41,0x06,0x60,0x6b,0x30,0xe1,0x8e,0xc2,0xc6,0x01,0x6b,0xf0, 0x98,0xd7,0xac,0x84,0x1d,0xfb,0x00,0x9c,0x07,0x07,0xe9,0x1d,0x6f,0x32,0x40,0xf5,0x9e,0x9c,0x8a,0x0c, diff --git a/code/espurna/static/index.light.html.ipp b/code/espurna/static/index.light.html.ipp index fef898e3..17729577 100644 --- a/code/espurna/static/index.light.html.ipp +++ b/code/espurna/static/index.light.html.ipp @@ -1,7 +1,8 @@ #pragma once #include #include -alignas(4) static constexpr char webui_content_encoding[] = "br"; +alignas(4) static constexpr char webui_last_modified[] PROGMEM = "Tue, 01 Apr 2025 00:16:24 GMT"; +alignas(4) static constexpr char webui_content_encoding[] PROGMEM = "br"; alignas(4) static constexpr uint8_t webui_data[] PROGMEM = { 0x5b,0x13,0x6a,0x52,0xc3,0x8e,0xbd,0x28,0x6e,0x07,0x8f,0x6c,0xa7,0xde,0xc1,0x82,0xe9,0x36,0x1f,0xe4, 0x76,0x10,0x35,0xe6,0xcf,0x79,0xa5,0x86,0xdd,0xc4,0x06,0xce,0xc3,0x81,0xf0,0xee,0x2d,0x2d,0xa0,0xaa, diff --git a/code/espurna/static/index.lightfox.html.ipp b/code/espurna/static/index.lightfox.html.ipp index 282ee58c..e31dbbba 100644 --- a/code/espurna/static/index.lightfox.html.ipp +++ b/code/espurna/static/index.lightfox.html.ipp @@ -1,7 +1,8 @@ #pragma once #include #include -alignas(4) static constexpr char webui_content_encoding[] = "br"; +alignas(4) static constexpr char webui_last_modified[] PROGMEM = "Tue, 01 Apr 2025 00:16:24 GMT"; +alignas(4) static constexpr char webui_content_encoding[] PROGMEM = "br"; alignas(4) static constexpr uint8_t webui_data[] PROGMEM = { 0x5b,0xd7,0xda,0x51,0xb0,0x6d,0xd2,0xbb,0x1d,0x24,0x02,0xa9,0x7f,0x60,0x76,0xa0,0xf5,0x38,0x00,0x3c, 0xde,0xea,0xc0,0xe0,0x66,0x28,0xb8,0x1d,0xd8,0xb1,0xf3,0x2a,0xe5,0x02,0xaa,0x9e,0x8b,0x1b,0x63,0x40, diff --git a/code/espurna/static/index.rfbridge.html.ipp b/code/espurna/static/index.rfbridge.html.ipp index 3b3c88e6..b57697ea 100644 --- a/code/espurna/static/index.rfbridge.html.ipp +++ b/code/espurna/static/index.rfbridge.html.ipp @@ -1,7 +1,8 @@ #pragma once #include #include -alignas(4) static constexpr char webui_content_encoding[] = "br"; +alignas(4) static constexpr char webui_last_modified[] PROGMEM = "Tue, 01 Apr 2025 00:16:24 GMT"; +alignas(4) static constexpr char webui_content_encoding[] PROGMEM = "br"; alignas(4) static constexpr uint8_t webui_data[] PROGMEM = { 0x5b,0x72,0xe6,0x31,0xe1,0x0e,0xc3,0xc6,0xc1,0xc6,0xc0,0xd6,0x42,0xd1,0x81,0x18,0x74,0x07,0xd8,0x42, 0x91,0xa7,0x40,0x94,0xb0,0x5d,0x0d,0xbb,0x1d,0xf4,0x9e,0x6d,0x5d,0x08,0xa0,0x7a,0x2f,0x4e,0xe4,0x2a, diff --git a/code/espurna/static/index.rfm69.html.ipp b/code/espurna/static/index.rfm69.html.ipp index 50e9fd39..9ff0664a 100644 --- a/code/espurna/static/index.rfm69.html.ipp +++ b/code/espurna/static/index.rfm69.html.ipp @@ -1,7 +1,8 @@ #pragma once #include #include -alignas(4) static constexpr char webui_content_encoding[] = "br"; +alignas(4) static constexpr char webui_last_modified[] PROGMEM = "Tue, 01 Apr 2025 00:16:24 GMT"; +alignas(4) static constexpr char webui_content_encoding[] PROGMEM = "br"; alignas(4) static constexpr uint8_t webui_data[] PROGMEM = { 0x5b,0x37,0xe7,0x31,0xe1,0x0e,0xc3,0xc6,0xc1,0xc6,0xc0,0xd6,0xc2,0xc8,0x40,0xa0,0x3b,0xc0,0xa9,0xa2, 0x3e,0xd5,0xef,0x00,0xde,0x74,0x4b,0xca,0xed,0xa0,0xf8,0xfc,0xf8,0x46,0x00,0xd5,0x7b,0x71,0x43,0x86, diff --git a/code/espurna/static/index.sensor.html.ipp b/code/espurna/static/index.sensor.html.ipp index 8f2bcd44..58d5ff13 100644 --- a/code/espurna/static/index.sensor.html.ipp +++ b/code/espurna/static/index.sensor.html.ipp @@ -1,7 +1,8 @@ #pragma once #include #include -alignas(4) static constexpr char webui_content_encoding[] = "br"; +alignas(4) static constexpr char webui_last_modified[] PROGMEM = "Tue, 01 Apr 2025 00:16:24 GMT"; +alignas(4) static constexpr char webui_content_encoding[] PROGMEM = "br"; alignas(4) static constexpr uint8_t webui_data[] PROGMEM = { 0x5b,0x11,0x0b,0x52,0xc0,0x8d,0xe1,0x1a,0x36,0x0e,0x36,0x30,0xd6,0x16,0x2a,0x64,0xe7,0x6b,0x00,0xe5, 0x0d,0x3f,0xbb,0x1f,0x69,0x15,0xeb,0x92,0x07,0x64,0x73,0x5c,0x5b,0x91,0xde,0xac,0x48,0x23,0x0d,0xbf, diff --git a/code/espurna/static/index.small.html.ipp b/code/espurna/static/index.small.html.ipp index 791e59f3..386d259c 100644 --- a/code/espurna/static/index.small.html.ipp +++ b/code/espurna/static/index.small.html.ipp @@ -1,7 +1,8 @@ #pragma once #include #include -alignas(4) static constexpr char webui_content_encoding[] = "br"; +alignas(4) static constexpr char webui_last_modified[] PROGMEM = "Tue, 01 Apr 2025 00:16:24 GMT"; +alignas(4) static constexpr char webui_content_encoding[] PROGMEM = "br"; alignas(4) static constexpr uint8_t webui_data[] PROGMEM = { 0x5b,0x0b,0xd6,0x31,0xe1,0x0e,0xc3,0xc6,0xc1,0xc6,0xc0,0xd6,0x42,0xd1,0x81,0x18,0x74,0x87,0xba,0x46, 0x84,0xae,0x12,0x07,0xc6,0xb6,0x0c,0x9a,0x41,0x77,0x24,0x9c,0xb8,0xab,0x85,0x61,0x40,0xf5,0x5e,0xdc, diff --git a/code/espurna/static/index.thermostat.html.ipp b/code/espurna/static/index.thermostat.html.ipp index f7172513..12bf57ea 100644 --- a/code/espurna/static/index.thermostat.html.ipp +++ b/code/espurna/static/index.thermostat.html.ipp @@ -1,7 +1,8 @@ #pragma once #include #include -alignas(4) static constexpr char webui_content_encoding[] = "br"; +alignas(4) static constexpr char webui_last_modified[] PROGMEM = "Tue, 01 Apr 2025 00:16:24 GMT"; +alignas(4) static constexpr char webui_content_encoding[] PROGMEM = "br"; alignas(4) static constexpr uint8_t webui_data[] PROGMEM = { 0x5b,0x5a,0xe7,0x51,0xc0,0x8d,0xe1,0xda,0xed,0x20,0x01,0xa8,0xea,0x81,0xd9,0x88,0xd8,0xed,0xa0,0x1c, 0x7e,0xfb,0x85,0x94,0x19,0x70,0xb0,0x71,0x06,0x0c,0xd0,0xf7,0xc4,0x80,0xaa,0xf7,0xe2,0x86,0x0c,0xc1, diff --git a/code/espurna/web.cpp b/code/espurna/web.cpp index 52ef0f70..81b723b5 100644 --- a/code/espurna/web.cpp +++ b/code/espurna/web.cpp @@ -209,7 +209,6 @@ size_t RequestPrint::write(const uint8_t* data, size_t size) { namespace { -PROGMEM_STRING(LastModified, __DATE__ " " __TIME__ " GMT"); static constexpr size_t WebConfigBufferMax { 4096 }; // server instance can't (yet) be static, port is the ctor argument :/ @@ -471,7 +470,7 @@ void _onHome(AsyncWebServerRequest *request) { if (request->hasHeader(FPSTR(IfModifiedSince))) { const auto value = request->header(FPSTR(IfModifiedSince)); - if (strncmp_P(value.c_str(), LastModified, value.length()) == 0) { + if (strncmp_P(value.c_str(), webui_last_modified, value.length()) == 0) { request->send(304); return; } @@ -496,11 +495,14 @@ void _onHome(AsyncWebServerRequest *request) { auto* response = request->beginResponse_P(200, F("text/html"), webui_data, std::size(webui_data)); #endif - if (__builtin_strlen(webui_content_encoding) != 0) { - response->addHeader(F("Content-Encoding"), webui_content_encoding); + constexpr auto content_encoding = espurna::StringView(webui_content_encoding); + if (content_encoding.length()) { + response->addHeader(F("Content-Encoding"), content_encoding.toString()); } - response->addHeader(F("Last-Modified"), FPSTR(LastModified)); + constexpr auto last_modified = espurna::StringView(webui_last_modified); + response->addHeader(F("Last-Modified"), last_modified.toString()); + response->addHeader(F("X-XSS-Protection"), F("1; mode=block")); response->addHeader(F("X-Content-Type-Options"), F("nosniff")); response->addHeader(F("X-Frame-Options"), F("deny")); diff --git a/code/gulpfile.mjs b/code/gulpfile.mjs index 40af49ea..69c1ef02 100644 --- a/code/gulpfile.mjs +++ b/code/gulpfile.mjs @@ -332,6 +332,14 @@ function formatBufferLines(buffer, every = 20) { return lines.join(',\n'); } +/** + * @param {File} file + * @returns {string} + */ +function formatLastModified(file) { + return (file?.stat?.mtime ?? (new Date())).toUTCString() +} + /** * generates c++-friendly output from the stream contents * @param {BuildOptions} options @@ -351,7 +359,8 @@ function toOutput(options) { '#pragma once', '#include ', '#include ', - `alignas(4) static constexpr char webui_content_encoding[] = "${options.compress || ''}";`, + `alignas(4) static constexpr char webui_last_modified[] PROGMEM = "${formatLastModified(source)}";`, + `alignas(4) static constexpr char webui_content_encoding[] PROGMEM = "${options.compress || ''}";`, 'alignas(4) static constexpr uint8_t webui_data[] PROGMEM = {', formatBufferLines(source.contents), '};\n' @@ -384,15 +393,19 @@ function toOutput(options) { * @returns {Transform} */ function adjustFileStat() { + const now = new Date(); + return new Transform({ objectMode: true, transform(source, _, callback) { - if (source.stat) { - const now = new Date(); - source.stat.atime = now; - source.stat.mtime = now; - source.stat.ctime = now; + if (!source.stat) { + source.stat = {}; } + + source.stat.atime = now; + source.stat.mtime = now; + source.stat.ctime = now; + callback(null, source); }}); }