RequestMatcher.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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(function ($m) { return strtolower($m); }, is_array($method) ? $method : array($method));
  58. }
  59. /**
  60. * Adds a check for request attribute.
  61. *
  62. * @param string $key The request attribute name
  63. * @param string $regexp A Regexp
  64. */
  65. public function matchAttribute($key, $regexp)
  66. {
  67. $this->attributes[$key] = $regexp;
  68. }
  69. /**
  70. * {@inheritdoc}
  71. */
  72. public function matches(Request $request)
  73. {
  74. if (null !== $this->methods && !in_array(strtolower($request->getMethod()), $this->methods)) {
  75. return false;
  76. }
  77. foreach ($this->attributes as $key => $pattern) {
  78. if (!preg_match('#^'.$pattern.'$#', $request->attributes->get($key))) {
  79. return false;
  80. }
  81. }
  82. if (null !== $this->path && !preg_match('#^'.$this->path.'$#', $request->getPathInfo())) {
  83. return false;
  84. }
  85. if (null !== $this->host && !preg_match('#^'.$this->host.'$#', $request->getHost())) {
  86. return false;
  87. }
  88. if (null !== $this->ip && !$this->checkIp($this->host, $request->getClientIp())) {
  89. return false;
  90. }
  91. return true;
  92. }
  93. protected function checkIp($ip)
  94. {
  95. if (false !== strpos($this->ip, '/')) {
  96. list($address, $netmask) = $this->ip;
  97. if ($netmask <= 0) {
  98. return false;
  99. }
  100. } else {
  101. $address = $this->ip;
  102. $netmask = 1;
  103. }
  104. return 0 === substr_compare(sprintf('%032b', ip2long($ip)), sprintf('%032b', ip2long($address)), 0, $netmask);
  105. }
  106. }