Skip to content

Commit 1f9f2cd

Browse files
authored
Merge pull request #248 from clue-labs/set-cookie
Support sending same response header multiple times (e.g. Set-Cookie)
2 parents ffe6126 + 703d4de commit 1f9f2cd

File tree

2 files changed

+54
-8
lines changed

2 files changed

+54
-8
lines changed

src/Server.php

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@
33
namespace React\Http;
44

55
use Evenement\EventEmitter;
6-
use React\Socket\ServerInterface;
7-
use React\Socket\ConnectionInterface;
86
use Psr\Http\Message\RequestInterface;
97
use Psr\Http\Message\ResponseInterface;
10-
use React\Promise\Promise;
11-
use RingCentral\Psr7 as Psr7Implementation;
128
use Psr\Http\Message\ServerRequestInterface;
139
use React\Promise\CancellablePromiseInterface;
10+
use React\Promise\Promise;
11+
use React\Socket\ConnectionInterface;
12+
use React\Socket\ServerInterface;
13+
use React\Stream\ReadableStreamInterface;
1414
use React\Stream\WritableStreamInterface;
15+
use RingCentral\Psr7 as Psr7Implementation;
1516

1617
/**
1718
* The `Server` class is responsible for handling incoming connections and then
@@ -378,19 +379,26 @@ public function handleResponse(ConnectionInterface $connection, ServerRequestInt
378379

379380
private function handleResponseBody(ResponseInterface $response, ConnectionInterface $connection)
380381
{
381-
if (!$response->getBody() instanceof HttpBodyStream) {
382-
$connection->write(Psr7Implementation\str($response));
383-
return $connection->end();
382+
$headers = "HTTP/" . $response->getProtocolVersion() . " " . $response->getStatusCode() . " " . $response->getReasonPhrase() . "\r\n";
383+
foreach ($response->getHeaders() as $name => $values) {
384+
foreach ($values as $value) {
385+
$headers .= $name . ": " . $value . "\r\n";
386+
}
384387
}
385388

386389
$stream = $response->getBody();
387390

391+
if (!$stream instanceof ReadableStreamInterface) {
392+
$connection->write($headers . "\r\n" . $stream);
393+
return $connection->end();
394+
}
395+
388396
// close response stream if connection is already closed
389397
if (!$connection->isWritable()) {
390398
return $stream->close();
391399
}
392400

393-
$connection->write(Psr7Implementation\str($response));
401+
$connection->write($headers . "\r\n");
394402

395403
if ($stream->isReadable()) {
396404
if ($response->getHeaderLine('Transfer-Encoding') === 'chunked') {

tests/ServerTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2331,6 +2331,44 @@ function ($data) use (&$buffer) {
23312331
$this->assertContains("\r\n\r\n", $buffer);
23322332
}
23332333

2334+
public function testAddMultipleCookieHeaders()
2335+
{
2336+
$server = new Server(function (ServerRequestInterface $request) {
2337+
return new Response(
2338+
200,
2339+
array(
2340+
'Set-Cookie' => array(
2341+
'name=test',
2342+
'session=abc'
2343+
),
2344+
'Date' => '',
2345+
'X-Powered-By' => ''
2346+
)
2347+
);
2348+
});
2349+
2350+
$buffer = '';
2351+
$this->connection
2352+
->expects($this->any())
2353+
->method('write')
2354+
->will(
2355+
$this->returnCallback(
2356+
function ($data) use (&$buffer) {
2357+
$buffer .= $data;
2358+
}
2359+
)
2360+
);
2361+
2362+
$server->listen($this->socket);
2363+
$this->socket->emit('connection', array($this->connection));
2364+
2365+
$data = $this->createGetRequest();
2366+
2367+
$this->connection->emit('data', array($data));
2368+
2369+
$this->assertEquals("HTTP/1.1 200 OK\r\nSet-Cookie: name=test\r\nSet-Cookie: session=abc\r\nContent-Length: 0\r\nConnection: close\r\n\r\n", $buffer);
2370+
}
2371+
23342372
public function testOnlyChunkedEncodingIsAllowedForTransferEncoding()
23352373
{
23362374
$error = null;

0 commit comments

Comments
 (0)