Skip to content

Commit

Permalink
refactor to allow http 100 continue. closes #25
Browse files Browse the repository at this point in the history
  • Loading branch information
anlutro committed Jul 30, 2015
1 parent eaec383 commit 69d5a14
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 42 deletions.
70 changes: 30 additions & 40 deletions src/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,78 +51,68 @@ class Response

/**
* @param string $body
* @param array $headers
* @param string $headers
* @param mixed $info
*/
public function __construct($body, $headers, $info = array())
{
$this->body = $body;
$this->info = $info;
if (is_array($headers)) {
$this->headers = $headers;
} else {
$this->headers = static::headerToArray($headers);
}

if (isset($this->headers['http/1.1'])) {
$this->setCode($this->headers['http/1.1']);
} elseif (isset($this->headers['http/1.0'])) {
$this->setCode($this->headers['http/1.0']);
}
$this->parseHeader($headers);
}

/**
* Turn a header string into an array.
* Read a header string.
*
* @param string $header
*
* @return array
*/
protected static function headerToArray($header)
protected function parseHeader($header)
{
$headerLines = explode("\r\n", $header);
$headerLines = explode("\r\n", trim($header));
$headers = array();

if (!preg_match('/^HTTP\/\d\.\d [0-9]{3}/', $headerLines[0])) {
throw new \InvalidArgumentException('Invalid response header');
}
$this->setStatus($headerLines[0]);
unset($headerLines[0]);

foreach ($headerLines as $header) {
$key = null;
$val = null;
$delimiter = strpos($header, ': ');
// skip empty lines
if (!$header) {
continue;
}

if ($delimiter !== false) {
$key = substr($header, 0, $delimiter);
$val = substr($header, $delimiter + 2);
} else {
$delimiter = strpos($header, ' ');
if ($delimiter !== false) {
$key = substr($header, 0, $delimiter);
$val = substr($header, $delimiter + 1);
}
$delimiter = strpos($header, ':');
if (!$delimiter) {
continue;
}

if ($key !== null) {
$key = strtolower($key);
if (isset($headers[$key])) {
if (is_array($headers[$key])) {
$headers[$key][] = $val;
} else {
$headers[$key] = array($headers[$key], $val);
}
$key = trim(strtolower(substr($header, 0, $delimiter)));
$val = ltrim(substr($header, $delimiter + 1));

if (isset($headers[$key])) {
if (is_array($headers[$key])) {
$headers[$key][] = $val;
} else {
$headers[$key] = $val;
$headers[$key] = array($headers[$key], $val);
}
} else {
$headers[$key] = $val;
}
}

return $headers;
$this->headers = $headers;
}

/**
* Set the response code.
*
* @param string $code
*/
protected function setCode($code)
protected function setStatus($status)
{
list(, $code) = explode(' ', $status, 2);
$this->statusText = $code;
$code = explode(' ', $code);
$this->statusCode = (int) $code[0];
Expand Down
19 changes: 17 additions & 2 deletions tests/unit/ResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function parsesHttpResponseCodeCorrectly()
/** @test */
public function parsesHeaderStringCorrectly()
{
$header = "Content-Type: text/plain\r\nContent-Length: 0";
$header = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 0";
$r = $this->makeResponse('', $header);
$this->assertEquals('text/plain', $r->getHeader('content-type'));
$this->assertEquals('0', $r->getHeader('content-length'));
Expand All @@ -34,8 +34,23 @@ public function parsesHeaderStringCorrectly()
/** @test */
public function duplicateHeadersAreHandled()
{
$header = "X-Var: A\r\nX-Var: B\r\nX-Var: C";
$header = "HTTP/1.1 200 OK\r\nX-Var: A\r\nX-Var: B\r\nX-Var: C";
$r = $this->makeResponse('', $header);
$this->assertEquals(array('A', 'B', 'C'), $r->getHeader('X-Var'));
}

/** @test */
public function httpContinueResponsesAreHandled()
{
$header = "HTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK";
$r = $this->makeResponse('', $header);
$this->assertEquals(100, $r->statusCode);
}

/** @test */
public function throwsExceptionIfHeaderDoesntStartWithHttpStatus()
{
$this->setExpectedException('InvalidArgumentException', 'Invalid response header');
$this->makeResponse('', 'x-var: foo');
}
}

0 comments on commit 69d5a14

Please sign in to comment.