File indexing completed on 2025-01-26 05:29:13

0001 <?php
0002 namespace GuzzleHttp\Psr7;
0003 
0004 use InvalidArgumentException;
0005 use Psr\Http\Message\RequestInterface;
0006 use Psr\Http\Message\StreamInterface;
0007 use Psr\Http\Message\UriInterface;
0008 
0009 /**
0010  * PSR-7 request implementation.
0011  */
0012 class Request implements RequestInterface
0013 {
0014     use MessageTrait;
0015 
0016     /** @var string */
0017     private $method;
0018 
0019     /** @var null|string */
0020     private $requestTarget;
0021 
0022     /** @var UriInterface */
0023     private $uri;
0024 
0025     /**
0026      * @param string                               $method  HTTP method
0027      * @param string|UriInterface                  $uri     URI
0028      * @param array                                $headers Request headers
0029      * @param string|null|resource|StreamInterface $body    Request body
0030      * @param string                               $version Protocol version
0031      */
0032     public function __construct(
0033         $method,
0034         $uri,
0035         array $headers = [],
0036         $body = null,
0037         $version = '1.1'
0038     ) {
0039         if (!($uri instanceof UriInterface)) {
0040             $uri = new Uri($uri);
0041         }
0042 
0043         $this->method = strtoupper($method);
0044         $this->uri = $uri;
0045         $this->setHeaders($headers);
0046         $this->protocol = $version;
0047 
0048         if (!$this->hasHeader('Host')) {
0049             $this->updateHostFromUri();
0050         }
0051 
0052         if ($body !== '' && $body !== null) {
0053             $this->stream = stream_for($body);
0054         }
0055     }
0056 
0057     public function getRequestTarget()
0058     {
0059         if ($this->requestTarget !== null) {
0060             return $this->requestTarget;
0061         }
0062 
0063         $target = $this->uri->getPath();
0064         if ($target == '') {
0065             $target = '/';
0066         }
0067         if ($this->uri->getQuery() != '') {
0068             $target .= '?' . $this->uri->getQuery();
0069         }
0070 
0071         return $target;
0072     }
0073 
0074     public function withRequestTarget($requestTarget)
0075     {
0076         if (preg_match('#\s#', $requestTarget)) {
0077             throw new InvalidArgumentException(
0078                 'Invalid request target provided; cannot contain whitespace'
0079             );
0080         }
0081 
0082         $new = clone $this;
0083         $new->requestTarget = $requestTarget;
0084         return $new;
0085     }
0086 
0087     public function getMethod()
0088     {
0089         return $this->method;
0090     }
0091 
0092     public function withMethod($method)
0093     {
0094         $new = clone $this;
0095         $new->method = strtoupper($method);
0096         return $new;
0097     }
0098 
0099     public function getUri()
0100     {
0101         return $this->uri;
0102     }
0103 
0104     public function withUri(UriInterface $uri, $preserveHost = false)
0105     {
0106         if ($uri === $this->uri) {
0107             return $this;
0108         }
0109 
0110         $new = clone $this;
0111         $new->uri = $uri;
0112 
0113         if (!$preserveHost) {
0114             $new->updateHostFromUri();
0115         }
0116 
0117         return $new;
0118     }
0119 
0120     private function updateHostFromUri()
0121     {
0122         $host = $this->uri->getHost();
0123 
0124         if ($host == '') {
0125             return;
0126         }
0127 
0128         if (($port = $this->uri->getPort()) !== null) {
0129             $host .= ':' . $port;
0130         }
0131 
0132         if (isset($this->headerNames['host'])) {
0133             $header = $this->headerNames['host'];
0134         } else {
0135             $header = 'Host';
0136             $this->headerNames['host'] = 'Host';
0137         }
0138         // Ensure Host is the first header.
0139         // See: http://tools.ietf.org/html/rfc7230#section-5.4
0140         $this->headers = [$header => [$host]] + $this->headers;
0141     }
0142 }