diff --git a/src/Guzzle/Http/Message/RequestFactory.php b/src/Guzzle/Http/Message/RequestFactory.php index 06284912..3d0dc989 100644 --- a/src/Guzzle/Http/Message/RequestFactory.php +++ b/src/Guzzle/Http/Message/RequestFactory.php @@ -67,15 +67,23 @@ class RequestFactory implements RequestFactoryInterface return false; } - // Normalize new lines in the message - $message = preg_replace("/([^\r])(\n)\b/", "$1\r\n", $message); - $parts = explode("\r\n\r\n", $message, 2); $headers = new Collection(); - $scheme = $host = $method = $user = $pass = $query = $port = $version = $protocol = ''; + $scheme = $host = $body = $method = $user = $pass = $query = $port = $version = $protocol = ''; $path = '/'; - // Parse each line in the message - foreach (explode("\r\n", $parts[0]) as $line) { + // Inspired by https://github.com/kriswallsmith/Buzz/blob/message-interfaces/lib/Buzz/Message/Parser/Parser.php#L16 + $lines = preg_split('/(\\r?\\n)/', $message, -1, PREG_SPLIT_DELIM_CAPTURE); + for ($i = 0, $c = count($lines); $i < $c; $i += 2) { + + $line = $lines[$i]; + + // If two line breaks were encountered, then this is the body + if (empty($line)) { + $body = implode('', array_slice($lines, $i + 2)); + break; + } + + // Parse message headers $matches = array(); if (!$method && preg_match('#^(?P[A-Za-z]+)\s+(?P/.*)\s+(?P\w+)/(?P\d\.\d)\s*$#i', $line, $matches)) { $method = strtoupper($matches['method']); @@ -95,9 +103,6 @@ class RequestFactory implements RequestFactoryInterface } } - // Check if a body is present in the message - $body = isset($parts[1]) ? $parts[1] : null; - // Check for the Host header if (isset($headers['Host'])) { $host = $headers['Host']; diff --git a/tests/Guzzle/Tests/Http/Message/RequestFactoryTest.php b/tests/Guzzle/Tests/Http/Message/RequestFactoryTest.php index 0587c2fd..12973de3 100644 --- a/tests/Guzzle/Tests/Http/Message/RequestFactoryTest.php +++ b/tests/Guzzle/Tests/Http/Message/RequestFactoryTest.php @@ -329,7 +329,7 @@ class HttpRequestFactoryTest extends \Guzzle\Tests\GuzzleTestCase * @covers Guzzle\Http\Message\RequestFactory::parseMessage * @covers Guzzle\Http\Message\RequestFactory::create */ - public function testCreatesHttpMessagesWithBodies() + public function testCreatesHttpMessagesWithBodiesAndNormalizesLineEndings() { $message = "POST / http/1.1\r\n" . "Content-Type:application/x-www-form-urlencoded; charset=utf8\r\n" @@ -339,6 +339,15 @@ class HttpRequestFactoryTest extends \Guzzle\Tests\GuzzleTestCase $request = RequestFactory::getInstance()->fromMessage($message); $this->assertEquals('application/x-www-form-urlencoded; charset=utf8', (string) $request->getHeader('Content-Type')); + $this->assertEquals('foo=bar', (string) $request->getBody()); + + $message = "POST / http/1.1\n" + . "Content-Type:application/x-www-form-urlencoded; charset=utf8\n" + . "Date:Mon, 09 Sep 2011 23:36:00 GMT\n" + . "Host:host.foo.com\n\n" + . "foo=bar"; + $request = RequestFactory::getInstance()->fromMessage($message); + $this->assertEquals('foo=bar', (string) $request->getBody()); $message = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n"; $request = RequestFactory::getInstance()->fromMessage($message);