Http.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\App\Request;
  7. use Magento\Framework\App\HttpRequestInterface;
  8. use Magento\Framework\App\RequestContentInterface;
  9. use Magento\Framework\App\RequestSafetyInterface;
  10. use Magento\Framework\App\Route\ConfigInterface\Proxy as ConfigInterface;
  11. use Magento\Framework\HTTP\PhpEnvironment\Request;
  12. use Magento\Framework\ObjectManagerInterface;
  13. use Magento\Framework\Stdlib\Cookie\CookieReaderInterface;
  14. use Magento\Framework\Stdlib\StringUtils;
  15. /**
  16. * Http request
  17. */
  18. class Http extends Request implements RequestContentInterface, RequestSafetyInterface, HttpRequestInterface
  19. {
  20. /**#@+
  21. * HTTP Ports
  22. */
  23. const DEFAULT_HTTP_PORT = 80;
  24. const DEFAULT_HTTPS_PORT = 443;
  25. /**#@-*/
  26. // Configuration path
  27. const XML_PATH_OFFLOADER_HEADER = 'web/secure/offloader_header';
  28. /**
  29. * @var string
  30. */
  31. protected $route;
  32. /**
  33. * PATH_INFO
  34. *
  35. * @var string
  36. */
  37. protected $pathInfo = '';
  38. /**
  39. * ORIGINAL_PATH_INFO
  40. *
  41. * @var string
  42. */
  43. protected $originalPathInfo = '';
  44. /**
  45. * @var array
  46. */
  47. protected $directFrontNames;
  48. /**
  49. * @var string
  50. */
  51. protected $controllerModule;
  52. /**
  53. * Request's original information before forward.
  54. *
  55. * @var array
  56. */
  57. protected $beforeForwardInfo = [];
  58. /**
  59. * @var ConfigInterface
  60. */
  61. protected $routeConfig;
  62. /**
  63. * @var PathInfoProcessorInterface
  64. */
  65. protected $pathInfoProcessor;
  66. /**
  67. * @var ObjectManagerInterface
  68. */
  69. protected $objectManager;
  70. /**
  71. * @var bool|null
  72. */
  73. protected $isSafeMethod = null;
  74. /**
  75. * @var array
  76. */
  77. protected $safeRequestTypes = ['GET', 'HEAD', 'TRACE', 'OPTIONS'];
  78. /**
  79. * @var string
  80. */
  81. private $distroBaseUrl;
  82. /**
  83. * @var PathInfo
  84. */
  85. private $pathInfoService;
  86. /**
  87. * @param CookieReaderInterface $cookieReader
  88. * @param StringUtils $converter
  89. * @param ConfigInterface $routeConfig
  90. * @param PathInfoProcessorInterface $pathInfoProcessor
  91. * @param ObjectManagerInterface $objectManager
  92. * @param \Zend\Uri\UriInterface|string|null $uri
  93. * @param array $directFrontNames
  94. * @param PathInfo|null $pathInfoService
  95. */
  96. public function __construct(
  97. CookieReaderInterface $cookieReader,
  98. StringUtils $converter,
  99. ConfigInterface $routeConfig,
  100. PathInfoProcessorInterface $pathInfoProcessor,
  101. ObjectManagerInterface $objectManager,
  102. $uri = null,
  103. $directFrontNames = [],
  104. PathInfo $pathInfoService = null
  105. ) {
  106. parent::__construct($cookieReader, $converter, $uri);
  107. $this->routeConfig = $routeConfig;
  108. $this->pathInfoProcessor = $pathInfoProcessor;
  109. $this->objectManager = $objectManager;
  110. $this->directFrontNames = $directFrontNames;
  111. $this->pathInfoService = $pathInfoService ?: \Magento\Framework\App\ObjectManager::getInstance()->get(
  112. PathInfo::class
  113. );
  114. }
  115. /**
  116. * Return the ORIGINAL_PATH_INFO.
  117. * This value is calculated and processed from $_SERVER due to cross-platform differences.
  118. * instead of reading PATH_INFO
  119. *
  120. * @return string
  121. */
  122. public function getOriginalPathInfo()
  123. {
  124. if (empty($this->originalPathInfo)) {
  125. $originalPathInfoFromRequest = $this->pathInfoService->getPathInfo(
  126. $this->getRequestUri(),
  127. $this->getBaseUrl()
  128. );
  129. $this->originalPathInfo = (string)$this->pathInfoProcessor->process($this, $originalPathInfoFromRequest);
  130. $this->requestString = $this->originalPathInfo
  131. . $this->pathInfoService->getQueryString($this->getRequestUri());
  132. }
  133. return $this->originalPathInfo;
  134. }
  135. /**
  136. * Return the path info
  137. *
  138. * @return string
  139. */
  140. public function getPathInfo()
  141. {
  142. if (empty($this->pathInfo)) {
  143. $this->pathInfo = $this->getOriginalPathInfo();
  144. }
  145. return $this->pathInfo;
  146. }
  147. /**
  148. * Set the PATH_INFO string.
  149. *
  150. * Set the ORIGINAL_PATH_INFO string.
  151. *
  152. * @param string|null $pathInfo
  153. * @return $this
  154. */
  155. public function setPathInfo($pathInfo = null)
  156. {
  157. $this->pathInfo = (string)$pathInfo;
  158. return $this;
  159. }
  160. /**
  161. * Check if code declared as direct access frontend name.
  162. *
  163. * This means what this url can be used without store code.
  164. *
  165. * @param string $code
  166. * @return bool
  167. */
  168. public function isDirectAccessFrontendName($code)
  169. {
  170. return isset($this->directFrontNames[$code]);
  171. }
  172. /**
  173. * Get base path
  174. *
  175. * @return string
  176. */
  177. public function getBasePath()
  178. {
  179. $path = parent::getBasePath();
  180. if (empty($path)) {
  181. $path = '/';
  182. } else {
  183. $path = str_replace('\\', '/', $path);
  184. }
  185. return $path;
  186. }
  187. /**
  188. * Retrieve request front name
  189. *
  190. * @return string|null
  191. */
  192. public function getFrontName()
  193. {
  194. $pathParts = explode('/', trim($this->getPathInfo(), '/'));
  195. return reset($pathParts);
  196. }
  197. /**
  198. * Set route name
  199. *
  200. * @param string $route
  201. * @return $this
  202. */
  203. public function setRouteName($route)
  204. {
  205. $this->route = $route;
  206. $module = $this->routeConfig->getRouteFrontName($route);
  207. if ($module) {
  208. $this->setModuleName($module);
  209. }
  210. return $this;
  211. }
  212. /**
  213. * Retrieve route name
  214. *
  215. * @return string|null
  216. */
  217. public function getRouteName()
  218. {
  219. return $this->route;
  220. }
  221. /**
  222. * Specify module name where was found currently used controller
  223. *
  224. * @param string $module
  225. * @return $this
  226. */
  227. public function setControllerModule($module)
  228. {
  229. $this->controllerModule = $module;
  230. return $this;
  231. }
  232. /**
  233. * Get module name of currently used controller
  234. *
  235. * @return string
  236. */
  237. public function getControllerModule()
  238. {
  239. return $this->controllerModule;
  240. }
  241. /**
  242. * Collect properties changed by _forward in protected storage before _forward was called first time.
  243. *
  244. * @return $this
  245. */
  246. public function initForward()
  247. {
  248. if (empty($this->beforeForwardInfo)) {
  249. $this->beforeForwardInfo = [
  250. 'params' => $this->getParams(),
  251. 'action_name' => $this->getActionName(),
  252. 'controller_name' => $this->getControllerName(),
  253. 'module_name' => $this->getModuleName(),
  254. 'route_name' => $this->getRouteName(),
  255. ];
  256. }
  257. return $this;
  258. }
  259. /**
  260. * Retrieve property's value which was before _forward call.
  261. * If property was not changed during _forward call null will be returned.
  262. * If passed name will be null whole state array will be returned.
  263. *
  264. * @param string $name
  265. * @return array|string|null
  266. */
  267. public function getBeforeForwardInfo($name = null)
  268. {
  269. if ($name === null) {
  270. return $this->beforeForwardInfo;
  271. } elseif (isset($this->beforeForwardInfo[$name])) {
  272. return $this->beforeForwardInfo[$name];
  273. }
  274. return null;
  275. }
  276. /**
  277. * Check is Request from AJAX
  278. *
  279. * @return boolean
  280. */
  281. public function isAjax()
  282. {
  283. if ($this->isXmlHttpRequest()) {
  284. return true;
  285. }
  286. if ($this->getParam('ajax') || $this->getParam('isAjax')) {
  287. return true;
  288. }
  289. return false;
  290. }
  291. /**
  292. * Get website instance base url
  293. *
  294. * @return string
  295. *
  296. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  297. */
  298. public function getDistroBaseUrl()
  299. {
  300. if ($this->distroBaseUrl) {
  301. return $this->distroBaseUrl;
  302. }
  303. $headerHttpHost = $this->getServer('HTTP_HOST');
  304. $headerHttpHost = $this->converter->cleanString($headerHttpHost);
  305. $headerScriptName = $this->getServer('SCRIPT_NAME');
  306. if (isset($headerScriptName) && isset($headerHttpHost)) {
  307. if ($secure = $this->isSecure()) {
  308. $scheme = 'https://';
  309. } else {
  310. $scheme = 'http://';
  311. }
  312. $hostArr = explode(':', $headerHttpHost);
  313. $host = $hostArr[0];
  314. $port = isset($hostArr[1])
  315. && (!$secure && $hostArr[1] != 80 || $secure && $hostArr[1] != 443) ? ':' . $hostArr[1] : '';
  316. $path = $this->getBasePath();
  317. return $this->distroBaseUrl = $scheme . $host . $port . rtrim($path, '/') . '/';
  318. }
  319. return 'http://localhost/';
  320. }
  321. /**
  322. * Determines a base URL path from environment
  323. *
  324. * @param array $server
  325. * @return string
  326. */
  327. public static function getDistroBaseUrlPath($server)
  328. {
  329. $result = '';
  330. if (isset($server['SCRIPT_NAME'])) {
  331. $envPath = str_replace('\\', '/', dirname(str_replace('\\', '/', $server['SCRIPT_NAME'])));
  332. if ($envPath != '.' && $envPath != '/') {
  333. $result = $envPath;
  334. }
  335. }
  336. if (!preg_match('/\/$/', $result)) {
  337. $result .= '/';
  338. }
  339. return $result;
  340. }
  341. /**
  342. * Return url with no script name
  343. *
  344. * @param string $url
  345. * @return string
  346. */
  347. public static function getUrlNoScript($url)
  348. {
  349. if (!isset($_SERVER['SCRIPT_NAME'])) {
  350. return $url;
  351. }
  352. if (($pos = strripos($url, basename($_SERVER['SCRIPT_NAME']))) !== false) {
  353. $url = substr($url, 0, $pos);
  354. }
  355. return $url;
  356. }
  357. /**
  358. * Retrieve full action name
  359. *
  360. * @param string $delimiter
  361. * @return string
  362. */
  363. public function getFullActionName($delimiter = '_')
  364. {
  365. return $this->getRouteName() .
  366. $delimiter .
  367. $this->getControllerName() .
  368. $delimiter .
  369. $this->getActionName();
  370. }
  371. /**
  372. * Sleep
  373. *
  374. * @return array
  375. */
  376. public function __sleep()
  377. {
  378. return [];
  379. }
  380. /**
  381. * @inheritdoc
  382. */
  383. public function isSafeMethod()
  384. {
  385. if ($this->isSafeMethod === null) {
  386. if (isset($_SERVER['REQUEST_METHOD']) && (in_array($_SERVER['REQUEST_METHOD'], $this->safeRequestTypes))) {
  387. $this->isSafeMethod = true;
  388. } else {
  389. $this->isSafeMethod = false;
  390. }
  391. }
  392. return $this->isSafeMethod;
  393. }
  394. }