From 326dd3090ec5d71c21f2f3fdb3f716ef417d710f Mon Sep 17 00:00:00 2001 From: Nicholas Calugar Date: Fri, 23 Mar 2012 15:10:01 -0700 Subject: [PATCH 01/11] Supporting individual directives in CacheControl header --- src/Header/CacheControl.php | 63 +++++++++++++++++++++++++++++++- test/Header/CacheControlTest.php | 55 +++++++++++++++++++++++++++- 2 files changed, 114 insertions(+), 4 deletions(-) diff --git a/src/Header/CacheControl.php b/src/Header/CacheControl.php index 71caf0e1a2..cb5ac702a4 100755 --- a/src/Header/CacheControl.php +++ b/src/Header/CacheControl.php @@ -9,6 +9,15 @@ class CacheControl implements HeaderDescription { + protected $directives = array(); + + /** + * Creates a CacheControl object from a headerLine + * + * @param string $headerLine + * @throws Exception\InvalidArgumentException + * @return CacheControl + */ public static function fromString($headerLine) { $header = new static(); @@ -21,7 +30,7 @@ public static function fromString($headerLine) } // @todo implementation details - $header->value = $value; + $header->directives = self::parseCacheControl($value); return $header; } @@ -31,9 +40,50 @@ public function getFieldName() return 'Cache-Control'; } + public function isEmpty() + { + return empty($this->directives); + } + + public function addDirective($key, $value = true) + { + $this->directives[$key] = $value; + return $this; + } + + public function hasDirective($key) + { + return array_key_exists($key, $this->directives); + } + + public function getDirective($key) + { + return array_key_exists($key, $this->directives) ? $this->directives[$key] : null; + } + + public function removeDirective($key) + { + unset($this->directives[$key]); + return $this; + } + public function getFieldValue() { - return $this->value; + $parts = array(); + ksort($this->directives); + foreach ($this->directives as $key => $value) { + if (true === $value) { + $parts[] = $key; + } else { + if (preg_match('#[^a-zA-Z0-9._-]#', $value)) { + $value = '"'.$value.'"'; + } + + $parts[] = "$key=$value"; + } + } + + return implode(', ', $parts); } public function toString() @@ -41,4 +91,13 @@ public function toString() return 'Cache-Control: ' . $this->getFieldValue(); } + protected static function parseCacheControl($value) + { + $directives = array(); + preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\s*(?:=(?:"([^"]*)"|([^ \t",;]*)))?#', $value, $matches, PREG_SET_ORDER); + foreach ($matches as $match) { + $directives[strtolower($match[1])] = isset($match[2]) && $match[2] ? $match[2] : (isset($match[3]) ? $match[3] : true); + } + return $directives; + } } diff --git a/test/Header/CacheControlTest.php b/test/Header/CacheControlTest.php index d61b0b2916..41c9ac370d 100644 --- a/test/Header/CacheControlTest.php +++ b/test/Header/CacheControlTest.php @@ -39,6 +39,57 @@ public function testCacheControlToStringReturnsHeaderFormattedString() } /** Implmentation specific tests here */ - -} + public function testCacheControlIsEmpty() + { + $cacheControlHeader = new CacheControl(); + $this->assertTrue($cacheControlHeader->isEmpty()); + $cacheControlHeader->addDirective('xxx'); + $this->assertFalse($cacheControlHeader->isEmpty()); + $cacheControlHeader->removeDirective('xxx'); + $this->assertTrue($cacheControlHeader->isEmpty()); + } + + public function testCacheControlAddHasGetRemove() + { + $cacheControlHeader = new CacheControl(); + $cacheControlHeader->addDirective('xxx'); + $this->assertTrue($cacheControlHeader->hasDirective('xxx')); + $this->assertTrue($cacheControlHeader->getDirective('xxx')); + $cacheControlHeader->removeDirective('xxx'); + $this->assertFalse($cacheControlHeader->hasDirective('xxx')); + $this->assertNull($cacheControlHeader->getDirective('xxx')); + + $cacheControlHeader->addDirective('xxx', 'foo'); + $this->assertTrue($cacheControlHeader->hasDirective('xxx')); + $this->assertEquals('foo', $cacheControlHeader->getDirective('xxx')); + $cacheControlHeader->removeDirective('xxx'); + $this->assertFalse($cacheControlHeader->hasDirective('xxx')); + $this->assertNull($cacheControlHeader->getDirective('xxx')); + } + + public function testCacheControlGetFieldValue() + { + $cacheControlHeader = new CacheControl(); + $this->assertEmpty($cacheControlHeader->getFieldValue()); + $cacheControlHeader->addDirective('xxx'); + $this->assertEquals('xxx', $cacheControlHeader->getFieldValue()); + $cacheControlHeader->addDirective('aaa'); + $this->assertEquals('aaa, xxx', $cacheControlHeader->getFieldValue()); + $cacheControlHeader->addDirective('yyy', 'foo'); + $this->assertEquals('aaa, xxx, yyy=foo', $cacheControlHeader->getFieldValue()); + $cacheControlHeader->addDirective('zzz', 'bar, baz'); + $this->assertEquals('aaa, xxx, yyy=foo, zzz="bar, baz"', $cacheControlHeader->getFieldValue()); + } + + public function testCacheControlParse() + { + $cacheControlHeader = CacheControl::fromString('Cache-Control: a, b=foo, c="bar, baz"'); + $this->assertTrue($cacheControlHeader->hasDirective('a')); + $this->assertTrue($cacheControlHeader->getDirective('a')); + $this->assertTrue($cacheControlHeader->hasDirective('b')); + $this->assertEquals('foo', $cacheControlHeader->getDirective('b')); + $this->assertTrue($cacheControlHeader->hasDirective('c')); + $this->assertEquals('bar, baz', $cacheControlHeader->getDirective('c')); + } +} From cc5e0c3cd6c42a5b07f10581c5bce6f74e432f87 Mon Sep 17 00:00:00 2001 From: Nicholas Calugar Date: Tue, 27 Mar 2012 11:13:44 -0700 Subject: [PATCH 02/11] Using a tokenizer to parse cache control headers --- src/Header/CacheControl.php | 68 +++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 7 deletions(-) diff --git a/src/Header/CacheControl.php b/src/Header/CacheControl.php index cb5ac702a4..885b048bf7 100755 --- a/src/Header/CacheControl.php +++ b/src/Header/CacheControl.php @@ -9,6 +9,8 @@ class CacheControl implements HeaderDescription { + const SEPARATOR = ", \t"; + protected $directives = array(); /** @@ -30,7 +32,7 @@ public static function fromString($headerLine) } // @todo implementation details - $header->directives = self::parseCacheControl($value); + $header->directives = self::parseValue($value); return $header; } @@ -78,11 +80,9 @@ public function getFieldValue() if (preg_match('#[^a-zA-Z0-9._-]#', $value)) { $value = '"'.$value.'"'; } - $parts[] = "$key=$value"; } } - return implode(', ', $parts); } @@ -91,13 +91,67 @@ public function toString() return 'Cache-Control: ' . $this->getFieldValue(); } - protected static function parseCacheControl($value) + protected static function parseValue($value) { $directives = array(); - preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\s*(?:=(?:"([^"]*)"|([^ \t",;]*)))?#', $value, $matches, PREG_SET_ORDER); - foreach ($matches as $match) { - $directives[strtolower($match[1])] = isset($match[2]) && $match[2] ? $match[2] : (isset($match[3]) ? $match[3] : true); + $lastPosition = 0; + while (false !== ($token = self::tokenizer($value, self::SEPARATOR, $lastPosition))) { + $directive = explode('=', trim($token)); + if (false === $directive) { + // explode shouldn't fail + throw new Exception\InvalidArgumentException( + 'Invalid header line for Cache-Control string: "' . $value . '"' + ); + } + if (preg_match('/^[^a-zA-Z]{1,1}/', $directive[0])) { + //directives should start with a letter + throw new Exception\InvalidArgumentException( + 'Invalid Cache-Control directive: "' . $token . '"' + ); + } + $directives[$directive[0]] = true; + if (isset($directive[1])) { + if (!preg_match('/^"([^"]*)"|([^a-zA-Z0-9._-]*)$/', $directive[1])) { + // the value should either be enclosed in quotes or contain only safe chars + throw new Exception\InvalidArgumentException( + 'Invalid Cache-Control directive: "' . $token . '"' + ); + } + $directives[$directive[0]] = trim($directive[1], '"'); + } } return $directives; } + + protected static function tokenizer($string, $sep, &$lastPosition) + { + $quoted = false; + $startPosition = $lastPosition; + $array = str_split($string); + $length = count($array); + if ($lastPosition > $length) { + return false; + } + for ($lastPosition; $lastPosition < $length; $lastPosition++) { + if (!$quoted) { + if ('"' == $array[$lastPosition]) { + $quoted = true; + } elseif (false !== strpos($sep, $array[$lastPosition])) { + if ($startPosition == $lastPosition) { + $startPosition = $lastPosition = $lastPosition++; + continue; + } else { + break; + } + } + } else { + if ('"' == $array[$lastPosition]) { + $quoted = false; + } + } + } + $return = substr($string, $startPosition, $lastPosition - $startPosition); + $lastPosition++; + return $return; + } } From 8de1bc59b183989de5470ccf81c29b43d636ac65 Mon Sep 17 00:00:00 2001 From: Nicholas Calugar Date: Tue, 27 Mar 2012 11:33:38 -0700 Subject: [PATCH 03/11] Using state machine to parse Cache Control header --- src/Header/CacheControl.php | 116 +++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 55 deletions(-) diff --git a/src/Header/CacheControl.php b/src/Header/CacheControl.php index 885b048bf7..e2471206a6 100755 --- a/src/Header/CacheControl.php +++ b/src/Header/CacheControl.php @@ -9,8 +9,6 @@ class CacheControl implements HeaderDescription { - const SEPARATOR = ", \t"; - protected $directives = array(); /** @@ -93,65 +91,73 @@ public function toString() protected static function parseValue($value) { + $value = trim($value); + $directives = array(); - $lastPosition = 0; - while (false !== ($token = self::tokenizer($value, self::SEPARATOR, $lastPosition))) { - $directive = explode('=', trim($token)); - if (false === $directive) { - // explode shouldn't fail - throw new Exception\InvalidArgumentException( - 'Invalid header line for Cache-Control string: "' . $value . '"' - ); - } - if (preg_match('/^[^a-zA-Z]{1,1}/', $directive[0])) { - //directives should start with a letter - throw new Exception\InvalidArgumentException( - 'Invalid Cache-Control directive: "' . $token . '"' - ); - } - $directives[$directive[0]] = true; - if (isset($directive[1])) { - if (!preg_match('/^"([^"]*)"|([^a-zA-Z0-9._-]*)$/', $directive[1])) { - // the value should either be enclosed in quotes or contain only safe chars - throw new Exception\InvalidArgumentException( - 'Invalid Cache-Control directive: "' . $token . '"' - ); - } - $directives[$directive[0]] = trim($directive[1], '"'); - } + + // handle empty string early so we don't need a separate start state + if ($value == '') { + return $directives; + } + + $lastMatch = null; + + state_directive: + switch (self::match(array('[a-zA-Z][a-zA-Z_-]*'), $value, $lastMatch)) { + case 0: + $directive = $lastMatch; + goto state_value; + break; + + default: + throw new Exception\InvalidArgumentException('expected DIRECTIVE'); + break; + } + + state_value: + switch (self::match(array('="[^"]*"', '=[^",\s;]*'), $value, $lastMatch)) { + case 0: + $directives[$directive] = substr($lastMatch, 2, -1); + goto state_separator; + break; + + case 1: + $directives[$directive] = rtrim(substr($lastMatch, 1)); + goto state_separator; + break; + + default: + $directives[$directive] = true; + goto state_separator; + break; + } + + state_separator: + switch (self::match(array('\s*,\s*', '$'), $value, $lastMatch)) { + case 0: + goto state_directive; + break; + + case 1: + return $directives; + break; + + default: + throw new Exception\InvalidArgumentException('expected SEPARATOR or END'); + break; + } - return $directives; } - protected static function tokenizer($string, $sep, &$lastPosition) + protected static function match($tokens, &$string, &$lastMatch) { - $quoted = false; - $startPosition = $lastPosition; - $array = str_split($string); - $length = count($array); - if ($lastPosition > $length) { - return false; - } - for ($lastPosition; $lastPosition < $length; $lastPosition++) { - if (!$quoted) { - if ('"' == $array[$lastPosition]) { - $quoted = true; - } elseif (false !== strpos($sep, $array[$lastPosition])) { - if ($startPosition == $lastPosition) { - $startPosition = $lastPosition = $lastPosition++; - continue; - } else { - break; - } - } - } else { - if ('"' == $array[$lastPosition]) { - $quoted = false; - } + foreach ($tokens as $i => $token) { + if (preg_match('/^'.$token.'/', $string, $matches)) { + $lastMatch = $matches[0]; + $string = substr($string, strlen($matches[0])); + return $i; } } - $return = substr($string, $startPosition, $lastPosition - $startPosition); - $lastPosition++; - return $return; + return -1; } } From 434d81456cc81e3f3900769c9df272c20d7e4f96 Mon Sep 17 00:00:00 2001 From: Nicholas Calugar Date: Tue, 27 Mar 2012 11:50:18 -0700 Subject: [PATCH 04/11] Cookies are already set in the setServer call on line 39 --- src/PhpEnvironment/Request.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/PhpEnvironment/Request.php b/src/PhpEnvironment/Request.php index aa9d56a537..fbe938b7bf 100755 --- a/src/PhpEnvironment/Request.php +++ b/src/PhpEnvironment/Request.php @@ -38,10 +38,6 @@ public function __construct() $this->setQuery(new Parameters($_GET)); $this->setServer(new Parameters($_SERVER)); - if ($_COOKIE) { - $this->setCookies($_COOKIE); - } - if ($_FILES) { $this->setFile(new Parameters($_FILES)); } From c2bc81cdfccd41cda44ece73239a3fb88c838643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Falk=20K=C3=BChnel?= Date: Thu, 12 Apr 2012 21:37:07 +0200 Subject: [PATCH 05/11] fixed camelCase and updated Exception --- src/Request.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Request.php b/src/Request.php index 88542d7164..6db6390419 100644 --- a/src/Request.php +++ b/src/Request.php @@ -180,7 +180,11 @@ public function setUri($uri) $newuri->parse($uri); $uri = $newuri; } catch (Exception\InvalidUriPartException $e) { - throw new exception\invalidargumentexception('invalid uri passed as string: ' . $e->getMessage()); + throw new Exception\InvalidArgumentException( + sprintf('Invalid URI passed as string (%s)', $uri), + $e->getCode(), + $e + ); } } elseif (!($uri instanceof \Zend\Uri\Http)) { throw new Exception\InvalidArgumentException('URI must be an instance of Zend\Uri\Http or a string'); From b4b47a9b1c68c7c1c68d07963b5e18c633799ef9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Falk=20K=C3=BChnel?= Date: Thu, 12 Apr 2012 22:08:21 +0200 Subject: [PATCH 06/11] changed Zend/Uri/Uri to Zend/Uri/Http as HttpUri --- src/Request.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Request.php b/src/Request.php index 6db6390419..aa40516ebb 100644 --- a/src/Request.php +++ b/src/Request.php @@ -176,7 +176,7 @@ public function setUri($uri) { if (is_string($uri)) { try { - $newuri = new \Zend\Uri\Uri; + $newuri = new HttpUri; $newuri->parse($uri); $uri = $newuri; } catch (Exception\InvalidUriPartException $e) { @@ -186,7 +186,7 @@ public function setUri($uri) $e ); } - } elseif (!($uri instanceof \Zend\Uri\Http)) { + } elseif (!($uri instanceof HttpUri)) { throw new Exception\InvalidArgumentException('URI must be an instance of Zend\Uri\Http or a string'); } $this->uri = $uri; From a4fd52f0b909145a6552689116caf1f460eb8ccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Falk=20K=C3=BChnel?= Date: Fri, 13 Apr 2012 21:34:31 +0200 Subject: [PATCH 07/11] added tests for uris with anchors, shortend the uri instantiation --- src/Request.php | 6 ++---- test/RequestTest.php | 22 +++++++++++++++++----- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/Request.php b/src/Request.php index aa40516ebb..5986f64fb6 100644 --- a/src/Request.php +++ b/src/Request.php @@ -176,12 +176,10 @@ public function setUri($uri) { if (is_string($uri)) { try { - $newuri = new HttpUri; - $newuri->parse($uri); - $uri = $newuri; + $uri = new HttpUri($uri); } catch (Exception\InvalidUriPartException $e) { throw new Exception\InvalidArgumentException( - sprintf('Invalid URI passed as string (%s)', $uri), + sprintf('Invalid URI passed as string (%s)', (string) $uri), $e->getCode(), $e ); diff --git a/test/RequestTest.php b/test/RequestTest.php index e67bf5ebfc..41a51221e2 100644 --- a/test/RequestTest.php +++ b/test/RequestTest.php @@ -82,14 +82,26 @@ public function testRequestCanAlwaysForcesUppecaseMethodName() $this->assertEquals('GET', $request->getMethod()); } - public function testRequestCanSetAndRetrieveUri() + /** + * @dataProvider uriDataProvider + */ + public function testRequestCanSetAndRetrieveUri($uri) { $request = new Request(); - $request->setUri('/foo'); - $this->assertEquals('/foo', $request->getUri()); + $request->setUri($uri); + $this->assertEquals($uri, $request->getUri()); $this->assertInstanceOf('Zend\Uri\Uri', $request->uri()); - $this->assertEquals('/foo', $request->uri()->toString()); - $this->assertEquals('/foo', $request->getUri()); + $this->assertEquals($uri, $request->uri()->toString()); + $this->assertEquals($uri, $request->getUri()); + } + + public function uriDataProvider() + { + return array( + array('/foo'), + array('/foo#test'), + array('/hello?what=true#noway') + ); } public function testRequestSetUriWillThrowExceptionOnInvalidArgument() From ed16b35e2998d811532ac81e8e0732ca0527bbb2 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 20 Apr 2012 09:01:24 -0500 Subject: [PATCH 08/11] Fixes HTTP socket tests - Stream was not being properly initialized by Http\Client; added logic to initialize it when no resource is present but stream usage is indicated. --- src/Client.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Client.php b/src/Client.php index 583df68267..ccfe8eb229 100755 --- a/src/Client.php +++ b/src/Client.php @@ -832,6 +832,14 @@ public function send(Request $request = null) } if ($this->config['outputstream']) { + $stream = $this->getStream(); + if (!is_resource($stream) && is_string($stream)) { + $stream = fopen($stream, 'r'); + } + if (!is_resource($stream)) { + $stream = $this->getUri()->toString(); + $stream = fopen($stream, 'r'); + } $streamMetaData = stream_get_meta_data($stream); if ($streamMetaData['seekable']) { rewind($stream); From 9d61905287b38a984138ebc4b2d2396b616b77ea Mon Sep 17 00:00:00 2001 From: prolic Date: Sun, 22 Apr 2012 14:58:17 +0200 Subject: [PATCH 09/11] [zen-27] Renamed interfaces in Zend\Stdlib, refactored: use Zend\Stdlib\DispatchableInterface => use Zend\Stdlib\DispatchableInterface as Dispatchable, Zend\Stdlib\RequestInterface => Zend\Stdlib\RequestInterface as Request, ... --- src/Client.php | 40 +++++++++++++++++++++------------------- src/Cookies.php | 3 +-- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/Client.php b/src/Client.php index e7c7842e4d..78c28b155b 100755 --- a/src/Client.php +++ b/src/Client.php @@ -25,11 +25,13 @@ Zend\Uri\Http, Zend\Http\Header\Cookie, Zend\Http\Header\SetCookie, + Zend\Http\Request as HttpRequest, + Zend\Http\Response as HttpResponse, + Zend\Http\Response\Stream as HttpResponseStream, Zend\Stdlib\Parameters, - Zend\Stdlib\ParametersInterface, - Zend\Stdlib\DispatchableInterface, - Zend\Stdlib\RequestInterface, - Zend\Stdlib\ResponseInterface; + Zend\Stdlib\DispatchableInterface as Dispatchable, + Zend\Stdlib\RequestInterface as Request, + Zend\Stdlib\ResponseInterface as Response; /** * Http client @@ -39,7 +41,7 @@ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ -class Client implements DispatchableInterface +class Client implements Dispatchable { /** * @const string Supported HTTP Authentication methods @@ -124,7 +126,7 @@ class Client implements DispatchableInterface 'useragent' => 'Zend\Http\Client', 'timeout' => 10, 'adapter' => 'Zend\Http\Client\Adapter\Socket', - 'httpversion' => Request::VERSION_11, + 'httpversion' => HttpRequest::VERSION_11, 'storeresponse' => true, 'keepalive' => false, 'outputstream' => false, @@ -195,7 +197,7 @@ public function setConfig($config = array()) * * @param Client\Adapter|string $adapter * @return Client - * @throws \Zend\Http\Client\Exception + * @throws Client\Exception\InvalidArgumentException */ public function setAdapter($adapter) { @@ -247,7 +249,7 @@ public function setRequest(Request $request) public function getRequest() { if (empty($this->request)) { - $this->request = new Request(); + $this->request = new HttpRequest(); } return $this->request; } @@ -272,7 +274,7 @@ public function setResponse(Response $response) public function getResponse() { if (empty($this->response)) { - $this->response = new Response(); + $this->response = new HttpResponse(); } return $this->response; } @@ -352,8 +354,8 @@ public function setMethod($method) { $method = $this->getRequest()->setMethod($method)->getMethod(); - if (($method == Request::METHOD_POST || $method == Request::METHOD_PUT || - $method == Request::METHOD_DELETE || $method == Request::METHOD_PATCH) + if (($method == HttpRequest::METHOD_POST || $method == HttpRequest::METHOD_PUT || + $method == HttpRequest::METHOD_DELETE || $method == HttpRequest::METHOD_PATCH) && empty($this->encType)) { $this->setEncType(self::ENC_URLENCODED); } @@ -732,11 +734,11 @@ public function resetParameters($clearCookies = false) /** * Dispatch * - * @param RequestInterface $request - * @param ResponseInterface $response - * @return ResponseInterface + * @param Request $request + * @param Response $response + * @return Response */ - public function dispatch(RequestInterface $request, ResponseInterface $response = null) + public function dispatch(Request $request, Response $response = null) { $response = $this->send($request); return $response; @@ -846,14 +848,14 @@ public function send(Request $request = null) } // cleanup the adapter $this->adapter->setOutputStream(null); - $response = Response\Stream::fromStream($response, $stream); + $response = HttpResponseStream::fromStream($response, $stream); $response->setStreamName($this->streamName); if (!is_string($this->config['outputstream'])) { // we used temp name, will need to clean up $response->setCleanup(true); } } else { - $response = Response::fromString($response); + $response = HttpResponse::fromString($response); } // Get the cookies from response (if any) @@ -876,7 +878,7 @@ public function send(Request $request = null) $response->getStatusCode() == 301))) { $this->resetParameters(); - $this->setMethod(Request::METHOD_GET); + $this->setMethod(HttpRequest::METHOD_GET); } // If we got a well formed absolute URI @@ -1016,7 +1018,7 @@ protected function prepareHeaders($body, $uri) $headers = array(); // Set the host header - if ($this->config['httpversion'] == Request::VERSION_11) { + if ($this->config['httpversion'] == HttpRequest::VERSION_11) { $host = $uri->getHost(); // If the port is not default, add it if (!(($uri->getScheme() == 'http' && $uri->getPort() == 80) || diff --git a/src/Cookies.php b/src/Cookies.php index b1158b4565..b9927973ca 100755 --- a/src/Cookies.php +++ b/src/Cookies.php @@ -2,8 +2,7 @@ namespace Zend\Http; -use Zend\Stdlib\ParametersInterface, - Zend\Uri, +use Zend\Uri, Zend\Http\Header\Cookie, Zend\Http\Response; From 316f26a0c727174b2896ae76938f60e41e46813d Mon Sep 17 00:00:00 2001 From: Nicholas Calugar Date: Fri, 4 May 2012 15:36:47 -0700 Subject: [PATCH 10/11] Adding DocBlocks --- src/Header/CacheControl.php | 67 +++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/Header/CacheControl.php b/src/Header/CacheControl.php index e2471206a6..c4f4bf5875 100755 --- a/src/Header/CacheControl.php +++ b/src/Header/CacheControl.php @@ -9,6 +9,11 @@ class CacheControl implements HeaderDescription { + /** + * Array of Cache-Control directives + * + * @var array + */ protected $directives = array(); /** @@ -35,38 +40,80 @@ public static function fromString($headerLine) return $header; } + /** + * Required from HeaderDescription interface + * + * @return string + */ public function getFieldName() { return 'Cache-Control'; } + /** + * Checks if the internal directives array is empty + * + * @return boolean + */ public function isEmpty() { return empty($this->directives); } + /** + * Add a directive + * For directives like 'max-age=60', $value = '60' + * For directives like 'private', use the default $value = true + * + * @param string $key + * @param string|boolean $value + * @return CacheControl - provides the fluent interface + */ public function addDirective($key, $value = true) { $this->directives[$key] = $value; return $this; } + /** + * Check the internal directives array for a directive + * + * @param string $key + * @return boolean + */ public function hasDirective($key) { return array_key_exists($key, $this->directives); } + /** + * Fetch the value of a directive from the internal directive array + * + * @param string $key + * @return string|null + */ public function getDirective($key) { return array_key_exists($key, $this->directives) ? $this->directives[$key] : null; } + /** + * Remove a directive + * + * @param string $key + * @return CacheControl - provides the fluent interface + */ public function removeDirective($key) { unset($this->directives[$key]); return $this; } + /** + * Assembles the directives into a comma-delimeted string + * + * @return string + */ public function getFieldValue() { $parts = array(); @@ -84,11 +131,24 @@ public function getFieldValue() return implode(', ', $parts); } + /** + * Returns a string representation of the HTTP Cache-Control header + * + * @return string + */ public function toString() { return 'Cache-Control: ' . $this->getFieldValue(); } + /** + * Internal function for parsing the value part of a + * HTTP Cache-Control header + * + * @param string $value + * @throws Exception\InvalidArgumentException + * @return array + */ protected static function parseValue($value) { $value = trim($value); @@ -149,6 +209,13 @@ protected static function parseValue($value) } } + /** + * Internal function used by parseValue to match tokens + * + * @param array $tokens + * @param string $string + * @param string $lastMatch + */ protected static function match($tokens, &$string, &$lastMatch) { foreach ($tokens as $i => $token) { From 385f9eed7c1959a6618bc5ab2a17fd283fddae7f Mon Sep 17 00:00:00 2001 From: DeNix Date: Fri, 27 Apr 2012 19:14:01 +0400 Subject: [PATCH 11/11] minor CS fixes --- src/Client.php | 5 ++--- src/Response.php | 14 ++++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Client.php b/src/Client.php index 444681531e..1a6a670398 100755 --- a/src/Client.php +++ b/src/Client.php @@ -1204,7 +1204,7 @@ protected function detectFileMimeType($file) public function encodeFormData($boundary, $name, $value, $filename = null, $headers = array()) { $ret = "--{$boundary}\r\n" . - 'Content-Disposition: form-data; name="' . $name .'"'; + 'Content-Disposition: form-data; name="' . $name . '"'; if ($filename) { $ret .= '; filename="' . $filename . '"'; @@ -1215,7 +1215,6 @@ public function encodeFormData($boundary, $name, $value, $filename = null, $head $ret .= "{$hname}: {$hvalue}\r\n"; } $ret .= "\r\n"; - $ret .= "{$value}\r\n"; return $ret; @@ -1298,4 +1297,4 @@ protected function doRequest(Http $uri, $method, $secure = false, $headers = arr return $this->adapter->read(); } -} +} \ No newline at end of file diff --git a/src/Response.php b/src/Response.php index 4e23016c60..256d3905c1 100644 --- a/src/Response.php +++ b/src/Response.php @@ -176,7 +176,7 @@ class Response extends Message implements ResponseDescription public static function fromString($string) { $lines = explode("\r\n", $string); - if (!is_array($lines) || count($lines)==1) { + if (!is_array($lines) || count($lines) == 1) { $lines = explode("\n", $string); } @@ -487,13 +487,15 @@ protected function decodeChunkedBody($body) while (trim($body)) { if (! preg_match("/^([\da-fA-F]+)[^\r\n]*\r\n/sm", $body, $m)) { - throw new Exception\RuntimeException("Error parsing body - doesn't seem to be a chunked message"); + throw new Exception\RuntimeException( + "Error parsing body - doesn't seem to be a chunked message" + ); } - $length = hexdec(trim($m[1])); - $cut = strlen($m[0]); + $length = hexdec(trim($m[1])); + $cut = strlen($m[0]); $decBody .= substr($body, $cut, $length); - $body = substr($body, $cut + $length + 2); + $body = substr($body, $cut + $length + 2); } return $decBody; @@ -553,4 +555,4 @@ protected function decodeDeflate($body) return gzinflate($body); } } -} +} \ No newline at end of file