diff --git a/AbstractBrowser.php b/AbstractBrowser.php index b1f0a0a..325d915 100644 --- a/AbstractBrowser.php +++ b/AbstractBrowser.php @@ -161,6 +161,24 @@ public function xmlHttpRequest(string $method, string $uri, array $parameters = } } + /** + * Converts the request parameters into a JSON string and uses it as request content. + */ + public function jsonRequest(string $method, string $uri, array $parameters = [], array $server = [], bool $changeHistory = true): Crawler + { + $content = json_encode($parameters); + + $this->setServerParameter('CONTENT_TYPE', 'application/json'); + $this->setServerParameter('HTTP_ACCEPT', 'application/json'); + + try { + return $this->request($method, $uri, [], [], $server, $content, $changeHistory); + } finally { + unset($this->server['CONTENT_TYPE']); + unset($this->server['HTTP_ACCEPT']); + } + } + /** * Returns the History instance. * diff --git a/CHANGELOG.md b/CHANGELOG.md index 8506ad8..41301b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +5.3 +--- + + * Added `jsonRequest` method to `AbstractBrowser` + * Allowed sending a body with GET requests when a content-type is defined + 5.2.0 ----- @@ -19,7 +25,7 @@ CHANGELOG 4.2.0 ----- - * The method `Client::submit()` will have a new `$serverParameters` argument + * The method `Client::submit()` will have a new `$serverParameters` argument in version 5.0, not defining it is deprecated * Added ability to read the "samesite" attribute of cookies using `Cookie::getSameSite()` diff --git a/HttpBrowser.php b/HttpBrowser.php index 0ad87b5..eba038e 100644 --- a/HttpBrowser.php +++ b/HttpBrowser.php @@ -61,7 +61,7 @@ protected function doRequest($request): Response */ private function getBodyAndExtraHeaders(Request $request, array $headers): array { - if (\in_array($request->getMethod(), ['GET', 'HEAD'])) { + if (\in_array($request->getMethod(), ['GET', 'HEAD']) && !isset($headers['content-type'])) { return ['', []]; } diff --git a/Tests/AbstractBrowserTest.php b/Tests/AbstractBrowserTest.php index b71f545..c714a25 100644 --- a/Tests/AbstractBrowserTest.php +++ b/Tests/AbstractBrowserTest.php @@ -62,6 +62,17 @@ public function testXmlHttpRequest() $this->assertFalse($client->getServerParameter('HTTP_X_REQUESTED_WITH', false)); } + public function testJsonRequest() + { + $client = $this->getBrowser(); + $client->jsonRequest('GET', 'http://example.com/', ['param' => 1], [], true); + $this->assertSame('application/json', $client->getRequest()->getServer()['CONTENT_TYPE']); + $this->assertSame('application/json', $client->getRequest()->getServer()['HTTP_ACCEPT']); + $this->assertFalse($client->getServerParameter('CONTENT_TYPE', false)); + $this->assertFalse($client->getServerParameter('HTTP_ACCEPT', false)); + $this->assertSame('{"param":1}', $client->getRequest()->getContent()); + } + public function testGetRequestWithIpAsHttpHost() { $client = $this->getBrowser(); diff --git a/Tests/HttpBrowserTest.php b/Tests/HttpBrowserTest.php index 8125d1a..f41fccf 100644 --- a/Tests/HttpBrowserTest.php +++ b/Tests/HttpBrowserTest.php @@ -75,6 +75,14 @@ public function validContentTypes() ['PUT', 'http://example.com/', [], [], ['Content-Type' => 'application/json'], '["content"]'], ['PUT', 'http://example.com/', ['headers' => $defaultHeaders + ['content-type' => 'application/json'], 'body' => '["content"]', 'max_redirects' => 0]], ]; + yield 'GET JSON' => [ + ['GET', 'http://example.com/jsonrpc', [], [], ['CONTENT_TYPE' => 'application/json'], '["content"]'], + ['GET', 'http://example.com/jsonrpc', ['headers' => $defaultHeaders + ['content-type' => 'application/json'], 'body' => '["content"]', 'max_redirects' => 0]], + ]; + yield 'HEAD JSON' => [ + ['HEAD', 'http://example.com/jsonrpc', [], [], ['CONTENT_TYPE' => 'application/json'], '["content"]'], + ['HEAD', 'http://example.com/jsonrpc', ['headers' => $defaultHeaders + ['content-type' => 'application/json'], 'body' => '["content"]', 'max_redirects' => 0]], + ]; } public function testMultiPartRequestWithSingleFile()