diff --git a/src/Twilio/Http/CurlClient.php b/src/Twilio/Http/CurlClient.php index 95f1d50525..b849dd5805 100644 --- a/src/Twilio/Http/CurlClient.php +++ b/src/Twilio/Http/CurlClient.php @@ -131,18 +131,18 @@ public function options(string $method, string $url, break; case 'put': - // TODO: PUT doesn't used anywhere and it has strange implementation. Must investigate later - $options[CURLOPT_PUT] = true; - if ($data) { - if ($buffer = \fopen('php://memory', 'w+')) { - $dataString = $this->buildQuery($data); - \fwrite($buffer, $dataString); - \fseek($buffer, 0); - $options[CURLOPT_INFILE] = $buffer; - $options[CURLOPT_INFILESIZE] = \strlen($dataString); - } else { - throw new EnvironmentException('Unable to open a temporary file'); - } + $options[CURLOPT_CUSTOMREQUEST] = 'PUT'; + if ($this->hasFile($data)) { + [$headers, $body] = $this->buildMultipartOptions($data); + $options[CURLOPT_POSTFIELDS] = $body; + $options[CURLOPT_HTTPHEADER] = \array_merge($options[CURLOPT_HTTPHEADER], $headers); + } + elseif (array_key_exists('Content-Type', $headers)) { + $options[CURLOPT_POSTFIELDS] = json_encode($data); + } + else { + $options[CURLOPT_POSTFIELDS] = $this->buildQuery($data); + $options[CURLOPT_HTTPHEADER][] = 'Content-Type: application/x-www-form-urlencoded'; } break; case 'head': diff --git a/src/Twilio/Http/GuzzleClient.php b/src/Twilio/Http/GuzzleClient.php index a57a8b138c..8b88b09f8c 100644 --- a/src/Twilio/Http/GuzzleClient.php +++ b/src/Twilio/Http/GuzzleClient.php @@ -35,7 +35,7 @@ public function request(string $method, string $url, $options['query'] = Query::build($params, PHP_QUERY_RFC1738); } - if ($method === 'POST') { + if ($method === 'POST' || $method === 'PUT') { if ($this->hasFile($data)) { $options['multipart'] = $this->buildMultipartParam($data); } else { diff --git a/tests/Twilio/Unit/Http/CurlClientTest.php b/tests/Twilio/Unit/Http/CurlClientTest.php index 48361f9973..df4205d329 100644 --- a/tests/Twilio/Unit/Http/CurlClientTest.php +++ b/tests/Twilio/Unit/Http/CurlClientTest.php @@ -248,12 +248,26 @@ public function postFieldsProvider(): array { ]; } - public function testPutFile(): void { + /** + * @param array|string $params Parameters to put + * @param array|string $data Data to put + * @param string $expectedContentType Excpected Content-Type header + * @param string $expectedBody Expected POSTFIELDS + * @dataProvider postFieldsProvider + * @throws \Twilio\Exceptions\EnvironmentException + */ + public function testPutFile($params, $data, string $expectedContentType, string $expectedBody): void { $client = new CurlClient(); - $actual = $client->options('PUT', 'url', [], ['a' => 1, 'b' => 2]); - $this->assertNotNull($actual[CURLOPT_INFILE]); - $this->assertEquals('a=1&b=2', \fread($actual[CURLOPT_INFILE], $actual[CURLOPT_INFILESIZE])); - $this->assertEquals(7, $actual[CURLOPT_INFILESIZE]); + $actual = $client->options('PUT', 'url', $params, $data); + + foreach ($actual[CURLOPT_HTTPHEADER] as $header) { + if (strpos($header, 'Content-Type: ') === 0) { + $this->assertStringMatchesFormat($expectedContentType, substr($header, 14)); + break; + } + } + + $this->assertStringMatchesFormat($expectedBody, $actual[CURLOPT_POSTFIELDS]); } /**