Issues (29)

src/Http/Request.php (2 issues)

Labels
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
It seems like $uri can also be of type null; however, parameter $uri of One\createUriFromString() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

41
            $uri = \One\createUriFromString(/** @scrutinizer ignore-type */ $uri);
Loading history...
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
The condition $uri === $this->uri is always false.
Loading history...
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