Browse Source

Default the content type on string bodies.

If no content-type was set, and the payload is a string we have to
assume that it is form encoded data. This solves a warning that the
stream API was emitting and makes Http\Client easier to use in general.

Refs #6540
Mark Story 11 years ago
parent
commit
2d9867fb67
2 changed files with 38 additions and 1 deletions
  1. 5 1
      src/Network/Http/Client.php
  2. 33 0
      tests/TestCase/Network/Http/ClientTest.php

+ 5 - 1
src/Network/Http/Client.php

@@ -419,12 +419,16 @@ class Client
         $request->method($method)
             ->url($url)
             ->body($data);
+
         if (isset($options['type'])) {
             $request->header($this->_typeHeaders($options['type']));
         }
         if (isset($options['headers'])) {
             $request->header($options['headers']);
         }
+        if (is_string($data) && !$request->header('content-type')) {
+            $request->header('Content-Type', 'application/x-www-form-urlencoded');
+        }
         $request->cookie($this->_cookies->get($url));
         if (isset($options['cookies'])) {
             $request->cookie($options['cookies']);
@@ -459,7 +463,7 @@ class Client
             'xml' => 'application/xml',
         ];
         if (!isset($typeMap[$type])) {
-            throw new Exception('Unknown type alias.');
+            throw new Exception("Unknown type alias '$type'.");
         }
         return [
             'Accept' => $typeMap[$type],

+ 33 - 0
tests/TestCase/Network/Http/ClientTest.php

@@ -431,6 +431,39 @@ class ClientTest extends TestCase
     }
 
     /**
+     * Test that string payloads with no content type have a default content-type set.
+     *
+     * @return void
+     */
+    public function testPostWithStringDataDefaultsToFormEncoding()
+    {
+        $response = new Response();
+        $data = 'some=value&more=data';
+        $headers = [
+            'Connection' => 'close',
+            'User-Agent' => 'CakePHP',
+            'Content-Type' => 'application/x-www-form-urlencoded',
+        ];
+
+        $mock = $this->getMock('Cake\Network\Http\Adapter\Stream', ['send']);
+        $mock->expects($this->any())
+            ->method('send')
+            ->with($this->logicalAnd(
+                $this->attributeEqualTo('_body', $data),
+                $this->attributeEqualTo('_headers', $headers)
+            ))
+            ->will($this->returnValue([$response]));
+
+        $http = new Client([
+            'host' => 'cakephp.org',
+            'adapter' => $mock
+        ]);
+        $http->post('/projects/add', $data);
+        $http->put('/projects/add', $data);
+        $http->delete('/projects/add', $data);
+    }
+
+    /**
      * Test that exceptions are raised on invalid types.
      *
      * @expectedException \Cake\Core\Exception\Exception