ICanBoogie/HTTP v2.4.0
  • Namespace
  • Class

Namespaces

  • ICanBoogie
    • Exception
    • HTTP
      • Dispatcher
      • Headers
      • Request

Classes

  • ICanBoogie\Exception\RescueEvent
  • ICanBoogie\HTTP\CallableDispatcher
  • ICanBoogie\HTTP\Dispatcher
  • ICanBoogie\HTTP\Dispatcher\BeforeDispatchEvent
  • ICanBoogie\HTTP\Dispatcher\DispatchEvent
  • ICanBoogie\HTTP\File
  • ICanBoogie\HTTP\FileInfo
  • ICanBoogie\HTTP\FileList
  • ICanBoogie\HTTP\Headers
  • ICanBoogie\HTTP\Headers\CacheControl
  • ICanBoogie\HTTP\Headers\ContentDisposition
  • ICanBoogie\HTTP\Headers\ContentType
  • ICanBoogie\HTTP\Headers\Date
  • ICanBoogie\HTTP\Headers\Header
  • ICanBoogie\HTTP\Headers\HeaderParameter
  • ICanBoogie\HTTP\Helpers
  • ICanBoogie\HTTP\RedirectResponse
  • ICanBoogie\HTTP\Request
  • ICanBoogie\HTTP\Request\Context
  • ICanBoogie\HTTP\Response
  • ICanBoogie\HTTP\Status
  • ICanBoogie\HTTP\WeightedDispatcher

Interfaces

  • ICanBoogie\HTTP\DispatcherInterface
  • ICanBoogie\HTTP\Exception

Exceptions

  • ICanBoogie\HTTP\DispatcherNotDefined
  • ICanBoogie\HTTP\ForceRedirect
  • ICanBoogie\HTTP\MethodNotSupported
  • ICanBoogie\HTTP\NotFound
  • ICanBoogie\HTTP\ServiceUnavailable
  • ICanBoogie\HTTP\StatusCodeNotValid
   1 <?php
   2 
   3 /*
   4  * This file is part of the ICanBoogie package.
   5  *
   6  * (c) Olivier Laviale <olivier.laviale@gmail.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 namespace ICanBoogie\HTTP;
  13 
  14 use ICanBoogie\Accessor\AccessorTrait;
  15 use ICanBoogie\Prototype\MethodNotDefined;
  16 
  17 /**
  18  * An HTTP request.
  19  *
  20  * <pre>
  21  * <?php
  22  *
  23  * use ICanBoogie\HTTP\Request;
  24  *
  25  * # Creating the main request
  26  *
  27  * $request = Request::from($_SERVER);
  28  *
  29  * # Creating a request from scratch, with the current environment.
  30  *
  31  * $request = Request::from([
  32  *
  33  *     'uri' => '/path/to/my/page.html?page=2',
  34  *     'user_agent' => 'Mozilla'
  35  *     'is_get' => true,
  36  *     'is_xhr' => true,
  37  *     'is_local' => true
  38  *
  39  * ], $_SERVER);
  40  * </pre>
  41  *
  42  * @method Response connect() connect(array $params=null)
  43  * @method Response delete() delete(array $params=null)
  44  * @method Response get() get(array $params=null)
  45  * @method Response head() head(array $params=null)
  46  * @method Response options() options(array $params=null)
  47  * @method Response post() post(array $params=null)
  48  * @method Response put() put(array $params=null)
  49  * @method Response patch() patch(array $params=null)
  50  * @method Response trace() trace(array $params=null)
  51  *
  52  * @property-read \ICanBoogie\HTTP\Request\Context $context the request's context.
  53  * @property-read Request $parent Parent request.
  54  * @property-read FileList $files The files associated with the request.
  55  *
  56  * @property-read boolean $authorization Authorization of the request.
  57  * @property-read int $content_length Length of the request content.
  58  * @property-read int $cache_control A {@link \ICanBoogie\HTTP\Headers\CacheControl} object.
  59  * @property-read string $ip Remote IP of the request.
  60  * @property-read boolean $is_delete Is this a `DELETE` request?
  61  * @property-read boolean $is_get Is this a `GET` request?
  62  * @property-read boolean $is_head Is this a `HEAD` request?
  63  * @property-read boolean $is_options Is this a `OPTIONS` request?
  64  * @property-read boolean $is_patch Is this a `PATCH` request?
  65  * @property-read boolean $is_post Is this a `POST` request?
  66  * @property-read boolean $is_put Is this a `PUT` request?
  67  * @property-read boolean $is_trace Is this a `TRACE` request?
  68  * @property-read boolean $is_local Is this a local request?
  69  * @property-read boolean $is_xhr Is this an Ajax request?
  70  * @property-read string $method Method of the request.
  71  * @property-read string $normalized_path Path of the request normalized using the {@link \ICanBoogie\normalize_url_path()} function.
  72  * @property-read string $path Path info of the request.
  73  * @property-read string $extension The extension of the path.
  74  * @property-read int $port Port of the request.
  75  * @property-read string $query_string Query string of the request.
  76  * @property-read string $script_name Name of the entered script.
  77  * @property-read string $referer Referer of the request.
  78  * @property-read string $user_agent User agent of the request.
  79  * @property-read string $uri URI of the request. The `QUERY_STRING` value of the environment
  80  * is overwritten when the instance is created with the {@link $uri} property.
  81  *
  82  * @see http://en.wikipedia.org/wiki/Uniform_resource_locator
  83  */
  84 class Request implements \ArrayAccess, \IteratorAggregate
  85 {
  86     use AccessorTrait;
  87 
  88     /*
  89      * HTTP methods as defined by the {@link http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html Hypertext Transfer protocol 1.1}.
  90      */
  91     const METHOD_ANY = 'ANY';
  92     const METHOD_CONNECT = 'CONNECT';
  93     const METHOD_DELETE = 'DELETE';
  94     const METHOD_GET = 'GET';
  95     const METHOD_HEAD = 'HEAD';
  96     const METHOD_OPTIONS = 'OPTIONS';
  97     const METHOD_POST = 'POST';
  98     const METHOD_PUT = 'PUT';
  99     const METHOD_PATCH = 'PATCH';
 100     const METHOD_TRACE = 'TRACE';
 101 
 102     static public $methods = [
 103 
 104         self::METHOD_CONNECT,
 105         self::METHOD_DELETE,
 106         self::METHOD_GET,
 107         self::METHOD_HEAD,
 108         self::METHOD_OPTIONS,
 109         self::METHOD_POST,
 110         self::METHOD_PUT,
 111         self::METHOD_PATCH,
 112         self::METHOD_TRACE
 113 
 114     ];
 115 
 116     static private $properties_mappers;
 117 
 118     /**
 119      * Returns request properties mappers.
 120      *
 121      * @return \Closure[]
 122      */
 123     static protected function get_properties_mappers()
 124     {
 125         if (self::$properties_mappers)
 126         {
 127             return self::$properties_mappers;
 128         }
 129 
 130         return self::$properties_mappers = static::create_properties_mappers();
 131     }
 132 
 133     /**
 134      * Returns request properties mappers.
 135      *
 136      * @return \Closure[]
 137      */
 138     static protected function create_properties_mappers()
 139     {
 140         return [
 141 
 142             'path_params' =>    function($value) { return $value; },
 143             'query_params' =>   function($value) { return $value; },
 144             'request_params' => function($value) { return $value; },
 145             'cookie' =>         function($value) { return $value; },
 146             'files' =>          function($value) { return $value; },
 147             'headers' =>        function($value) { return ($value instanceof Headers) ? $value : new Headers($value); },
 148 
 149             'cache_control' =>  function($value, array &$env) { $env['HTTP_CACHE_CONTROL'] = $value; },
 150             'content_length' => function($value, array &$env) { $env['CONTENT_LENGTH'] = $value; },
 151             'ip' =>             function($value, array &$env) { if ($value) $env['REMOTE_ADDR'] = $value; },
 152             'is_local' =>       function($value, array &$env) { if ($value) $env['REMOTE_ADDR'] = '::1'; },
 153             'is_delete' =>      function($value, array &$env) { if ($value) $env['REQUEST_METHOD'] = Request::METHOD_DELETE; },
 154             'is_connect' =>     function($value, array &$env) { if ($value) $env['REQUEST_METHOD'] = Request::METHOD_CONNECT; },
 155             'is_get' =>         function($value, array &$env) { if ($value) $env['REQUEST_METHOD'] = Request::METHOD_GET; },
 156             'is_head' =>        function($value, array &$env) { if ($value) $env['REQUEST_METHOD'] = Request::METHOD_HEAD; },
 157             'is_options' =>     function($value, array &$env) { if ($value) $env['REQUEST_METHOD'] = Request::METHOD_OPTIONS; },
 158             'is_patch' =>       function($value, array &$env) { if ($value) $env['REQUEST_METHOD'] = Request::METHOD_PATCH; },
 159             'is_post' =>        function($value, array &$env) { if ($value) $env['REQUEST_METHOD'] = Request::METHOD_POST; },
 160             'is_put' =>         function($value, array &$env) { if ($value) $env['REQUEST_METHOD'] = Request::METHOD_PUT; },
 161             'is_trace' =>       function($value, array &$env) { if ($value) $env['REQUEST_METHOD'] = Request::METHOD_TRACE; },
 162             'is_xhr' =>         function($value, array &$env) { if ($value) $env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'; else unset($env['HTTP_X_REQUESTED_WITH']); },
 163             'method' =>         function($value, array &$env) { if ($value) $env['REQUEST_METHOD'] = $value; },
 164             'path' =>           function($value, array &$env) { $env['REQUEST_URI'] = $value; }, // TODO-20130521: handle query string
 165             'referer' =>        function($value, array &$env) { $env['HTTP_REFERER'] = $value; },
 166             'uri' =>            function($value, array &$env) { $env['REQUEST_URI'] = $value; $qs = strpos($value, '?'); $env['QUERY_STRING'] = $qs === false ? '' : substr($value, $qs + 1); },
 167             'user_agent' =>     function($value, array &$env) { $env['HTTP_USER_AGENT'] = $value; }
 168 
 169         ];
 170     }
 171 
 172     /**
 173      * Current request.
 174      *
 175      * @var Request
 176      */
 177     static protected $current_request;
 178 
 179     /**
 180      * Returns the current request.
 181      *
 182      * @return Request
 183      */
 184     static public function get_current_request()
 185     {
 186         return self::$current_request;
 187     }
 188 
 189     /**
 190      * Parameters extracted from the request path.
 191      *
 192      * @var array
 193      */
 194     public $path_params = [];
 195 
 196     /**
 197      * Parameters defined by the query string.
 198      *
 199      * @var array
 200      */
 201     public $query_params = [];
 202 
 203     /**
 204      * Parameters defined by the request body.
 205      *
 206      * @var array
 207      */
 208     public $request_params = [];
 209 
 210     /**
 211      * Union of {@link $path_params}, {@link $request_params} and {@link $query_params}.
 212      *
 213      * @var array
 214      */
 215     public $params;
 216 
 217     /**
 218      * General purpose container.
 219      *
 220      * @var Request\Context
 221      */
 222     protected $context;
 223 
 224     /**
 225      * The headers of the request.
 226      *
 227      * @var Headers
 228      */
 229     public $headers;
 230 
 231     /**
 232      * Request environment.
 233      *
 234      * @var array
 235      */
 236     protected $env;
 237 
 238     /**
 239      * Files associated with the request.
 240      *
 241      * @var FileList
 242      */
 243     protected $files;
 244 
 245     protected function get_files()
 246     {
 247         if ($this->files instanceof FileList)
 248         {
 249             return $this->files;
 250         }
 251 
 252         return $this->files = FileList::from($this->files);
 253     }
 254 
 255     public $cookie;
 256 
 257     /**
 258      * Parent request.
 259      *
 260      * @var Request
 261      */
 262     protected $parent;
 263 
 264     /**
 265      * A request can be created from the `$_SERVER` super global array. In that case `$_SERVER` is
 266      * used as environment the request is created with the following properties:
 267      *
 268      * - {@link $cookie}: a reference to the `$_COOKIE` super global array.
 269      * - {@link $path_params}: initialized to an empty array.
 270      * - {@link $query_params}: a reference to the `$_GET` super global array.
 271      * - {@link $request_params}: a reference to the `$_POST` super global array.
 272      * - {@link $files}: a reference to the `$_FILES` super global array.
 273      *
 274      * A request can also be created from an array of properties, in which case most of them are
 275      * mapped to the `$env` constructor param. For instance, `is_xhr` set the
 276      * `HTTP_X_REQUESTED_WITH` environment property to 'XMLHttpRequest'. In fact, only the
 277      * following parameters are preserved:
 278      *
 279      * - `path_params`
 280      * - `query_params`
 281      * - `request_params`
 282      * - `files`: The files associated with the request.
 283      * - `headers`: The header fields of the request. If specified, the headers available in the
 284      * environment are ignored.
 285      *
 286      * @param array $properties Properties of the request.
 287      * @param array $env Environment, usually the `$_SERVER` array.
 288      *
 289      * @throws \InvalidArgumentException in attempt to use a property that is not mapped to an
 290      * environment property.
 291      *
 292      * @return Request
 293      */
 294     static public function from($properties = null, array $env = [])
 295     {
 296         if (!$properties)
 297         {
 298             return new static([], $env);
 299         }
 300 
 301         if ($properties === $_SERVER)
 302         {
 303             return static::from_server();
 304         }
 305 
 306         if (is_string($properties) || (is_object($properties) && method_exists($properties, '__toString')))
 307         {
 308             return static::from_uri((string) $properties, $env);
 309         }
 310 
 311         return static::from_properties($properties, $env);
 312     }
 313 
 314     /**
 315      * Creates an instance from the `$_SERVER` array.
 316      *
 317      * @return Request
 318      */
 319     static protected function from_server()
 320     {
 321         return static::from([
 322 
 323             'cookie' => &$_COOKIE,
 324             'path_params' => [],
 325             'query_params' => &$_GET,
 326             'request_params' => &$_POST,
 327             'files' => &$_FILES // @codeCoverageIgnore
 328 
 329         ], $_SERVER);
 330     }
 331 
 332     /**
 333      * Creates an instance from an URI.
 334      *
 335      * @param string $uri
 336      * @param array $env
 337      *
 338      * @return Request
 339      */
 340     static protected function from_uri($uri, array $env)
 341     {
 342         return static::from([ 'uri' => $uri ], $env);
 343     }
 344 
 345     /**
 346      * Creates an instance from an array of properties.
 347      *
 348      * @param array $properties
 349      * @param array $env
 350      *
 351      * @return Request
 352      */
 353     static protected function from_properties(array $properties, array $env)
 354     {
 355         $properties = $properties ?: [];
 356 
 357         $mappers = static::get_properties_mappers();
 358 
 359         foreach ($properties as $property => &$value)
 360         {
 361             if (empty($mappers[$property]))
 362             {
 363                 throw new \InvalidArgumentException("Unsupported property: <q>$property</q>.");
 364             }
 365 
 366             $value = $mappers[$property]($value, $env);
 367 
 368             if ($value === null)
 369             {
 370                 unset($properties[$property]);
 371             }
 372         }
 373 
 374         if (!empty($env['QUERY_STRING']))
 375         {
 376             parse_str($env['QUERY_STRING'], $properties['query_params']);
 377         }
 378 
 379         return new static($properties, $env);
 380     }
 381 
 382     /**
 383      * Initialize the properties {@link $env}, {@link $headers} and {@link $context}.
 384      *
 385      * If the {@link $params} property is `null` it is set with an union of {@link $path_params},
 386      * {@link $request_params} and {@link $query_params}.
 387      *
 388      * @param array $properties Initial properties.
 389      * @param array $env Environment of the request, usually the `$_SERVER` super global.
 390      *
 391      * @throws MethodNotSupported when the request method is not supported.
 392      */
 393     protected function __construct(array $properties, array $env = [])
 394     {
 395         $this->context = new Request\Context($this);
 396         $this->env = $env;
 397 
 398         foreach ($properties as $property => $value)
 399         {
 400             $this->$property = $value;
 401         }
 402 
 403         $this->assert_method($this->method);
 404 
 405         if (!$this->headers)
 406         {
 407             $this->headers = new Headers($env);
 408         }
 409 
 410         if ($this->params === null)
 411         {
 412             $this->params = $this->path_params + $this->request_params + $this->query_params;
 413         }
 414     }
 415 
 416     /**
 417      * Clone {@link $headers} and {@link $context}, and unset {@link $params}.
 418      */
 419     public function __clone()
 420     {
 421         $this->headers = clone $this->headers;
 422         $this->context = clone $this->context;
 423         unset($this->params);
 424     }
 425 
 426     /**
 427      * Alias for {@link send()}.
 428      *
 429      * @return Response The response to the request.
 430      */
 431     public function __invoke()
 432     {
 433         return $this->send();
 434     }
 435 
 436     /**
 437      * Dispatch the request.
 438      *
 439      * The {@link parent} property is used for request chaining.
 440      *
 441      * Note: If an exception is thrown during dispatch {@link $current_request} is not updated!
 442      *
 443      * Note: If the request is changed because of the `$method` or `$params` parameters, it
 444      * is the _changed_ instance that is dispatched, not the actual instance.
 445      *
 446      * @param string|null $method Use this parameter to change the request method.
 447      * @param array|null $params Use this parameter to change the {@link $request_params}
 448      * property of the request.
 449      *
 450      * @return Response The response to the request.
 451      *
 452      * @throws \Exception re-throws exception raised during dispatch.
 453      */
 454     public function send($method = null, array $params = null)
 455     {
 456         $request = $this->adapt($method, $params);
 457 
 458         $this->parent = self::$current_request;
 459 
 460         self::$current_request = $request;
 461 
 462         try
 463         {
 464             $response = $request->dispatch();
 465 
 466             self::$current_request = $request->parent;
 467 
 468             return $response;
 469         }
 470         catch (\Exception $e)
 471         {
 472             self::$current_request = $request->parent;
 473 
 474             throw $e;
 475         }
 476     }
 477 
 478     /**
 479      * Dispatches the request using the {@link dispatch()} helper.
 480      *
 481      * @return Response
 482      */
 483     protected function dispatch()
 484     {
 485         return dispatch($this); // @codeCoverageIgnore
 486     }
 487 
 488     /**
 489      * Asserts that a method is supported.
 490      *
 491      * @param string $method
 492      *
 493      * @throws MethodNotSupported
 494      */
 495     private function assert_method($method)
 496     {
 497         if (!in_array($method, self::$methods))
 498         {
 499             throw new MethodNotSupported($method);
 500         }
 501     }
 502 
 503     /**
 504      * Returns a new instance with the specified changed properties.
 505      *
 506      * @param array $properties
 507      *
 508      * @throws \InvalidArgumentException
 509      *
 510      * @return Request
 511      */
 512     public function with(array $properties)
 513     {
 514         $changed = clone $this;
 515         $mappers = static::get_properties_mappers();
 516         $env = &$changed->env;
 517 
 518         foreach ($properties as $property => $value)
 519         {
 520             if (empty($mappers[$property]))
 521             {
 522                 throw new \InvalidArgumentException("Unsupported property: <q>$property</q>.");
 523             }
 524 
 525             $value = $mappers[$property]($value, $env);
 526 
 527             if ($value === null)
 528             {
 529                 continue;
 530             }
 531 
 532             $changed->$property = $value;
 533         }
 534 
 535         return $changed;
 536     }
 537 
 538     /**
 539      * Adapts the request to the specified method and params.
 540      *
 541      * @param string $method The method.
 542      * @param array $params The params.
 543      *
 544      * @return Request The same instance is returned if the method is the same and the params
 545      * are `null`. Otherwise a _changed_ request is returned.
 546      */
 547     protected function adapt($method, array $params = null)
 548     {
 549         if ((!$method || $method == $this->method) && !$params)
 550         {
 551             return $this;
 552         }
 553 
 554         $properties = [];
 555 
 556         if ($method)
 557         {
 558             $properties = [ 'method' => $method ];
 559         }
 560 
 561         if ($params !== null)
 562         {
 563             $properties['request_params'] = $params;
 564             $properties['path_params'] = [];
 565             $properties['query_params'] = [];
 566         }
 567 
 568         return $this->with($properties);
 569     }
 570 
 571     /**
 572      * Overrides the method to provide a virtual method for each request method.
 573      *
 574      * Example:
 575      *
 576      * <pre>
 577      * <?php
 578      *
 579      * Request::from('/api/core/aloha')->get();
 580      * </pre>
 581      *
 582      * @param $method
 583      * @param $arguments
 584      *
 585      * @return mixed
 586      */
 587     public function __call($method, $arguments)
 588     {
 589         $http_method = strtoupper($method);
 590 
 591         if (in_array($http_method, self::$methods))
 592         {
 593             array_unshift($arguments, $http_method);
 594 
 595             return call_user_func_array([ $this, 'send' ], $arguments);
 596         }
 597 
 598         throw new MethodNotDefined($method, $this);
 599     }
 600 
 601     /**
 602      * Checks if the specified param exists in the request's params.
 603      *
 604      * @param string $param The name of the parameter.
 605      *
 606      * @return bool
 607      */
 608     public function offsetExists($param)
 609     {
 610         return isset($this->params[$param]);
 611     }
 612 
 613     /**
 614      * Get the specified param from the request's params.
 615      *
 616      * @param string $param The name of the parameter.
 617      *
 618      * @return mixed|null The value of the parameter, or `null` if the parameter does not exists.
 619      */
 620     public function offsetGet($param)
 621     {
 622         return isset($this->params[$param]) ? $this->params[$param] : null;
 623     }
 624 
 625     /**
 626      * Set the specified param to the specified value.
 627      *
 628      * @param string $param The name of the parameter.
 629      * @param mixed $value The value of the parameter.
 630      */
 631     public function offsetSet($param, $value)
 632     {
 633         $this->params;
 634         $this->params[$param] = $value;
 635         $this->request_params[$param] = $value;
 636     }
 637 
 638     /**
 639      * Remove the specified param from the request's parameters.
 640      *
 641      * @param mixed $param
 642      */
 643     public function offsetUnset($param)
 644     {
 645         unset($this->params[$param]);
 646     }
 647 
 648     /**
 649      * Returns an array iterator for the params.
 650      *
 651      * @return \ArrayIterator
 652      */
 653     public function getIterator()
 654     {
 655         return new \ArrayIterator($this->params);
 656     }
 657 
 658     /**
 659      * Returns the parent request.
 660      *
 661      * @return Request
 662      */
 663     protected function get_parent()
 664     {
 665         return $this->parent;
 666     }
 667 
 668     /**
 669      * Returns the request's context.
 670      *
 671      * @return Request\Context
 672      */
 673     protected function get_context()
 674     {
 675         return $this->context;
 676     }
 677 
 678     /**
 679      * Returns the `Cache-Control` header.
 680      *
 681      * @return Headers\CacheControl
 682      */
 683     protected function get_cache_control()
 684     {
 685         return $this->headers['Cache-Control'];
 686     }
 687 
 688     /**
 689      * Returns the script name.
 690      *
 691      * The setter is volatile, the value is returned from the ENV key `SCRIPT_NAME`.
 692      *
 693      * @return string
 694      */
 695     protected function get_script_name()
 696     {
 697         return $this->env['SCRIPT_NAME'];
 698     }
 699 
 700     /**
 701      * Returns the request method.
 702      *
 703      * This is the getter for the `method` magic property.
 704      *
 705      * The method is retrieved from {@link $env}, if the key `REQUEST_METHOD` is not defined,
 706      * the method defaults to {@link METHOD_GET}.
 707      *
 708      * @return string
 709      */
 710     protected function get_method()
 711     {
 712         $method = isset($this->env['REQUEST_METHOD']) ? $this->env['REQUEST_METHOD'] : self::METHOD_GET;
 713 
 714         if ($method == self::METHOD_POST && !empty($this->request_params['_method']))
 715         {
 716             $method = strtoupper($this->request_params['_method']);
 717         }
 718 
 719         return $method;
 720     }
 721 
 722     /**
 723      * Returns the query string of the request.
 724      *
 725      * The value is obtained from the `QUERY_STRING` key of the {@link $env} array.
 726      *
 727      * @return string|null
 728      */
 729     protected function get_query_string()
 730     {
 731         return isset($this->env['QUERY_STRING']) ? $this->env['QUERY_STRING'] : null;
 732     }
 733 
 734     /**
 735      * Returns the content length of the request.
 736      *
 737      * The value is obtained from the `CONTENT_LENGTH` key of the {@link $env} array.
 738      *
 739      * @return int|null
 740      */
 741     protected function get_content_length()
 742     {
 743         return isset($this->env['CONTENT_LENGTH']) ? $this->env['CONTENT_LENGTH'] : null;
 744     }
 745 
 746     /**
 747      * Returns the referer of the request.
 748      *
 749      * The value is obtained from the `HTTP_REFERER` key of the {@link $env} array.
 750      *
 751      * @return string|null
 752      */
 753     protected function get_referer()
 754     {
 755         return isset($this->env['HTTP_REFERER']) ? $this->env['HTTP_REFERER'] : null;
 756     }
 757 
 758     /**
 759      * Returns the user agent of the request.
 760      *
 761      * The value is obtained from the `HTTP_USER_AGENT` key of the {@link $env} array.
 762      *
 763      * @return string|null
 764      */
 765     protected function get_user_agent()
 766     {
 767         return isset($this->env['HTTP_USER_AGENT']) ? $this->env['HTTP_USER_AGENT'] : null;
 768     }
 769 
 770     /**
 771      * Checks if the request method is `DELETE`.
 772      *
 773      * @return boolean
 774      */
 775     protected function get_is_delete()
 776     {
 777         return $this->method == self::METHOD_DELETE;
 778     }
 779 
 780     /**
 781      * Checks if the request method is `GET`.
 782      *
 783      * @return boolean
 784      */
 785     protected function get_is_get()
 786     {
 787         return $this->method == self::METHOD_GET;
 788     }
 789 
 790     /**
 791      * Checks if the request method is `HEAD`.
 792      *
 793      * @return boolean
 794      */
 795     protected function get_is_head()
 796     {
 797         return $this->method == self::METHOD_HEAD;
 798     }
 799 
 800     /**
 801      * Checks if the request method is `OPTIONS`.
 802      *
 803      * @return boolean
 804      */
 805     protected function get_is_options()
 806     {
 807         return $this->method == self::METHOD_OPTIONS;
 808     }
 809 
 810     /**
 811      * Checks if the request method is `PATCH`.
 812      *
 813      * @return boolean
 814      */
 815     protected function get_is_patch()
 816     {
 817         return $this->method == self::METHOD_PATCH;
 818     }
 819 
 820     /**
 821      * Checks if the request method is `POST`.
 822      *
 823      * @return boolean
 824      */
 825     protected function get_is_post()
 826     {
 827         return $this->method == self::METHOD_POST;
 828     }
 829 
 830     /**
 831      * Checks if the request method is `PUT`.
 832      *
 833      * @return boolean
 834      */
 835     protected function get_is_put()
 836     {
 837         return $this->method == self::METHOD_PUT;
 838     }
 839 
 840     /**
 841      * Checks if the request method is `TRACE`.
 842      *
 843      * @return boolean
 844      */
 845     protected function get_is_trace()
 846     {
 847         return $this->method == self::METHOD_TRACE;
 848     }
 849 
 850     /**
 851      * Checks if the request is a `XMLHTTPRequest`.
 852      *
 853      * @return boolean
 854      */
 855     protected function get_is_xhr()
 856     {
 857         return !empty($this->env['HTTP_X_REQUESTED_WITH']) && preg_match('/XMLHttpRequest/', $this->env['HTTP_X_REQUESTED_WITH']);
 858     }
 859 
 860     /**
 861      * Checks if the request is local.
 862      *
 863      * @return boolean
 864      */
 865     protected function get_is_local()
 866     {
 867         $ip = $this->ip;
 868 
 869         if ($ip == '::1' || preg_match('/^127\.0\.0\.\d{1,3}$/', $ip))
 870         {
 871             return true;
 872         }
 873 
 874         return preg_match('/^0:0:0:0:0:0:0:1(%.*)?$/', $ip);
 875     }
 876 
 877     /**
 878      * Returns the remote IP of the request.
 879      *
 880      * If defined, the `HTTP_X_FORWARDED_FOR` header is used to retrieve the original IP.
 881      *
 882      * If the `REMOTE_ADDR` header is empty the request is considered local thus `::1` is returned.
 883      *
 884      * @see http://en.wikipedia.org/wiki/X-Forwarded-For
 885      *
 886      * @return string
 887      */
 888     protected function get_ip()
 889     {
 890         $forwarded_for = $this->headers['X-Forwarded-For'];
 891 
 892         if ($forwarded_for)
 893         {
 894             list($ip) = explode(',', $forwarded_for);
 895 
 896             return $ip;
 897         }
 898 
 899         return (isset($this->env['REMOTE_ADDR']) ? $this->env['REMOTE_ADDR'] : null) ?: '::1';
 900     }
 901 
 902     protected function get_authorization()
 903     {
 904         if (isset($this->env['HTTP_AUTHORIZATION']))
 905         {
 906             return $this->env['HTTP_AUTHORIZATION'];
 907         }
 908         else if (isset($this->env['X-HTTP_AUTHORIZATION']))
 909         {
 910             return $this->env['X-HTTP_AUTHORIZATION'];
 911         }
 912         else if (isset($this->env['X_HTTP_AUTHORIZATION']))
 913         {
 914             return $this->env['X_HTTP_AUTHORIZATION'];
 915         }
 916         else if (isset($this->env['REDIRECT_X_HTTP_AUTHORIZATION']))
 917         {
 918             return $this->env['REDIRECT_X_HTTP_AUTHORIZATION'];
 919         }
 920 
 921         return null;
 922     }
 923 
 924     /**
 925      * Returns the `REQUEST_URI` environment key.
 926      *
 927      * If the `REQUEST_URI` key is not defined by the environment, the value is fetched from
 928      * the `$_SERVER` array. If the key is not defined in the `$_SERVER` array `null` is returned.
 929      *
 930      * @return string
 931      */
 932     protected function get_uri()
 933     {
 934         return isset($this->env['REQUEST_URI'])
 935             ? $this->env['REQUEST_URI']
 936             : (isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : null);
 937     }
 938 
 939     /**
 940      * Returns the port of the request.
 941      *
 942      * @return int
 943      */
 944     protected function get_port()
 945     {
 946         return $this->env['REQUEST_PORT'];
 947     }
 948 
 949     /**
 950      * Returns the path of the request, that is the `REQUEST_URI` without the query string.
 951      *
 952      * @return string
 953      */
 954     protected function get_path()
 955     {
 956         $uri = $this->uri;
 957         $qs_pos = strpos($uri, '?');
 958 
 959         return ($qs_pos === false) ? $uri : substr($uri, 0, $qs_pos);
 960     }
 961 
 962     /**
 963      * Returns the {@link $path} property normalized using the
 964      * {@link \ICanBoogie\normalize_url_path()} function.
 965      *
 966      * @return string
 967      */
 968     protected function get_normalized_path()
 969     {
 970         return \ICanBoogie\normalize_url_path($this->path);
 971     }
 972 
 973     /**
 974      * Returns the extension of the path info.
 975      *
 976      * @return mixed
 977      */
 978     protected function get_extension()
 979     {
 980         return pathinfo($this->path, PATHINFO_EXTENSION);
 981     }
 982 
 983     protected function lazy_set_params($params)
 984     {
 985         return $params;
 986     }
 987 
 988     /**
 989      * Returns the union of the {@link path_params}, {@link request_params} and
 990      * {@link query_params} properties.
 991      *
 992      * This method is the getter of the {@link $params} magic property.
 993      *
 994      * @return array
 995      */
 996     protected function lazy_get_params()
 997     {
 998         return $this->path_params + $this->request_params + $this->query_params;
 999     }
1000 }
1001 
ICanBoogie/HTTP v2.4.0 API documentation generated by ApiGen