%PDF- %PDF-
Direktori : /www/varak.net/losik.varak.net/vendor/nette/http/src/Bridges/HttpDI/ |
Current File : /www/varak.net/losik.varak.net/vendor/nette/http/src/Bridges/HttpDI/HttpExtension.php |
<?php /** * This file is part of the Nette Framework (https://nette.org) * Copyright (c) 2004 David Grudl (https://davidgrudl.com) */ declare(strict_types=1); namespace Nette\Bridges\HttpDI; use Nette; use Nette\Schema\Expect; /** * HTTP extension for Nette DI. */ class HttpExtension extends Nette\DI\CompilerExtension { /** @var bool */ private $cliMode; public function __construct(bool $cliMode = false) { $this->cliMode = $cliMode; } public function getConfigSchema(): Nette\Schema\Schema { return Expect::structure([ 'proxy' => Expect::anyOf(Expect::arrayOf('string'), Expect::string()->castTo('array'))->firstIsDefault()->dynamic(), 'headers' => Expect::arrayOf('scalar|null')->default([ 'X-Powered-By' => 'Nette Framework 3', 'Content-Type' => 'text/html; charset=utf-8', ])->mergeDefaults(), 'frames' => Expect::anyOf(Expect::string(), Expect::bool(), null)->default('SAMEORIGIN'), // X-Frame-Options 'csp' => Expect::arrayOf('array|scalar|null'), // Content-Security-Policy 'cspReportOnly' => Expect::arrayOf('array|scalar|null'), // Content-Security-Policy-Report-Only 'featurePolicy' => Expect::arrayOf('array|scalar|null'), // Feature-Policy 'cookiePath' => Expect::string()->dynamic(), 'cookieDomain' => Expect::string()->dynamic(), 'cookieSecure' => Expect::anyOf('auto', null, true, false)->firstIsDefault()->dynamic(), // Whether the cookie is available only through HTTPS 'disableNetteCookie' => Expect::bool(false), // disables cookie use by Nette ]); } public function loadConfiguration() { $builder = $this->getContainerBuilder(); $config = $this->config; $builder->addDefinition($this->prefix('requestFactory')) ->setFactory(Nette\Http\RequestFactory::class) ->addSetup('setProxy', [$config->proxy]); $request = $builder->addDefinition($this->prefix('request')) ->setFactory('@Nette\Http\RequestFactory::fromGlobals'); $response = $builder->addDefinition($this->prefix('response')) ->setFactory(Nette\Http\Response::class); if ($config->cookiePath !== null) { $response->addSetup('$cookiePath', [$config->cookiePath]); } if ($config->cookieDomain !== null) { $value = $config->cookieDomain === 'domain' ? $builder::literal('$this->getService(?)->getUrl()->getDomain(2)', [$request->getName()]) : $config->cookieDomain; $response->addSetup('$cookieDomain', [$value]); } if ($config->cookieSecure !== null) { $value = $config->cookieSecure === 'auto' ? $builder::literal('$this->getService(?)->isSecured()', [$request->getName()]) : $config->cookieSecure; $response->addSetup('$cookieSecure', [$value]); } if ($this->name === 'http') { $builder->addAlias('nette.httpRequestFactory', $this->prefix('requestFactory')); $builder->addAlias('httpRequest', $this->prefix('request')); $builder->addAlias('httpResponse', $this->prefix('response')); } if (!$this->cliMode) { $this->sendHeaders(); } } private function sendHeaders() { $config = $this->config; $headers = array_map('strval', $config->headers); if (isset($config->frames) && $config->frames !== true && !isset($headers['X-Frame-Options'])) { $frames = $config->frames; if ($frames === false) { $frames = 'DENY'; } elseif (preg_match('#^https?:#', $frames)) { $frames = "ALLOW-FROM $frames"; } $headers['X-Frame-Options'] = $frames; } foreach (['csp', 'cspReportOnly'] as $key) { if (empty($config->$key)) { continue; } $value = self::buildPolicy($config->$key); if (strpos($value, "'nonce'")) { $this->initialization->addBody('$cspNonce = base64_encode(random_bytes(16));'); $value = Nette\DI\ContainerBuilder::literal( 'str_replace(?, ? . $cspNonce, ?)', ["'nonce", "'nonce-", $value] ); } $headers['Content-Security-Policy' . ($key === 'csp' ? '' : '-Report-Only')] = $value; } if (!empty($config->featurePolicy)) { $headers['Feature-Policy'] = self::buildPolicy($config->featurePolicy); } $this->initialization->addBody('$response = $this->getService(?);', [$this->prefix('response')]); foreach ($headers as $key => $value) { if ($value !== '') { $this->initialization->addBody('$response->setHeader(?, ?);', [$key, $value]); } } if (!$config->disableNetteCookie) { $this->initialization->addBody( 'Nette\Http\Helpers::initCookie($this->getService(?), $response);', [$this->prefix('request')] ); } } private static function buildPolicy(array $config): string { $nonQuoted = ['require-sri-for' => 1, 'sandbox' => 1]; $value = ''; foreach ($config as $type => $policy) { if ($policy === false) { continue; } $policy = $policy === true ? [] : (array) $policy; $value .= $type; foreach ($policy as $item) { if (is_array($item)) { $item = key($item) . ':'; } $value .= !isset($nonQuoted[$type]) && preg_match('#^[a-z-]+$#D', $item) ? " '$item'" : " $item"; } $value .= '; '; } return $value; } }