update v1.0.7.9 R.C.

This is a Release Candidate. We are still testing.
This commit is contained in:
Sujit Prasad
2016-08-03 20:04:36 +05:30
parent 8b6b924d09
commit ffa56a43cb
3830 changed files with 181529 additions and 495353 deletions

View File

@@ -0,0 +1,171 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Http\PhpEnvironment;
/**
* Functionality for determining client IP address.
*/
class RemoteAddress
{
/**
* Whether to use proxy addresses or not.
*
* As default this setting is disabled - IP address is mostly needed to increase
* security. HTTP_* are not reliable since can easily be spoofed. It can be enabled
* just for more flexibility, but if user uses proxy to connect to trusted services
* it's his/her own risk, only reliable field for IP address is $_SERVER['REMOTE_ADDR'].
*
* @var bool
*/
protected $useProxy = false;
/**
* List of trusted proxy IP addresses
*
* @var array
*/
protected $trustedProxies = [];
/**
* HTTP header to introspect for proxies
*
* @var string
*/
protected $proxyHeader = 'HTTP_X_FORWARDED_FOR';
/**
* Changes proxy handling setting.
*
* This must be static method, since validators are recovered automatically
* at session read, so this is the only way to switch setting.
*
* @param bool $useProxy Whether to check also proxied IP addresses.
* @return RemoteAddress
*/
public function setUseProxy($useProxy = true)
{
$this->useProxy = $useProxy;
return $this;
}
/**
* Checks proxy handling setting.
*
* @return bool Current setting value.
*/
public function getUseProxy()
{
return $this->useProxy;
}
/**
* Set list of trusted proxy addresses
*
* @param array $trustedProxies
* @return RemoteAddress
*/
public function setTrustedProxies(array $trustedProxies)
{
$this->trustedProxies = $trustedProxies;
return $this;
}
/**
* Set the header to introspect for proxy IPs
*
* @param string $header
* @return RemoteAddress
*/
public function setProxyHeader($header = 'X-Forwarded-For')
{
$this->proxyHeader = $this->normalizeProxyHeader($header);
return $this;
}
/**
* Returns client IP address.
*
* @return string IP address.
*/
public function getIpAddress()
{
$ip = $this->getIpAddressFromProxy();
if ($ip) {
return $ip;
}
// direct IP address
if (isset($_SERVER['REMOTE_ADDR'])) {
return $_SERVER['REMOTE_ADDR'];
}
return '';
}
/**
* Attempt to get the IP address for a proxied client
*
* @see http://tools.ietf.org/html/draft-ietf-appsawg-http-forwarded-10#section-5.2
* @return false|string
*/
protected function getIpAddressFromProxy()
{
if (!$this->useProxy
|| (isset($_SERVER['REMOTE_ADDR']) && !in_array($_SERVER['REMOTE_ADDR'], $this->trustedProxies))
) {
return false;
}
$header = $this->proxyHeader;
if (!isset($_SERVER[$header]) || empty($_SERVER[$header])) {
return false;
}
// Extract IPs
$ips = explode(',', $_SERVER[$header]);
// trim, so we can compare against trusted proxies properly
$ips = array_map('trim', $ips);
// remove trusted proxy IPs
$ips = array_diff($ips, $this->trustedProxies);
// Any left?
if (empty($ips)) {
return false;
}
// Since we've removed any known, trusted proxy servers, the right-most
// address represents the first IP we do not know about -- i.e., we do
// not know if it is a proxy server, or a client. As such, we treat it
// as the originating IP.
// @see http://en.wikipedia.org/wiki/X-Forwarded-For
$ip = array_pop($ips);
return $ip;
}
/**
* Normalize a header string
*
* Normalizes a header string to a format that is compatible with
* $_SERVER
*
* @param string $header
* @return string
*/
protected function normalizeProxyHeader($header)
{
$header = strtoupper($header);
$header = str_replace('-', '_', $header);
if (0 !== strpos($header, 'HTTP_')) {
$header = 'HTTP_' . $header;
}
return $header;
}
}

View File

@@ -0,0 +1,587 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Http\PhpEnvironment;
use Zend\Http\Header\Cookie;
use Zend\Http\Request as HttpRequest;
use Zend\Stdlib\Parameters;
use Zend\Stdlib\ParametersInterface;
use Zend\Uri\Http as HttpUri;
use Zend\Validator\Hostname as HostnameValidator;
/**
* HTTP Request for current PHP environment
*/
class Request extends HttpRequest
{
/**
* Base URL of the application.
*
* @var string
*/
protected $baseUrl;
/**
* Base Path of the application.
*
* @var string
*/
protected $basePath;
/**
* Actual request URI, independent of the platform.
*
* @var string
*/
protected $requestUri;
/**
* PHP server params ($_SERVER)
*
* @var ParametersInterface
*/
protected $serverParams = null;
/**
* PHP environment params ($_ENV)
*
* @var ParametersInterface
*/
protected $envParams = null;
/**
* Construct
* Instantiates request.
*
* @param bool $allowCustomMethods
*/
public function __construct($allowCustomMethods = true)
{
$this->setAllowCustomMethods($allowCustomMethods);
$this->setEnv(new Parameters($_ENV));
if ($_GET) {
$this->setQuery(new Parameters($_GET));
}
if ($_POST) {
$this->setPost(new Parameters($_POST));
}
if ($_COOKIE) {
$this->setCookies(new Parameters($_COOKIE));
}
if ($_FILES) {
// convert PHP $_FILES superglobal
$files = $this->mapPhpFiles();
$this->setFiles(new Parameters($files));
}
$this->setServer(new Parameters($_SERVER));
}
/**
* Get raw request body
*
* @return string
*/
public function getContent()
{
if (empty($this->content)) {
$requestBody = file_get_contents('php://input');
if (strlen($requestBody) > 0) {
$this->content = $requestBody;
}
}
return $this->content;
}
/**
* Set cookies
*
* Instantiate and set cookies.
*
* @param $cookie
* @return Request
*/
public function setCookies($cookie)
{
$this->getHeaders()->addHeader(new Cookie((array) $cookie));
return $this;
}
/**
* Set the request URI.
*
* @param string $requestUri
* @return self
*/
public function setRequestUri($requestUri)
{
$this->requestUri = $requestUri;
return $this;
}
/**
* Get the request URI.
*
* @return string
*/
public function getRequestUri()
{
if ($this->requestUri === null) {
$this->requestUri = $this->detectRequestUri();
}
return $this->requestUri;
}
/**
* Set the base URL.
*
* @param string $baseUrl
* @return self
*/
public function setBaseUrl($baseUrl)
{
$this->baseUrl = rtrim($baseUrl, '/');
return $this;
}
/**
* Get the base URL.
*
* @return string
*/
public function getBaseUrl()
{
if ($this->baseUrl === null) {
$this->setBaseUrl($this->detectBaseUrl());
}
return $this->baseUrl;
}
/**
* Set the base path.
*
* @param string $basePath
* @return self
*/
public function setBasePath($basePath)
{
$this->basePath = rtrim($basePath, '/');
return $this;
}
/**
* Get the base path.
*
* @return string
*/
public function getBasePath()
{
if ($this->basePath === null) {
$this->setBasePath($this->detectBasePath());
}
return $this->basePath;
}
/**
* Provide an alternate Parameter Container implementation for server parameters in this object,
* (this is NOT the primary API for value setting, for that see getServer())
*
* @param ParametersInterface $server
* @return Request
*/
public function setServer(ParametersInterface $server)
{
$this->serverParams = $server;
// This seems to be the only way to get the Authorization header on Apache
if (function_exists('apache_request_headers')) {
$apacheRequestHeaders = apache_request_headers();
if (!isset($this->serverParams['HTTP_AUTHORIZATION'])) {
if (isset($apacheRequestHeaders['Authorization'])) {
$this->serverParams->set('HTTP_AUTHORIZATION', $apacheRequestHeaders['Authorization']);
} elseif (isset($apacheRequestHeaders['authorization'])) {
$this->serverParams->set('HTTP_AUTHORIZATION', $apacheRequestHeaders['authorization']);
}
}
}
// set headers
$headers = [];
foreach ($server as $key => $value) {
if ($value || (!is_array($value) && strlen($value))) {
if (strpos($key, 'HTTP_') === 0) {
if (strpos($key, 'HTTP_COOKIE') === 0) {
// Cookies are handled using the $_COOKIE superglobal
continue;
}
$headers[strtr(ucwords(strtolower(strtr(substr($key, 5), '_', ' '))), ' ', '-')] = $value;
} elseif (strpos($key, 'CONTENT_') === 0) {
$name = substr($key, 8); // Remove "Content-"
$headers['Content-' . (($name == 'MD5') ? $name : ucfirst(strtolower($name)))] = $value;
}
}
}
$this->getHeaders()->addHeaders($headers);
// set method
if (isset($this->serverParams['REQUEST_METHOD'])) {
$this->setMethod($this->serverParams['REQUEST_METHOD']);
}
// set HTTP version
if (isset($this->serverParams['SERVER_PROTOCOL'])
&& strpos($this->serverParams['SERVER_PROTOCOL'], self::VERSION_10) !== false
) {
$this->setVersion(self::VERSION_10);
}
// set URI
$uri = new HttpUri();
// URI scheme
if ((!empty($this->serverParams['HTTPS']) && strtolower($this->serverParams['HTTPS']) !== 'off')
|| (!empty($this->serverParams['HTTP_X_FORWARDED_PROTO'])
&& $this->serverParams['HTTP_X_FORWARDED_PROTO'] == 'https')
) {
$scheme = 'https';
} else {
$scheme = 'http';
}
$uri->setScheme($scheme);
// URI host & port
$host = null;
$port = null;
// Set the host
if ($this->getHeaders()->get('host')) {
$host = $this->getHeaders()->get('host')->getFieldValue();
// works for regname, IPv4 & IPv6
if (preg_match('|\:(\d+)$|', $host, $matches)) {
$host = substr($host, 0, -1 * (strlen($matches[1]) + 1));
$port = (int) $matches[1];
}
// set up a validator that check if the hostname is legal (not spoofed)
$hostnameValidator = new HostnameValidator([
'allow' => HostnameValidator::ALLOW_ALL,
'useIdnCheck' => false,
'useTldCheck' => false,
]);
// If invalid. Reset the host & port
if (!$hostnameValidator->isValid($host)) {
$host = null;
$port = null;
}
}
if (!$host && isset($this->serverParams['SERVER_NAME'])) {
$host = $this->serverParams['SERVER_NAME'];
if (isset($this->serverParams['SERVER_PORT'])) {
$port = (int) $this->serverParams['SERVER_PORT'];
}
// Check for missinterpreted IPv6-Address
// Reported at least for Safari on Windows
if (isset($this->serverParams['SERVER_ADDR']) && preg_match('/^\[[0-9a-fA-F\:]+\]$/', $host)) {
$host = '[' . $this->serverParams['SERVER_ADDR'] . ']';
if ($port . ']' == substr($host, strrpos($host, ':')+1)) {
// The last digit of the IPv6-Address has been taken as port
// Unset the port so the default port can be used
$port = null;
}
}
}
$uri->setHost($host);
$uri->setPort($port);
// URI path
$requestUri = $this->getRequestUri();
if (($qpos = strpos($requestUri, '?')) !== false) {
$requestUri = substr($requestUri, 0, $qpos);
}
$uri->setPath($requestUri);
// URI query
if (isset($this->serverParams['QUERY_STRING'])) {
$uri->setQuery($this->serverParams['QUERY_STRING']);
}
$this->setUri($uri);
return $this;
}
/**
* Return the parameter container responsible for server parameters or a single parameter value.
*
* @param string|null $name Parameter name to retrieve, or null to get the whole container.
* @param mixed|null $default Default value to use when the parameter is missing.
* @see http://www.faqs.org/rfcs/rfc3875.html
* @return \Zend\Stdlib\ParametersInterface|mixed
*/
public function getServer($name = null, $default = null)
{
if ($this->serverParams === null) {
$this->serverParams = new Parameters();
}
if ($name === null) {
return $this->serverParams;
}
return $this->serverParams->get($name, $default);
}
/**
* Provide an alternate Parameter Container implementation for env parameters in this object,
* (this is NOT the primary API for value setting, for that see env())
*
* @param ParametersInterface $env
* @return Request
*/
public function setEnv(ParametersInterface $env)
{
$this->envParams = $env;
return $this;
}
/**
* Return the parameter container responsible for env parameters or a single parameter value.
*
* @param string|null $name Parameter name to retrieve, or null to get the whole container.
* @param mixed|null $default Default value to use when the parameter is missing.
* @return \Zend\Stdlib\ParametersInterface|mixed
*/
public function getEnv($name = null, $default = null)
{
if ($this->envParams === null) {
$this->envParams = new Parameters();
}
if ($name === null) {
return $this->envParams;
}
return $this->envParams->get($name, $default);
}
/**
* Convert PHP superglobal $_FILES into more sane parameter=value structure
* This handles form file input with brackets (name=files[])
*
* @return array
*/
protected function mapPhpFiles()
{
$files = [];
foreach ($_FILES as $fileName => $fileParams) {
$files[$fileName] = [];
foreach ($fileParams as $param => $data) {
if (!is_array($data)) {
$files[$fileName][$param] = $data;
} else {
foreach ($data as $i => $v) {
$this->mapPhpFileParam($files[$fileName], $param, $i, $v);
}
}
}
}
return $files;
}
/**
* @param array $array
* @param string $paramName
* @param int|string $index
* @param string|array $value
*/
protected function mapPhpFileParam(&$array, $paramName, $index, $value)
{
if (!is_array($value)) {
$array[$index][$paramName] = $value;
} else {
foreach ($value as $i => $v) {
$this->mapPhpFileParam($array[$index], $paramName, $i, $v);
}
}
}
/**
* Detect the base URI for the request
*
* Looks at a variety of criteria in order to attempt to autodetect a base
* URI, including rewrite URIs, proxy URIs, etc.
*
* @return string
*/
protected function detectRequestUri()
{
$requestUri = null;
$server = $this->getServer();
// Check this first so IIS will catch.
$httpXRewriteUrl = $server->get('HTTP_X_REWRITE_URL');
if ($httpXRewriteUrl !== null) {
$requestUri = $httpXRewriteUrl;
}
// Check for IIS 7.0 or later with ISAPI_Rewrite
$httpXOriginalUrl = $server->get('HTTP_X_ORIGINAL_URL');
if ($httpXOriginalUrl !== null) {
$requestUri = $httpXOriginalUrl;
}
// IIS7 with URL Rewrite: make sure we get the unencoded url
// (double slash problem).
$iisUrlRewritten = $server->get('IIS_WasUrlRewritten');
$unencodedUrl = $server->get('UNENCODED_URL', '');
if ('1' == $iisUrlRewritten && '' !== $unencodedUrl) {
return $unencodedUrl;
}
// HTTP proxy requests setup request URI with scheme and host [and port]
// + the URL path, only use URL path.
if (!$httpXRewriteUrl) {
$requestUri = $server->get('REQUEST_URI');
}
if ($requestUri !== null) {
return preg_replace('#^[^/:]+://[^/]+#', '', $requestUri);
}
// IIS 5.0, PHP as CGI.
$origPathInfo = $server->get('ORIG_PATH_INFO');
if ($origPathInfo !== null) {
$queryString = $server->get('QUERY_STRING', '');
if ($queryString !== '') {
$origPathInfo .= '?' . $queryString;
}
return $origPathInfo;
}
return '/';
}
/**
* Auto-detect the base path from the request environment
*
* Uses a variety of criteria in order to detect the base URL of the request
* (i.e., anything additional to the document root).
*
*
* @return string
*/
protected function detectBaseUrl()
{
$filename = $this->getServer()->get('SCRIPT_FILENAME', '');
$scriptName = $this->getServer()->get('SCRIPT_NAME');
$phpSelf = $this->getServer()->get('PHP_SELF');
$origScriptName = $this->getServer()->get('ORIG_SCRIPT_NAME');
if ($scriptName !== null && basename($scriptName) === $filename) {
$baseUrl = $scriptName;
} elseif ($phpSelf !== null && basename($phpSelf) === $filename) {
$baseUrl = $phpSelf;
} elseif ($origScriptName !== null && basename($origScriptName) === $filename) {
// 1and1 shared hosting compatibility.
$baseUrl = $origScriptName;
} else {
// Backtrack up the SCRIPT_FILENAME to find the portion
// matching PHP_SELF.
$baseUrl = '/';
$basename = basename($filename);
if ($basename) {
$path = ($phpSelf ? trim($phpSelf, '/') : '');
$basePos = strpos($path, $basename) ?: 0;
$baseUrl .= substr($path, 0, $basePos) . $basename;
}
}
// If the baseUrl is empty, then simply return it.
if (empty($baseUrl)) {
return '';
}
// Does the base URL have anything in common with the request URI?
$requestUri = $this->getRequestUri();
// Full base URL matches.
if (0 === strpos($requestUri, $baseUrl)) {
return $baseUrl;
}
// Directory portion of base path matches.
$baseDir = str_replace('\\', '/', dirname($baseUrl));
if (0 === strpos($requestUri, $baseDir)) {
return $baseDir;
}
$truncatedRequestUri = $requestUri;
if (false !== ($pos = strpos($requestUri, '?'))) {
$truncatedRequestUri = substr($requestUri, 0, $pos);
}
$basename = basename($baseUrl);
// No match whatsoever
if (empty($basename) || false === strpos($truncatedRequestUri, $basename)) {
return '';
}
// If using mod_rewrite or ISAPI_Rewrite strip the script filename
// out of the base path. $pos !== 0 makes sure it is not matching a
// value from PATH_INFO or QUERY_STRING.
if (strlen($requestUri) >= strlen($baseUrl)
&& (false !== ($pos = strpos($requestUri, $baseUrl)) && $pos !== 0)
) {
$baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
}
return $baseUrl;
}
/**
* Autodetect the base path of the request
*
* Uses several criteria to determine the base path of the request.
*
* @return string
*/
protected function detectBasePath()
{
$filename = basename($this->getServer()->get('SCRIPT_FILENAME', ''));
$baseUrl = $this->getBaseUrl();
// Empty base url detected
if ($baseUrl === '') {
return '';
}
// basename() matches the script filename; return the directory
if (basename($baseUrl) === $filename) {
return str_replace('\\', '/', dirname($baseUrl));
}
// Base path is identical to base URL
return $baseUrl;
}
}

View File

@@ -0,0 +1,132 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Http\PhpEnvironment;
use Zend\Http\Header\MultipleHeaderInterface;
use Zend\Http\Response as HttpResponse;
/**
* HTTP Response for current PHP environment
*/
class Response extends HttpResponse
{
/**
* The current used version
* (The value will be detected on getVersion)
*
* @var null|string
*/
protected $version;
/**
* @var bool
*/
protected $contentSent = false;
/**
* Return the HTTP version for this response
*
* @return string
* @see \Zend\Http\AbstractMessage::getVersion()
*/
public function getVersion()
{
if (!$this->version) {
$this->version = $this->detectVersion();
}
return $this->version;
}
/**
* Detect the current used protocol version.
* If detection failed it falls back to version 1.0.
*
* @return string
*/
protected function detectVersion()
{
if (isset($_SERVER['SERVER_PROTOCOL']) && $_SERVER['SERVER_PROTOCOL'] == 'HTTP/1.1') {
return self::VERSION_11;
}
return self::VERSION_10;
}
/**
* @return bool
*/
public function headersSent()
{
return headers_sent();
}
/**
* @return bool
*/
public function contentSent()
{
return $this->contentSent;
}
/**
* Send HTTP headers
*
* @return Response
*/
public function sendHeaders()
{
if ($this->headersSent()) {
return $this;
}
$status = $this->renderStatusLine();
header($status);
/** @var \Zend\Http\Header\HeaderInterface $header */
foreach ($this->getHeaders() as $header) {
if ($header instanceof MultipleHeaderInterface) {
header($header->toString(), false);
continue;
}
header($header->toString());
}
$this->headersSent = true;
return $this;
}
/**
* Send content
*
* @return Response
*/
public function sendContent()
{
if ($this->contentSent()) {
return $this;
}
echo $this->getContent();
$this->contentSent = true;
return $this;
}
/**
* Send HTTP response
*
* @return Response
*/
public function send()
{
$this->sendHeaders()
->sendContent();
return $this;
}
}