Skip to content

Commit 24cc55a

Browse files
committed
The Curl Handler supports the receipt of duplicate HTTP headers.
1 parent 0167a78 commit 24cc55a

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

src/core/Curl/Handler.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -867,11 +867,14 @@ private function execute()
867867
$headerContent .= $row;
868868
}
869869
foreach ($client->headers as $k => $v) {
870-
$row = "{$k}: {$v}\r\n";
871-
if ($cb) {
872-
$cb($this, $row);
870+
$list = is_array($v) ? $v : [$v];
871+
foreach ($list as $_v) {
872+
$row = "{$k}: {$_v}\r\n";
873+
if ($cb) {
874+
$cb($this, $row);
875+
}
876+
$headerContent .= $row;
873877
}
874-
$headerContent .= $row;
875878
}
876879
$headerContent .= "\r\n";
877880
$this->info['header_size'] = strlen($headerContent);

tests/unit/Curl/HandlerTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
1616
use PHPUnit\Framework\TestCase;
1717
use Swoole\Coroutine;
18+
use Swoole\Coroutine\Http\Server;
1819
use Swoole\Tests\HookFlagsTrait;
1920

2021
/**
@@ -262,4 +263,31 @@ public function testOptPrivate(): void
262263
curl_close($ch);
263264
});
264265
}
266+
267+
public function testRepeatHeader(): void
268+
{
269+
Coroutine\run(function () {
270+
$server = new Server('127.0.0.1', 0);
271+
Coroutine\go(function () use ($server) {
272+
$server->handle('/', function ($request, $response) {
273+
$response->header('X-Test-Header1', ['value1', 'value2']);
274+
$response->header('X-Test-Header2', 'value3');
275+
$response->end();
276+
});
277+
$server->start();
278+
});
279+
$ch = curl_init('http://127.0.0.1:' . $server->port);
280+
curl_setopt($ch, CURLOPT_HEADER, true);
281+
curl_setopt($ch, CURLOPT_HTTPHEADER, ['X-Test-Header: value1', 'X-Test-Header: value2']);
282+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
283+
$response = curl_exec($ch);
284+
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
285+
$headers = substr($response, 0, $headerSize);
286+
$this->assertStringContainsStringIgnoringCase("x-test-header1: value1\r\n", $headers);
287+
$this->assertStringContainsStringIgnoringCase("x-test-header1: value2\r\n", $headers);
288+
$this->assertStringContainsStringIgnoringCase("x-test-header2: value3\r\n", $headers);
289+
$server->shutdown();
290+
curl_close($ch);
291+
});
292+
}
265293
}

0 commit comments

Comments
 (0)