From c5dfb7b31dbac0093f13822ad698afbe99213021 Mon Sep 17 00:00:00 2001 From: drslebedev Date: Thu, 3 Sep 2026 12:43:39 +0200 Subject: [PATCH 1/2] RestClient: avoid CORS preflights for Emscripten GETs Send Content-Type only for POST requests while retaining Accept for GET and long-poll requests. This avoids unnecessary OPTIONS requests without changing response content negotiation. Signed-off-by: drslebedev --- src/client/include/RestClientEmscripten.hpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/client/include/RestClientEmscripten.hpp b/src/client/include/RestClientEmscripten.hpp index 2712c472..12040577 100644 --- a/src/client/include/RestClientEmscripten.hpp +++ b/src/client/include/RestClientEmscripten.hpp @@ -191,19 +191,22 @@ struct RestWorkerState { if (const auto entry = query.find("contentType"); entry != query.end() && entry->second) { contentType = *entry->second; } - const std::array headers{ "accept", contentType.c_str(), "content-type", contentType.c_str(), nullptr }; - - const std::string_view method = activeFetch->command.has_value() && activeFetch->command->command == mdp::Command::Set ? "POST" : "GET"; + const std::string_view method = activeFetch->command.has_value() && activeFetch->command->command == mdp::Command::Set ? "POST" : "GET"; + std::array headers{ "accept", contentType.c_str(), nullptr, nullptr, nullptr }; + if (method == "POST") { + headers[2] = "content-type"; + headers[3] = contentType.c_str(); + } - emscripten_fetch_attr_t attr; + emscripten_fetch_attr_t attr; emscripten_fetch_attr_init(&attr); method.copy(attr.requestMethod, method.size()); attr.requestMethod[method.size()] = '\0'; - attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY; - attr.requestHeaders = headers.data(); - attr.onsuccess = &RestWorkerState::onFetchSuccess; - attr.onerror = &RestWorkerState::onFetchError; - attr.userData = activeFetch.get(); + attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY; + attr.requestHeaders = headers.data(); + attr.onsuccess = &RestWorkerState::onFetchSuccess; + attr.onerror = &RestWorkerState::onFetchError; + attr.userData = activeFetch.get(); if (!activeFetch->body.empty()) { attr.requestData = activeFetch->body.data(); attr.requestDataSize = activeFetch->body.size(); From 5d8c086b1001f8d20a4dfb74dba0954f07486c4e Mon Sep 17 00:00:00 2001 From: drslebedev Date: Thu, 3 Sep 2026 12:49:33 +0200 Subject: [PATCH 2/2] RestClient: bypass IndexedDB for Emscripten fetches Use EMSCRIPTEN_FETCH_REPLACE to skip Emscripten's implicit IndexedDB lookup. REST responses are not persisted and should be fetched directly. Signed-off-by: drslebedev --- src/client/include/RestClientEmscripten.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/include/RestClientEmscripten.hpp b/src/client/include/RestClientEmscripten.hpp index 12040577..74b2dfdf 100644 --- a/src/client/include/RestClientEmscripten.hpp +++ b/src/client/include/RestClientEmscripten.hpp @@ -202,7 +202,7 @@ struct RestWorkerState { emscripten_fetch_attr_init(&attr); method.copy(attr.requestMethod, method.size()); attr.requestMethod[method.size()] = '\0'; - attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY; + attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_REPLACE; attr.requestHeaders = headers.data(); attr.onsuccess = &RestWorkerState::onFetchSuccess; attr.onerror = &RestWorkerState::onFetchError;