PageRenderTime 49ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/zendframework/zend-http/src/PhpEnvironment/Request.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 582 lines | 338 code | 66 blank | 178 comment | 63 complexity | c8e98050ea3b7d2b1944d2414c600e9c MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace Zend\Http\PhpEnvironment;
  10. use Zend\Http\Header\Cookie;
  11. use Zend\Http\Request as HttpRequest;
  12. use Zend\Stdlib\Parameters;
  13. use Zend\Stdlib\ParametersInterface;
  14. use Zend\Uri\Http as HttpUri;
  15. use Zend\Validator\Hostname as HostnameValidator;
  16. /**
  17. * HTTP Request for current PHP environment
  18. */
  19. class Request extends HttpRequest
  20. {
  21. /**
  22. * Base URL of the application.
  23. *
  24. * @var string
  25. */
  26. protected $baseUrl;
  27. /**
  28. * Base Path of the application.
  29. *
  30. * @var string
  31. */
  32. protected $basePath;
  33. /**
  34. * Actual request URI, independent of the platform.
  35. *
  36. * @var string
  37. */
  38. protected $requestUri;
  39. /**
  40. * PHP server params ($_SERVER)
  41. *
  42. * @var ParametersInterface
  43. */
  44. protected $serverParams = null;
  45. /**
  46. * PHP environment params ($_ENV)
  47. *
  48. * @var ParametersInterface
  49. */
  50. protected $envParams = null;
  51. /**
  52. * Construct
  53. * Instantiates request.
  54. *
  55. * @param bool $allowCustomMethods
  56. */
  57. public function __construct($allowCustomMethods = true)
  58. {
  59. $this->setAllowCustomMethods($allowCustomMethods);
  60. $this->setEnv(new Parameters($_ENV));
  61. if ($_GET) {
  62. $this->setQuery(new Parameters($_GET));
  63. }
  64. if ($_POST) {
  65. $this->setPost(new Parameters($_POST));
  66. }
  67. if ($_COOKIE) {
  68. $this->setCookies(new Parameters($_COOKIE));
  69. }
  70. if ($_FILES) {
  71. // convert PHP $_FILES superglobal
  72. $files = $this->mapPhpFiles();
  73. $this->setFiles(new Parameters($files));
  74. }
  75. $this->setServer(new Parameters($_SERVER));
  76. }
  77. /**
  78. * Get raw request body
  79. *
  80. * @return string
  81. */
  82. public function getContent()
  83. {
  84. if (empty($this->content)) {
  85. $requestBody = file_get_contents('php://input');
  86. if (strlen($requestBody) > 0) {
  87. $this->content = $requestBody;
  88. }
  89. }
  90. return $this->content;
  91. }
  92. /**
  93. * Set cookies
  94. *
  95. * Instantiate and set cookies.
  96. *
  97. * @param $cookie
  98. * @return Request
  99. */
  100. public function setCookies($cookie)
  101. {
  102. $this->getHeaders()->addHeader(new Cookie((array) $cookie));
  103. return $this;
  104. }
  105. /**
  106. * Set the request URI.
  107. *
  108. * @param string $requestUri
  109. * @return self
  110. */
  111. public function setRequestUri($requestUri)
  112. {
  113. $this->requestUri = $requestUri;
  114. return $this;
  115. }
  116. /**
  117. * Get the request URI.
  118. *
  119. * @return string
  120. */
  121. public function getRequestUri()
  122. {
  123. if ($this->requestUri === null) {
  124. $this->requestUri = $this->detectRequestUri();
  125. }
  126. return $this->requestUri;
  127. }
  128. /**
  129. * Set the base URL.
  130. *
  131. * @param string $baseUrl
  132. * @return self
  133. */
  134. public function setBaseUrl($baseUrl)
  135. {
  136. $this->baseUrl = rtrim($baseUrl, '/');
  137. return $this;
  138. }
  139. /**
  140. * Get the base URL.
  141. *
  142. * @return string
  143. */
  144. public function getBaseUrl()
  145. {
  146. if ($this->baseUrl === null) {
  147. $this->setBaseUrl($this->detectBaseUrl());
  148. }
  149. return $this->baseUrl;
  150. }
  151. /**
  152. * Set the base path.
  153. *
  154. * @param string $basePath
  155. * @return self
  156. */
  157. public function setBasePath($basePath)
  158. {
  159. $this->basePath = rtrim($basePath, '/');
  160. return $this;
  161. }
  162. /**
  163. * Get the base path.
  164. *
  165. * @return string
  166. */
  167. public function getBasePath()
  168. {
  169. if ($this->basePath === null) {
  170. $this->setBasePath($this->detectBasePath());
  171. }
  172. return $this->basePath;
  173. }
  174. /**
  175. * Provide an alternate Parameter Container implementation for server parameters in this object,
  176. * (this is NOT the primary API for value setting, for that see getServer())
  177. *
  178. * @param ParametersInterface $server
  179. * @return Request
  180. */
  181. public function setServer(ParametersInterface $server)
  182. {
  183. $this->serverParams = $server;
  184. // This seems to be the only way to get the Authorization header on Apache
  185. if (function_exists('apache_request_headers')) {
  186. $apacheRequestHeaders = apache_request_headers();
  187. if (!isset($this->serverParams['HTTP_AUTHORIZATION'])) {
  188. if (isset($apacheRequestHeaders['Authorization'])) {
  189. $this->serverParams->set('HTTP_AUTHORIZATION', $apacheRequestHeaders['Authorization']);
  190. } elseif (isset($apacheRequestHeaders['authorization'])) {
  191. $this->serverParams->set('HTTP_AUTHORIZATION', $apacheRequestHeaders['authorization']);
  192. }
  193. }
  194. }
  195. // set headers
  196. $headers = array();
  197. foreach ($server as $key => $value) {
  198. if ($value || (!is_array($value) && strlen($value))) {
  199. if (strpos($key, 'HTTP_') === 0) {
  200. if (strpos($key, 'HTTP_COOKIE') === 0) {
  201. // Cookies are handled using the $_COOKIE superglobal
  202. continue;
  203. }
  204. $headers[strtr(ucwords(strtolower(strtr(substr($key, 5), '_', ' '))), ' ', '-')] = $value;
  205. } elseif (strpos($key, 'CONTENT_') === 0) {
  206. $name = substr($key, 8); // Remove "Content-"
  207. $headers['Content-' . (($name == 'MD5') ? $name : ucfirst(strtolower($name)))] = $value;
  208. }
  209. }
  210. }
  211. $this->getHeaders()->addHeaders($headers);
  212. // set method
  213. if (isset($this->serverParams['REQUEST_METHOD'])) {
  214. $this->setMethod($this->serverParams['REQUEST_METHOD']);
  215. }
  216. // set HTTP version
  217. if (isset($this->serverParams['SERVER_PROTOCOL'])
  218. && strpos($this->serverParams['SERVER_PROTOCOL'], self::VERSION_10) !== false
  219. ) {
  220. $this->setVersion(self::VERSION_10);
  221. }
  222. // set URI
  223. $uri = new HttpUri();
  224. // URI scheme
  225. if ((!empty($this->serverParams['HTTPS']) && strtolower($this->serverParams['HTTPS']) !== 'off')
  226. || (!empty($this->serverParams['HTTP_X_FORWARDED_PROTO'])
  227. && $this->serverParams['HTTP_X_FORWARDED_PROTO'] == 'https')
  228. ) {
  229. $scheme = 'https';
  230. } else {
  231. $scheme = 'http';
  232. }
  233. $uri->setScheme($scheme);
  234. // URI host & port
  235. $host = null;
  236. $port = null;
  237. // Set the host
  238. if ($this->getHeaders()->get('host')) {
  239. $host = $this->getHeaders()->get('host')->getFieldValue();
  240. // works for regname, IPv4 & IPv6
  241. if (preg_match('|\:(\d+)$|', $host, $matches)) {
  242. $host = substr($host, 0, -1 * (strlen($matches[1]) + 1));
  243. $port = (int) $matches[1];
  244. }
  245. // set up a validator that check if the hostname is legal (not spoofed)
  246. $hostnameValidator = new HostnameValidator(array(
  247. 'allow' => HostnameValidator::ALLOW_ALL,
  248. 'useIdnCheck' => false,
  249. 'useTldCheck' => false,
  250. ));
  251. // If invalid. Reset the host & port
  252. if (!$hostnameValidator->isValid($host)) {
  253. $host = null;
  254. $port = null;
  255. }
  256. }
  257. if (!$host && isset($this->serverParams['SERVER_NAME'])) {
  258. $host = $this->serverParams['SERVER_NAME'];
  259. if (isset($this->serverParams['SERVER_PORT'])) {
  260. $port = (int) $this->serverParams['SERVER_PORT'];
  261. }
  262. // Check for missinterpreted IPv6-Address
  263. // Reported at least for Safari on Windows
  264. if (isset($this->serverParams['SERVER_ADDR']) && preg_match('/^\[[0-9a-fA-F\:]+\]$/', $host)) {
  265. $host = '[' . $this->serverParams['SERVER_ADDR'] . ']';
  266. if ($port . ']' == substr($host, strrpos($host, ':')+1)) {
  267. // The last digit of the IPv6-Address has been taken as port
  268. // Unset the port so the default port can be used
  269. $port = null;
  270. }
  271. }
  272. }
  273. $uri->setHost($host);
  274. $uri->setPort($port);
  275. // URI path
  276. $requestUri = $this->getRequestUri();
  277. if (($qpos = strpos($requestUri, '?')) !== false) {
  278. $requestUri = substr($requestUri, 0, $qpos);
  279. }
  280. $uri->setPath($requestUri);
  281. // URI query
  282. if (isset($this->serverParams['QUERY_STRING'])) {
  283. $uri->setQuery($this->serverParams['QUERY_STRING']);
  284. }
  285. $this->setUri($uri);
  286. return $this;
  287. }
  288. /**
  289. * Return the parameter container responsible for server parameters or a single parameter value.
  290. *
  291. * @param string|null $name Parameter name to retrieve, or null to get the whole container.
  292. * @param mixed|null $default Default value to use when the parameter is missing.
  293. * @see http://www.faqs.org/rfcs/rfc3875.html
  294. * @return \Zend\Stdlib\ParametersInterface|mixed
  295. */
  296. public function getServer($name = null, $default = null)
  297. {
  298. if ($this->serverParams === null) {
  299. $this->serverParams = new Parameters();
  300. }
  301. if ($name === null) {
  302. return $this->serverParams;
  303. }
  304. return $this->serverParams->get($name, $default);
  305. }
  306. /**
  307. * Provide an alternate Parameter Container implementation for env parameters in this object,
  308. * (this is NOT the primary API for value setting, for that see env())
  309. *
  310. * @param ParametersInterface $env
  311. * @return Request
  312. */
  313. public function setEnv(ParametersInterface $env)
  314. {
  315. $this->envParams = $env;
  316. return $this;
  317. }
  318. /**
  319. * Return the parameter container responsible for env parameters or a single parameter value.
  320. *
  321. * @param string|null $name Parameter name to retrieve, or null to get the whole container.
  322. * @param mixed|null $default Default value to use when the parameter is missing.
  323. * @return \Zend\Stdlib\ParametersInterface|mixed
  324. */
  325. public function getEnv($name = null, $default = null)
  326. {
  327. if ($this->envParams === null) {
  328. $this->envParams = new Parameters();
  329. }
  330. if ($name === null) {
  331. return $this->envParams;
  332. }
  333. return $this->envParams->get($name, $default);
  334. }
  335. /**
  336. * Convert PHP superglobal $_FILES into more sane parameter=value structure
  337. * This handles form file input with brackets (name=files[])
  338. *
  339. * @return array
  340. */
  341. protected function mapPhpFiles()
  342. {
  343. $files = array();
  344. foreach ($_FILES as $fileName => $fileParams) {
  345. $files[$fileName] = array();
  346. foreach ($fileParams as $param => $data) {
  347. if (!is_array($data)) {
  348. $files[$fileName][$param] = $data;
  349. } else {
  350. foreach ($data as $i => $v) {
  351. $this->mapPhpFileParam($files[$fileName], $param, $i, $v);
  352. }
  353. }
  354. }
  355. }
  356. return $files;
  357. }
  358. /**
  359. * @param array $array
  360. * @param string $paramName
  361. * @param int|string $index
  362. * @param string|array $value
  363. */
  364. protected function mapPhpFileParam(&$array, $paramName, $index, $value)
  365. {
  366. if (!is_array($value)) {
  367. $array[$index][$paramName] = $value;
  368. } else {
  369. foreach ($value as $i => $v) {
  370. $this->mapPhpFileParam($array[$index], $paramName, $i, $v);
  371. }
  372. }
  373. }
  374. /**
  375. * Detect the base URI for the request
  376. *
  377. * Looks at a variety of criteria in order to attempt to autodetect a base
  378. * URI, including rewrite URIs, proxy URIs, etc.
  379. *
  380. * @return string
  381. */
  382. protected function detectRequestUri()
  383. {
  384. $requestUri = null;
  385. $server = $this->getServer();
  386. // Check this first so IIS will catch.
  387. $httpXRewriteUrl = $server->get('HTTP_X_REWRITE_URL');
  388. if ($httpXRewriteUrl !== null) {
  389. $requestUri = $httpXRewriteUrl;
  390. }
  391. // Check for IIS 7.0 or later with ISAPI_Rewrite
  392. $httpXOriginalUrl = $server->get('HTTP_X_ORIGINAL_URL');
  393. if ($httpXOriginalUrl !== null) {
  394. $requestUri = $httpXOriginalUrl;
  395. }
  396. // IIS7 with URL Rewrite: make sure we get the unencoded url
  397. // (double slash problem).
  398. $iisUrlRewritten = $server->get('IIS_WasUrlRewritten');
  399. $unencodedUrl = $server->get('UNENCODED_URL', '');
  400. if ('1' == $iisUrlRewritten && '' !== $unencodedUrl) {
  401. return $unencodedUrl;
  402. }
  403. // HTTP proxy requests setup request URI with scheme and host [and port]
  404. // + the URL path, only use URL path.
  405. if (!$httpXRewriteUrl) {
  406. $requestUri = $server->get('REQUEST_URI');
  407. }
  408. if ($requestUri !== null) {
  409. return preg_replace('#^[^/:]+://[^/]+#', '', $requestUri);
  410. }
  411. // IIS 5.0, PHP as CGI.
  412. $origPathInfo = $server->get('ORIG_PATH_INFO');
  413. if ($origPathInfo !== null) {
  414. $queryString = $server->get('QUERY_STRING', '');
  415. if ($queryString !== '') {
  416. $origPathInfo .= '?' . $queryString;
  417. }
  418. return $origPathInfo;
  419. }
  420. return '/';
  421. }
  422. /**
  423. * Auto-detect the base path from the request environment
  424. *
  425. * Uses a variety of criteria in order to detect the base URL of the request
  426. * (i.e., anything additional to the document root).
  427. *
  428. *
  429. * @return string
  430. */
  431. protected function detectBaseUrl()
  432. {
  433. $filename = $this->getServer()->get('SCRIPT_FILENAME', '');
  434. $scriptName = $this->getServer()->get('SCRIPT_NAME');
  435. $phpSelf = $this->getServer()->get('PHP_SELF');
  436. $origScriptName = $this->getServer()->get('ORIG_SCRIPT_NAME');
  437. if ($scriptName !== null && basename($scriptName) === $filename) {
  438. $baseUrl = $scriptName;
  439. } elseif ($phpSelf !== null && basename($phpSelf) === $filename) {
  440. $baseUrl = $phpSelf;
  441. } elseif ($origScriptName !== null && basename($origScriptName) === $filename) {
  442. // 1and1 shared hosting compatibility.
  443. $baseUrl = $origScriptName;
  444. } else {
  445. // Backtrack up the SCRIPT_FILENAME to find the portion
  446. // matching PHP_SELF.
  447. $baseUrl = '/';
  448. $basename = basename($filename);
  449. if ($basename) {
  450. $path = ($phpSelf ? trim($phpSelf, '/') : '');
  451. $basePos = strpos($path, $basename) ?: 0;
  452. $baseUrl .= substr($path, 0, $basePos) . $basename;
  453. }
  454. }
  455. // Does the base URL have anything in common with the request URI?
  456. $requestUri = $this->getRequestUri();
  457. // Full base URL matches.
  458. if (0 === strpos($requestUri, $baseUrl)) {
  459. return $baseUrl;
  460. }
  461. // Directory portion of base path matches.
  462. $baseDir = str_replace('\\', '/', dirname($baseUrl));
  463. if (0 === strpos($requestUri, $baseDir)) {
  464. return $baseDir;
  465. }
  466. $truncatedRequestUri = $requestUri;
  467. if (false !== ($pos = strpos($requestUri, '?'))) {
  468. $truncatedRequestUri = substr($requestUri, 0, $pos);
  469. }
  470. $basename = basename($baseUrl);
  471. // No match whatsoever
  472. if (empty($basename) || false === strpos($truncatedRequestUri, $basename)) {
  473. return '';
  474. }
  475. // If using mod_rewrite or ISAPI_Rewrite strip the script filename
  476. // out of the base path. $pos !== 0 makes sure it is not matching a
  477. // value from PATH_INFO or QUERY_STRING.
  478. if (strlen($requestUri) >= strlen($baseUrl)
  479. && (false !== ($pos = strpos($requestUri, $baseUrl)) && $pos !== 0)
  480. ) {
  481. $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
  482. }
  483. return $baseUrl;
  484. }
  485. /**
  486. * Autodetect the base path of the request
  487. *
  488. * Uses several criteria to determine the base path of the request.
  489. *
  490. * @return string
  491. */
  492. protected function detectBasePath()
  493. {
  494. $filename = basename($this->getServer()->get('SCRIPT_FILENAME', ''));
  495. $baseUrl = $this->getBaseUrl();
  496. // Empty base url detected
  497. if ($baseUrl === '') {
  498. return '';
  499. }
  500. // basename() matches the script filename; return the directory
  501. if (basename($baseUrl) === $filename) {
  502. return str_replace('\\', '/', dirname($baseUrl));
  503. }
  504. // Base path is identical to base URL
  505. return $baseUrl;
  506. }
  507. }