Skip to content

Commit cca94bf

Browse files
committed
Merge pull request php-vcr#46 from php-vcr/guzzle-post-fix
Guzzle POST fix
2 parents 244f1f8 + c4c649c commit cca94bf

File tree

6 files changed

+143
-14
lines changed

6 files changed

+143
-14
lines changed

src/VCR/LibraryHooks/CurlHook.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ public static function curlGetinfo($curlHandle, $option = 0)
302302
*/
303303
public static function curlSetopt($curlHandle, $option, $value)
304304
{
305-
CurlHelper::setCurlOptionOnRequest(self::$requests[(int) $curlHandle], $option, $value);
305+
CurlHelper::setCurlOptionOnRequest(self::$requests[(int) $curlHandle], $option, $value, $curlHandle);
306306

307307
static::$curlOptions[(int) $curlHandle][$option] = $value;
308308

src/VCR/Util/CurlHelper.php

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,12 @@ function ($curlInfo) use (&$info, $response) {
114114
/**
115115
* Sets a cURL option on a Request.
116116
*
117-
* @param Request $request Request to set cURL option to.
118-
* @param integer $option cURL option to set.
119-
* @param mixed $value Value of the cURL option.
117+
* @param Request $request Request to set cURL option to.
118+
* @param integer $option cURL option to set.
119+
* @param mixed $value Value of the cURL option.
120+
* @param resource $curlHandle cURL handle where this option is set on (optional).
120121
*/
121-
public static function setCurlOptionOnRequest(Request $request, $option, $value)
122+
public static function setCurlOptionOnRequest(Request $request, $option, $value, $curlHandle = null)
122123
{
123124
switch ($option) {
124125
case CURLOPT_URL:
@@ -130,6 +131,9 @@ public static function setCurlOptionOnRequest(Request $request, $option, $value)
130131
case CURLOPT_MAXREDIRS:
131132
$request->getParams()->set('redirect.max', $value);
132133
break;
134+
case CURLOPT_CUSTOMREQUEST:
135+
$request->setMethod($value);
136+
break;
133137
case CURLOPT_POST:
134138
if ($value == true) {
135139
$request->setMethod('POST');
@@ -156,11 +160,17 @@ public static function setCurlOptionOnRequest(Request $request, $option, $value)
156160
case CURLOPT_HEADERFUNCTION:
157161
// Ignore writer and header functions
158162
break;
163+
case CURLOPT_READFUNCTION:
164+
// Guzzle provides a callback to let curl read the body string.
165+
// To get the body, this callback is called manually.
166+
$bodySize = $request->getCurlOptions()->get(CURLOPT_INFILESIZE);
167+
Assertion::notEmpty($bodySize, "To set a CURLOPT_READFUNCTION, CURLOPT_INFILESIZE must be set.");
168+
$body = call_user_func_array($value, array($curlHandle, fopen('php://memory', 'r'), $bodySize));
169+
$request->setBody($body);
170+
break;
159171
default:
160172
$request->getCurlOptions()->set($option, $value);
161173
break;
162174
}
163-
164175
}
165-
166176
}

tests/VCR/LibraryHooks/CurlHookTest.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,65 @@ function ($request) use ($testClass, &$callCount) {
262262
$this->assertFalse($afterLastInfo, 'Multi info called the last time should return false.');
263263
}
264264

265+
public function testShouldSetGuzzleCurlOptionsPost()
266+
{
267+
$url = 'http://example.com';
268+
$body = json_encode(array('key' => 'value'));
269+
$headers = array(
270+
'content-type' => 'application/json',
271+
'host' => 'example.com',
272+
'user-agent' => 'Guzzle/3.8.1 curl/7.30.0 PHP/5.4.16',
273+
'content-length' => strlen($body),
274+
);
275+
276+
$testClass = $this;
277+
$this->curlHook->enable(
278+
function ($request) use ($testClass, $url, $body, $headers) {
279+
$testClass->assertEquals('POST', $request->getMethod());
280+
$testClass->assertEquals($url, $request->getUrl());
281+
$testClass->assertEquals($body, $request->getBody());
282+
$testClass->assertEquals($headers, $request->getHeaders());
283+
284+
return new Response(200);
285+
}
286+
);
287+
288+
$client = new \Guzzle\Http\Client();
289+
$client->post($url, $headers, $body)->send();
290+
291+
$this->curlHook->disable();
292+
}
293+
294+
295+
public function testShouldSetGuzzleCurlOptionsPut()
296+
{
297+
$url = 'http://example.com';
298+
$body = json_encode(array('key' => 'value'));
299+
$headers = array(
300+
'content-type' => 'application/json',
301+
'host' => 'example.com',
302+
'user-agent' => 'Guzzle/3.8.1 curl/7.30.0 PHP/5.4.16',
303+
'content-length' => strlen($body),
304+
);
305+
306+
$testClass = $this;
307+
$this->curlHook->enable(
308+
function ($request) use ($testClass, $url, $body, $headers) {
309+
$testClass->assertEquals("PUT", $request->getMethod());
310+
$testClass->assertEquals($url, $request->getUrl());
311+
$testClass->assertEquals($body, $request->getBody());
312+
$testClass->assertEquals($headers, $request->getHeaders());
313+
314+
return new Response(200);
315+
}
316+
);
317+
318+
$client = new \Guzzle\Http\Client();
319+
$client->put($url, $headers, $body)->send();
320+
321+
$this->curlHook->disable();
322+
}
323+
265324
public function testShouldNotInterceptMultiCallWhenDisabled()
266325
{
267326
$testClass = $this;

tests/VCR/Util/CurlHelperTest.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,38 @@
66

77
class CurlHelperTest extends \PHPUnit_Framework_TestCase
88
{
9+
/**
10+
* @dataProvider getHttpMethodsProvider()
11+
*/
12+
public function testSetCurlOptionMethods($method)
13+
{
14+
$request = new Request($method, 'example.com');
15+
$headers = array('Host: example.com');
16+
17+
CurlHelper::setCurlOptionOnRequest($request, CURLOPT_HTTPHEADER, $headers);
18+
19+
$this->assertEquals($method, $request->getMethod());
20+
}
21+
22+
/**
23+
* Returns a list of HTTP methods for testing testSetCurlOptionMethods.
24+
*
25+
* @return array HTTP methods.
26+
*/
27+
public function getHttpMethodsProvider()
28+
{
29+
return array(
30+
array('CONNECT'),
31+
array('DELETE'),
32+
array('GET'),
33+
array('HEAD'),
34+
array('OPTIONS'),
35+
array('POST'),
36+
array('PUT'),
37+
array('TRACE'),
38+
);
39+
}
40+
941
public function testSetCurlOptionOnRequestSetSingleHeader()
1042
{
1143
$request = new Request('GET', 'example.com');
@@ -44,4 +76,34 @@ public function testSetCurlOptionOnRequestSetMultipleHeadersTwice()
4476
);
4577
$this->assertEquals($expected, $request->getHeaders());
4678
}
79+
80+
public function testSetCurlOptionReadFunctionMissingSize()
81+
{
82+
$this->setExpectedException('\VCR\VCRException', 'To set a CURLOPT_READFUNCTION, CURLOPT_INFILESIZE must be set.');
83+
$request = new Request('POST', 'example.com');
84+
85+
CurlHelper::setCurlOptionOnRequest($request, CURLOPT_READFUNCTION, null, curl_init());
86+
87+
$this->assertEquals($expected, $request->getBody());
88+
}
89+
90+
public function testSetCurlOptionReadFunction()
91+
{
92+
$expected = 'test body';
93+
$request = new Request('POST', 'example.com');
94+
95+
$test = $this;
96+
$callback = function ($curlHandle, $fileHandle, $size) use ($test, $expected) {
97+
$test->assertInternalType('resource', $curlHandle);
98+
$test->assertInternalType('resource', $fileHandle);
99+
$test->assertEquals(strlen($expected), $size);
100+
101+
return $expected;
102+
};
103+
104+
CurlHelper::setCurlOptionOnRequest($request, CURLOPT_INFILESIZE, strlen($expected));
105+
CurlHelper::setCurlOptionOnRequest($request, CURLOPT_READFUNCTION, $callback, curl_init());
106+
107+
$this->assertEquals($expected, $request->getBody());
108+
}
47109
}

tests/VCR/VCRTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function testShouldInterceptGuzzleLibrary()
3535
VCR::turnOn();
3636
VCR::insertCassette('unittest_guzzle_test');
3737
$client = new \Guzzle\Http\Client();
38-
$response = $client->get('http://example.com')->send();
38+
$response = $client->post('http://example.com')->send();
3939
$this->assertEquals('This is a guzzle test dummy.', (string) $response->getBody(), 'Guzzle call was not intercepted.');
4040
VCR::eject();
4141
VCR::turnOff();
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
21
-
32
request:
4-
method: GET
3+
method: POST
54
url: 'http://example.com'
65
headers:
76
host: example.com
@@ -13,12 +12,11 @@
1312
Accept-Ranges: bytes
1413
Cache-Control: max-age=604800
1514
Content-Type: text/html
16-
Date: 'Thu, 20 Feb 2014 16:41:24 GMT'
15+
Date: 'Wed, 26 Feb 2014 21:50:54 GMT'
1716
Etag: '"359670651"'
18-
Expires: 'Thu, 27 Feb 2014 16:41:24 GMT'
17+
Expires: 'Wed, 05 Mar 2014 21:50:54 GMT'
1918
Last-Modified: 'Fri, 09 Aug 2013 23:54:35 GMT'
20-
Server: 'ECS (iad/19AB)'
21-
X-Cache: HIT
19+
Server: 'EOS (lax004/45BF)'
2220
x-ec-custom-error: '1'
2321
Content-Length: '1270'
2422
body: "This is a guzzle test dummy."

0 commit comments

Comments
 (0)