Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
62 / 62
98.36% covered (success)
98.36%
60 / 61
40.91% covered (danger)
40.91%
27 / 66
88.89% covered (warning)
88.89%
8 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
Sapi
100.00% covered (success)
100.00%
62 / 62
98.36% covered (success)
98.36%
60 / 61
40.91% covered (danger)
40.91%
27 / 66
100.00% covered (success)
100.00%
9 / 9
215.70
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 emit
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
8 / 8
66.67% covered (warning)
66.67%
4 / 6
100.00% covered (success)
100.00%
1 / 1
4.59
 assertNoPreviousOutput
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 emitHeaders
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
7 / 7
40.00% covered (danger)
40.00%
2 / 5
100.00% covered (success)
100.00%
1 / 1
4.94
 emitStatusLine
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 isBodyless
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
5 / 5
75.00% covered (warning)
75.00%
3 / 4
100.00% covered (success)
100.00%
1 / 1
3.14
 contentRange
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 emitBody
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
8 / 8
50.00% covered (danger)
50.00%
3 / 6
100.00% covered (success)
100.00%
1 / 1
6.00
 emitBodyRange
100.00% covered (success)
100.00%
14 / 14
94.12% covered (success)
94.12%
16 / 17
16.67% covered (danger)
16.67%
6 / 36
100.00% covered (success)
100.00%
1 / 1
35.36
1<?php
2
3declare(strict_types=1);
4
5namespace Celema\Core\Emitter;
6
7use Celema\Core\Exception\RuntimeException;
8use Override;
9use Psr\Http\Message\ResponseInterface as Response;
10use Psr\Http\Message\StreamInterface as Stream;
11
12/**
13 * Derived from the SAPI emitters of laminas/laminas-httphandlerrunner,
14 * copyright (c) 2020 Laminas Project a Series of LF Projects, LLC,
15 * distributed under the BSD-3-Clause license. See LICENSE.md.
16 *
17 * @api
18 */
19final class Sapi implements Emitter
20{
21    public function __construct(
22        private readonly int $maxBufferLength = 8192,
23    ) {}
24
25    #[Override]
26    public function emit(Response $response, bool $withoutBody = false): bool
27    {
28        $this->assertNoPreviousOutput();
29        $this->emitHeaders($response);
30        $this->emitStatusLine($response);
31        flush();
32
33        if ($withoutBody || $this->isBodyless($response->getStatusCode())) {
34            return true;
35        }
36
37        $range = $this->contentRange($response->getHeaderLine('Content-Range'));
38
39        if ($range === null) {
40            $this->emitBody($response->getBody());
41        } else {
42            $this->emitBodyRange($response->getBody(), $range[0], $range[1]);
43        }
44
45        return true;
46    }
47
48    private function assertNoPreviousOutput(): void
49    {
50        if (headers_sent($file, $line)) {
51            throw new RuntimeException("Headers already sent in {$file} on line {$line}");
52        }
53
54        // ob_get_length() is false without an active buffer.
55        if (ob_get_length() > 0) {
56            throw new RuntimeException('Output already present in the output buffer');
57        }
58    }
59
60    /**
61     * Emitted before the status line so PHP cannot override the status
62     * code with one derived from a header like Location.
63     */
64    private function emitHeaders(Response $response): void
65    {
66        $statusCode = $response->getStatusCode();
67
68        foreach ($response->getHeaders() as $name => $values) {
69            $name = ucwords((string) $name, '-');
70            $replace = $name !== 'Set-Cookie';
71
72            foreach ($values as $value) {
73                header("{$name}: {$value}", $replace, $statusCode);
74                $replace = false;
75            }
76        }
77    }
78
79    private function emitStatusLine(Response $response): void
80    {
81        $statusCode = $response->getStatusCode();
82        $reasonPhrase = $response->getReasonPhrase();
83
84        header(
85            sprintf(
86                'HTTP/%s %d%s',
87                $response->getProtocolVersion(),
88                $statusCode,
89                $reasonPhrase === '' ? '' : " {$reasonPhrase}",
90            ),
91            true,
92            $statusCode,
93        );
94    }
95
96    /**
97     * A 1xx, 204, or 304 response must not include a body (RFC 9110).
98     */
99    private function isBodyless(int $statusCode): bool
100    {
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
102    }
103
104    /**
105     * Returns [first, last] byte positions from a valid bytes Content-Range
106     * header, or null when the whole body should be emitted.
107     *
108     * @return array{0: int, 1: int}|null
109     */
110    private function contentRange(string $header): ?array
111    {
112        if (preg_match('/^bytes (?P<first>\d+)-(?P<last>\d+)\/(?:\d+|\*)$/', $header, $matches) !== 1) {
113            return null;
114        }
115
116        $first = (int) $matches['first'];
117        $last = (int) $matches['last'];
118
119        return $first <= $last ? [$first, $last] : null;
120    }
121
122    private function emitBody(Stream $body): void
123    {
124        if ($body->isSeekable()) {
125            $body->rewind();
126        }
127
128        if (!$body->isReadable()) {
129            echo (string) $body;
130
131            return;
132        }
133
134        while (!$body->eof()) {
135            echo $body->read($this->maxBufferLength);
136        }
137    }
138
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
149            echo substr($body->getContents(), $first, $length);
150
151            return;
152        }
153
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
158            $remaining -= strlen($contents);
159            echo $contents;
160        }
161
162        if ($remaining > 0 && !$body->eof()) {
163            echo $body->read($remaining);
164        }
165    }
166}

Paths

Below are the source code lines that represent each code path as identified by Xdebug. Please note a path is not necessarily coterminous with a line, a line may contain multiple paths and therefore show up more than once. Please also be aware that some paths may include implicit rather than explicit branches, e.g. an if statement always has an else as part of its logical flow even if you didn't write one.

Sapi->__construct
22        private readonly int $maxBufferLength = 8192,
23    ) {}
Sapi->assertNoPreviousOutput
50        if (headers_sent($file, $line)) {
 
51            throw new RuntimeException("Headers already sent in {$file} on line {$line}");
50        if (headers_sent($file, $line)) {
 
55        if (ob_get_length() > 0) {
 
56            throw new RuntimeException('Output already present in the output buffer');
50        if (headers_sent($file, $line)) {
 
55        if (ob_get_length() > 0) {
 
58    }
Sapi->contentRange
110    private function contentRange(string $header): ?array
111    {
112        if (preg_match('/^bytes (?P<first>\d+)-(?P<last>\d+)\/(?:\d+|\*)$/', $header, $matches) !== 1) {
 
113            return null;
110    private function contentRange(string $header): ?array
111    {
112        if (preg_match('/^bytes (?P<first>\d+)-(?P<last>\d+)\/(?:\d+|\*)$/', $header, $matches) !== 1) {
 
116        $first = (int) $matches['first'];
117        $last = (int) $matches['last'];
118
119        return $first <= $last ? [$first, $last] : null;
 
119        return $first <= $last ? [$first, $last] : null;
 
119        return $first <= $last ? [$first, $last] : null;
120    }
110    private function contentRange(string $header): ?array
111    {
112        if (preg_match('/^bytes (?P<first>\d+)-(?P<last>\d+)\/(?:\d+|\*)$/', $header, $matches) !== 1) {
 
116        $first = (int) $matches['first'];
117        $last = (int) $matches['last'];
118
119        return $first <= $last ? [$first, $last] : null;
 
119        return $first <= $last ? [$first, $last] : null;
 
119        return $first <= $last ? [$first, $last] : null;
120    }
Sapi->emit
26    public function emit(Response $response, bool $withoutBody = false): bool
27    {
28        $this->assertNoPreviousOutput();
29        $this->emitHeaders($response);
30        $this->emitStatusLine($response);
31        flush();
32
33        if ($withoutBody || $this->isBodyless($response->getStatusCode())) {
 
33        if ($withoutBody || $this->isBodyless($response->getStatusCode())) {
 
33        if ($withoutBody || $this->isBodyless($response->getStatusCode())) {
 
34            return true;
26    public function emit(Response $response, bool $withoutBody = false): bool
27    {
28        $this->assertNoPreviousOutput();
29        $this->emitHeaders($response);
30        $this->emitStatusLine($response);
31        flush();
32
33        if ($withoutBody || $this->isBodyless($response->getStatusCode())) {
 
33        if ($withoutBody || $this->isBodyless($response->getStatusCode())) {
 
33        if ($withoutBody || $this->isBodyless($response->getStatusCode())) {
 
37        $range = $this->contentRange($response->getHeaderLine('Content-Range'));
38
39        if ($range === null) {
 
39        if ($range === null) {
40            $this->emitBody($response->getBody());
 
45        return true;
46    }
26    public function emit(Response $response, bool $withoutBody = false): bool
27    {
28        $this->assertNoPreviousOutput();
29        $this->emitHeaders($response);
30        $this->emitStatusLine($response);
31        flush();
32
33        if ($withoutBody || $this->isBodyless($response->getStatusCode())) {
 
33        if ($withoutBody || $this->isBodyless($response->getStatusCode())) {
 
33        if ($withoutBody || $this->isBodyless($response->getStatusCode())) {
 
37        $range = $this->contentRange($response->getHeaderLine('Content-Range'));
38
39        if ($range === null) {
 
42            $this->emitBodyRange($response->getBody(), $range[0], $range[1]);
43        }
44
45        return true;
 
45        return true;
46    }
26    public function emit(Response $response, bool $withoutBody = false): bool
27    {
28        $this->assertNoPreviousOutput();
29        $this->emitHeaders($response);
30        $this->emitStatusLine($response);
31        flush();
32
33        if ($withoutBody || $this->isBodyless($response->getStatusCode())) {
 
33        if ($withoutBody || $this->isBodyless($response->getStatusCode())) {
 
34            return true;
26    public function emit(Response $response, bool $withoutBody = false): bool
27    {
28        $this->assertNoPreviousOutput();
29        $this->emitHeaders($response);
30        $this->emitStatusLine($response);
31        flush();
32
33        if ($withoutBody || $this->isBodyless($response->getStatusCode())) {
 
33        if ($withoutBody || $this->isBodyless($response->getStatusCode())) {
 
37        $range = $this->contentRange($response->getHeaderLine('Content-Range'));
38
39        if ($range === null) {
 
39        if ($range === null) {
40            $this->emitBody($response->getBody());
 
45        return true;
46    }
26    public function emit(Response $response, bool $withoutBody = false): bool
27    {
28        $this->assertNoPreviousOutput();
29        $this->emitHeaders($response);
30        $this->emitStatusLine($response);
31        flush();
32
33        if ($withoutBody || $this->isBodyless($response->getStatusCode())) {
 
33        if ($withoutBody || $this->isBodyless($response->getStatusCode())) {
 
37        $range = $this->contentRange($response->getHeaderLine('Content-Range'));
38
39        if ($range === null) {
 
42            $this->emitBodyRange($response->getBody(), $range[0], $range[1]);
43        }
44
45        return true;
 
45        return true;
46    }
Sapi->emitBody
122    private function emitBody(Stream $body): void
123    {
124        if ($body->isSeekable()) {
 
125            $body->rewind();
126        }
127
128        if (!$body->isReadable()) {
 
128        if (!$body->isReadable()) {
 
129            echo (string) $body;
130
131            return;
122    private function emitBody(Stream $body): void
123    {
124        if ($body->isSeekable()) {
 
125            $body->rewind();
126        }
127
128        if (!$body->isReadable()) {
 
128        if (!$body->isReadable()) {
 
134        while (!$body->eof()) {
 
134        while (!$body->eof()) {
 
137    }
122    private function emitBody(Stream $body): void
123    {
124        if ($body->isSeekable()) {
 
125            $body->rewind();
126        }
127
128        if (!$body->isReadable()) {
 
128        if (!$body->isReadable()) {
 
134        while (!$body->eof()) {
 
134        while (!$body->eof()) {
 
134        while (!$body->eof()) {
135            echo $body->read($this->maxBufferLength);
 
134        while (!$body->eof()) {
 
137    }
122    private function emitBody(Stream $body): void
123    {
124        if ($body->isSeekable()) {
 
128        if (!$body->isReadable()) {
 
129            echo (string) $body;
130
131            return;
122    private function emitBody(Stream $body): void
123    {
124        if ($body->isSeekable()) {
 
128        if (!$body->isReadable()) {
 
134        while (!$body->eof()) {
 
134        while (!$body->eof()) {
 
137    }
122    private function emitBody(Stream $body): void
123    {
124        if ($body->isSeekable()) {
 
128        if (!$body->isReadable()) {
 
134        while (!$body->eof()) {
 
134        while (!$body->eof()) {
 
134        while (!$body->eof()) {
135            echo $body->read($this->maxBufferLength);
 
134        while (!$body->eof()) {
 
137    }
Sapi->emitBodyRange
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
149            echo substr($body->getContents(), $first, $length);
 
149            echo substr($body->getContents(), $first, $length);
 
149            echo substr($body->getContents(), $first, $length);
150
151            return;
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
149            echo substr($body->getContents(), $first, $length);
 
149            echo substr($body->getContents(), $first, $length);
 
149            echo substr($body->getContents(), $first, $length);
150
151            return;
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
163            echo $body->read($remaining);
164        }
165    }
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
163            echo $body->read($remaining);
164        }
165    }
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
163            echo $body->read($remaining);
164        }
165    }
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
163            echo $body->read($remaining);
164        }
165    }
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
163            echo $body->read($remaining);
164        }
165    }
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
163            echo $body->read($remaining);
164        }
165    }
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
163            echo $body->read($remaining);
164        }
165    }
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
163            echo $body->read($remaining);
164        }
165    }
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
144            $body->seek($first);
145            $first = 0;
146        }
147
148        if (!$body->isReadable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
149            echo substr($body->getContents(), $first, $length);
 
149            echo substr($body->getContents(), $first, $length);
 
149            echo substr($body->getContents(), $first, $length);
150
151            return;
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
149            echo substr($body->getContents(), $first, $length);
 
149            echo substr($body->getContents(), $first, $length);
 
149            echo substr($body->getContents(), $first, $length);
150
151            return;
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
163            echo $body->read($remaining);
164        }
165    }
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
163            echo $body->read($remaining);
164        }
165    }
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
163            echo $body->read($remaining);
164        }
165    }
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
163            echo $body->read($remaining);
164        }
165    }
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
163            echo $body->read($remaining);
164        }
165    }
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
163            echo $body->read($remaining);
164        }
165    }
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
163            echo $body->read($remaining);
164        }
165    }
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
163            echo $body->read($remaining);
164        }
165    }
 
165    }
139    private function emitBodyRange(Stream $body, int $first, int $last): void
140    {
141        $length = $last - $first + 1;
142
143        if ($body->isSeekable()) {
 
148        if (!$body->isReadable()) {
 
154        $remaining = $length;
155
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
157            $contents = $body->read($this->maxBufferLength);
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
156        while ($remaining >= $this->maxBufferLength && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
162        if ($remaining > 0 && !$body->eof()) {
 
165    }
Sapi->emitHeaders
64    private function emitHeaders(Response $response): void
65    {
66        $statusCode = $response->getStatusCode();
67
68        foreach ($response->getHeaders() as $name => $values) {
 
68        foreach ($response->getHeaders() as $name => $values) {
 
68        foreach ($response->getHeaders() as $name => $values) {
69            $name = ucwords((string) $name, '-');
70            $replace = $name !== 'Set-Cookie';
71
72            foreach ($values as $value) {
 
72            foreach ($values as $value) {
 
72            foreach ($values as $value) {
73                header("{$name}: {$value}", $replace, $statusCode);
 
72            foreach ($values as $value) {
 
68        foreach ($response->getHeaders() as $name => $values) {
69            $name = ucwords((string) $name, '-');
70            $replace = $name !== 'Set-Cookie';
71
72            foreach ($values as $value) {
 
68        foreach ($response->getHeaders() as $name => $values) {
 
68        foreach ($response->getHeaders() as $name => $values) {
69            $name = ucwords((string) $name, '-');
70            $replace = $name !== 'Set-Cookie';
71
72            foreach ($values as $value) {
73                header("{$name}: {$value}", $replace, $statusCode);
74                $replace = false;
75            }
76        }
77    }
64    private function emitHeaders(Response $response): void
65    {
66        $statusCode = $response->getStatusCode();
67
68        foreach ($response->getHeaders() as $name => $values) {
 
68        foreach ($response->getHeaders() as $name => $values) {
 
68        foreach ($response->getHeaders() as $name => $values) {
69            $name = ucwords((string) $name, '-');
70            $replace = $name !== 'Set-Cookie';
71
72            foreach ($values as $value) {
 
72            foreach ($values as $value) {
 
68        foreach ($response->getHeaders() as $name => $values) {
69            $name = ucwords((string) $name, '-');
70            $replace = $name !== 'Set-Cookie';
71
72            foreach ($values as $value) {
 
68        foreach ($response->getHeaders() as $name => $values) {
 
68        foreach ($response->getHeaders() as $name => $values) {
69            $name = ucwords((string) $name, '-');
70            $replace = $name !== 'Set-Cookie';
71
72            foreach ($values as $value) {
73                header("{$name}: {$value}", $replace, $statusCode);
74                $replace = false;
75            }
76        }
77    }
64    private function emitHeaders(Response $response): void
65    {
66        $statusCode = $response->getStatusCode();
67
68        foreach ($response->getHeaders() as $name => $values) {
 
68        foreach ($response->getHeaders() as $name => $values) {
 
68        foreach ($response->getHeaders() as $name => $values) {
69            $name = ucwords((string) $name, '-');
70            $replace = $name !== 'Set-Cookie';
71
72            foreach ($values as $value) {
 
68        foreach ($response->getHeaders() as $name => $values) {
69            $name = ucwords((string) $name, '-');
70            $replace = $name !== 'Set-Cookie';
71
72            foreach ($values as $value) {
 
68        foreach ($response->getHeaders() as $name => $values) {
 
68        foreach ($response->getHeaders() as $name => $values) {
69            $name = ucwords((string) $name, '-');
70            $replace = $name !== 'Set-Cookie';
71
72            foreach ($values as $value) {
73                header("{$name}: {$value}", $replace, $statusCode);
74                $replace = false;
75            }
76        }
77    }
64    private function emitHeaders(Response $response): void
65    {
66        $statusCode = $response->getStatusCode();
67
68        foreach ($response->getHeaders() as $name => $values) {
 
68        foreach ($response->getHeaders() as $name => $values) {
 
68        foreach ($response->getHeaders() as $name => $values) {
69            $name = ucwords((string) $name, '-');
70            $replace = $name !== 'Set-Cookie';
71
72            foreach ($values as $value) {
73                header("{$name}: {$value}", $replace, $statusCode);
74                $replace = false;
75            }
76        }
77    }
64    private function emitHeaders(Response $response): void
65    {
66        $statusCode = $response->getStatusCode();
67
68        foreach ($response->getHeaders() as $name => $values) {
 
68        foreach ($response->getHeaders() as $name => $values) {
69            $name = ucwords((string) $name, '-');
70            $replace = $name !== 'Set-Cookie';
71
72            foreach ($values as $value) {
73                header("{$name}: {$value}", $replace, $statusCode);
74                $replace = false;
75            }
76        }
77    }
Sapi->emitStatusLine
79    private function emitStatusLine(Response $response): void
80    {
81        $statusCode = $response->getStatusCode();
82        $reasonPhrase = $response->getReasonPhrase();
83
84        header(
85            sprintf(
86                'HTTP/%s %d%s',
87                $response->getProtocolVersion(),
88                $statusCode,
89                $reasonPhrase === '' ? '' : " {$reasonPhrase}",
 
89                $reasonPhrase === '' ? '' : " {$reasonPhrase}",
 
89                $reasonPhrase === '' ? '' : " {$reasonPhrase}",
90            ),
91            true,
92            $statusCode,
93        );
94    }
79    private function emitStatusLine(Response $response): void
80    {
81        $statusCode = $response->getStatusCode();
82        $reasonPhrase = $response->getReasonPhrase();
83
84        header(
85            sprintf(
86                'HTTP/%s %d%s',
87                $response->getProtocolVersion(),
88                $statusCode,
89                $reasonPhrase === '' ? '' : " {$reasonPhrase}",
 
89                $reasonPhrase === '' ? '' : " {$reasonPhrase}",
 
89                $reasonPhrase === '' ? '' : " {$reasonPhrase}",
90            ),
91            true,
92            $statusCode,
93        );
94    }
Sapi->isBodyless
99    private function isBodyless(int $statusCode): bool
100    {
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
 
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
 
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
 
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
 
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
102    }
99    private function isBodyless(int $statusCode): bool
100    {
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
 
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
 
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
 
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
102    }
99    private function isBodyless(int $statusCode): bool
100    {
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
 
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
 
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
 
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
102    }
99    private function isBodyless(int $statusCode): bool
100    {
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
 
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
 
101        return $statusCode < 200 || $statusCode === 204 || $statusCode === 304;
102    }