Skip to content

Commit 8432f0d

Browse files
committed
fix(webserver): reflect requested headers in CORS preflight
The OPTIONS preflight returned a fixed Access-Control-Allow-Headers list (Content-Type, Authorization), so any cross-origin request carrying a header outside that set (custom X-* headers, x-api-key, etc.) was rejected by the browser as a CORS failure. Echo back the browser's Access-Control-Request-Headers instead, falling back to the previous defaults when none are advertised.
1 parent a97a9e3 commit 8432f0d

1 file changed

Lines changed: 8 additions & 1 deletion

File tree

plugins/webserver/webserver_plugin.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,14 @@ namespace graphene {
435435
if (con->get_request().get_method() == "OPTIONS") {
436436
con->append_header("Access-Control-Allow-Origin", "*");
437437
con->append_header("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
438-
con->append_header("Access-Control-Allow-Headers", "Content-Type, Authorization");
438+
// Reflect exactly the headers the browser asked to send. A fixed
439+
// allow-list blocks any request carrying a header outside it
440+
// (custom X-* headers, x-api-key, etc.), which the browser reports
441+
// as a CORS preflight failure. Falls back to the common defaults
442+
// when the browser did not advertise any headers.
443+
const std::string &requested_headers = con->get_request().get_header("Access-Control-Request-Headers");
444+
con->append_header("Access-Control-Allow-Headers",
445+
requested_headers.empty() ? std::string("Content-Type, Authorization") : requested_headers);
439446
con->append_header("Access-Control-Max-Age", "86400");
440447
con->set_status(websocketpp::http::status_code::ok);
441448
try { con->send_http_response(); } catch (...) {}

0 commit comments

Comments
 (0)