Bug Report
Swoole version
6.2.0
Hyperf version
hyperf/http-message ~3.1.0 (tested on v3.1.65)
Bug description
Swoole 6.2.0 introduced a new server_addr field in $swooleRequest->server (the server's local IP address). This breaks getUriFromGlobals() in Hyperf\HttpMessage\Server\Request, because server_addr has higher priority than header['host'] in the fallback chain.
In src/Server/Request.php, the current logic is:
if (isset($server['http_host'])) {
// ...
} elseif (isset($server['server_name'])) {
// ...
} elseif (isset($server['server_addr'])) { // ← swoole 6.2.0 hits here
$uri = $uri->withHost($server['server_addr']); // value: "127.0.0.1" or local IP
} elseif (isset($header['host'])) { // ← never reached anymore
// ...
}
Before swoole 6.2.0, server_addr was never set by swoole, so the code fell through to header['host'] which contains the correct domain name (e.g. ai-service.example.com). Now $request->getUri()->getHost() returns the server's local IP instead of the requested domain.
Swoole 6.2.0 change
The relevant new code in swoole 6.2.0 (ext-src/swoole_http_server.cc):
void swoole_http_server_populate_ip_and_port(...) {
// NEW in 6.2.0 - sets $request->server['server_addr']
http_server_add_server_array(ht, SW_ZSTR_KNOWN(SW_ZEND_STR_SERVER_ADDR), server->get_local_addr(conn));
http_server_add_server_array(ht, SW_ZSTR_KNOWN(SW_ZEND_STR_REMOTE_ADDR), server->get_remote_addr(conn));
}
This field did not exist in swoole 5.x or 6.0.0.
How to reproduce
- Run Hyperf with swoole 6.2.0
- Send a request with
Host: example.com header
- Check
$request->getUri()->getHost() — it returns the server's local IP (e.g. 127.0.0.1) instead of example.com
Evidence from production logs
Normal (swoole 5.x) — server_addr absent, host resolved from header['host']:
{
"uri_host": "ai-service.example.com",
"header_host": "ai-service.example.com",
"server": {
"server_port": 9501,
"remote_addr": "127.0.0.1"
}
}
Broken (swoole 6.2.0) — server_addr present, overrides header['host']:
{
"uri_host": "127.0.0.1",
"header_host": "ai-service.example.com",
"server": {
"server_port": 9501,
"server_addr": "127.0.0.1",
"remote_addr": "127.0.0.1"
}
}
Note: header['host'] is correct in both cases, but getUri()->getHost() is wrong in swoole 6.2.0.
Suggested fix
The header['host'] (HTTP Host header from the client) should take priority over server_addr (server's own IP), since server_addr represents the server's local address, not the requested domain. This aligns with how PHP-FPM and nginx handle the same situation — $_SERVER['HTTP_HOST'] always takes precedence.
if (isset($server['http_host'])) {
// ...
} elseif (isset($header['host'])) { // ← move this BEFORE server_name/server_addr
// ...
} elseif (isset($server['server_name'])) {
// ...
} elseif (isset($server['server_addr'])) {
// ...
}
Bug Report
Swoole version
6.2.0
Hyperf version
hyperf/http-message ~3.1.0 (tested on v3.1.65)
Bug description
Swoole 6.2.0 introduced a new
server_addrfield in$swooleRequest->server(the server's local IP address). This breaksgetUriFromGlobals()inHyperf\HttpMessage\Server\Request, becauseserver_addrhas higher priority thanheader['host']in the fallback chain.In
src/Server/Request.php, the current logic is:Before swoole 6.2.0,
server_addrwas never set by swoole, so the code fell through toheader['host']which contains the correct domain name (e.g.ai-service.example.com). Now$request->getUri()->getHost()returns the server's local IP instead of the requested domain.Swoole 6.2.0 change
The relevant new code in swoole 6.2.0 (
ext-src/swoole_http_server.cc):This field did not exist in swoole 5.x or 6.0.0.
How to reproduce
Host: example.comheader$request->getUri()->getHost()— it returns the server's local IP (e.g.127.0.0.1) instead ofexample.comEvidence from production logs
Normal (swoole 5.x) —
server_addrabsent, host resolved fromheader['host']:{ "uri_host": "ai-service.example.com", "header_host": "ai-service.example.com", "server": { "server_port": 9501, "remote_addr": "127.0.0.1" } }Broken (swoole 6.2.0) —
server_addrpresent, overridesheader['host']:{ "uri_host": "127.0.0.1", "header_host": "ai-service.example.com", "server": { "server_port": 9501, "server_addr": "127.0.0.1", "remote_addr": "127.0.0.1" } }Note:
header['host']is correct in both cases, butgetUri()->getHost()is wrong in swoole 6.2.0.Suggested fix
The
header['host'](HTTP Host header from the client) should take priority overserver_addr(server's own IP), sinceserver_addrrepresents the server's local address, not the requested domain. This aligns with how PHP-FPM and nginx handle the same situation —$_SERVER['HTTP_HOST']always takes precedence.