22 Commits

Author SHA1 Message Date
Ahmad Nassri
53656bf519 Merge pull request #105 from voodoodrul/patch-2
Don't use CURLOPT_CUSTOMREQUEST for POSTs
2016-04-29 19:54:44 -04:00
Ahmad Nassri
889ca14f5f Merge pull request #106 from Lozzano/master
Fixing current version in README.
2016-04-25 10:03:29 -04:00
André Valentin
45274fd536 Fixing current version in README.
The current version wasn't showed as the one people should add in their composer files. Updated from 2.* to 3.*.
2016-04-25 15:02:42 +02:00
Jesse Skrivseth
a3446f6d99 Update Request.php
Remove curl_setopt(self::$handle, CURLOPT_POSTREDIR, 3);  in favor of the caller being well-behaved and setting this option as needed
2016-04-19 23:05:11 -06:00
Jesse Skrivseth
e9ea4dbee2 Don't use CURLOPT_CUSTOMREQUEST for POSTs
I think the current usage of CURLOPT_CUSTOMREQUEST is wrong. As far as I can tell CURLOPT_CUSTOMREQUEST = Method::POST is not the same thing as CURLOPT_POST = true. 

I struggled for hours with POSTed data not being accepted by IIS. First IIS threw an HTTP 411 due to curl not sending a Content-Length header. That is solved by replacing CURLOPT_CUSTOMREQUEST with CURLOPT_POST in the case of actual POSTs. Also, IIS in my case returns an HTTP 301 redirect, which I need Unirest to follow, so I set the CURLOPT_POSTREDIR = 3 in order to let the POST follow on redirect via 301 or 302. 

Notice this: https://curl.haxx.se/libcurl/c/CURLOPT_CUSTOMREQUEST.html - "Many people have wrongly used this option to replace the entire request with their own, including multiple headers and POST contents. While that might work in many cases, it will cause libcurl to send invalid requests and it could possibly confuse the remote server badly. Use CURLOPT_POST and CURLOPT_POSTFIELDS to set POST data. Use CURLOPT_HTTPHEADER to replace or extend the set of headers sent by libcurl. Use CURLOPT_HTTP_VERSION to change HTTP version."

In any case, I know that the CURLOPT_POSTREDIR option probably shouldn't go here and should be client configurable, but I can't find a good place for it. It would be nice to have one-shot $curlOpts passed in with the send method, or curlOpts() that otherwise live for only one curl_exec().
2016-04-19 22:49:27 -06:00
Colin Hutchinson
d71cd15d4a Merge pull request #102 from xcopy/master
Typofix
2016-04-14 08:33:01 -04:00
Kairat Jenishev
2d0cd4c8d9 Typofix 2016-04-14 17:01:32 +06:00
Ahmad Nassri
c01f685e3b Merge pull request #98 from RusinovIG/master
Issue with priority of headers
2016-03-23 00:18:08 -04:00
Igor Rusinov
28080c975c Fixedissue with priority of headers 2016-03-20 20:53:52 +03:00
Ahmad Nassri
2bedcf05ac docs(readme): fix content-types in labels [ci skip] 2016-02-24 23:27:05 -05:00
Ahmad Nassri
b6328f270f chore(travis): fix namespacing issues 2016-02-24 23:23:54 -05:00
Ahmad Nassri
1e86cc751f chore(travis): move to container mode in travis 2016-02-24 23:13:33 -05:00
Ahmad Nassri
825cee7dc7 chore(travis): fix namespacing issues 2016-02-24 23:12:45 -05:00
Ahmad Nassri
eb470e929c chore(travis): test on all current PHP versions 2016-02-24 23:02:39 -05:00
Ahmad Nassri
d23cdc5593 refactor(request): request body management is now externalized to helper methods 2016-02-24 23:01:21 -05:00
Ahmad Nassri
0f3a22d63e feat(json): json pecl extension may be available all the time 2016-02-24 22:07:25 -05:00
Ahmad Nassri
f7f13bd940 Merge pull request #91 from Furgas/fix-curlfile
Fix creating CURLFile
2016-02-16 14:25:22 -05:00
Tomasz Sawicki
d950a88257 Fix creating CURLFile 2016-02-16 19:54:45 +01:00
Ahmad Nassri
73c2d90323 Merge pull request #90 from Furgas/fix-phpdoc
Fix PHPDoc
2016-02-16 11:45:52 -05:00
Tomasz Sawicki
d0fc831a00 Fix PHPDoc 2016-02-16 10:49:00 +01:00
Ahmad Nassri
4a480b156b Merge pull request #89 from RusinovIG/master
Fixed setting of default headers array
2016-01-20 14:41:35 -05:00
Igor Rusinov
ca6a3b1daf Fixed setting of default headers array 2016-01-18 23:24:14 +03:00
15 changed files with 470 additions and 162 deletions

4
.gitignore vendored
View File

@@ -1,5 +1,7 @@
.DS_Store .DS_Store
.idea
build build
vendor
composer.lock composer.lock
composer.phar composer.phar
coverage
vendor

View File

@@ -1,9 +1,12 @@
sudo: false
language: php language: php
php: php:
- 5.4 - '5.4'
- 5.5 - '5.5'
- 5.6 - '5.6'
- '7.0'
- hhvm - hhvm
before_script: before_script:

115
README.md
View File

@@ -37,7 +37,7 @@ To install unirest-php with Composer, just add the following to your `composer.j
```json ```json
{ {
"require-dev": { "require-dev": {
"mashape/unirest-php": "2.*" "mashape/unirest-php": "3.*"
} }
} }
``` ```
@@ -83,10 +83,10 @@ require_once '/path/to/unirest-php/src/Unirest.php';
So you're probably wondering how using Unirest makes creating requests in PHP easier, let's look at a working example: So you're probably wondering how using Unirest makes creating requests in PHP easier, let's look at a working example:
```php ```php
$headers = array("Accept" => "application/json"); $headers = array('Accept' => 'application/json');
$body = array("foo" => "hellow", "bar" => "world"); $query = array('foo' => 'hello', 'bar' => 'world');
$response = Unirest\Request::post("http://mockbin.com/request", $headers, $body); $response = Unirest\Request::post('http://mockbin.com/request', $headers, $query);
$response->code; // HTTP Status code $response->code; // HTTP Status code
$response->headers; // Headers $response->headers; // Headers
@@ -94,25 +94,98 @@ $response->body; // Parsed body
$response->raw_body; // Unparsed body $response->raw_body; // Unparsed body
``` ```
### File Uploads ### JSON Requests *(`application/json`)*
To upload files in a multipart form representation use the return value of `Unirest\File::add($path)` as the value of a parameter: A JSON Request can be constructed using the `Unirest\Request\Body::Json` helper:
```php ```php
$headers = array("Accept" => "application/json"); $headers = array('Accept' => 'application/json');
$body = array("file" => Unirest\File::add("/tmp/file.txt")); $data = array('name' => 'ahmad', 'company' => 'mashape');
$response = Unirest\Request::post("http://mockbin.com/request", $headers, $body); $body = Unirest\Request\Body::json($data);
$response = Unirest\Request::post('http://mockbin.com/request', $headers, $body);
``` ```
### Custom Entity Body **Notes:**
- `Content-Type` headers will be automatically set to `application/json`
- the data variable will be processed through [`json_encode`](http://php.net/manual/en/function.json-encode.php) with default values for arguments.
- an error will be thrown if the [JSON Extension](http://php.net/manual/en/book.json.php) is not available.
### Form Requests *(`application/x-www-form-urlencoded`)*
A typical Form Request can be constructed using the `Unirest\Request\Body::Form` helper:
Sending a custom body such as a JSON Object rather than a string or form style parameters we utilize json_encode for the body:
```php ```php
$headers = array("Accept" => "application/json"); $headers = array('Accept' => 'application/json');
$body = json_encode(array("foo" => "hellow", "bar" => "world")); $data = array('name' => 'ahmad', 'company' => 'mashape');
$response = Unirest\Request::post("http://mockbin.com/request", $headers, $body); $body = Unirest\Request\Body::form($data);
$response = Unirest\Request::post('http://mockbin.com/request', $headers, $body);
```
**Notes:**
- `Content-Type` headers will be automatically set to `application/x-www-form-urlencoded`
- the final data array will be processed through [`http_build_query`](http://php.net/manual/en/function.http-build-query.php) with default values for arguments.
### Multipart Requests *(`multipart/form-data`)*
A Multipart Request can be constructed using the `Unirest\Request\Body::Multipart` helper:
```php
$headers = array('Accept' => 'application/json');
$data = array('name' => 'ahmad', 'company' => 'mashape');
$body = Unirest\Request\Body::multipart($data);
$response = Unirest\Request::post('http://mockbin.com/request', $headers, $body);
```
**Notes:**
- `Content-Type` headers will be automatically set to `multipart/form-data`.
- an auto-generated `--boundary` will be set.
### Multipart File Upload
simply add an array of files as the second argument to to the `Multipart` helper:
```php
$headers = array('Accept' => 'application/json');
$data = array('name' => 'ahmad', 'company' => 'mashape');
$files = array('bio' => '/path/to/bio.txt', 'avatar' => '/path/to/avatar.jpg');
$body = Unirest\Request\Body::multipart($data, $files);
$response = Unirest\Request::post('http://mockbin.com/request', $headers, $body);
```
If you wish to further customize the properties of files uploaded you can do so with the `Unirest\Request\Body::File` helper:
```php
$headers = array('Accept' => 'application/json');
$body = array(
'name' => 'ahmad',
'company' => 'mashape'
'bio' => Unirest\Request\Body::file('/path/to/bio.txt', 'text/plain'),
'avatar' => Unirest\Request\Body::file('/path/to/my_avatar.jpg', 'text/plain', 'avatar.jpg')
);
$response = Unirest\Request::post('http://mockbin.com/request', $headers, $body);
```
**Note**: we did not use the `Unirest\Request\Body::multipart` helper in this example, it is not needed when manually adding files.
### Custom Body
Sending a custom body such rather than using the `Unirest\Request\Body` helpers is also possible, for example, using a [`serialize`](http://php.net/manual/en/function.serialize.php) body string with a custom `Content-Type`:
```php
$headers = array('Accept' => 'application/json', 'Content-Type' => 'application/x-php-serialized');
$body = serialize((array('foo' => 'hello', 'bar' => 'world'));
$response = Unirest\Request::post('http://mockbin.com/request', $headers, $body);
``` ```
### Authentication ### Authentication
@@ -156,7 +229,7 @@ Unirest\Request::proxyAuth('username', 'password', CURLAUTH_DIGEST);
Previous versions of **Unirest** support *Basic Authentication* by providing the `username` and `password` arguments: Previous versions of **Unirest** support *Basic Authentication* by providing the `username` and `password` arguments:
```php ```php
$response = Unirest\Request::get("http://mockbin.com/request", null, null, "username", "password"); $response = Unirest\Request::get('http://mockbin.com/request', null, null, 'username', 'password');
``` ```
**This has been deprecated, and will be completely removed in `v.3.0.0` please use the `Unirest\Request::auth()` method instead** **This has been deprecated, and will be completely removed in `v.3.0.0` please use the `Unirest\Request::auth()` method instead**
@@ -275,16 +348,16 @@ Unirest\Request::proxyAuth('username', 'password', CURLAUTH_DIGEST);
You can set default headers that will be sent on every request: You can set default headers that will be sent on every request:
```php ```php
Unirest\Request::defaultHeader("Header1", "Value1"); Unirest\Request::defaultHeader('Header1', 'Value1');
Unirest\Request::defaultHeader("Header2", "Value2"); Unirest\Request::defaultHeader('Header2', 'Value2');
``` ```
You can set default headers in bulk by passing an array: You can set default headers in bulk by passing an array:
```php ```php
Unirest\Request::defaultHeaders(array( Unirest\Request::defaultHeaders(array(
"Header1" => "Value1", 'Header1' => 'Value1',
"Header2" => "Value2" 'Header2' => 'Value2'
)); ));
``` ```
@@ -299,14 +372,14 @@ Unirest\Request::clearDefaultHeaders();
You can set default [cURL options](http://php.net/manual/en/function.curl-setopt.php) that will be sent on every request: You can set default [cURL options](http://php.net/manual/en/function.curl-setopt.php) that will be sent on every request:
```php ```php
Unirest\Request::curlOpt(CURLOPT_COOKIE, "foo=bar"); Unirest\Request::curlOpt(CURLOPT_COOKIE, 'foo=bar');
``` ```
You can set options bulk by passing an array: You can set options bulk by passing an array:
```php ```php
Unirest\Request::curlOpts(array( Unirest\Request::curlOpts(array(
CURLOPT_COOKIE => "foo=bar" CURLOPT_COOKIE => 'foo=bar'
)); ));
``` ```

View File

@@ -8,8 +8,10 @@
"author": "Mashape <opensource@mashape.com> (https://www.mashape.com)", "author": "Mashape <opensource@mashape.com> (https://www.mashape.com)",
"require": { "require": {
"php": ">=5.4.0", "php": ">=5.4.0",
"ext-curl": "*", "ext-curl": "*"
"ext-json": "*" },
"suggest": {
"ext-json": "Allows using JSON Bodies for sending and parsing requests"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "~4.4", "phpunit/phpunit": "~4.4",

View File

@@ -1,6 +1,7 @@
<?php <?php
require_once dirname(__FILE__) . '/Unirest/File.php'; require_once dirname(__FILE__) . '/Unirest/Exception.php';
require_once dirname(__FILE__) . '/Unirest/Method.php'; require_once dirname(__FILE__) . '/Unirest/Method.php';
require_once dirname(__FILE__) . '/Unirest/Response.php'; require_once dirname(__FILE__) . '/Unirest/Response.php';
require_once dirname(__FILE__) . '/Unirest/Request.php'; require_once dirname(__FILE__) . '/Unirest/Request.php';
require_once dirname(__FILE__) . '/Unirest/Request/Body.php';

View File

@@ -0,0 +1,5 @@
<?php
namespace Unirest;
class Exception extends \Exception {}

View File

@@ -1,19 +0,0 @@
<?php
namespace Unirest;
class File
{
/**
* Prepares a file for upload. To be used inside the parameters declaration for a request.
* @param string $path The file path
*/
public static function add($filename, $mimetype = '', $postname = '')
{
if (function_exists('curl_file_create')) {
return curl_file_create($filename, $mimetype = '', $postname = '');
} else {
return sprintf('@%s;filename=%s;type=%s', $filename, $postname ?: basename($filename), $mimetype);
}
}
}

View File

@@ -2,8 +2,9 @@
namespace Unirest; namespace Unirest;
use Unirest\Method; use Unirest\Method as Method;
use Unirest\Response; use Unirest\Response as Response;
use Unirest\Exception as Exception;
class Request class Request
{ {
@@ -39,8 +40,9 @@ class Request
* Set JSON decode mode * Set JSON decode mode
* *
* @param bool $assoc When TRUE, returned objects will be converted into associative arrays. * @param bool $assoc When TRUE, returned objects will be converted into associative arrays.
* @param bool $depth User specified recursion depth. * @param integer $depth User specified recursion depth.
* @param bool $options Bitmask of JSON decode options. Currently only JSON_BIGINT_AS_STRING is supported (default is to cast large integers as floats) * @param integer $options Bitmask of JSON decode options. Currently only JSON_BIGINT_AS_STRING is supported (default is to cast large integers as floats)
* @return array
*/ */
public static function jsonOpts($assoc = false, $depth = 512, $options = 0) public static function jsonOpts($assoc = false, $depth = 512, $options = 0)
{ {
@@ -51,6 +53,7 @@ class Request
* Verify SSL peer * Verify SSL peer
* *
* @param bool $enabled enable SSL verification, by default is true * @param bool $enabled enable SSL verification, by default is true
* @return bool
*/ */
public static function verifyPeer($enabled) public static function verifyPeer($enabled)
{ {
@@ -61,6 +64,7 @@ class Request
* Verify SSL host * Verify SSL host
* *
* @param bool $enabled enable SSL host verification, by default is true * @param bool $enabled enable SSL host verification, by default is true
* @return bool
*/ */
public static function verifyHost($enabled) public static function verifyHost($enabled)
{ {
@@ -71,6 +75,7 @@ class Request
* Set a timeout * Set a timeout
* *
* @param integer $seconds timeout value in seconds * @param integer $seconds timeout value in seconds
* @return integer
*/ */
public static function timeout($seconds) public static function timeout($seconds)
{ {
@@ -84,7 +89,7 @@ class Request
*/ */
public static function defaultHeaders($headers) public static function defaultHeaders($headers)
{ {
return array_merge(self::$defaultHeaders, $headers); return self::$defaultHeaders = array_merge(self::$defaultHeaders, $headers);
} }
/** /**
@@ -92,6 +97,7 @@ class Request
* *
* @param string $name header name * @param string $name header name
* @param string $value header value * @param string $value header value
* @return string
*/ */
public static function defaultHeader($name, $value) public static function defaultHeader($name, $value)
{ {
@@ -122,6 +128,7 @@ class Request
* *
* @param string $name header name * @param string $name header name
* @param string $value header value * @param string $value header value
* @return string
*/ */
public static function curlOpt($name, $value) public static function curlOpt($name, $value)
{ {
@@ -144,6 +151,7 @@ class Request
* Be aware of which key you are using and do not share your Production key. * Be aware of which key you are using and do not share your Production key.
* *
* @param string $key Mashape key * @param string $key Mashape key
* @return string
*/ */
public static function setMashapeKey($key) public static function setMashapeKey($key)
{ {
@@ -151,7 +159,7 @@ class Request
} }
/** /**
* Set a coockie string for enabling coockie handling * Set a cookie string for enabling cookie handling
* *
* @param string $cookie * @param string $cookie
*/ */
@@ -161,7 +169,7 @@ class Request
} }
/** /**
* Set a coockie file path for enabling coockie handling * Set a cookie file path for enabling cookie handling
* *
* $cookieFile must be a correct path with write permission * $cookieFile must be a correct path with write permission
* *
@@ -177,7 +185,7 @@ class Request
* *
* @param string $username authentication username * @param string $username authentication username
* @param string $password authentication password * @param string $password authentication password
* @param string $method authentication method * @param integer $method authentication method
*/ */
public static function auth($username = '', $password = '', $method = CURLAUTH_BASIC) public static function auth($username = '', $password = '', $method = CURLAUTH_BASIC)
{ {
@@ -190,9 +198,9 @@ class Request
* Set proxy to use * Set proxy to use
* *
* @param string $address proxy address * @param string $address proxy address
* @param string $port proxy port * @param integer $port proxy port
* @param string $port proxy type (Available options for this are CURLPROXY_HTTP, CURLPROXY_HTTP_1_0 CURLPROXY_SOCKS4, CURLPROXY_SOCKS5, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5_HOSTNAME) * @param integer $type (Available options for this are CURLPROXY_HTTP, CURLPROXY_HTTP_1_0 CURLPROXY_SOCKS4, CURLPROXY_SOCKS5, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5_HOSTNAME)
* @param string $tunnel enable/disable tunneling * @param bool $tunnel enable/disable tunneling
*/ */
public static function proxy($address, $port = 1080, $type = CURLPROXY_HTTP, $tunnel = false) public static function proxy($address, $port = 1080, $type = CURLPROXY_HTTP, $tunnel = false)
{ {
@@ -207,8 +215,7 @@ class Request
* *
* @param string $username authentication username * @param string $username authentication username
* @param string $password authentication password * @param string $password authentication password
* @param string $method authentication method * @param integer $method authentication method
* @param string $tunnel enable/disable tunneling
*/ */
public static function proxyAuth($username = '', $password = '', $method = CURLAUTH_BASIC) public static function proxyAuth($username = '', $password = '', $method = CURLAUTH_BASIC)
{ {
@@ -347,6 +354,9 @@ class Request
/** /**
* This function is useful for serializing multidimensional arrays, and avoid getting * This function is useful for serializing multidimensional arrays, and avoid getting
* the 'Array to string conversion' notice * the 'Array to string conversion' notice
* @param array|object $data array to flatten.
* @param bool|string $parent parent key or false if no parent
* @return array
*/ */
public static function buildHTTPCurlQuery($data, $parent = false) public static function buildHTTPCurlQuery($data, $parent = false)
{ {
@@ -375,13 +385,13 @@ class Request
/** /**
* Send a cURL request * Send a cURL request
* @param Unirest\Method $method HTTP method to use * @param Unirest\Method|string $method HTTP method to use
* @param string $url URL to send the request to * @param string $url URL to send the request to
* @param mixed $body request body * @param mixed $body request body
* @param array $headers additional headers to send * @param array $headers additional headers to send
* @param string $username Authentication username (deprecated) * @param string $username Authentication username (deprecated)
* @param string $password Authentication password (deprecated) * @param string $password Authentication password (deprecated)
* @throws Exception if a cURL error occurs * @throws Unirest\Exception if a cURL error occurs
* @return Unirest\Response * @return Unirest\Response
*/ */
public static function send($method, $url, $body = null, $headers = array(), $username = null, $password = null) public static function send($method, $url, $body = null, $headers = array(), $username = null, $password = null)
@@ -389,13 +399,13 @@ class Request
self::$handle = curl_init(); self::$handle = curl_init();
if ($method !== Method::GET) { if ($method !== Method::GET) {
curl_setopt(self::$handle, CURLOPT_CUSTOMREQUEST, $method); if ($method === Method::POST) {
curl_setopt(self::$handle, CURLOPT_POST, true);
if (is_array($body) || $body instanceof \Traversable) {
curl_setopt(self::$handle, CURLOPT_POSTFIELDS, self::buildHTTPCurlQuery($body));
} else { } else {
curl_setopt(self::$handle, CURLOPT_POSTFIELDS, $body); curl_setopt(self::$handle, CURLOPT_CUSTOMREQUEST, $method);
} }
curl_setopt(self::$handle, CURLOPT_POSTFIELDS, $body);
} elseif (is_array($body)) { } elseif (is_array($body)) {
if (strpos($url, '?') !== false) { if (strpos($url, '?') !== false) {
$url .= '&'; $url .= '&';
@@ -466,7 +476,7 @@ class Request
$info = self::getInfo(); $info = self::getInfo();
if ($error) { if ($error) {
throw new \Exception($error); throw new Exception($error);
} }
// Split the full response in its headers and body // Split the full response in its headers and body
@@ -498,7 +508,7 @@ class Request
{ {
$formattedHeaders = array(); $formattedHeaders = array();
$combinedHeaders = array_change_key_case(array_merge((array) $headers, self::$defaultHeaders)); $combinedHeaders = array_change_key_case(array_merge(self::$defaultHeaders, (array) $headers));
foreach ($combinedHeaders as $key => $val) { foreach ($combinedHeaders as $key => $val) {
$formattedHeaders[] = self::getHeaderString($key, $val); $formattedHeaders[] = self::getHeaderString($key, $val);

View File

@@ -0,0 +1,66 @@
<?php
namespace Unirest\Request;
use Unirest\Request as Request;
use Unirest\Exception as Exception;
class Body
{
/**
* Prepares a file for upload. To be used inside the parameters declaration for a request.
* @param string $filename The file path
* @param string $mimetype MIME type
* @param string $postname the file name
* @return string|\CURLFile
*/
public static function File($filename, $mimetype = '', $postname = '')
{
if (class_exists('CURLFile')) {
return new \CURLFile($filename, $mimetype, $postname);
}
if (function_exists('curl_file_create')) {
return curl_file_create($filename, $mimetype, $postname);
}
return sprintf('@%s;filename=%s;type=%s', $filename, $postname ?: basename($filename), $mimetype);
}
public static function Json($data)
{
if (!function_exists('json_encode')) {
throw new Exception('JSON Extension not available');
}
return json_encode($data);
}
public static function Form($data)
{
if (is_array($data) || is_object($data) || $data instanceof \Traversable) {
return http_build_query(Request::buildHTTPCurlQuery($data));
}
return $data;
}
public static function Multipart($data, $files = false)
{
if (is_object($data)) {
return get_object_vars($data);
}
if (!is_array($data)) {
return array($data);
}
if ($files !== false) {
foreach ($files as $name => $file) {
$data[$name] = call_user_func(array(__CLASS__, 'File'), $file);
}
}
return $data;
}
}

View File

@@ -25,18 +25,22 @@ class Response
// make sure raw_body is the first argument // make sure raw_body is the first argument
array_unshift($json_args, $raw_body); array_unshift($json_args, $raw_body);
if (function_exists('json_decode')) {
$json = call_user_func_array('json_decode', $json_args); $json = call_user_func_array('json_decode', $json_args);
if (json_last_error() === JSON_ERROR_NONE) { if (json_last_error() === JSON_ERROR_NONE) {
$this->body = $json; $this->body = $json;
} }
} }
}
/** /**
* if PECL_HTTP is not available use a fall back function * if PECL_HTTP is not available use a fall back function
* *
* thanks to ricardovermeltfoort@gmail.com * thanks to ricardovermeltfoort@gmail.com
* http://php.net/manual/en/function.http-parse-headers.php#112986 * http://php.net/manual/en/function.http-parse-headers.php#112986
* @param string $raw_headers raw headers
* @return array
*/ */
private function parseHeaders($raw_headers) private function parseHeaders($raw_headers)
{ {

View File

@@ -0,0 +1,89 @@
<?php
namespace Unirest\Request\Body\Test;
use Unirest\Request as Request;
use Unirest\Request\Body as Body;
require_once __DIR__ . '/../../src/Unirest.php';
class BodyTest extends \PHPUnit_Framework_TestCase
{
public function testCURLFile()
{
$fixture = __DIR__ . '/fixtures/upload.txt';
$file = Body::File($fixture);
if (PHP_MAJOR_VERSION === 5 && PHP_MINOR_VERSION === 4) {
$this->assertEquals($file, sprintf('@%s;filename=%s;type=', $fixture, basename($fixture)));
} else {
$this->assertTrue($file instanceof \CURLFile);
}
}
public function testHttpBuildQueryWithCurlFile()
{
$fixture = __DIR__ . '/fixtures/upload.txt';
$file = Body::File($fixture);
$body = array(
'to' => 'mail@mailinator.com',
'from' => 'mail@mailinator.com',
'file' => $file
);
$result = Request::buildHTTPCurlQuery($body);
$this->assertEquals($result['file'], $file);
}
public function testJson()
{
$body = Body::Json(array('foo', 'bar'));
$this->assertEquals($body, '["foo","bar"]');
}
public function testForm()
{
$body = Body::Form(array('foo' => 'bar', 'bar' => 'baz'));
$this->assertEquals($body, 'foo=bar&bar=baz');
// try again with a string
$body = Body::Form($body);
$this->assertEquals($body, 'foo=bar&bar=baz');
}
public function testMultipart()
{
$arr = array('foo' => 'bar', 'bar' => 'baz');
$body = Body::Multipart((object) $arr);
$this->assertEquals($body, $arr);
$body = Body::Multipart('flat');
$this->assertEquals($body, array('flat'));
}
public function testMultipartFiles()
{
$fixture = __DIR__ . '/fixtures/upload.txt';
$data = array('foo' => 'bar', 'bar' => 'baz');
$files = array('test' => $fixture);
$body = Body::Multipart($data, $files);
// echo $body;
$this->assertEquals($body, array(
'foo' => 'bar',
'bar' => 'baz',
'test' => Body::File($fixture)
));
}
}

View File

@@ -1,17 +0,0 @@
<?php
use Unirest\File as File;
class UnirestFileTest extends \PHPUnit_Framework_TestCase
{
public function testCURLFile()
{
$file = File::add(UPLOAD_FIXTURE);
if (PHP_MAJOR_VERSION === 5 && PHP_MINOR_VERSION === 4) {
$this->assertEquals($file, sprintf('@%s;filename=%s;type=', UPLOAD_FIXTURE, basename(UPLOAD_FIXTURE)));
} else {
$this->assertTrue($file instanceof \CURLFile);
}
}
}

View File

@@ -1,57 +1,81 @@
<?php <?php
namespace Unirest\Request\Test;
use Unirest\Request as Request;
require __DIR__ . '/../../src/Unirest.php';
class UnirestRequestTest extends \PHPUnit_Framework_TestCase class UnirestRequestTest extends \PHPUnit_Framework_TestCase
{ {
// Generic // Generic
public function testHttpBuildQueryWhenCurlFile()
{
$file = Unirest\File::add(UPLOAD_FIXTURE);
$body = array(
'to' => 'mail@mailinator.com',
'from' => 'mail@mailinator.com',
'file' => $file
);
$result = Unirest\Request::buildHTTPCurlQuery($body);
$this->assertEquals($result['file'], $file);
}
public function testCurlOpts() public function testCurlOpts()
{ {
Unirest\Request::curlOpt(CURLOPT_COOKIE, 'foo=bar'); Request::curlOpt(CURLOPT_COOKIE, 'foo=bar');
$response = Unirest\Request::get('http://mockbin.com/request'); $response = Request::get('http://mockbin.com/request');
$this->assertTrue(property_exists($response->body->cookies, 'foo')); $this->assertTrue(property_exists($response->body->cookies, 'foo'));
Unirest\Request::clearCurlOpts(); Request::clearCurlOpts();
} }
/** /**
* @expectedException Exception * @expectedException \Unirest\Exception
*/ */
public function testTimeoutFail() public function testTimeoutFail()
{ {
Unirest\Request::timeout(1); Request::timeout(1);
Unirest\Request::get('http://mockbin.com/delay/1000'); Request::get('http://mockbin.com/delay/1000');
Unirest\Request::timeout(null); // Cleaning timeout for the other tests Request::timeout(null); // Cleaning timeout for the other tests
}
public function testDefaultHeaders()
{
$defaultHeaders = array(
'header1' => 'Hello',
'header2' => 'world'
);
Request::defaultHeaders($defaultHeaders);
$response = Request::get('http://mockbin.com/request');
$this->assertEquals(200, $response->code);
$this->assertObjectHasAttribute('header1', $response->body->headers);
$this->assertEquals('Hello', $response->body->headers->header1);
$this->assertObjectHasAttribute('header2', $response->body->headers);
$this->assertEquals('world', $response->body->headers->header2);
$response = Request::get('http://mockbin.com/request', ['header1' => 'Custom value']);
$this->assertEquals(200, $response->code);
$this->assertObjectHasAttribute('header1', $response->body->headers);
$this->assertEquals('Custom value', $response->body->headers->header1);
Request::clearDefaultHeaders();
$response = Request::get('http://mockbin.com/request');
$this->assertEquals(200, $response->code);
$this->assertObjectNotHasAttribute('header1', $response->body->headers);
$this->assertObjectNotHasAttribute('header2', $response->body->headers);
} }
public function testDefaultHeader() public function testDefaultHeader()
{ {
Unirest\Request::defaultHeader('Hello', 'custom'); Request::defaultHeader('Hello', 'custom');
$response = Unirest\Request::get('http://mockbin.com/request'); $response = Request::get('http://mockbin.com/request');
$this->assertEquals(200, $response->code); $this->assertEquals(200, $response->code);
$this->assertTrue(property_exists($response->body->headers, 'hello')); $this->assertTrue(property_exists($response->body->headers, 'hello'));
$this->assertEquals('custom', $response->body->headers->hello); $this->assertEquals('custom', $response->body->headers->hello);
Unirest\Request::clearDefaultHeaders(); Request::clearDefaultHeaders();
$response = Unirest\Request::get('http://mockbin.com/request'); $response = Request::get('http://mockbin.com/request');
$this->assertEquals(200, $response->code); $this->assertEquals(200, $response->code);
$this->assertFalse(property_exists($response->body->headers, 'hello')); $this->assertFalse(property_exists($response->body->headers, 'hello'));
@@ -59,24 +83,24 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
public function testSetMashapeKey() public function testSetMashapeKey()
{ {
Unirest\Request::setMashapeKey('abcd'); Request::setMashapeKey('abcd');
$response = Unirest\Request::get('http://mockbin.com/request'); $response = Request::get('http://mockbin.com/request');
$this->assertEquals(200, $response->code); $this->assertEquals(200, $response->code);
$this->assertTrue(property_exists($response->body->headers, 'x-mashape-key')); $this->assertTrue(property_exists($response->body->headers, 'x-mashape-key'));
$this->assertEquals('abcd', $response->body->headers->{'x-mashape-key'}); $this->assertEquals('abcd', $response->body->headers->{'x-mashape-key'});
// send another request // send another request
$response = Unirest\Request::get('http://mockbin.com/request'); $response = Request::get('http://mockbin.com/request');
$this->assertEquals(200, $response->code); $this->assertEquals(200, $response->code);
$this->assertTrue(property_exists($response->body->headers, 'x-mashape-key')); $this->assertTrue(property_exists($response->body->headers, 'x-mashape-key'));
$this->assertEquals('abcd', $response->body->headers->{'x-mashape-key'}); $this->assertEquals('abcd', $response->body->headers->{'x-mashape-key'});
Unirest\Request::clearDefaultHeaders(); Request::clearDefaultHeaders();
$response = Unirest\Request::get('http://mockbin.com/request'); $response = Request::get('http://mockbin.com/request');
$this->assertEquals(200, $response->code); $this->assertEquals(200, $response->code);
$this->assertFalse(property_exists($response->body->headers, 'x-mashape-key')); $this->assertFalse(property_exists($response->body->headers, 'x-mashape-key'));
@@ -84,30 +108,30 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
public function testGzip() public function testGzip()
{ {
$response = Unirest\Request::get('http://mockbin.com/gzip/request'); $response = Request::get('http://mockbin.com/gzip/request');
$this->assertEquals('gzip', $response->headers['Content-Encoding']); $this->assertEquals('gzip', $response->headers['Content-Encoding']);
} }
public function testBasicAuthenticationDeprecated() public function testBasicAuthenticationDeprecated()
{ {
$response = Unirest\Request::get('http://mockbin.com/request', array(), array(), 'user', 'password'); $response = Request::get('http://mockbin.com/request', array(), array(), 'user', 'password');
$this->assertEquals('Basic dXNlcjpwYXNzd29yZA==', $response->body->headers->authorization); $this->assertEquals('Basic dXNlcjpwYXNzd29yZA==', $response->body->headers->authorization);
} }
public function testBasicAuthentication() public function testBasicAuthentication()
{ {
Unirest\Request::auth('user', 'password'); Request::auth('user', 'password');
$response = Unirest\Request::get('http://mockbin.com/request'); $response = Request::get('http://mockbin.com/request');
$this->assertEquals('Basic dXNlcjpwYXNzd29yZA==', $response->body->headers->authorization); $this->assertEquals('Basic dXNlcjpwYXNzd29yZA==', $response->body->headers->authorization);
} }
public function testCustomHeaders() public function testCustomHeaders()
{ {
$response = Unirest\Request::get('http://mockbin.com/request', array( $response = Request::get('http://mockbin.com/request', array(
'user-agent' => 'unirest-php', 'user-agent' => 'unirest-php',
)); ));
@@ -118,7 +142,7 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
// GET // GET
public function testGet() public function testGet()
{ {
$response = Unirest\Request::get('http://mockbin.com/request?name=Mark', array( $response = Request::get('http://mockbin.com/request?name=Mark', array(
'Accept' => 'application/json' 'Accept' => 'application/json'
), array( ), array(
'nick' => 'thefosk' 'nick' => 'thefosk'
@@ -132,7 +156,7 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
public function testGetMultidimensionalArray() public function testGetMultidimensionalArray()
{ {
$response = Unirest\Request::get('http://mockbin.com/request', array( $response = Request::get('http://mockbin.com/request', array(
'Accept' => 'application/json' 'Accept' => 'application/json'
), array( ), array(
'key' => 'value', 'key' => 'value',
@@ -151,7 +175,7 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
public function testGetWithDots() public function testGetWithDots()
{ {
$response = Unirest\Request::get('http://mockbin.com/request', array( $response = Request::get('http://mockbin.com/request', array(
'Accept' => 'application/json' 'Accept' => 'application/json'
), array( ), array(
'user.name' => 'Mark', 'user.name' => 'Mark',
@@ -166,7 +190,7 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
public function testGetWithDotsAlt() public function testGetWithDotsAlt()
{ {
$response = Unirest\Request::get('http://mockbin.com/request', array( $response = Request::get('http://mockbin.com/request', array(
'Accept' => 'application/json' 'Accept' => 'application/json'
), array( ), array(
'user.name' => 'Mark Bond', 'user.name' => 'Mark Bond',
@@ -180,7 +204,7 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
} }
public function testGetWithEqualSign() public function testGetWithEqualSign()
{ {
$response = Unirest\Request::get('http://mockbin.com/request', array( $response = Request::get('http://mockbin.com/request', array(
'Accept' => 'application/json' 'Accept' => 'application/json'
), array( ), array(
'name' => 'Mark=Hello' 'name' => 'Mark=Hello'
@@ -193,7 +217,7 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
public function testGetWithEqualSignAlt() public function testGetWithEqualSignAlt()
{ {
$response = Unirest\Request::get('http://mockbin.com/request', array( $response = Request::get('http://mockbin.com/request', array(
'Accept' => 'application/json' 'Accept' => 'application/json'
), array( ), array(
'name' => 'Mark=Hello=John' 'name' => 'Mark=Hello=John'
@@ -206,7 +230,7 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
public function testGetWithComplexQuery() public function testGetWithComplexQuery()
{ {
$response = Unirest\Request::get('http://mockbin.com/request?query=[{"type":"/music/album","name":null,"artist":{"id":"/en/bob_dylan"},"limit":3}]&cursor'); $response = Request::get('http://mockbin.com/request?query=[{"type":"/music/album","name":null,"artist":{"id":"/en/bob_dylan"},"limit":3}]&cursor');
$this->assertEquals(200, $response->code); $this->assertEquals(200, $response->code);
$this->assertEquals('GET', $response->body->method); $this->assertEquals('GET', $response->body->method);
@@ -216,7 +240,7 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
public function testGetArray() public function testGetArray()
{ {
$response = Unirest\Request::get('http://mockbin.com/request', array(), array( $response = Request::get('http://mockbin.com/request', array(), array(
'name[0]' => 'Mark', 'name[0]' => 'Mark',
'name[1]' => 'John' 'name[1]' => 'John'
)); ));
@@ -230,7 +254,7 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
// POST // POST
public function testPost() public function testPost()
{ {
$response = Unirest\Request::post('http://mockbin.com/request', array( $response = Request::post('http://mockbin.com/request', array(
'Accept' => 'application/json' 'Accept' => 'application/json'
), array( ), array(
'name' => 'Mark', 'name' => 'Mark',
@@ -243,14 +267,52 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('thefosk', $response->body->postData->params->nick); $this->assertEquals('thefosk', $response->body->postData->params->nick);
} }
public function testPostForm()
{
$body = Request\Body::Form(array(
'name' => 'Mark',
'nick' => 'thefosk'
));
$response = Request::post('http://mockbin.com/request', array(
'Accept' => 'application/json'
), $body);
$this->assertEquals('POST', $response->body->method);
$this->assertEquals('application/x-www-form-urlencoded', $response->body->headers->{'content-type'});
$this->assertEquals('application/x-www-form-urlencoded', $response->body->postData->mimeType);
$this->assertEquals('Mark', $response->body->postData->params->name);
$this->assertEquals('thefosk', $response->body->postData->params->nick);
}
public function testPostMultipart()
{
$body = Request\Body::Multipart(array(
'name' => 'Mark',
'nick' => 'thefosk'
));
$response = Request::post('http://mockbin.com/request', (object) array(
'Accept' => 'application/json',
), $body);
$this->assertEquals('POST', $response->body->method);
$this->assertEquals('multipart/form-data', explode(';', $response->body->headers->{'content-type'})[0]);
$this->assertEquals('multipart/form-data', $response->body->postData->mimeType);
$this->assertEquals('Mark', $response->body->postData->params->name);
$this->assertEquals('thefosk', $response->body->postData->params->nick);
}
public function testPostWithEqualSign() public function testPostWithEqualSign()
{ {
$response = Unirest\Request::post('http://mockbin.com/request', array( $body = Request\Body::Form(array(
'Accept' => 'application/json'
), array(
'name' => 'Mark=Hello' 'name' => 'Mark=Hello'
)); ));
$response = Request::post('http://mockbin.com/request', array(
'Accept' => 'application/json'
), $body);
$this->assertEquals(200, $response->code); $this->assertEquals(200, $response->code);
$this->assertEquals('POST', $response->body->method); $this->assertEquals('POST', $response->body->method);
$this->assertEquals('Mark=Hello', $response->body->postData->params->name); $this->assertEquals('Mark=Hello', $response->body->postData->params->name);
@@ -258,7 +320,7 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
public function testPostArray() public function testPostArray()
{ {
$response = Unirest\Request::post('http://mockbin.com/request', array( $response = Request::post('http://mockbin.com/request', array(
'Accept' => 'application/json' 'Accept' => 'application/json'
), array( ), array(
'name[0]' => 'Mark', 'name[0]' => 'Mark',
@@ -273,7 +335,7 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
public function testPostWithDots() public function testPostWithDots()
{ {
$response = Unirest\Request::post('http://mockbin.com/request', array( $response = Request::post('http://mockbin.com/request', array(
'Accept' => 'application/json' 'Accept' => 'application/json'
), array( ), array(
'user.name' => 'Mark', 'user.name' => 'Mark',
@@ -288,7 +350,7 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
public function testRawPost() public function testRawPost()
{ {
$response = Unirest\Request::post('http://mockbin.com/request', array( $response = Request::post('http://mockbin.com/request', array(
'Accept' => 'application/json', 'Accept' => 'application/json',
'Content-Type' => 'application/json' 'Content-Type' => 'application/json'
), json_encode(array( ), json_encode(array(
@@ -302,9 +364,7 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
public function testPostMultidimensionalArray() public function testPostMultidimensionalArray()
{ {
$response = Unirest\Request::post('http://mockbin.com/request', array( $body = Request\Body::Form(array(
'Accept' => 'application/json'
), array(
'key' => 'value', 'key' => 'value',
'items' => array( 'items' => array(
'item1', 'item1',
@@ -312,6 +372,10 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
) )
)); ));
$response = Request::post('http://mockbin.com/request', array(
'Accept' => 'application/json'
), $body);
$this->assertEquals(200, $response->code); $this->assertEquals(200, $response->code);
$this->assertEquals('POST', $response->body->method); $this->assertEquals('POST', $response->body->method);
$this->assertEquals('value', $response->body->postData->params->key); $this->assertEquals('value', $response->body->postData->params->key);
@@ -322,7 +386,7 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
// PUT // PUT
public function testPut() public function testPut()
{ {
$response = Unirest\Request::put('http://mockbin.com/request', array( $response = Request::put('http://mockbin.com/request', array(
'Accept' => 'application/json' 'Accept' => 'application/json'
), array( ), array(
'name' => 'Mark', 'name' => 'Mark',
@@ -338,7 +402,7 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
// PATCH // PATCH
public function testPatch() public function testPatch()
{ {
$response = Unirest\Request::patch('http://mockbin.com/request', array( $response = Request::patch('http://mockbin.com/request', array(
'Accept' => 'application/json' 'Accept' => 'application/json'
), array( ), array(
'name' => 'Mark', 'name' => 'Mark',
@@ -354,7 +418,7 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
// DELETE // DELETE
public function testDelete() public function testDelete()
{ {
$response = Unirest\Request::delete('http://mockbin.com/request', array( $response = Request::delete('http://mockbin.com/request', array(
'Accept' => 'application/json', 'Accept' => 'application/json',
'Content-Type' => 'application/x-www-form-urlencoded' 'Content-Type' => 'application/x-www-form-urlencoded'
), array( ), array(
@@ -369,11 +433,31 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
// Upload // Upload
public function testUpload() public function testUpload()
{ {
$response = Unirest\Request::post('http://mockbin.com/request', array( $fixture = __DIR__ . '/../fixtures/upload.txt';
$headers = array('Accept' => 'application/json');
$files = array('file' => $fixture);
$data = array('name' => 'ahmad');
$body = Request\Body::Multipart($data, $files);
$response = Request::post('http://mockbin.com/request', $headers, $body);
$this->assertEquals(200, $response->code);
$this->assertEquals('POST', $response->body->method);
$this->assertEquals('ahmad', $response->body->postData->params->name);
$this->assertEquals('This is a test', $response->body->postData->params->file);
}
public function testUploadWithoutHelper()
{
$fixture = __DIR__ . '/../fixtures/upload.txt';
$response = Request::post('http://mockbin.com/request', array(
'Accept' => 'application/json' 'Accept' => 'application/json'
), array( ), array(
'name' => 'Mark', 'name' => 'Mark',
'file' => Unirest\File::add(UPLOAD_FIXTURE) 'file' => Request\Body::File($fixture)
)); ));
$this->assertEquals(200, $response->code); $this->assertEquals(200, $response->code);
@@ -384,11 +468,13 @@ class UnirestRequestTest extends \PHPUnit_Framework_TestCase
public function testUploadIfFilePartOfData() public function testUploadIfFilePartOfData()
{ {
$response = Unirest\Request::post('http://mockbin.com/request', array( $fixture = __DIR__ . '/../fixtures/upload.txt';
$response = Request::post('http://mockbin.com/request', array(
'Accept' => 'application/json' 'Accept' => 'application/json'
), array( ), array(
'name' => 'Mark', 'name' => 'Mark',
'files[owl.gif]' => Unirest\File::add(UPLOAD_FIXTURE) 'files[owl.gif]' => Request\Body::File($fixture)
)); ));
$this->assertEquals(200, $response->code); $this->assertEquals(200, $response->code);

View File

@@ -1,27 +1,34 @@
<?php <?php
namespace Unirest\Response\Test;
use Unirest\Request as Request;
use Unirest\Response as Response;
require __DIR__ . '/../../src/Unirest.php';
class UnirestResponseTest extends \PHPUnit_Framework_TestCase class UnirestResponseTest extends \PHPUnit_Framework_TestCase
{ {
public function testJSONAssociativeArrays() public function testJSONAssociativeArrays()
{ {
$opts = Unirest\Request::jsonOpts(true); $opts = Request::jsonOpts(true);
$response = new Unirest\Response(200, '{"a":1,"b":2,"c":3,"d":4,"e":5}', '', $opts); $response = new Response(200, '{"a":1,"b":2,"c":3,"d":4,"e":5}', '', $opts);
$this->assertEquals($response->body['a'], 1); $this->assertEquals($response->body['a'], 1);
} }
public function testJSONAObjects() public function testJSONAObjects()
{ {
$opts = Unirest\Request::jsonOpts(false); $opts = Request::jsonOpts(false);
$response = new Unirest\Response(200, '{"a":1,"b":2,"c":3,"d":4,"e":5}', '', $opts); $response = new Response(200, '{"a":1,"b":2,"c":3,"d":4,"e":5}', '', $opts);
$this->assertEquals($response->body->a, 1); $this->assertEquals($response->body->a, 1);
} }
public function testJSONOpts() public function testJSONOpts()
{ {
$opts = Unirest\Request::jsonOpts(false, 512, JSON_NUMERIC_CHECK); $opts = Request::jsonOpts(false, 512, JSON_NUMERIC_CHECK);
$response = new Unirest\Response(200, '{"number": 1234567890}', '', $opts); $response = new Response(200, '{"number": 1234567890}', '', $opts);
$this->assertSame($response->body->number, 1234567890); $this->assertSame($response->body->number, 1234567890);
} }

View File

@@ -1,5 +1 @@
<?php <?php ?>
require_once __DIR__ . '/../src/Unirest.php';
define('UPLOAD_FIXTURE', __DIR__ . '/fixtures/upload.txt');