mirror of
https://github.com/php/frankenphp.git
synced 2026-03-24 00:52:11 +01:00
feat: add go_apache_request_headers()
This commit is contained in:
23
frankenphp.c
23
frankenphp.c
@@ -242,6 +242,29 @@ PHP_FUNCTION(frankenphp_finish_request) { /* {{{ */
|
||||
RETURN_TRUE;
|
||||
} /* }}} */
|
||||
|
||||
/* {{{ Fetch all HTTP request headers */
|
||||
PHP_FUNCTION(apache_request_headers) {
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
frankenphp_server_context *ctx = SG(server_context);
|
||||
struct go_apache_request_headers_return headers =
|
||||
go_apache_request_headers(ctx->current_request);
|
||||
|
||||
array_init_size(return_value, headers.r1);
|
||||
|
||||
for (size_t i = 0; i < headers.r1; i++) {
|
||||
go_string key = headers.r0[i * 2];
|
||||
go_string val = headers.r0[i * 2 + 1];
|
||||
|
||||
add_assoc_stringl_ex(return_value, key.data, key.len, val.data, val.len);
|
||||
}
|
||||
|
||||
free(headers.r0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHP_FUNCTION(frankenphp_handle_request) {
|
||||
zend_fcall_info fci;
|
||||
zend_fcall_info_cache fcc;
|
||||
|
||||
@@ -581,6 +581,27 @@ func go_register_variables(rh C.uintptr_t, trackVarsArray *C.zval) {
|
||||
fc.env = nil
|
||||
}
|
||||
|
||||
//export go_apache_request_headers
|
||||
func go_apache_request_headers(rh C.uintptr_t) (*C.go_string, C.size_t) {
|
||||
r := cgo.Handle(rh).Value().(*http.Request)
|
||||
|
||||
rl := len(r.Header)
|
||||
scs := unsafe.Sizeof(C.go_string{})
|
||||
|
||||
headers := (*C.go_string)(unsafe.Pointer(C.malloc(C.size_t(rl*2) * (C.size_t)(scs))))
|
||||
header := headers
|
||||
for field, val := range r.Header {
|
||||
*header = C.go_string{C.size_t(len(field)), (*C.char)(unsafe.Pointer(unsafe.StringData(field)))}
|
||||
header = (*C.go_string)(unsafe.Add(unsafe.Pointer(header), scs))
|
||||
|
||||
cv := strings.Join(val, ", ")
|
||||
*header = C.go_string{C.size_t(len(cv)), (*C.char)(unsafe.Pointer(unsafe.StringData(cv)))}
|
||||
header = (*C.go_string)(unsafe.Add(unsafe.Pointer(header), scs))
|
||||
}
|
||||
|
||||
return headers, C.size_t(rl)
|
||||
}
|
||||
|
||||
func addHeader(fc *FrankenPHPContext, cString *C.char, length C.int) {
|
||||
parts := strings.SplitN(C.GoStringN(cString, length), ": ", 2)
|
||||
if len(parts) != 2 {
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
#define STRINGIFY(x) #x
|
||||
#define TOSTRING(x) STRINGIFY(x)
|
||||
|
||||
typedef struct go_string {
|
||||
size_t len;
|
||||
const char *data;
|
||||
} go_string;
|
||||
|
||||
typedef struct frankenphp_version {
|
||||
unsigned char major_version;
|
||||
unsigned char minor_version;
|
||||
|
||||
@@ -12,3 +12,10 @@ function frankenphp_finish_request(): bool {}
|
||||
* @alias frankenphp_finish_request
|
||||
*/
|
||||
function fastcgi_finish_request(): bool {}
|
||||
|
||||
function apache_request_headers(): array {}
|
||||
|
||||
/**
|
||||
* @alias apache_request_headers
|
||||
*/
|
||||
function getallheaders(): array {}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: de4dc4063fafd8c933e3068c8349889a7ece5f03 */
|
||||
* Stub hash: f925a1c280fb955eb32d0823cbd4f360b0cbabed */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_frankenphp_handle_request, 0, 1,
|
||||
_IS_BOOL, 0)
|
||||
@@ -16,13 +16,23 @@ ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_fastcgi_finish_request arginfo_frankenphp_finish_request
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_apache_request_headers, 0, 0,
|
||||
IS_ARRAY, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_getallheaders arginfo_apache_request_headers
|
||||
|
||||
ZEND_FUNCTION(frankenphp_handle_request);
|
||||
ZEND_FUNCTION(headers_send);
|
||||
ZEND_FUNCTION(frankenphp_finish_request);
|
||||
ZEND_FUNCTION(apache_request_headers);
|
||||
|
||||
static const zend_function_entry ext_functions[] = {
|
||||
ZEND_FE(frankenphp_handle_request, arginfo_frankenphp_handle_request)
|
||||
ZEND_FE(headers_send, arginfo_headers_send) ZEND_FE(
|
||||
frankenphp_finish_request, arginfo_frankenphp_finish_request)
|
||||
ZEND_FALIAS(fastcgi_finish_request, frankenphp_finish_request,
|
||||
arginfo_fastcgi_finish_request) ZEND_FE_END};
|
||||
arginfo_fastcgi_finish_request)
|
||||
ZEND_FE(apache_request_headers, arginfo_apache_request_headers)
|
||||
ZEND_FALIAS(getallheaders, apache_request_headers,
|
||||
arginfo_getallheaders) ZEND_FE_END};
|
||||
|
||||
@@ -553,6 +553,27 @@ func testFiberNoCgo(t *testing.T, opts *testOptions) {
|
||||
}, opts)
|
||||
}
|
||||
|
||||
func TestApacheRequestHeaders_module(t *testing.T) { testApacheRequestHeaders(t, &testOptions{}) }
|
||||
func TestApacheRequestHeaders_worker(t *testing.T) {
|
||||
testApacheRequestHeaders(t, &testOptions{workerScript: "apache-request-headers.php"})
|
||||
}
|
||||
func testApacheRequestHeaders(t *testing.T, opts *testOptions) {
|
||||
runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) {
|
||||
req := httptest.NewRequest("GET", fmt.Sprintf("http://example.com/apache-request-headers.php?i=%d", i), nil)
|
||||
req.Header.Add("Content-Type", "text/plain")
|
||||
req.Header.Add("Frankenphp-I", strconv.Itoa(i))
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
handler(w, req)
|
||||
|
||||
resp := w.Result()
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
|
||||
assert.Contains(t, string(body), "[Content-Type] => text/plain")
|
||||
assert.Contains(t, string(body), fmt.Sprintf("[Frankenphp-I] => %d", i))
|
||||
}, opts)
|
||||
}
|
||||
|
||||
func TestExecuteScriptCLI(t *testing.T) {
|
||||
if _, err := os.Stat("internal/testcli/testcli"); err != nil {
|
||||
t.Skip("internal/testcli/testcli has not been compiled, run `cd internal/testcli/ && go build`")
|
||||
|
||||
7
testdata/apache-request-headers.php
vendored
Normal file
7
testdata/apache-request-headers.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__.'/_executor.php';
|
||||
|
||||
return function() {
|
||||
print_r(apache_request_headers());
|
||||
};
|
||||
Reference in New Issue
Block a user