Frame brokered HTTP responses once
This commit is contained in:
parent
6e4ef8ed7a
commit
f89e33e241
@ -62,6 +62,15 @@ forced by Wasmtime: an `Engine`/`Store` cannot be safely re-created across
|
||||
runtime. So the brokers hold the long-lived connection and units respond to
|
||||
events the same way they respond to a page request — through a clean worker.
|
||||
|
||||
The broker-to-worker hop explicitly sets `GATEWAY_INTERFACE=CGI/1.1`. After
|
||||
the Wasm core decodes request parameters it derives the guest's default status
|
||||
syntax from that marker (`Status:` for FastCGI, `HTTP/1.1` for direct HTTP).
|
||||
The FastCGI transport clears completed stdout/stderr as soon as their records
|
||||
are queued and emits no stream records after `FCGI_END_REQUEST`. Together these
|
||||
boundaries prevent a forwarded dynamic response from being parsed as body and
|
||||
wrapped in a second HTTP response. The TCP and custom-server tests reject an
|
||||
inner status line and require the exact dynamic body.
|
||||
|
||||
---
|
||||
|
||||
## 2. The membrane and the DValue ABI
|
||||
|
||||
@ -421,6 +421,11 @@ void cli_run_tcp_smoke()
|
||||
cli_test_case("uce_tcp_smoke:http websocket port 8080", fd8080 != 0, "TCP connect " + String(fd8080 != 0 ? "succeeded" : "failed") + " on port 8080");
|
||||
if(fd8080 != 0)
|
||||
socket_close(fd8080);
|
||||
CliHttpResponse direct = cli_direct_http("/tests/pool-isolation.uce?token=raw-http-framing");
|
||||
StringList direct_parts = split(trim(direct.body), "|");
|
||||
bool one_response = direct.status == 200 && direct_parts.size() == 3 && direct_parts[0] == "fresh" && direct_parts[1] == "raw-http-framing" && direct.body.find("HTTP/1.1 ") == String::npos;
|
||||
cli_test_case("uce_tcp_smoke:raw HTTP dynamic response is framed once", one_response,
|
||||
one_response ? "single status/header block and exact dynamic body" : "status=" + std::to_string(direct.status) + " body=" + cli_truncate(direct.body));
|
||||
}
|
||||
|
||||
void cli_run_wasm_kill(bool include_kill)
|
||||
|
||||
@ -66,7 +66,7 @@ RENDER(Request& context)
|
||||
socket_close(stopped_sockfd);
|
||||
mark(
|
||||
"server_start_http() / SERVE_HTTP:named / server_stop()",
|
||||
(custom_http_pid != 0 && write_ok && response.find("custom-http-named") != String::npos && response.find("query=alpha=1") != String::npos && stopped && listener_closed) ? "pass" : "fail",
|
||||
(custom_http_pid != 0 && write_ok && response.find("custom-http-named") != String::npos && response.find("query=alpha=1") != String::npos && response.find("\r\nHTTP/1.1 ") == String::npos && stopped && listener_closed) ? "pass" : "fail",
|
||||
response.substr(0, response.length() > 260 ? 260 : response.length()) + " stopped=" + (stopped ? "true" : "false") + " listener_closed=" + (listener_closed ? "true" : "false")
|
||||
);
|
||||
}
|
||||
|
||||
@ -1388,6 +1388,8 @@ FastCGIServer::request_write_fgci(Connection& connection, RequestID id,
|
||||
//switch_to_system_alloc();
|
||||
write_data_fcgi(connection.output_buffer, id, request.out, FCGI_STDOUT);
|
||||
write_data_fcgi(connection.output_buffer, id, request.err, FCGI_STDERR);
|
||||
request.out.clear();
|
||||
request.err.clear();
|
||||
|
||||
FCGI_EndRequestRecord complete;
|
||||
bzero(&complete, sizeof(complete));
|
||||
|
||||
@ -855,7 +855,13 @@ static String custom_server_dispatcher_key = "";
|
||||
int forward_request_to_worker(FastCGIRequest& request, u32 timeout_seconds = 30)
|
||||
{
|
||||
String fcgi_socket = first(server_state.config["FCGI_SOCKET_PATH"], "/run/uce.sock");
|
||||
FcgiForwardResult fwd = fcgi_forward_request(fcgi_socket, request.params, request.in, timeout_seconds);
|
||||
StringMap forward_params = request.params;
|
||||
// The broker accepted raw HTTP, but this hop is FastCGI. Without the CGI
|
||||
// marker Request::set_status() emits an HTTP status line that the FastCGI
|
||||
// reply parser correctly treats as body; the broker would then wrap that
|
||||
// complete response in a second HTTP response.
|
||||
forward_params["GATEWAY_INTERFACE"] = "CGI/1.1";
|
||||
FcgiForwardResult fwd = fcgi_forward_request(fcgi_socket, forward_params, request.in, timeout_seconds);
|
||||
request.ob_start();
|
||||
if(!fwd.ok)
|
||||
{
|
||||
|
||||
@ -830,6 +830,8 @@ int uce_wasm_apply_context(const char* buf, size_t len)
|
||||
if(applied.key("server_config"))
|
||||
apply_map(applied.key("server_config"), wasm_server.config);
|
||||
apply_map(applied.key("params"), wasm_request.params);
|
||||
wasm_request.response_code = wasm_request.params["GATEWAY_INTERFACE"] != "" ?
|
||||
"Status: 200 OK" : "HTTP/1.1 200 OK";
|
||||
apply_map(applied.key("get"), wasm_request.get);
|
||||
apply_map(applied.key("post"), wasm_request.post);
|
||||
apply_map(applied.key("cookies"), wasm_request.cookies);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user