fix: headers before flushing (#1622)

* add tests

* fix test

* attempt to send headers when flushing

* Update testdata/only-headers.php

Co-authored-by: Kévin Dunglas <kevin@dunglas.fr>

---------

Co-authored-by: Kévin Dunglas <kevin@dunglas.fr>
This commit is contained in:
Rob Landers
2025-06-01 14:58:36 +02:00
committed by GitHub
parent 68a4548bf4
commit a59b649dac
4 changed files with 32 additions and 0 deletions

View File

@@ -588,6 +588,7 @@ static int frankenphp_send_headers(sapi_headers_struct *sapi_headers) {
}
static void frankenphp_sapi_flush(void *server_context) {
sapi_send_headers();
if (go_sapi_flush(thread_index)) {
php_handle_aborted_connection();
}

View File

@@ -492,6 +492,10 @@ func addHeader(fc *frankenPHPContext, cString *C.char, length C.int) {
func go_write_headers(threadIndex C.uintptr_t, status C.int, headers *C.zend_llist) C.bool {
fc := phpThreads[threadIndex].getRequestContext()
if fc == nil {
return C.bool(false)
}
if fc.isDone {
return C.bool(false)
}

View File

@@ -1023,6 +1023,22 @@ func testRejectInvalidHeaders(t *testing.T, opts *testOptions) {
}
}
func TestFlushEmptyResponse_module(t *testing.T) { testFlushEmptyResponse(t, &testOptions{}) }
func TestFlushEmptyRespnse_worker(t *testing.T) {
testFlushEmptyResponse(t, &testOptions{workerScript: "only-headers.php"})
}
func testFlushEmptyResponse(t *testing.T, opts *testOptions) {
runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, _ int) {
req := httptest.NewRequest("GET", "http://example.com/only-headers.php", nil)
w := httptest.NewRecorder()
handler(w, req)
resp := w.Result()
assert.Equal(t, 204, resp.StatusCode)
}, opts)
}
// Worker mode will clean up unreferenced streams between requests
// Make sure referenced streams are not cleaned up
func TestFileStreamInWorkerMode(t *testing.T) {

11
testdata/only-headers.php vendored Normal file
View File

@@ -0,0 +1,11 @@
<?php
require_once __DIR__.'/_executor.php';
return function () {
header('Content-Type: application/json');
header('HTTP/1.1 204 No Content', true, 204);
echo '{"status": "test"}';
flush();
};