Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/GlobalState.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ public static function enrichServerVars(Request $request): array
$server['REQUEST_METHOD'] = $request->method;
$server['HTTP_USER_AGENT'] = '';

$parts = \parse_url($request->uri);

if (isset($parts['host'])) {
$server['HTTP_HOST'] = isset($parts['port'])
? $parts['host'] . ':' . $parts['port']
: $parts['host'];
}
foreach ($request->headers as $key => $value) {
$key = \strtoupper(\str_replace('-', '_', $key));

Expand Down
71 changes: 71 additions & 0 deletions tests/Unit/GlobalStateTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

namespace Spiral\RoadRunner\Tests\Http\Unit;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Spiral\RoadRunner\Http\GlobalState;
use Spiral\RoadRunner\Http\Request;

final class GlobalStateTest extends TestCase
{
/**
* @return iterable<array{0: Request, 1: array<array-key, mixed>}>
*/
public static function enrichServerVarsDataProvider(): iterable
{
yield [
new Request(),
[
'REQUEST_URI' => 'http://localhost',
'REMOTE_ADDR' => '127.0.0.1',
'REQUEST_METHOD' => 'GET',
'HTTP_USER_AGENT' => '',
'HTTP_HOST' => 'localhost',
],
];

yield [
new Request(uri: 'https://roadrunner.dev'),
[
'REQUEST_URI' => 'https://roadrunner.dev',
'REMOTE_ADDR' => '127.0.0.1',
'REQUEST_METHOD' => 'GET',
'HTTP_USER_AGENT' => '',
'HTTP_HOST' => 'roadrunner.dev',
],
];

yield [
new Request(uri: 'https://roadrunner.dev:8080'),
[
'REQUEST_URI' => 'https://roadrunner.dev:8080',
'REMOTE_ADDR' => '127.0.0.1',
'REQUEST_METHOD' => 'GET',
'HTTP_USER_AGENT' => '',
'HTTP_HOST' => 'roadrunner.dev:8080',
],
];
}

/**
* @param array<array-key, mixed> $expected
*/
#[DataProvider('enrichServerVarsDataProvider')]
public function testEnrichServerVars(Request $request, array $expected): void
{
$_SERVER = [];

$server = GlobalState::enrichServerVars($request);

Comment on lines +59 to +62
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Initialize GlobalState cache in test setup to avoid cross-test leakage

This test resets $_SERVER, but GlobalState::enrichServerVars() uses GlobalState::$cachedServer (static), not $_SERVER directly. Without calling GlobalState::cacheServerVars(), this can become order-dependent and flaky.

Proposed fix
     $_SERVER = [];
+    GlobalState::cacheServerVars();

     $server = GlobalState::enrichServerVars($request);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
$_SERVER = [];
$server = GlobalState::enrichServerVars($request);
$_SERVER = [];
GlobalState::cacheServerVars();
$server = GlobalState::enrichServerVars($request);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Unit/GlobalStateTest.php` around lines 59 - 62, The test clears
$_SERVER but calls GlobalState::enrichServerVars($request) which reads the
static GlobalState::$cachedServer and can leak state between tests; update the
test setup to initialize the GlobalState cache by invoking
GlobalState::cacheServerVars() (or explicitly reset GlobalState::$cachedServer)
before calling GlobalState::enrichServerVars() so the cached server vars are
deterministic for the test.

$this->assertArrayHasKey('REQUEST_TIME', $server);
$this->assertArrayHasKey('REQUEST_TIME_FLOAT', $server);

unset($server['REQUEST_TIME']);
unset($server['REQUEST_TIME_FLOAT']);

$this->assertEquals($server, $expected);
}
}
2 changes: 2 additions & 0 deletions tests/Unit/PSR7WorkerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public function testStateServerLeak(): void
'HTTP_USER_AGENT' => '',
'CONTENT_TYPE' => 'application/html',
'HTTP_CONNECTION' => 'keep-alive',
'HTTP_HOST' => 'localhost',
],
],
[
Expand All @@ -56,6 +57,7 @@ public function testStateServerLeak(): void
'REQUEST_METHOD' => 'GET',
'HTTP_USER_AGENT' => '',
'CONTENT_TYPE' => 'application/json',
'HTTP_HOST' => 'localhost',
],
],
];
Expand Down
Loading