Browse Source

Merge branch 'master' into 3.next

Mark Story 6 years ago
parent
commit
d02de91af8

+ 4 - 0
src/Http/Client.php

@@ -114,6 +114,7 @@ class Client
         'ssl_verify_depth' => 5,
         'ssl_verify_host' => true,
         'redirect' => false,
+        'protocolVersion' => '1.1',
     ];
 
     /**
@@ -156,6 +157,7 @@ class Client
      * - adapter - The adapter class name or instance. Defaults to
      *   \Cake\Http\Client\Adapter\Curl if `curl` extension is loaded else
      *   \Cake\Http\Client\Adapter\Stream.
+     * - protocolVersion - The HTTP protocol version to use. Defaults to 1.1
      *
      * @param array $config Config options for scoped clients.
      * @throws \InvalidArgumentException
@@ -518,6 +520,8 @@ class Client
         }
 
         $request = new Request($url, $method, $headers, $data);
+        $request = $request->withProtocolVersion($this->getConfig('protocolVersion'));
+
         $cookies = isset($options['cookies']) ? $options['cookies'] : [];
         /** @var \Cake\Http\Client\Request $request */
         $request = $this->_cookies->addToRequest($request, $cookies);

+ 5 - 1
src/Http/Client/Adapter/Curl.php

@@ -148,11 +148,15 @@ class Curl implements AdapterInterface
                 return CURL_HTTP_VERSION_1_0;
             case '1.1':
                 return CURL_HTTP_VERSION_1_1;
+            case '2':
             case '2.0':
+                if (defined('CURL_HTTP_VERSION_2TLS')) {
+                    return CURL_HTTP_VERSION_2TLS;
+                }
                 if (defined('CURL_HTTP_VERSION_2_0')) {
                     return CURL_HTTP_VERSION_2_0;
                 }
-                throw new HttpException('libcurl 7.33 needed for HTTP 2.0 support');
+                throw new HttpException('libcurl 7.33 or greater required for HTTP/2 support');
         }
 
         return CURL_HTTP_VERSION_NONE;

+ 16 - 0
tests/TestCase/Http/Client/Adapter/CurlTest.php

@@ -309,4 +309,20 @@ class CurlTest extends TestCase
         ];
         $this->assertSame($expected, $result);
     }
+
+    /**
+     * Test converting client options into curl ones.
+     *
+     * @return void
+     */
+    public function testBuildOptionsProtocolVersion()
+    {
+        $this->skipIf(!defined('CURL_HTTP_VERSION_2TLS'), 'Requires libcurl 7.42');
+        $options = [];
+        $request = new Request('http://localhost/things', 'GET');
+        $request = $request->withProtocolVersion('2');
+
+        $result = $this->curl->buildOptions($request, $options);
+        $this->assertSame(CURL_HTTP_VERSION_2TLS, $result[CURLOPT_HTTP_VERSION]);
+    }
 }

+ 4 - 2
tests/TestCase/Http/ClientTest.php

@@ -54,6 +54,7 @@ class ClientTest extends TestCase
             'scheme' => 'http',
             'host' => 'example.org',
             'auth' => ['username' => 'mark', 'password' => 'secret'],
+            'protocolVersion' => '1.1',
         ];
         foreach ($expected as $key => $val) {
             $this->assertEquals($val, $result[$key]);
@@ -209,9 +210,10 @@ class ClientTest extends TestCase
             ->getMock();
         $mock->expects($this->once())
             ->method('send')
-            ->with($this->callback(function ($request) use ($cookies, $headers) {
+            ->with($this->callback(function ($request) use ($headers) {
                 $this->assertInstanceOf('Cake\Http\Client\Request', $request);
                 $this->assertEquals(Request::METHOD_GET, $request->getMethod());
+                $this->assertSame('2', $request->getProtocolVersion());
                 $this->assertEquals('http://cakephp.org/test.html', $request->getUri() . '');
                 $this->assertEquals('split=value', $request->getHeaderLine('Cookie'));
                 $this->assertEquals($headers['Content-Type'], $request->getHeaderLine('content-type'));
@@ -221,7 +223,7 @@ class ClientTest extends TestCase
             }))
             ->will($this->returnValue([$response]));
 
-        $http = new Client(['adapter' => $mock]);
+        $http = new Client(['adapter' => $mock, 'protocolVersion' => '2']);
         $result = $http->get('http://cakephp.org/test.html', [], [
             'headers' => $headers,
             'cookies' => $cookies,