diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..1162f43
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..bc416df
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..c80f219
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/wellrested.iml b/.idea/wellrested.iml
new file mode 100644
index 0000000..6b8184f
--- /dev/null
+++ b/.idea/wellrested.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/README.md b/README.md
index a44341f..63998aa 100644
--- a/README.md
+++ b/README.md
@@ -180,7 +180,11 @@ if ($rqst->getMethod() === 'PUT') {
}
```
-The Request class can also make a request to another server and provide the response as a Response object. (This feature requires [PHP cURL](http://php.net/manual/en/book.curl.php).)
+### HTTP Client
+
+You can also use the `Client` class to make a request using cURL.
+
+(This feature requires [PHP cURL](http://php.net/manual/en/book.curl.php).)
```php
// Prepare a request.
@@ -189,8 +193,9 @@ $rqst->setUri('http://my.api.local/resources/');
$rqst->setMethod('POST');
$rqst->setBody(json_encode($newResource));
-// Make the request.
-$resp = $rqst->request();
+// Use a Client to get a Response.
+$client = new Client();
+$resp = $client->request($rqst);
// Read the response.
if ($resp->getStatusCode() === 201) {
@@ -200,12 +205,6 @@ if ($resp->getStatusCode() === 201) {
```
-More Examples
----------------
-
-For more examples, see the project [pjdietz/wellrested-samples](https://github.com/pjdietz/wellrested-samples). **Not yet updated for version 2.0**
-
-
Copyright and License
---------------------
Copyright © 2014 by PJ Dietz
diff --git a/src/pjdietz/WellRESTed/Client.php b/src/pjdietz/WellRESTed/Client.php
new file mode 100644
index 0000000..670d9e6
--- /dev/null
+++ b/src/pjdietz/WellRESTed/Client.php
@@ -0,0 +1,122 @@
+
+ * @copyright Copyright 2014 by PJ Dietz
+ * @license MIT
+ */
+
+namespace pjdietz\WellRESTed;
+
+use pjdietz\WellRESTed\Exceptions\CurlException;
+use pjdietz\WellRESTed\Interfaces\RequestInterface;
+use pjdietz\WellRESTed\Interfaces\ResponseInterface;
+
+/**
+ * Class for making HTTP requests using cURL.
+ */
+class Client
+{
+ /** @var array cURL options */
+ private $curlOpts;
+
+ public function __construct(array $curlOpts = null) {
+ if (is_array($curlOpts)) {
+ $this->curlOpts = $curlOpts;
+ } else {
+ $this->curlOpts = array();
+ }
+ }
+
+ /**
+ * Make an HTTP request and return a Response.
+ *
+ * @param RequestInterface $rqst
+ * @param array $curlOpts Option array of cURL options
+ * @throws \pjdietz\WellRESTed\Exceptions\CurlException
+ * @return ResponseInterface
+ */
+ public function request(RequestInterface $rqst, $curlOpts = null)
+ {
+ $ch = curl_init();
+
+ $headers = array();
+ foreach ($rqst->getHeaders() as $field => $value) {
+ $lines[] = sprintf('%s: %s', $field, $value);
+ }
+
+ $options = $this->curlOpts;
+ $options[CURLOPT_URL] = $rqst->getUri();
+ $options[CURLOPT_PORT] = $rqst->getPort();
+ $options[CURLOPT_HEADER] = 1;
+ $options[CURLOPT_RETURNTRANSFER] = 1;
+ $options[CURLOPT_HTTPHEADER] = $headers;
+
+ // Set the method. Include the body, if needed.
+ switch ($rqst->getMethod()) {
+ case 'GET':
+ $options[CURLOPT_HTTPGET] = 1;
+ break;
+ case 'POST':
+ $options[CURLOPT_POST] = 1;
+ $options[CURLOPT_POSTFIELDS] = $rqst->getBody();
+ break;
+ case 'PUT':
+ $options[CURLOPT_CUSTOMREQUEST] = 'PUT';
+ $options[CURLOPT_POSTFIELDS] = $rqst->getBody();
+ break;
+ default:
+ $options[CURLOPT_CUSTOMREQUEST] = $rqst->getMethod();
+ $options[CURLOPT_POSTFIELDS] = $rqst->getBody();
+ break;
+ }
+
+ // Override cURL options with the user options passed in.
+ if ($curlOpts) {
+ foreach ($curlOpts as $optKey => $optValue) {
+ $options[$optKey] = $optValue;
+ }
+ }
+
+ // Set the cURL options.
+ curl_setopt_array($ch, $options);
+
+ // Make the cURL request.
+ $result = curl_exec($ch);
+
+ // Throw an exception in the event of a cURL error.
+ if ($result === false) {
+ $error = curl_error($ch);
+ $errno = curl_errno($ch);
+ curl_close($ch);
+ throw new CurlException($error, $errno);
+ }
+
+ // Make a reponse to populate and return with data obtained via cURL.
+ $resp = new Response();
+
+ $resp->setStatusCode(curl_getinfo($ch, CURLINFO_HTTP_CODE));
+
+ // Split the result into headers and body.
+ $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $headers = substr($result, 0, $headerSize);
+ $body = substr($result, $headerSize);
+
+ // Set the body. Do not auto-add the Content-length header.
+ $resp->setBody($body, false);
+
+ // Iterate over the headers line by line and add each one.
+ foreach (explode("\r\n", $headers) as $header) {
+ if (strpos($header, ':')) {
+ list ($headerName, $headerValue) = explode(':', $header, 2);
+ $resp->setHeader($headerName, ltrim($headerValue));
+ }
+ }
+
+ curl_close($ch);
+
+ return $resp;
+ }
+}
diff --git a/src/pjdietz/WellRESTed/Interfaces/RequestInterface.php b/src/pjdietz/WellRESTed/Interfaces/RequestInterface.php
index 1770306..e697232 100644
--- a/src/pjdietz/WellRESTed/Interfaces/RequestInterface.php
+++ b/src/pjdietz/WellRESTed/Interfaces/RequestInterface.php
@@ -22,6 +22,20 @@ interface RequestInterface
*/
public function getMethod();
+ /**
+ * Return the full URI for the request.
+ *
+ * @return string
+ */
+ public function getUri();
+
+ /**
+ * Return the hostname portion of the URI
+ *
+ * @return string
+ */
+ public function getHostname();
+
/**
* Return path component of the request URI.
*
@@ -29,6 +43,13 @@ interface RequestInterface
*/
public function getPath();
+ /**
+ * Return the HTTP port
+ *
+ * @return int
+ */
+ public function getPort();
+
/**
* Return an associative array of query paramters.
*
@@ -47,6 +68,13 @@ interface RequestInterface
*/
public function getHeader($headerName);
+ /**
+ * Return an associative array of headers.
+ *
+ * @return array
+ */
+ public function getHeaders();
+
/**
* Return the body of the request.
*
diff --git a/src/pjdietz/WellRESTed/Message.php b/src/pjdietz/WellRESTed/Message.php
index 8596cc0..5f66f5a 100644
--- a/src/pjdietz/WellRESTed/Message.php
+++ b/src/pjdietz/WellRESTed/Message.php
@@ -72,20 +72,6 @@ abstract class Message
return $this->headers;
}
- /**
- * Return an array containing one string for each header as "field: value"
- *
- * @return string
- */
- public function getHeaderLines()
- {
- $lines = array();
- foreach ($this->headers as $field => $value) {
- $lines[] = sprintf('%s: %s', $field, $value);
- }
- return $lines;
- }
-
/**
* Return the value of a given header, or false if it does not exist.
*
diff --git a/src/pjdietz/WellRESTed/Request.php b/src/pjdietz/WellRESTed/Request.php
index f57b4b0..6ef078e 100644
--- a/src/pjdietz/WellRESTed/Request.php
+++ b/src/pjdietz/WellRESTed/Request.php
@@ -336,91 +336,6 @@ class Request extends Message implements RequestInterface
// -------------------------------------------------------------------------
- /**
- * Make a cURL request out of the instance and return a Response.
- *
- * @param array|null $curlOpts Associative array of options to set using curl_setopt_array before making the request.
- * @throws Exceptions\CurlException
- * @return Response
- */
- public function request($curlOpts = null)
- {
- $ch = curl_init();
-
- $options = array(
- CURLOPT_URL => $this->getUri(),
- CURLOPT_PORT => $this->port,
- CURLOPT_HEADER => 1,
- CURLOPT_RETURNTRANSFER => 1,
- CURLOPT_HTTPHEADER => $this->getHeaderLines()
- );
-
- // Set the method. Include the body, if needed.
- switch ($this->method) {
- case 'GET':
- $options[CURLOPT_HTTPGET] = 1;
- break;
- case 'POST':
- $options[CURLOPT_POST] = 1;
- $options[CURLOPT_POSTFIELDS] = $this->body;
- break;
- case 'PUT':
- $options[CURLOPT_CUSTOMREQUEST] = 'PUT';
- $options[CURLOPT_POSTFIELDS] = $this->body;
- break;
- default:
- $options[CURLOPT_CUSTOMREQUEST] = $this->method;
- $options[CURLOPT_POSTFIELDS] = $this->body;
- break;
- }
-
- // Override cURL options with the user options passed in.
- if ($curlOpts) {
- foreach ($curlOpts as $optKey => $optValue) {
- $options[$optKey] = $optValue;
- }
- }
-
- // Set the cURL options.
- curl_setopt_array($ch, $options);
-
- // Make the cURL request.
- $result = curl_exec($ch);
-
- // Throw an exception in the event of a cURL error.
- if ($result === false) {
- $error = curl_error($ch);
- $errno = curl_errno($ch);
- curl_close($ch);
- throw new CurlException($error, $errno);
- }
-
- // Make a reponse to populate and return with data obtained via cURL.
- $resp = new Response();
-
- $resp->setStatusCode(curl_getinfo($ch, CURLINFO_HTTP_CODE));
-
- // Split the result into headers and body.
- $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
- $headers = substr($result, 0, $headerSize);
- $body = substr($result, $headerSize);
-
- // Set the body. Do not auto-add the Content-length header.
- $resp->setBody($body, false);
-
- // Iterate over the headers line by line and add each one.
- foreach (explode("\r\n", $headers) as $header) {
- if (strpos($header, ':')) {
- list ($headerName, $headerValue) = explode(':', $header, 2);
- $resp->setHeader($headerName, ltrim($headerValue));
- }
- }
-
- curl_close($ch);
-
- return $resp;
- }
-
/**
* Return the default port for the currently set scheme.
*
diff --git a/test/ClientTest.php b/test/ClientTest.php
new file mode 100644
index 0000000..241f073
--- /dev/null
+++ b/test/ClientTest.php
@@ -0,0 +1,82 @@
+assertTrue(true);
+ }
+
+ /**
+ * @dataProvider curlProvider
+ */
+ public function testCurl($method, $uri, $opts, $code)
+ {
+ $rqst = $this->getMockBuilder('pjdietz\WellRESTed\Request')->getMock();
+ $rqst->expects($this->any())
+ ->method("getUri")
+ ->will($this->returnValue($uri));
+ $rqst->expects($this->any())
+ ->method("getMethod")
+ ->will($this->returnValue($method));
+ $rqst->expects($this->any())
+ ->method("getPort")
+ ->will($this->returnValue(80));
+ $rqst->expects($this->any())
+ ->method("getHeaders")
+ ->will($this->returnValue(array(
+ "Cache-control" => "max-age=0"
+ )));
+
+ $client = new Client(array(CURLOPT_HTTPHEADER => array("Cache-control" => "max-age=0")));
+ $resp = $client->request($rqst, $opts);
+ $this->assertEquals($code, $resp->getStatusCode());
+ }
+
+ public function curlProvider()
+ {
+ return [
+ ["GET", "http://icanhasip.com", [
+ [CURLOPT_MAXREDIRS => 2]
+ ], 200],
+ ["POST", "http://icanhasip.com", [], 200],
+ ["PUT", "http://icanhasip.com", [], 405],
+ ["DELETE", "http://icanhasip.com", [], 405]
+ ];
+ }
+
+ /**
+ * @dataProvider curlErrorProvider
+ * @expectedException \pjdietz\WellRESTed\Exceptions\CurlException
+ */
+ public function testErrorCurl($uri, $opts)
+ {
+ $rqst = $this->getMockBuilder('pjdietz\WellRESTed\Request')->getMock();
+ $rqst->expects($this->any())
+ ->method("getUri")
+ ->will($this->returnValue($uri));
+ $rqst->expects($this->any())
+ ->method("getHeaders")
+ ->will($this->returnValue(array(
+ "Cache-control" => "max-age=0"
+ )));
+
+ $rqst = new Request($uri);
+ $client = new Client();
+ $client->request($rqst, $opts);
+ }
+
+ public function curlErrorProvider()
+ {
+ return [
+ ["http://localhost:9991", [
+ CURLOPT_FAILONERROR, true,
+ CURLOPT_TIMEOUT_MS, 10
+ ]],
+ ];
+ }
+}
diff --git a/test/RequestTest.php b/test/RequestTest.php
index cd66245..3f3fd16 100644
--- a/test/RequestTest.php
+++ b/test/RequestTest.php
@@ -45,15 +45,6 @@ class RequestBuilderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(3, count($this->request->getHeaders()));
}
- /**
- * @dataProvider headerProvider
- */
- public function testHeaderLines($name, $value, $testName)
- {
- $line = "$name: $value";
- $this->assertTrue(in_array($line, $this->request->getHeaderLines()));
- }
-
/**
* @dataProvider headerProvider
*/
@@ -498,46 +489,4 @@ class RequestBuilderTest extends \PHPUnit_Framework_TestCase
];
}
- /**
- * @dataProvider curlProvider
- */
- public function testCurl($method, $uri, $opts, $code)
- {
- $rqst = new Request($uri);
- $rqst->setMethod($method);
- $resp = $rqst->request($opts);
- $this->assertEquals($code, $resp->getStatusCode());
- }
-
- public function curlProvider()
- {
- return [
- ["GET", "http://icanhasip.com", [
- [CURLOPT_MAXREDIRS => 2]
- ], 200],
- ["POST", "http://icanhasip.com", [], 200],
- ["PUT", "http://icanhasip.com", [], 405],
- ["DELETE", "http://icanhasip.com", [], 405]
- ];
- }
-
- /**
- * @dataProvider curlErrorProvider
- * @expectedException \pjdietz\WellRESTed\Exceptions\CurlException
- */
- public function testErrorCurl($uri, $opts)
- {
- $rqst = new Request($uri);
- $resp = $rqst->request($opts);
- }
-
- public function curlErrorProvider()
- {
- return [
- ["http://localhost:9991", [
- CURLOPT_FAILONERROR, true,
- CURLOPT_TIMEOUT_MS, 10
- ]],
- ];
- }
}
diff --git a/test/ResponseTest.php b/test/ResponseTest.php
index 0e80a27..3d30368 100644
--- a/test/ResponseTest.php
+++ b/test/ResponseTest.php
@@ -173,6 +173,4 @@ class ResponseBuilderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($body, $captured);
}
-
-
}