From 57313e8b8d16721d2c602a89996f40425ddcb97c Mon Sep 17 00:00:00 2001 From: Andreas Lutro Date: Tue, 30 Oct 2018 17:58:16 +0100 Subject: [PATCH 1/7] add allowsData method --- src/Request.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Request.php b/src/Request.php index fc4967f..018d478 100644 --- a/src/Request.php +++ b/src/Request.php @@ -120,7 +120,7 @@ public function setMethod($method) throw new \InvalidArgumentException("Method [$method] not a valid HTTP method."); } - if ($this->data && !static::$methods[$method]) { + if ($this->data && !$this->allowsData()) { throw new \LogicException('Request has POST data, but tried changing HTTP method to one that does not allow POST data'); } @@ -314,6 +314,16 @@ public function formatHeaders() return $headers; } + /** + * Detemine if a request allows data to be set. + * + * @return bool + */ + public function allowsData() + { + return static::$methods[$this->method]; + } + /** * Set the POST data to be sent with the request. * @@ -321,7 +331,7 @@ public function formatHeaders() */ public function setData($data) { - if ($data && !static::$methods[$this->method]) { + if (!$this->allowsData()) { throw new \InvalidArgumentException("HTTP method [$this->method] does not allow POST data."); } From 5b3bb481d7833edae3941a71107fb656f3414825 Mon Sep 17 00:00:00 2001 From: Andreas Lutro Date: Tue, 30 Oct 2018 17:59:19 +0100 Subject: [PATCH 2/7] add getEncodedData method which caches encoded data --- src/Request.php | 26 ++++++++++++++++++++++++++ src/cURL.php | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/Request.php b/src/Request.php index 018d478..836e38b 100644 --- a/src/Request.php +++ b/src/Request.php @@ -99,6 +99,13 @@ class Request */ private $encoding = Request::ENCODING_QUERY; + /** + * Cache of encoded data. + * + * @var string|null + */ + private $encodedData = null; + /** * @param cURL $curl */ @@ -336,6 +343,7 @@ public function setData($data) } $this->data = $data; + $this->encodedData = null; return $this; } @@ -382,6 +390,7 @@ public function setEncoding($encoding) } $this->encoding = $encoding; + $this->encodedData = null; return $this; } @@ -403,6 +412,10 @@ public function getEncoding() */ public function encodeData() { + if ($this->data === null) { + return ''; + } + switch ($this->encoding) { case static::ENCODING_JSON: return json_encode($this->data); @@ -415,6 +428,19 @@ public function encodeData() } } + /** + * Get the encoded POST data as a string. + * + * @return string + */ + public function getEncodedData() + { + if ($this->encodedData === null) { + $this->encodedData = $this->encodeData(); + } + return $this->encodedData; + } + /** * Set a specific curl option for the request. * diff --git a/src/cURL.php b/src/cURL.php index ae72c41..d089f5a 100644 --- a/src/cURL.php +++ b/src/cURL.php @@ -264,7 +264,7 @@ public function prepareRequest(Request $request) curl_setopt($this->ch, CURLOPT_HTTPHEADER, $request->formatHeaders()); if ($request->hasData()) { - curl_setopt($this->ch, CURLOPT_POSTFIELDS, $request->encodeData()); + curl_setopt($this->ch, CURLOPT_POSTFIELDS, $request->getEncodedData()); } if ($method === 'head') { From b28b17b59d65295dee3e0530a7e2820a5af2b227 Mon Sep 17 00:00:00 2001 From: Andreas Lutro Date: Tue, 30 Oct 2018 17:59:44 +0100 Subject: [PATCH 3/7] check encoded data instead of raw data --- src/Request.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Request.php b/src/Request.php index 836e38b..30c21a5 100644 --- a/src/Request.php +++ b/src/Request.php @@ -355,7 +355,7 @@ public function setData($data) */ public function hasData() { - return (bool) $this->data; + return (bool) $this->getEncodedData(); } /** From 60c556331e5e1b6928a1545fca19501406ac6742 Mon Sep 17 00:00:00 2001 From: Andreas Lutro Date: Tue, 30 Oct 2018 17:59:52 +0100 Subject: [PATCH 4/7] add json encoding tests --- tests/unit/RequestTest.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/unit/RequestTest.php b/tests/unit/RequestTest.php index b477e0e..f6bfcbd 100644 --- a/tests/unit/RequestTest.php +++ b/tests/unit/RequestTest.php @@ -50,6 +50,20 @@ public function encodeData() $this->assertEquals('ArbitraryValue', $r->encodeData()); } + /** @test */ + public function encodeJsonData() + { + $r = $this->makeRequest(); + $r->setMethod('post'); + $r->setEncoding(Request::ENCODING_JSON); + + $r->setData([]); + $this->assertEquals('[]', $r->encodeData()); + + $r->setData(new \stdClass); + $this->assertEquals('{}', $r->encodeData()); + } + /** @test */ public function formatHeaders() { From 2b8e3c5074d5a6dd7edd890947c52aaafe84656e Mon Sep 17 00:00:00 2001 From: Andreas Lutro Date: Tue, 30 Oct 2018 18:02:41 +0100 Subject: [PATCH 5/7] add tests for changing encoding or data --- tests/unit/RequestTest.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/unit/RequestTest.php b/tests/unit/RequestTest.php index f6bfcbd..95aee91 100644 --- a/tests/unit/RequestTest.php +++ b/tests/unit/RequestTest.php @@ -64,6 +64,36 @@ public function encodeJsonData() $this->assertEquals('{}', $r->encodeData()); } + /** @test */ + public function changeDataUpdatesEncodedData() + { + $r = $this->makeRequest(); + $r->setMethod('post'); + $r->setEncoding(Request::ENCODING_JSON); + + $r->setData(['foo' => 'bar']); + $data1 = $r->getEncodedData(); + $r->setData(['bar' => 'qux']); + $data2 = $r->getEncodedData(); + + $this->assertNotEquals($data1, $data2); + } + + /** @test */ + public function changeEncodingUpdatesEncodedData() + { + $r = $this->makeRequest(); + $r->setMethod('post'); + $r->setData(['foo' => 'bar']); + + $r->setEncoding(Request::ENCODING_JSON); + $jsonData = $r->getEncodedData(); + $r->setEncoding(Request::ENCODING_QUERY); + $queryData = $r->getEncodedData(); + + $this->assertNotEquals($jsonData, $queryData); + } + /** @test */ public function formatHeaders() { From 3a022001d796e6d8970d3cc22e87221846622181 Mon Sep 17 00:00:00 2001 From: Andreas Lutro Date: Tue, 30 Oct 2018 18:58:45 +0100 Subject: [PATCH 6/7] only set data when explicitly passed --- src/cURL.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cURL.php b/src/cURL.php index d089f5a..98f0a62 100644 --- a/src/cURL.php +++ b/src/cURL.php @@ -185,7 +185,7 @@ public function buildUrl($url, array $query) * * @return Request */ - public function newRequest($method, $url, $data = array(), $encoding = Request::ENCODING_QUERY) + public function newRequest($method, $url, $data = null, $encoding = Request::ENCODING_QUERY) { $class = $this->requestClass; $request = new $class($this); @@ -198,9 +198,12 @@ public function newRequest($method, $url, $data = array(), $encoding = Request:: } $request->setMethod($method); $request->setUrl($url); - $request->setData($data); $request->setEncoding($encoding); + if ($data !== null) { + $request->setData($data); + } + return $request; } From 6bffb3442c5ceadad65944e0321878613ed4e6bd Mon Sep 17 00:00:00 2001 From: Andreas Lutro Date: Tue, 30 Oct 2018 19:04:47 +0100 Subject: [PATCH 7/7] re-instate data check in setData --- src/Request.php | 2 +- src/cURL.php | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Request.php b/src/Request.php index 30c21a5..f9db93c 100644 --- a/src/Request.php +++ b/src/Request.php @@ -338,7 +338,7 @@ public function allowsData() */ public function setData($data) { - if (!$this->allowsData()) { + if ($data !== null && !$this->allowsData()) { throw new \InvalidArgumentException("HTTP method [$this->method] does not allow POST data."); } diff --git a/src/cURL.php b/src/cURL.php index 98f0a62..24c0b7e 100644 --- a/src/cURL.php +++ b/src/cURL.php @@ -198,12 +198,9 @@ public function newRequest($method, $url, $data = null, $encoding = Request::ENC } $request->setMethod($method); $request->setUrl($url); + $request->setData($data); $request->setEncoding($encoding); - if ($data !== null) { - $request->setData($data); - } - return $request; }