[HttpFoundation] added request matcher
This commit is contained in:
parent
af96c87104
commit
4f337615e3
@ -134,7 +134,7 @@ class Request
|
||||
'SERVER_NAME' => 'localhost',
|
||||
'SERVER_PORT' => 80,
|
||||
'HTTP_HOST' => 'localhost',
|
||||
'HTTP_USER_AGENT' => 'Symfony/X.X',
|
||||
'HTTP_USER_AGENT' => 'Symfony/2.X',
|
||||
'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5',
|
||||
'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
|
||||
|
105
src/Symfony/Component/HttpFoundation/RequestMatcher.php
Normal file
105
src/Symfony/Component/HttpFoundation/RequestMatcher.php
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\HttpFoundation;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* RequestMatcher compares a pre-defined set of checks against a Request instance.
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class RequestMatcher implements RequestMatcherInterface
|
||||
{
|
||||
protected $path;
|
||||
protected $host;
|
||||
protected $methods;
|
||||
protected $ip;
|
||||
|
||||
/**
|
||||
* Adds a check for the URL host name.
|
||||
*
|
||||
* @param string $regexp A Regexp
|
||||
*/
|
||||
public function matchHost($regexp)
|
||||
{
|
||||
$this->host = $regexp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a check for the URL path info.
|
||||
*
|
||||
* @param string $regexp A Regexp
|
||||
*/
|
||||
public function matchPath($regexp)
|
||||
{
|
||||
$this->path = $regexp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a check for the client IP.
|
||||
*
|
||||
* @param string $ip A specific IP address or a range specified using IP/netmask like 192.168.1.0/24
|
||||
*/
|
||||
public function matchIp($ip)
|
||||
{
|
||||
$this->ip = $ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a check for the HTTP method.
|
||||
*
|
||||
* @param string|array An HTTP method or an array of HTTP methods
|
||||
*/
|
||||
public function matchMethod($method)
|
||||
{
|
||||
$this->methods = array_map(function ($m) { return strtolower($m); }, is_array($method) ? $method : array($method));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function matches(Request $request)
|
||||
{
|
||||
if (null !== $this->methods && !in_array(strtolower($request->getMethod()), $this->methods)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null !== $this->path && !preg_match($this->path, $request->getPathInfo())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null !== $this->host && !preg_match($this->host, $request->getHost())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null !== $this->ip && !$this->checkIp($this->host, $request->getClientIp())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function checkIp($ip)
|
||||
{
|
||||
if (false !== strpos($this->ip, '/')) {
|
||||
list($address, $netmask) = $this->ip;
|
||||
|
||||
if ($netmask <= 0) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$address = $this->ip;
|
||||
$netmask = 1;
|
||||
}
|
||||
|
||||
return 0 === substr_compare(sprintf('%032b', ip2long($ip)), sprintf('%032b', ip2long($address)), 0, $netmask);
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\HttpFoundation;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* RequestMatcherInterface is an interface for strategies to match a Request.
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
interface RequestMatcherInterface
|
||||
{
|
||||
/**
|
||||
* Decides whether the rule(s) implemented by the strategy matches the supplied request.
|
||||
*
|
||||
* @param Request $request The request to check for a match
|
||||
*
|
||||
* @return Boolean true if the request matches, false otherwise
|
||||
*/
|
||||
function matches(Request $request);
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Tests\Component\HttpFoundation;
|
||||
|
||||
use Symfony\Component\HttpFoundation\RequestMatcher;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class RequestMatcherTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testIp()
|
||||
{
|
||||
$matcher = new RequestMatcher();
|
||||
|
||||
$matcher->matchIp('192.168.1.1/1');
|
||||
$request = Request::create('', 'get', array(), array(), array(), array('REMOTE_ADDR' => '192.168.1.1'));
|
||||
$this->assertTrue($matcher->matches($request));
|
||||
|
||||
$matcher->matchIp('192.168.1.0/24');
|
||||
$this->assertTrue($matcher->matches($request));
|
||||
|
||||
$matcher->matchIp('1.2.3.4/1');
|
||||
$this->assertFalse($matcher->matches($request));
|
||||
}
|
||||
|
||||
public function testMethod()
|
||||
{
|
||||
$matcher = new RequestMatcher();
|
||||
|
||||
$matcher->matchMethod('get');
|
||||
$request = Request::create('', 'get');
|
||||
$this->assertTrue($matcher->matches($request));
|
||||
|
||||
$matcher->matchMethod('post');
|
||||
$this->assertFalse($matcher->matches($request));
|
||||
|
||||
$matcher->matchMethod(array('get', 'post'));
|
||||
$this->assertTrue($matcher->matches($request));
|
||||
}
|
||||
|
||||
public function testHost()
|
||||
{
|
||||
$matcher = new RequestMatcher();
|
||||
|
||||
$matcher->matchHost('#.*\.example\.com#i');
|
||||
$request = Request::create('', 'get', array(), array(), array(), array('HTTP_HOST' => 'foo.example.com'));
|
||||
$this->assertTrue($matcher->matches($request));
|
||||
|
||||
$matcher->matchMethod('#sensio\.com#i');
|
||||
$this->assertFalse($matcher->matches($request));
|
||||
}
|
||||
|
||||
public function testPath()
|
||||
{
|
||||
$matcher = new RequestMatcher();
|
||||
|
||||
$matcher->matchPath('#^/admin#');
|
||||
$request = Request::create('/admin/foo');
|
||||
$this->assertTrue($matcher->matches($request));
|
||||
|
||||
$matcher->matchMethod('#^/blog#i');
|
||||
$this->assertFalse($matcher->matches($request));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user