RequestMatcher.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <?php
  2. namespace Symfony\Component\HttpFoundation;
  3. /*
  4. * This file is part of the Symfony package.
  5. *
  6. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. /**
  12. * RequestMatcher compares a pre-defined set of checks against a Request instance.
  13. *
  14. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  15. */
  16. class RequestMatcher implements RequestMatcherInterface
  17. {
  18. protected $path;
  19. protected $host;
  20. protected $methods;
  21. protected $ip;
  22. protected $attributes = array();
  23. /**
  24. * Adds a check for the URL host name.
  25. *
  26. * @param string $regexp A Regexp
  27. */
  28. public function matchHost($regexp)
  29. {
  30. $this->host = $regexp;
  31. }
  32. /**
  33. * Adds a check for the URL path info.
  34. *
  35. * @param string $regexp A Regexp
  36. */
  37. public function matchPath($regexp)
  38. {
  39. $this->path = $regexp;
  40. }
  41. /**
  42. * Adds a check for the client IP.
  43. *
  44. * @param string $ip A specific IP address or a range specified using IP/netmask like 192.168.1.0/24
  45. */
  46. public function matchIp($ip)
  47. {
  48. $this->ip = $ip;
  49. }
  50. /**
  51. * Adds a check for the HTTP method.
  52. *
  53. * @param string|array An HTTP method or an array of HTTP methods
  54. */
  55. public function matchMethod($method)
  56. {
  57. $this->methods = array_map(
  58. function ($m)
  59. {
  60. return strtolower($m);
  61. },
  62. is_array($method) ? $method : array($method)
  63. );
  64. }
  65. /**
  66. * Adds a check for request attribute.
  67. *
  68. * @param string $key The request attribute name
  69. * @param string $regexp A Regexp
  70. */
  71. public function matchAttribute($key, $regexp)
  72. {
  73. $this->attributes[$key] = $regexp;
  74. }
  75. /**
  76. * {@inheritdoc}
  77. */
  78. public function matches(Request $request)
  79. {
  80. if (null !== $this->methods && !in_array(strtolower($request->getMethod()), $this->methods)) {
  81. return false;
  82. }
  83. foreach ($this->attributes as $key => $pattern) {
  84. if (!preg_match('#^'.$pattern.'$#', $request->attributes->get($key))) {
  85. return false;
  86. }
  87. }
  88. if (null !== $this->path && !preg_match('#^'.$this->path.'$#', $request->getPathInfo())) {
  89. return false;
  90. }
  91. if (null !== $this->host && !preg_match('#^'.$this->host.'$#', $request->getHost())) {
  92. return false;
  93. }
  94. if (null !== $this->ip && !$this->checkIp($request->getClientIp())) {
  95. return false;
  96. }
  97. return true;
  98. }
  99. protected function checkIp($ip)
  100. {
  101. if (false !== strpos($this->ip, '/')) {
  102. list($address, $netmask) = explode('/', $this->ip);
  103. if ($netmask < 1 || $netmask > 32) {
  104. return false;
  105. }
  106. } else {
  107. $address = $this->ip;
  108. $netmask = 32;
  109. }
  110. return 0 === substr_compare(sprintf('%032b', ip2long($ip)), sprintf('%032b', ip2long($address)), 0, $netmask);
  111. }
  112. }