Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Commit

Permalink
Merge branch 'feature/http-headers' of https://github.com/denixport/zf2
Browse files Browse the repository at this point in the history
… into feature/http-header-additions
  • Loading branch information
Show file tree
Hide file tree
Showing 32 changed files with 1,394 additions and 518 deletions.
236 changes: 236 additions & 0 deletions src/Header/AbstractDate.php
@@ -0,0 +1,236 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Uri
*/

namespace Zend\Http\Header;

use DateTime;
use DateTimeZone;

/**
* Abstract Date/Time Header
* Supports headers that have date/time as value
*
* @see Zend\Http\Header\Date
* @see Zend\Http\Header\Expires
* @see Zend\Http\Header\IfModifiedSince
* @see Zend\Http\Header\IfUnmodifiedSince
* @see Zend\Http\Header\LastModified
*
* Note for 'Location' header:
* While RFC 1945 requires an absolute URI, most of the browsers also support relative URI
* This class allows relative URIs, and let user retrieve URI instance if strict validation needed
*
* @category Zend
* @package Zend_Http
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class AbstractDate implements HeaderInterface
{
/**
* Date formats according to RFC 2616
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3
*/
const DATE_RFC1123 = 0;
const DATE_RFC1036 = 1;
const DATE_ANSIC = 2;

/**
* Date instance for this header
*
* @var DateTime
*/
protected $date = null;

/**
* Date output format
*
* @var string
*/
protected static $dateFormat = 'D, d M Y H:i:s \G\M\T';

/**
* Date formats defined by RFC 2616. RFC 1123 date is required
* RFC 1036 and ANSI C formats are provided for compatibility with old servers/clients
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3
*
* @var array
*/
protected static $dateFormats = array(
self::DATE_RFC1123 => 'D, d M Y H:i:s \G\M\T',
self::DATE_RFC1036 => 'D, d M y H:i:s \G\M\T',
self::DATE_ANSIC => 'D M j H:i:s Y',
);

/**
* Create date-based header from string
*
* @param string $headerLine
* @return AbstractDate
* @throws Exception\InvalidArgumentException
*/
public static function fromString($headerLine)
{
$dateHeader = new static();

list($name, $date) = explode(': ', $headerLine, 2);

// check to ensure proper header type for this factory
if (strtolower($name) !== strtolower($dateHeader->getFieldName())) {
throw new Exception\InvalidArgumentException(
'Invalid header line for "' . $dateHeader->getFieldName() . '" header string'
);
}

$dateHeader->setDate($date);

return $dateHeader;
}

/**
* Set date output format
*
* @param int $format
* @throws Exception\InvalidArgumentException
*/
public static function setDateFormat($format)
{
if (!isset(static::$dateFormats[$format])) {
throw new Exception\InvalidArgumentException(
"No constant defined for provided date format: {$format}"
);
}

static::$dateFormat = static::$dateFormats[$format];
}

/**
* Return current date output format
*
* @return string
*/
public static function getDateFormat()
{
return static::$dateFormat;
}

/**
* Set the date for this header, this can be a string or an instance of \DateTime
*
* @param string|DateTime $date
* @return AbstractDate
* @throws Exception\InvalidArgumentException
*/
public function setDate($date)
{
if (is_string($date)) {
try {
$date = new DateTime($date, new DateTimeZone('GMT'));
} catch (\Exception $e) {
throw new Exception\InvalidArgumentException(
sprintf('Invalid date passed as string (%s)', (string) $date),
$e->getCode(),
$e
);
}
} elseif (!($date instanceof DateTime)) {
throw new Exception\InvalidArgumentException('Date must be an instance of \DateTime or a string');
}

$date->setTimezone(new DateTimeZone('GMT'));
$this->date = $date;

return $this;
}

/**
* Return date for this header
*
* @return string
*/
public function getDate()
{
return $this->date()->format(static::$dateFormat);
}

/**
* Return date for this header as an instance of \DateTime
*
* @return DateTime
*/
public function date()
{
if ($this->date === null) {
$this->date = new DateTime(null, new DateTimeZone('GMT'));
}
return $this->date;
}

/**
* Compare provided date to date for this header
* Returns < 0 if date in header is less than $date; > 0 if it's greater, and 0 if they are equal.
* @see \strcmp()
*
* @param string|DateTime $date
* @return int
* @throws Exception\InvalidArgumentException
*/
public function compareTo($date)
{
if (is_string($date)) {
try {
$date = new DateTime($date, new DateTimeZone('GMT'));
} catch (\Exception $e) {
throw new Exception\InvalidArgumentException(
sprintf('Invalid Date passed as string (%s)', (string) $date),
$e->getCode(),
$e
);
}
} elseif (!($date instanceof DateTime)) {
throw new Exception\InvalidArgumentException('Date must be an instance of \DateTime or a string');
}

$dateTimestamp = $date->getTimestamp();
$thisTimestamp = $this->date()->getTimestamp();

return ($thisTimestamp === $dateTimestamp) ? 0 : (($thisTimestamp > $dateTimestamp) ? 1 : -1);
}

/**
* Get header value as formatted date
*
* @return string
*/
public function getFieldValue()
{
return $this->getDate();
}

/**
* Return header line
*
* @return string
*/
public function toString()
{
return $this->getFieldName() . ': ' . $this->getDate();
}

/**
* Allow casting to string
*
* @return string
*/
public function __toString()
{
return $this->toString();
}
}
149 changes: 149 additions & 0 deletions src/Header/AbstractLocation.php
@@ -0,0 +1,149 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Uri
*/

namespace Zend\Http\Header;

use Zend\Uri\Http as HttpUri;
use Zend\Uri\Exception as UriException;

/**
* Abstract Location Header
* Supports headers that have URI as value
* @see Zend\Http\Header\Location
* @see Zend\Http\Header\ContentLocation
* @see Zend\Http\Header\Referer
*
* Note for 'Location' header:
* While RFC 1945 requires an absolute URI, most of the browsers also support relative URI
* This class allows relative URIs, and let user retrieve URI instance if strict validation needed
*
* @category Zend
* @package Zend_Http
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class AbstractLocation implements HeaderInterface
{
/**
* URI for this header
*
* @var HttpUri
*/
protected $uri = null;

/**
* Create location-based header from string
*
* @param string $headerLine
* @return AbstractLocation
* @throws Exception\InvalidArgumentException
*/
public static function fromString($headerLine)
{
$locationHeader = new static();

// ZF-5520 - IIS bug, no space after colon
list($name, $uri) = explode(':', $headerLine, 2);

// check to ensure proper header type for this factory
if (strtolower($name) !== strtolower($locationHeader->getFieldName())) {
throw new Exception\InvalidArgumentException(
'Invalid header line for "' . $locationHeader->getFieldName() . '" header string'
);
}

$locationHeader->setUri(trim($uri));

return $locationHeader;
}

/**
* Set the URI/URL for this header, this can be a string or an instance of Zend\Uri\Http
*
* @param string|HttpUri $uri
* @return AbstractLocation
* @throws Exception\InvalidArgumentException
*/
public function setUri($uri)
{
if (is_string($uri)) {
try {
$uri = new HttpUri($uri);
} catch (UriException\InvalidUriPartException $e) {
throw new Exception\InvalidArgumentException(
sprintf('Invalid URI passed as string (%s)', (string) $uri),
$e->getCode(),
$e
);
}
} elseif (!($uri instanceof HttpUri)) {
throw new Exception\InvalidArgumentException('URI must be an instance of Zend\Uri\Http or a string');
}
$this->uri = $uri;

return $this;
}

/**
* Return the URI for this header
*
* @return string
*/
public function getUri()
{
if ($this->uri instanceof HttpUri) {
return $this->uri->toString();
}
return $this->uri;
}

/**
* Return the URI for this header as an instance of Zend\Uri\Http
*
* @return HttpUri
*/
public function uri()
{
if ($this->uri === null || is_string($this->uri)) {
$this->uri = new HttpUri($this->uri);
}
return $this->uri;
}

/**
* Get header value as URI string
*
* @return string
*/
public function getFieldValue()
{
return $this->getUri();
}

/**
* Output header line
*
* @return string
*/
public function toString()
{
return $this->getFieldName() . ': ' . $this->getUri();
}

/**
* Allow casting to string
*
* @return string
*/
public function __toString()
{
return $this->toString();
}
}

0 comments on commit 9c15ae8

Please sign in to comment.