diff --git a/docs/usage.md b/docs/usage.md index 63c65f87d..9e41aa2a6 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -102,6 +102,23 @@ on the internal execution path, so it's recommended to set this explicitly if you need to. +Make a QUERY Request +-------------------- +The [`QUERY`][rfc10008] method (RFC 10008) is like `GET`, but sends its data in +the request body instead of the URL query string. This lets you send large or +complex queries while keeping the safe and idempotent semantics of `GET`: + +```php +$data = array('key1' => 'value1', 'key2' => 'value2'); +$response = \WpOrg\Requests\Requests::query('https://httpbin.org/anything', array(), $data); +``` + +As with `POST`, you can pass a string instead of an array to send raw data, and +you'll probably want to set the `Content-Type` header to match. + +[rfc10008]: https://tools.ietf.org/html/rfc10008 + + Status Codes ------------ The Response object also gives you access to the status code: diff --git a/src/Requests.php b/src/Requests.php index 9d29c9958..50ac300ac 100644 --- a/src/Requests.php +++ b/src/Requests.php @@ -97,6 +97,14 @@ class Requests { */ const PATCH = 'PATCH'; + /** + * QUERY method + * + * @link https://tools.ietf.org/html/rfc10008 + * @var string + */ + const QUERY = 'QUERY'; + /** * Default size of buffer size to read streams * @@ -365,6 +373,18 @@ public static function options($url, $headers = [], $data = [], $options = []) { public static function patch($url, $headers, $data = [], $options = []) { return self::request($url, $headers, $data, self::PATCH, $options); } + + /** + * Send a QUERY request + * + * Note: Unlike {@see \WpOrg\Requests\Requests::get()}, the `$data` is sent in the + * request body (like POST), not appended to the URL as a query string. + * + * @link https://tools.ietf.org/html/rfc10008 + */ + public static function query($url, $headers = [], $data = [], $options = []) { + return self::request($url, $headers, $data, self::QUERY, $options); + } /**#@-*/ /** @@ -416,7 +436,7 @@ public static function patch($url, $headers, $data = [], $options = []) { * (bool, default: true) * - `data_format`: How should we send the `$data` parameter? * (string, one of 'query' or 'body', default: 'query' for - * HEAD/GET/DELETE, 'body' for POST/PUT/OPTIONS/PATCH) + * HEAD/GET/DELETE, 'body' for POST/PUT/OPTIONS/PATCH/QUERY) * * @param string|\Stringable $url URL to request * @param array $headers Extra headers to send with the request diff --git a/tests/Transport/BaseTestCase.php b/tests/Transport/BaseTestCase.php index 03bb657cb..385da810f 100644 --- a/tests/Transport/BaseTestCase.php +++ b/tests/Transport/BaseTestCase.php @@ -570,6 +570,23 @@ public function testLOCKWithData() { $this->assertSame(['test' => 'true', 'test2' => 'test'], $result['form']); } + public function testQUERY() { + $request = Requests::query($this->httpbin('/query'), [], [], $this->getOptions()); + $this->assertSame(200, $request->status_code); + } + + public function testQUERYWithData() { + $data = [ + 'test' => 'true', + 'test2' => 'test', + ]; + $request = Requests::query($this->httpbin('/query'), [], $data, $this->getOptions()); + $this->assertSame(200, $request->status_code); + + $result = json_decode($request->body, true); + $this->assertSame(['test' => 'true', 'test2' => 'test'], $result['form']); + } + public function testRedirects() { $request = Requests::get($this->httpbin('/redirect/6'), [], $this->getOptions()); $this->assertSame(200, $request->status_code);