|
1 | 1 | <?php
|
2 | 2 | /**
|
3 | 3 | * @see https://github.com/zendframework/zend-http for the canonical source repository
|
4 |
| - * @copyright Copyright (c) 2005-2017 Zend Technologies USA Inc. (http://www.zend.com) |
| 4 | + * @copyright Copyright (c) 2005-2018 Zend Technologies USA Inc. (http://www.zend.com) |
5 | 5 | * @license https://github.com/zendframework/zend-http/blob/master/LICENSE.md New BSD License
|
6 | 6 | */
|
7 | 7 |
|
@@ -179,6 +179,67 @@ public function testChunkedResponseCaseInsensitiveZF5438()
|
179 | 179 | $this->assertEquals('c0cc9d44790fa2a58078059bab1902a9', md5($res->getContent()));
|
180 | 180 | }
|
181 | 181 |
|
| 182 | + /** |
| 183 | + * @param int $chunksize the data size of the chunk to create |
| 184 | + * @return string a chunk of data for embedding inside a chunked response |
| 185 | + */ |
| 186 | + private function makeChunk($chunksize) |
| 187 | + { |
| 188 | + return sprintf("%d\r\n%s\r\n", $chunksize, str_repeat('W', $chunksize)); |
| 189 | + } |
| 190 | + |
| 191 | + /** |
| 192 | + * @param Response $response |
| 193 | + * @return float the time that calling the getBody function took on the response |
| 194 | + */ |
| 195 | + private function getTimeForGetBody(Response $response) |
| 196 | + { |
| 197 | + $timeStart = microtime(true); |
| 198 | + $response->getBody(); |
| 199 | + return microtime(true) - $timeStart; |
| 200 | + } |
| 201 | + |
| 202 | + /** |
| 203 | + * @small |
| 204 | + */ |
| 205 | + public function testChunkedResponsePerformance() |
| 206 | + { |
| 207 | + $headers = new Headers(); |
| 208 | + $headers->addHeaders([ |
| 209 | + 'Date' => 'Sun, 25 Jun 2006 19:55:19 GMT', |
| 210 | + 'Server' => 'Apache', |
| 211 | + 'X-powered-by' => 'PHP/5.1.4-pl3-gentoo', |
| 212 | + 'Connection' => 'close', |
| 213 | + 'Transfer-encoding' => 'chunked', |
| 214 | + 'Content-type' => 'text/html', |
| 215 | + ]); |
| 216 | + |
| 217 | + $response = new Response(); |
| 218 | + $response->setHeaders($headers); |
| 219 | + |
| 220 | + // avoid flakiness, repeat test |
| 221 | + $timings = []; |
| 222 | + for ($i = 0; $i < 4; $i++) { |
| 223 | + // get baseline for timing: 2000 x 1 Byte chunks |
| 224 | + $responseData = str_repeat($this->makeChunk(1), 2000); |
| 225 | + $response->setContent($responseData); |
| 226 | + $time1 = $this->getTimeForGetBody($response); |
| 227 | + |
| 228 | + // 'worst case' response, where 2000 1 Byte chunks are followed by a 10 MB Chunk |
| 229 | + $responseData2 = $responseData . $this->makeChunk(10000000); |
| 230 | + $response->setContent($responseData2); |
| 231 | + $time2 = $this->getTimeForGetBody($response); |
| 232 | + |
| 233 | + $timings[] = floor($time2 / $time1); |
| 234 | + } |
| 235 | + |
| 236 | + array_shift($timings); // do not measure first iteration |
| 237 | + |
| 238 | + // make sure that the worst case packet will have an equal timing as the baseline |
| 239 | + $errMsg = 'Chunked response is not parsing large packets efficiently! Timings:'; |
| 240 | + $this->assertLessThan(20, min($timings), $errMsg . print_r($timings, true)); |
| 241 | + } |
| 242 | + |
182 | 243 | public function testLineBreaksCompatibility()
|
183 | 244 | {
|
184 | 245 | $responseTestLf = $this->readResponse('response_lfonly');
|
|
0 commit comments