Preserve WebSocket handshake context in broker worker requests

This commit is contained in:
udo authored and root committed 2026-10-15 13:21:29 +00:00
1 parent 55477b8c34
commit d23381b4b9
7 files changed
+264 -3

No files matched your search

+39
View File
@@ -183,6 +183,45 @@ static FcgiRequestResult run(int family, int mode, u64 limit = 8 * 1024 * 1024,
int main()
{
signal(SIGPIPE, SIG_IGN);
auto handshake = [](String path, String cookie, String origin) {
StringMap params = split_http_headers("GET " + path + " HTTP/1.1\r\n"
"Host: socket.example.test\r\nCookie: discarded=1\r\ncOoKiE: " + cookie + "\r\n"
"Origin: https://discarded.example.test\r\noRiGiN: " + origin + "\r\n"
"Authorization: Bearer test-token\r\nX-Forwarded-Proto: https\r\n"
"Bearer-CLI: 1\r\nContent-Length: 4\r\nContent-Type: text/plain\r\n\r\n");
params["SCRIPT_FILENAME"] = "/srv/site" + params["DOCUMENT_URI"];
params["DOCUMENT_ROOT"] = "/srv/site";
params["REMOTE_ADDR"] = "192.0.2.1";
params["HTTPS"] = "on";
params["BEARER_CLI"] = "1";
params["BEARER_WS_DISPATCH"] = "1";
params["BEARER_WS_STATE"] = "stale-worker-state";
params["ROUTE_PAGE"] = "stale-route";
return(params);
};
const StringMap alice = handshake("/alice.capy?room=one&%2Fprivate", "session=alice; csrf=a", "https://alice.example.test");
const StringMap bob = handshake("/bob.capy?room=two", "session=bob; csrf=b", "https://bob.example.test");
StringMap alice_frame = fcgi_websocket_request_context(alice);
StringMap bob_frame = fcgi_websocket_request_context(bob);
assert(alice_frame.at("HTTP_COOKIE") == "session=alice; csrf=a");
assert(alice_frame.at("HTTP_ORIGIN") == "https://alice.example.test");
assert(bob_frame.at("HTTP_COOKIE") == "session=bob; csrf=b");
assert(bob_frame.at("HTTP_ORIGIN") == "https://bob.example.test");
for(const StringMap* source : {&alice, &bob})
{
StringMap frame = fcgi_websocket_request_context(*source);
for(const String key : {"REQUEST_URI", "DOCUMENT_URI", "SCRIPT_FILENAME", "QUERY_STRING", "DOCUMENT_ROOT", "REMOTE_ADDR", "HTTPS", "HTTP_AUTHORIZATION", "HTTP_X_FORWARDED_PROTO"})
assert(frame.at(key) == source->at(key));
for(const String key : {"CONTENT_LENGTH", "CONTENT_TYPE", "REQUEST_METHOD", "BEARER_CLI", "BEARER_WS_DISPATCH", "BEARER_WS_STATE", "ROUTE_PAGE"})
assert(!frame.contains(key));
assert(frame.at("HTTP_BEARER_CLI") == "1");
}
alice_frame["HTTP_COOKIE"] = "session=forged";
alice_frame["QUERY_STRING"] = "room=other";
assert(fcgi_websocket_request_context(alice).at("HTTP_COOKIE") == "session=alice; csrf=a");
assert(fcgi_websocket_request_context(alice).at("QUERY_STRING") == "room=one&%2Fprivate");
assert(bob_frame.at("HTTP_COOKIE") == "session=bob; csrf=b");
assert(fcgi_websocket_request_context(split_http_headers("GET /anonymous.capy HTTP/1.1\r\nHost: socket.example.test\r\n\r\n")).count("HTTP_COOKIE") == 0);
String lengths;
fcgi_forward_put_len(lengths, 127);
fcgi_forward_put_len(lengths, 128);