Browse Source

Fix GET requests with bodies being sent as POST

While infrequently used, GET requests with bodies are allowed and used
by applications like elasticsearch. Fix GET requests being sent as post.

Fixes #13406
Mark Story 6 years ago
parent
commit
e179b386dc
2 changed files with 40 additions and 0 deletions
  1. 4 0
      src/Http/Client/Adapter/Curl.php
  2. 36 0
      tests/TestCase/Http/Client/Adapter/CurlTest.php

+ 4 - 0
src/Http/Client/Adapter/Curl.php

@@ -96,6 +96,10 @@ class Curl implements AdapterInterface
         if ($body) {
             $body->rewind();
             $out[CURLOPT_POSTFIELDS] = $body->getContents();
+            // GET requests with bodies require custom request to be used.
+            if (isset($out[CURLOPT_HTTPGET])) {
+                $out[CURLOPT_CUSTOMREQUEST] = 'get';
+            }
         }
 
         if (empty($options['ssl_cafile'])) {

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

@@ -119,6 +119,42 @@ class CurlTest extends TestCase
      *
      * @return void
      */
+    public function testBuildOptionsGetWithBody()
+    {
+        $options = [
+            'timeout' => 5,
+        ];
+        $request = new Request(
+            'http://localhost/things',
+            'GET',
+            ['Cookie' => 'testing=value'],
+            '{"some":"body"}'
+        );
+        $result = $this->curl->buildOptions($request, $options);
+        $expected = [
+            CURLOPT_URL => 'http://localhost/things',
+            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
+            CURLOPT_RETURNTRANSFER => true,
+            CURLOPT_HEADER => true,
+            CURLOPT_HTTPHEADER => [
+                'Cookie: testing=value',
+                'Connection: close',
+                'User-Agent: CakePHP',
+            ],
+            CURLOPT_HTTPGET => true,
+            CURLOPT_POSTFIELDS => '{"some":"body"}',
+            CURLOPT_CUSTOMREQUEST => 'get',
+            CURLOPT_TIMEOUT => 5,
+            CURLOPT_CAINFO => $this->caFile,
+        ];
+        $this->assertSame($expected, $result);
+    }
+
+    /**
+     * Test converting client options into curl ones.
+     *
+     * @return void
+     */
     public function testBuildOptionsPost()
     {
         $options = [];