Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions library/Requests/Exception/InvalidArgument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

/**
* Exception for an invalid argument passed.
*
* @package Requests
*/
class Requests_Exception_InvalidArgument extends InvalidArgumentException {}
19 changes: 19 additions & 0 deletions library/Requests/Transport/cURL.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,25 @@ public function __destruct() {
* @return string Raw HTTP result
*/
public function request($url, $headers = array(), $data = array(), $options = array()) {
if (!is_array($data) && !is_string($data)) {
if ($data === null) {
$data = '';
} elseif (is_int($data) || is_float($data)) {
$data = (string) $data;
} else {
throw new Requests_Exception_InvalidArgument(
sprintf(
'%s: Argument #%d (%s) must be of type %s, %s given',
__METHOD__,
3,
'$data',
'array|string',
gettype($data)
)
);
}
}

$this->hooks = $options['hooks'];

$this->setup_handle($url, $headers, $data, $options);
Expand Down
19 changes: 19 additions & 0 deletions library/Requests/Transport/fsockopen.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,25 @@ class Requests_Transport_fsockopen implements Requests_Transport {
* @return string Raw HTTP result
*/
public function request($url, $headers = array(), $data = array(), $options = array()) {
if (!is_array($data) && !is_string($data)) {
if ($data === null) {
$data = '';
} elseif (is_int($data) || is_float($data)) {
$data = (string) $data;
} else {
throw new Requests_Exception_InvalidArgument(
sprintf(
'%s: Argument #%d (%s) must be of type %s, %s given',
__METHOD__,
3,
'$data',
'array|string',
gettype($data)
)
);
}
}

$options['hooks']->dispatch('fsockopen.before_request');

$url_parts = parse_url($url);
Expand Down
71 changes: 71 additions & 0 deletions tests/Transport/BaseTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Requests_Exception;
use Requests_Hooks;
use Requests_Response;
use stdClass;

abstract class BaseTestCase extends TestCase {
public function set_up() {
Expand Down Expand Up @@ -176,6 +177,76 @@ public function testEmptyPOST() {
}
}

/**
* Test that when a $data parameter of an incorrect type gets passed, it gets handled correctly.
*
* Only string/array are officially supported as accepted data types, but null, integers and floats
* will also be handled (cast to string).
*
* This test safeguards handling of data types in response to changes in PHP 8.1.
*
* @dataProvider dataIncorrectDataTypeAccepted
*
* @param mixed $data Input to be used as the $data parameter.
* @param string $expected Expected value for the Json decoded request body data key.
*
* @return void
*/
public function testIncorrectDataTypeAcceptedPOST($data, $expected) {
$request = Requests::post(httpbin('/post'), array(), $data, $this->getOptions());
$this->assertIsObject($request, 'POST request did not return an object');
$this->assertObjectHasAttribute('status_code', $request, 'POST request object does not have a "status_code" property');
$this->assertSame(200, $request->status_code, 'POST request status code is not 200');

$this->assertObjectHasAttribute('body', $request, 'POST request object does not have a "body" property');
$result = json_decode($request->body, true);

$this->assertIsArray($result, 'Json decoded POST request body is not an array');
$this->assertArrayHasKey('data', $result, 'Json decoded POST request body does not contain array key "data"');
$this->assertSame($expected, $result['data'], 'Json decoded POST request body "data" key did not match expected contents');
}

/**
* Data provider.
*
* @return array
*/
public function dataIncorrectDataTypeAccepted() {
return array(
'null' => array(null, ''),
'integer' => array(12345, '12345'),
'float' => array(12.345, '12.345'),
);
}

/**
* Test that when a $data parameter of an unhandled incorrect type gets passed, an exception gets thrown.
*
* @dataProvider dataIncorrectDataTypeException
*
* @param mixed $data Input to be used as the $data parameter.
*
* @return void
*/
public function testIncorrectDataTypeExceptionPOST($data) {
$this->expectException('Requests_Exception_InvalidArgument');
$this->expectExceptionMessage('Argument #3 ($data) must be of type array|string');

$request = Requests::post(httpbin('/post'), array(), $data, $this->getOptions());
}

/**
* Data provider.
*
* @return array
*/
public function dataIncorrectDataTypeException() {
return array(
'boolean' => array(true),
'object' => array(new stdClass()),
);
}

public function testFormPost() {
$data = 'test=true&test2=test';
$request = Requests::post(httpbin('/post'), array(), $data, $this->getOptions());
Expand Down