Skip to content
This repository was archived by the owner on Jan 30, 2020. It is now read-only.

Commit 34286df

Browse files
committed
Merge branch 'feature/173-http2' into develop
Close #173 Fixes #172
2 parents e6963dd + a7dcedf commit 34286df

File tree

7 files changed

+75
-18
lines changed

7 files changed

+75
-18
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ All notable changes to this project will be documented in this file, in reverse
2828

2929
### Added
3030

31-
- Nothing.
31+
- [#173](https://github.com/zendframework/zend-http/pull/173) adds support for HTTP/2 requests and responses.
3232

3333
### Changed
3434

docs/book/client/intro.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ Parameter | Description
7777
`strictredirects` | Whether to strictly follow the RFC when redirecting (see this section) | boolean | FALSE
7878
`useragent` | User agent identifier string (sent in request headers) | string | `Zend\Http\Client`
7979
`timeout` | Connection timeout (seconds) | integer | 10
80-
`httpversion` | HTTP protocol version (usually '1.1' or '1.0') | string | 1.1
80+
`httpversion` | HTTP protocol version (usually '1.1', '1.0' or '2'; 2 is only supported starting in 2.10.0) | string | 1.1
8181
`adapter` | Connection adapter class to use (see this section) | mixed | `Zend\Http\Client\Adapter\Socket`
8282
`keepalive` | Whether to enable keep-alive connections with the server. Useful and might improve performance if several consecutive requests to the same server are performed. | boolean | FALSE
8383
`storeresponse` | Whether to store last response for later retrieval with getLastResponse(). If set to FALSE, getLastResponse() will return NULL. | boolean | TRUE

docs/book/request.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ Method signature | De
7575
`setUri(string|Uri $uri) : self` | Set the URI/URL for this request; this can be a string or an instance of `Zend\Uri\Http`.
7676
`getUri() : Uri` | Return the URI for this request object.
7777
`getUriString() : string` | Return the URI for this request object as a string.
78-
`setVersion(string $version) : self` | Set the HTTP version for this object, one of 1.0 or 1.1 (`Request::VERSION_10`, `Request::VERSION_11`).
78+
`setVersion(string $version) : self` | Set the HTTP version for this object, one of 1.0, 1.1 or 2 (`Request::VERSION_10`, `Request::VERSION_11`, `Request::VERSION_2`). HTTP/2 support was added in zend-http 2.10.0.
7979
`getVersion() : string` | Return the HTTP version for this request.
8080
`setQuery(Parameters $query) : self` | Provide an alternate Parameter Container implementation for query parameters in this object. (This is NOT the primary API for value setting; for that, see `getQuery()`).
8181
`getQuery(string|null $name, mixed|null $default) : null|string|Parameters` | Return the parameter container responsible for query parameters or a single query parameter based on `$name`.

docs/book/response.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ Method signature | Descrip
7777
`renderStatusLine() : string` | Render the status line header
7878
`setHeaders(Headers $headers) : self` | Provide an alternate Parameter Container implementation for headers in this object. (This is NOT the primary API for value setting; for that, see `getHeaders()`.)
7979
`getHeaders() : Headers` | Return the container responsible for storing HTTP headers. This container exposes the primary API for manipulating headers set in the HTTP response. See the section on [Headers](headers.md) for more information.
80-
`setVersion(string $version) : self` | Set the HTTP version for this object, one of 1.0 or 1.1 (`Request::VERSION_10`, `Request::VERSION_11`).
81-
`getVersion() : string` | Return the HTTP version for this request.
80+
`setVersion(string $version) : self` | Set the HTTP version for this object, one of 1.0, 1.1 or 2 (`Response::VERSION_10`, `Response::VERSION_11`, `Response::VERSION_2`). HTTP/2 support was added in zend-http 2.10.0.
81+
`getVersion() : string` | Return the HTTP version for this response.
8282
`setStatusCode(int $code) : self` | Set HTTP status code.
8383
`getStatusCode() : int` | Retrieve HTTP status code.
8484
`setReasonPhrase(string $reasonPhrase) : self` | Set custom HTTP status message.

src/AbstractMessage.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ abstract class AbstractMessage extends Message
2121
*/
2222
const VERSION_10 = '1.0';
2323
const VERSION_11 = '1.1';
24+
const VERSION_2 = '2';
2425
/**#@-*/
2526

2627
/**
@@ -34,16 +35,16 @@ abstract class AbstractMessage extends Message
3435
protected $headers;
3536

3637
/**
37-
* Set the HTTP version for this object, one of 1.0 or 1.1
38-
* (AbstractMessage::VERSION_10, AbstractMessage::VERSION_11)
38+
* Set the HTTP version for this object, one of 1.0, 1.1 or 2
39+
* (AbstractMessage::VERSION_10, AbstractMessage::VERSION_11, AbstractMessage::VERSION_2)
3940
*
40-
* @param string $version (Must be 1.0 or 1.1)
41+
* @param string $version (Must be 1.0, 1.1 or 2)
4142
* @return AbstractMessage
4243
* @throws Exception\InvalidArgumentException
4344
*/
4445
public function setVersion($version)
4546
{
46-
if ($version != self::VERSION_10 && $version != self::VERSION_11) {
47+
if (! in_array($version, [self::VERSION_10, self::VERSION_11, self::VERSION_2])) {
4748
throw new Exception\InvalidArgumentException(
4849
'Not valid or not supported HTTP version: ' . $version
4950
);

src/Response.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ public static function fromString($string)
249249
*/
250250
protected function parseStatusLine($line)
251251
{
252-
$regex = '/^HTTP\/(?P<version>1\.[01]) (?P<status>\d{3})(?:[ ]+(?P<reason>.*))?$/';
252+
$regex = '/^HTTP\/(?P<version>1\.[01]|2) (?P<status>\d{3})(?:[ ]+(?P<reason>.*))?$/';
253253
$matches = [];
254254
if (! preg_match($regex, $line, $matches)) {
255255
throw new Exception\InvalidArgumentException(

test/ResponseTest.php

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,79 @@
1616

1717
class ResponseTest extends TestCase
1818
{
19-
public function testResponseFactoryFromStringCreatesValidResponse()
19+
public function validHttpVersions()
2020
{
21-
$string = 'HTTP/1.0 200 OK' . "\r\n\r\n" . 'Foo Bar';
21+
yield 'http/1.0' => ['1.0'];
22+
yield 'http/1.1' => ['1.1'];
23+
yield 'http/2' => ['2'];
24+
}
25+
26+
public function validResponseHttpVersionProvider()
27+
{
28+
$responseTemplate = "HTTP/%s 200 OK\r\n\r\nFoo Bar";
29+
foreach ($this->validHttpVersions() as $testCase => $data) {
30+
$version = array_shift($data);
31+
yield $testCase => [
32+
'response' => sprintf($responseTemplate, $version),
33+
'expectedVersion' => $version,
34+
'expectedStatus' => '200',
35+
'expectedContent' => 'Foo Bar',
36+
];
37+
}
38+
}
39+
40+
/**
41+
* @dataProvider validResponseHttpVersionProvider
42+
* @param string $string Response string
43+
* @param string $expectedVersion
44+
* @param string $expectedStatus
45+
* @param string $expectedContent
46+
*/
47+
public function testResponseFactoryFromStringCreatesValidResponse(
48+
$string,
49+
$expectedVersion,
50+
$expectedStatus,
51+
$expectedContent
52+
) {
2253
$response = Response::fromString($string);
23-
$this->assertEquals(200, $response->getStatusCode());
24-
$this->assertEquals('Foo Bar', $response->getContent());
54+
$this->assertEquals($expectedVersion, $response->getVersion());
55+
$this->assertEquals($expectedStatus, $response->getStatusCode());
56+
$this->assertEquals($expectedContent, $response->getContent());
2557
}
2658

27-
public function testResponseCanRenderStatusLine()
59+
/**
60+
* @dataProvider validHttpVersions
61+
* @param string $version
62+
*/
63+
public function testResponseCanRenderStatusLineUsingDefaultReasonPhrase($version)
2864
{
65+
$expected = sprintf('HTTP/%s 404 Not Found', $version);
2966
$response = new Response();
30-
$response->setVersion(1.1);
67+
$response->setVersion($version);
3168
$response->setStatusCode(Response::STATUS_CODE_404);
32-
$this->assertEquals('HTTP/1.1 404 Not Found', $response->renderStatusLine());
69+
$this->assertEquals($expected, $response->renderStatusLine());
70+
}
3371

72+
/**
73+
* @dataProvider validHttpVersions
74+
* @param string $version
75+
*/
76+
public function testResponseCanRenderStatusLineUsingCustomReasonPhrase($version)
77+
{
78+
$expected = sprintf('HTTP/%s 404 Foo Bar', $version);
79+
$response = new Response();
80+
$response->setVersion($version);
81+
$response->setStatusCode(Response::STATUS_CODE_404);
3482
$response->setReasonPhrase('Foo Bar');
35-
$this->assertEquals('HTTP/1.1 404 Foo Bar', $response->renderStatusLine());
83+
$this->assertEquals($expected, $response->renderStatusLine());
84+
}
85+
86+
public function testInvalidHTTP2VersionString()
87+
{
88+
$this->expectException(InvalidArgumentException::class);
89+
$this->expectExceptionMessage('A valid response status line was not found in the provided string');
90+
$string = 'HTTP/2.0 200 OK' . "\r\n\r\n" . 'Foo Bar';
91+
$response = \Zend\Http\Response::fromString($string);
3692
}
3793

3894
public function testResponseUsesHeadersContainerByDefault()

0 commit comments

Comments
 (0)