1 | <?php declare(strict_types=1); |
||
2 | |||
3 | namespace One\Http; |
||
4 | |||
5 | use One\Uri; |
||
6 | |||
7 | class Request extends Message implements \Psr\Http\Message\RequestInterface |
||
8 | { |
||
9 | /** |
||
10 | * Method |
||
11 | * @var string |
||
12 | */ |
||
13 | private $method; |
||
14 | |||
15 | /** |
||
16 | * Request Target |
||
17 | * @var string |
||
18 | */ |
||
19 | private $requestTarget; |
||
20 | |||
21 | /** |
||
22 | * Uri |
||
23 | * @var \Psr\Http\Message\UriInterface |
||
24 | */ |
||
25 | private $uri; |
||
26 | |||
27 | /** |
||
28 | * Default Constructor |
||
29 | * @param string|\Psr\Http\Message\UriInterface $uri |
||
30 | * @param mixed $body |
||
31 | * @param string $version |
||
32 | */ |
||
33 | public function __construct( |
||
34 | string $method, |
||
35 | $uri = null, |
||
36 | array $headers = [], |
||
37 | $body = null, |
||
38 | $version = '1.1' |
||
39 | ) { |
||
40 | if (! ($uri instanceof \Psr\Http\Message\UriInterface)) { |
||
41 | $uri = \One\createUriFromString($uri); |
||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||
42 | } |
||
43 | $this->method = strtoupper($method); |
||
44 | $this->uri = $uri; |
||
45 | $this->setHeaders($headers); |
||
46 | $this->protocol = $version; |
||
47 | if (! $this->hasHeader('Host')) { |
||
48 | $this->updateHostFromUri(); |
||
49 | } |
||
50 | if ($body !== '' && $body !== null) { |
||
51 | $this->stream = \One\stream_for($body); |
||
52 | } |
||
53 | } |
||
54 | |||
55 | /** |
||
56 | * @inheritDoc |
||
57 | */ |
||
58 | public function getRequestTarget() |
||
59 | { |
||
60 | if (! empty($this->requestTarget)) { |
||
61 | return $this->requestTarget; |
||
62 | } |
||
63 | $target = $this->uri->getPath(); |
||
64 | if ($target === '') { |
||
65 | $target = '/'; |
||
66 | } |
||
67 | if ($this->uri->getQuery() !== '') { |
||
68 | $target .= '?' . $this->uri->getQuery(); |
||
69 | } |
||
70 | return $target; |
||
71 | } |
||
72 | |||
73 | /** |
||
74 | * @inheritDoc |
||
75 | */ |
||
76 | public function withRequestTarget($requestTarget) |
||
77 | { |
||
78 | if (preg_match('#\s#', $requestTarget)) { |
||
79 | throw new \InvalidArgumentException( |
||
80 | 'Invalid request target provided; cannot contain whitespace' |
||
81 | ); |
||
82 | } |
||
83 | $new = clone $this; |
||
84 | $new->requestTarget = $requestTarget; |
||
85 | return $new; |
||
86 | } |
||
87 | |||
88 | /** |
||
89 | * @inheritDoc |
||
90 | */ |
||
91 | public function getMethod() |
||
92 | { |
||
93 | return $this->method; |
||
94 | } |
||
95 | |||
96 | /** |
||
97 | * @inheritDoc |
||
98 | */ |
||
99 | public function withMethod($method) |
||
100 | { |
||
101 | $new = clone $this; |
||
102 | $new->method = strtoupper($method); |
||
103 | return $new; |
||
104 | } |
||
105 | |||
106 | /** |
||
107 | * @inheritDoc |
||
108 | */ |
||
109 | public function getUri() |
||
110 | { |
||
111 | return $this->uri; |
||
112 | } |
||
113 | |||
114 | /** |
||
115 | * @inheritDoc |
||
116 | */ |
||
117 | public function withUri(\Psr\Http\message\UriInterface $uri, $preserveHost = false) |
||
118 | { |
||
119 | if ($uri === $this->uri) { |
||
0 ignored issues
–
show
|
|||
120 | return $this; |
||
121 | } |
||
122 | $new = clone $this; |
||
123 | $new->uri = $uri; |
||
124 | if (! $preserveHost) { |
||
125 | $new->updateHostFromUri(); |
||
126 | } |
||
127 | return $new; |
||
128 | } |
||
129 | |||
130 | /** |
||
131 | * Ensure Host is the first header |
||
132 | * See: http://tools.ietf.org/html/rfc7230#section-5.4 |
||
133 | */ |
||
134 | private function updateHostFromUri(): void |
||
135 | { |
||
136 | $host = $this->uri->getHost(); |
||
137 | $port = $this->uri->getPort(); |
||
138 | if ($host === '') { |
||
139 | return; |
||
140 | } |
||
141 | if ($port !== null) { |
||
142 | $host .= ':' . $port; |
||
143 | } |
||
144 | if (isset($this->headerNames['host'])) { |
||
145 | $header = $this->headerNames['host']; |
||
146 | } else { |
||
147 | $header = 'Host'; |
||
148 | $this->headerNames['host'] = 'Host'; |
||
149 | } |
||
150 | |||
151 | $this->headers = [$header => [$host]] + $this->headers; |
||
152 | } |
||
153 | } |
||
154 |