Skip to content

Commit

Permalink
Merge pull request #35 from nickl-/development
Browse files Browse the repository at this point in the history
Resubmit pull request... on request
  • Loading branch information
Nate Good committed Jun 20, 2012
2 parents 423838c + 79b323c commit 63a1d20
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 22 deletions.
45 changes: 40 additions & 5 deletions src/Httpful/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class Request
public $uri,
$method = Http::GET,
$headers = array(),
$raw_headers = '',
$strict_ssl = false,
$content_type,
$expected_type,
Expand Down Expand Up @@ -685,15 +686,49 @@ public function _curlPrep()

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$headers = array("Content-Type: {$this->content_type}");

$headers[] = !empty($this->expected_type) ?
"Accept: {$this->expected_type}, text/plain" :
"Accept: */*";
$headers = array();
if (!isset($this->headers['User-Agent'])) {
$user_agent = 'User-Agent: HttpFul/1.0 (cURL/';
$curl = \curl_version();
if (isset($curl['version']))
$user_agent .= $curl['version'];
else
$user_agent .= '?.?.?';
$user_agent .= ' PHP/'.PHP_VERSION.' ('.PHP_OS.')';
if (isset($_SERVER['SERVER_SOFTWARE']))
$user_agent .= ' '.\preg_replace('~PHP/[\d\.]+~U', '', $_SERVER['SERVER_SOFTWARE']);
else {
if (isset($_SERVER['TERM_PROGRAM']))
$user_agent .= " {$_SERVER['TERM_PROGRAM']}";
if (isset($_SERVER['TERM_PROGRAM_VERSION']))
$user_agent .= "/{$_SERVER['TERM_PROGRAM_VERSION']}";
}
if (isset($_SERVER['HTTP_USER_AGENT']))
$user_agent .= " {$_SERVER['HTTP_USER_AGENT']}";
$user_agent .= ')';
$headers[] = $user_agent;
}
$headers[] = "Content-Type: {$this->content_type}";

// http://pretty-rfc.herokuapp.com/RFC2616#header.accept
$accept = "Accept: */*; q=0.5, text/plain; q=0.8,\r\n\t" .
'text/html;level=3; q=0.9';
if (!empty($this->expected_type))
$accept .= ", {$this->expected_type}";
$headers[] = $accept;

foreach ($this->headers as $header => $value) {
$headers[] = "$header: $value";
}

$url = \parse_url($this->uri);
$path = (isset($url['path']) ? $url['path'] : '/').(isset($url['query']) ? '?'.$url['query'] : '');
$this->raw_headers = "{$this->method} $path HTTP/1.1\r\n";
$host = (isset($url['host']) ? $url['host'] : 'localhost').(isset($url['port']) ? ':'.$url['port'] : '');
$this->raw_headers .= "Host: $host\r\n";
$this->raw_headers .= \implode("\r\n", $headers);
$this->raw_headers .= "\r\n";

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

if (isset($this->payload)) {
Expand Down
18 changes: 15 additions & 3 deletions src/Httpful/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Response
public $body,
$raw_body,
$headers,
$raw_headers,
$request,
$code = 0,
$content_type,
Expand Down Expand Up @@ -42,11 +43,21 @@ public function __construct($body, $headers, Request $request)
}

/**
* @return bool Did we receive a 400 or 500?
* Status Code Definitions
*
* Informational 1xx
* Successful 2xx
* Redirection 3xx
* Client Error 4xx
* Server Error 5xx
*
* http://pretty-rfc.herokuapp.com/RFC2616#status.codes
*
* @return bool Did we receive a 4xx or 5xx?
*/
public function hasErrors()
{
return $this->code < 100 || $this->code >= 400;
return $this->code >= 400;
}

/**
Expand Down Expand Up @@ -100,7 +111,8 @@ public function _parse($body)
*/
public function _parseHeaders($headers)
{
$headers = preg_split("/(\r|\n)+/", $headers);
$headers = preg_split("/(\r|\n)+/", $headers, -1, \PREG_SPLIT_NO_EMPTY);
$parse_headers = array();
for ($i = 1; $i < count($headers); $i++) {
list($key, $raw_value) = explode(':', $headers[$i], 2);
$parse_headers[trim($key)] = trim($raw_value);
Expand Down
92 changes: 84 additions & 8 deletions tests/Httpful/HttpfulTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ class HttpfulTest extends \PHPUnit_Framework_TestCase
"HTTP/1.1 200 OK
Content-Type: application/json
Connection: keep-alive
Transfer-Encoding: chunked";
Transfer-Encoding: chunked\r\n";
const SAMPLE_JSON_RESPONSE = '{"key":"value","object":{"key":"value"},"array":[1,2,3,4]}';
const SAMPLE_CSV_HEADER =
"HTTP/1.1 200 OK
Content-Type: text/csv
Connection: keep-alive
Transfer-Encoding: chunked";
Transfer-Encoding: chunked\r\n";
const SAMPLE_CSV_RESPONSE =
"Key1,Key2
Value1,Value2
Expand All @@ -44,12 +44,12 @@ class HttpfulTest extends \PHPUnit_Framework_TestCase
"HTTP/1.1 200 OK
Content-Type: application/xml
Connection: keep-alive
Transfer-Encoding: chunked";
Transfer-Encoding: chunked\r\n";
const SAMPLE_VENDOR_HEADER =
"HTTP/1.1 200 OK
Content-Type: application/vnd.nategood.message+xml
Connection: keep-alive
Transfer-Encoding: chunked";
Transfer-Encoding: chunked\r\n";
const SAMPLE_VENDOR_TYPE = "application/vnd.nategood.message+xml";

function testInit()
Expand Down Expand Up @@ -169,7 +169,35 @@ function testIni()
Request::resetIni();
}

function testAuthSetup()
function testAccept()
{
$r = Request::get('http://example.com/')
->expectsType(Mime::JSON);

$this->assertEquals(Mime::JSON, $r->expected_type);
$r->_curlPrep();
$this->assertContains('application/json', $r->raw_headers);
}
function testUserAgent()
{
$r = Request::get('http://example.com/')
->withUserAgent('ACME/1.2.3');

$this->assertArrayHasKey('User-Agent', $r->headers);
$r->_curlPrep();
$this->assertContains('User-Agent: ACME/1.2.3', $r->raw_headers);
$this->assertNotContains('User-Agent: HttpFul/1.0', $r->raw_headers);

$r = Request::get('http://example.com/')
->withUserAgent('');

$this->assertArrayHasKey('User-Agent', $r->headers);
$r->_curlPrep();
$this->assertContains('User-Agent:', $r->raw_headers);
$this->assertNotContains('User-Agent: HttpFul/1.0', $r->raw_headers);
}

function testAuthSetup()
{
$username = 'nathan';
$password = 'opensesame';
Expand Down Expand Up @@ -228,7 +256,7 @@ function testParsingContentTypeCharset()
// $response = new Response(SAMPLE_JSON_RESPONSE, "", $req);
// // Check default content type of iso-8859-1
$response = new Response(self::SAMPLE_JSON_RESPONSE, "HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8", $req);
Content-Type: text/plain; charset=utf-8\r\n", $req);
$this->assertInternalType('array', $response->headers);
$this->assertEquals($response->headers['Content-Type'], 'text/plain; charset=utf-8');
$this->assertEquals($response->content_type, 'text/plain');
Expand Down Expand Up @@ -263,6 +291,53 @@ function testParseHeaders()
$this->assertEquals('application/json', $response->headers['Content-Type']);
}

function testRawHeaders()
{
$req = Request::init()->sendsAndExpects(Mime::JSON);
$response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req);
$this->assertContains('Content-Type: application/json', $response->raw_headers);
}

function testHasErrors()
{
$req = Request::init()->sendsAndExpects(Mime::JSON);
$response = new Response('', "HTTP/1.1 100 Continue\r\n", $req);
$this->assertFalse($response->hasErrors());
$response = new Response('', "HTTP/1.1 200 OK\r\n", $req);
$this->assertFalse($response->hasErrors());
$response = new Response('', "HTTP/1.1 300 Multiple Choices\r\n", $req);
$this->assertFalse($response->hasErrors());
$response = new Response('', "HTTP/1.1 400 Bad Request\r\n", $req);
$this->assertTrue($response->hasErrors());
$response = new Response('', "HTTP/1.1 500 Internal Server Error\r\n", $req);
$this->assertTrue($response->hasErrors());
}

function test_parseCode()
{
$req = Request::init()->sendsAndExpects(Mime::JSON);
$response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req);
$code = $response->_parseCode("HTTP/1.1 406 Not Acceptable\r\n");
$this->assertEquals(406, $code);
}

function testToString()
{
$req = Request::init()->sendsAndExpects(Mime::JSON);
$response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req);
$this->assertEquals(self::SAMPLE_JSON_RESPONSE, (string)$response);
}

function test_parseHeaders()
{
$req = Request::init();
$response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req);
$parse_headers = $response->_parseHeaders(self::SAMPLE_JSON_HEADER);
$this->assertEquals(3, count($parse_headers));
$this->assertEquals('application/json', $parse_headers['Content-Type']);
$this->assertArrayHasKey('Connection', $parse_headers);
}

function testDetectContentType()
{
$req = Request::init();
Expand Down Expand Up @@ -298,7 +373,7 @@ function testMissingContentType()
$response = new Response('<xml><name>Nathan</name></xml>',
"HTTP/1.1 200 OK
Connection: keep-alive
Transfer-Encoding: chunked", $request);
Transfer-Encoding: chunked\r\n", $request);

$this->assertEquals("", $response->content_type);
}
Expand Down Expand Up @@ -342,4 +417,5 @@ class DemoMimeHandler extends \Httpful\Handlers\MimeHandlerAdapter {
public function parse($body) {
return 'custom parse';
}
}
}

14 changes: 8 additions & 6 deletions tests/phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<phpunit>
<testsuites>
<testsuite name="Httpful">
<directory>Httpful</directory>
</testsuite>
</testsuites>
</phpunit>
<testsuite name="Httpful">
<directory>.</directory>
</testsuite>
<logging>
<log type="coverage-text" target="php://stdout" showUncoveredFiles="false"/>
</logging>
</phpunit>

0 comments on commit 63a1d20

Please sign in to comment.