Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\HttpFoundation; Chris@0: Chris@0: /** Chris@0: * RequestMatcher compares a pre-defined set of checks against a Request instance. Chris@0: * Chris@0: * @author Fabien Potencier Chris@0: */ Chris@0: class RequestMatcher implements RequestMatcherInterface Chris@0: { Chris@0: /** Chris@0: * @var string|null Chris@0: */ Chris@0: private $path; Chris@0: Chris@0: /** Chris@0: * @var string|null Chris@0: */ Chris@0: private $host; Chris@0: Chris@0: /** Chris@0: * @var string[] Chris@0: */ Chris@17: private $methods = []; Chris@0: Chris@0: /** Chris@0: * @var string[] Chris@0: */ Chris@17: private $ips = []; Chris@0: Chris@0: /** Chris@0: * @var array Chris@0: */ Chris@17: private $attributes = []; Chris@0: Chris@0: /** Chris@0: * @var string[] Chris@0: */ Chris@17: private $schemes = []; Chris@0: Chris@0: /** Chris@0: * @param string|null $path Chris@0: * @param string|null $host Chris@0: * @param string|string[]|null $methods Chris@0: * @param string|string[]|null $ips Chris@0: * @param array $attributes Chris@0: * @param string|string[]|null $schemes Chris@0: */ Chris@17: public function __construct($path = null, $host = null, $methods = null, $ips = null, array $attributes = [], $schemes = null) Chris@0: { Chris@0: $this->matchPath($path); Chris@0: $this->matchHost($host); Chris@0: $this->matchMethod($methods); Chris@0: $this->matchIps($ips); Chris@0: $this->matchScheme($schemes); Chris@0: Chris@0: foreach ($attributes as $k => $v) { Chris@0: $this->matchAttribute($k, $v); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a check for the HTTP scheme. Chris@0: * Chris@0: * @param string|string[]|null $scheme An HTTP scheme or an array of HTTP schemes Chris@0: */ Chris@0: public function matchScheme($scheme) Chris@0: { Chris@17: $this->schemes = null !== $scheme ? array_map('strtolower', (array) $scheme) : []; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a check for the URL host name. Chris@0: * Chris@0: * @param string|null $regexp A Regexp Chris@0: */ Chris@0: public function matchHost($regexp) Chris@0: { Chris@0: $this->host = $regexp; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a check for the URL path info. Chris@0: * Chris@0: * @param string|null $regexp A Regexp Chris@0: */ Chris@0: public function matchPath($regexp) Chris@0: { Chris@0: $this->path = $regexp; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a check for the client IP. Chris@0: * Chris@0: * @param string $ip A specific IP address or a range specified using IP/netmask like 192.168.1.0/24 Chris@0: */ Chris@0: public function matchIp($ip) Chris@0: { Chris@0: $this->matchIps($ip); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a check for the client IP. Chris@0: * Chris@0: * @param string|string[]|null $ips A specific IP address or a range specified using IP/netmask like 192.168.1.0/24 Chris@0: */ Chris@0: public function matchIps($ips) Chris@0: { Chris@17: $this->ips = null !== $ips ? (array) $ips : []; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a check for the HTTP method. Chris@0: * Chris@0: * @param string|string[]|null $method An HTTP method or an array of HTTP methods Chris@0: */ Chris@0: public function matchMethod($method) Chris@0: { Chris@17: $this->methods = null !== $method ? array_map('strtoupper', (array) $method) : []; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a check for request attribute. Chris@0: * Chris@0: * @param string $key The request attribute name Chris@0: * @param string $regexp A Regexp Chris@0: */ Chris@0: public function matchAttribute($key, $regexp) Chris@0: { Chris@0: $this->attributes[$key] = $regexp; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function matches(Request $request) Chris@0: { Chris@17: if ($this->schemes && !\in_array($request->getScheme(), $this->schemes, true)) { Chris@0: return false; Chris@0: } Chris@0: Chris@17: if ($this->methods && !\in_array($request->getMethod(), $this->methods, true)) { Chris@0: return false; Chris@0: } Chris@0: Chris@0: foreach ($this->attributes as $key => $pattern) { Chris@0: if (!preg_match('{'.$pattern.'}', $request->attributes->get($key))) { Chris@0: return false; Chris@0: } Chris@0: } Chris@0: Chris@0: if (null !== $this->path && !preg_match('{'.$this->path.'}', rawurldecode($request->getPathInfo()))) { Chris@0: return false; Chris@0: } Chris@0: Chris@0: if (null !== $this->host && !preg_match('{'.$this->host.'}i', $request->getHost())) { Chris@0: return false; Chris@0: } Chris@0: Chris@0: if (IpUtils::checkIp($request->getClientIp(), $this->ips)) { Chris@0: return true; Chris@0: } Chris@0: Chris@0: // Note to future implementors: add additional checks above the Chris@0: // foreach above or else your check might not be run! Chris@17: return 0 === \count($this->ips); Chris@0: } Chris@0: }