Passed
Pull Request — master (#41)
by kenny
02:45
created

Message::withAddedHeader()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 12
nc 4
nop 2
dl 0
loc 16
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
namespace One\Http;
4
5
use \Psr\Http\Message\StreamInterface;
6
7
use function One\stream_for;
8
9
/**
10
 *
11
 */
12
class Message implements \Psr\Http\Message\MessageInterface
13
{
14
    protected $headers = [];
15
16
    protected $headerNames = [];
17
18
    protected $protocol = '1.1';
19
20
    protected $stream;
21
22
    public function getProtocolVersion()
23
    {
24
        return $this->protocol;
25
    }
26
    public function withProtocolVersion($version)
27
    {
28
        if ($this->protocol == $version) {
29
            return $this;
30
        }
31
32
        $new = clone $this;
33
34
        $new->protocol = $version;
35
36
        return $new;
37
    }
38
    public function getHeaders()
39
    {
40
        return $this->headers;
41
    }
42
    public function hasHeader($name)
43
    {
44
        return isset($this->headerNames[strtolower($name)]);
45
    }
46
    public function getHeader($name)
47
    {
48
        $lower = strtolower($name);
49
50
        if (!isset($this->headerNames[$lower])) {
51
            return array();
52
        }
53
54
        return $this->headers[$this->headerNames[$lower]];
55
    }
56
    public function getHeaderLine($header)
57
    {
58
        return implode(', ', $this->getHeader($header));
59
    }
60
    public function withHeader($header, $value)
61
    {
62
        if (!is_array($value)) {
63
            $value = [$value];
64
        }
65
        $value      = $this->trimHeaderValues($value);
66
        $normalized = strtolower($header);
67
        $new        = clone $this;
68
        if (isset($new->headerNames[$normalized])) {
69
            unset($new->headers[$new->headerNames[$normalized]]);
70
        }
71
        $new->headerNames[$normalized] = $header;
72
        $new->headers[$header]         = $value;
73
        return $new;
74
    }
75
    public function withAddedHeader($header, $value)
76
    {
77
        if (!is_array($value)) {
78
            $value = [$value];
79
        }
80
        $value      = $this->trimHeaderValues($value);
81
        $normalized = strtolower($header);
82
        $new        = clone $this;
83
        if (isset($new->headerNames[$normalized])) {
84
            $header                = $this->headerNames[$normalized];
85
            $new->headers[$header] = array_merge($this->headers[$header], $value);
86
        } else {
87
            $new->headerNames[$normalized] = $header;
88
            $new->headers[$header]         = $value;
89
        }
90
        return $new;
91
    }
92
    public function withoutHeader($header)
93
    {
94
        $normalized = strtolower($header);
95
        if (!isset($this->headerNames[$normalized])) {
96
            return $this;
97
        }
98
        $header = $this->headerNames[$normalized];
99
        $new    = clone $this;
100
        unset($new->headers[$header], $new->headerNames[$normalized]);
101
        return $new;
102
    }
103
    public function getBody()
104
    {
105
        if (!$this->stream) {
106
            $this->stream = stream_for('');
107
        }
108
        return $this->stream;
109
    }
110
    public function withBody(\Psr\Http\Message\StreamInterface $body)
111
    {
112
        if ($body === $this->stream) {
113
            return $this;
114
        }
115
        $new = clone $this;
116
        $new->stream = $body;
117
        return $new;
118
    }
119
120
    protected function setHeaders(array $headers)
121
    {
122
        $this->headerNames = $this->headers = [];
123
        foreach ($headers as $header => $value) {
124
            if (!is_array($value)) {
125
                $value = [$value];
126
            }
127
            $value = $this->trimHeaderValues($value);
128
            $normalized = strtolower($header);
129
            if (isset($this->headerNames[$normalized])) {
130
                $header = $this->headerNames[$normalized];
131
                $this->headers[$header] = array_merge($this->headers[$header], $value);
132
            } else {
133
                $this->headerNames[$normalized] = $header;
134
                $this->headers[$header] = $value;
135
            }
136
        }
137
    }
138
    /**
139
     * Trims whitespace from the header values.
140
     *
141
     * Spaces and tabs ought to be excluded by parsers when extracting the field value from a header field.
142
     *
143
     * header-field = field-name ":" OWS field-value OWS
144
     * OWS          = *( SP / HTAB )
145
     *
146
     * @param string[] $values Header values
147
     *
148
     * @return string[] Trimmed header values
149
     *
150
     * @see https://tools.ietf.org/html/rfc7230#section-3.2.4
151
     */
152
    protected function trimHeaderValues(array $values)
153
    {
154
        return array_map(function ($value) {
155
            return trim($value, " \t");
156
        }, $values);
157
    }
158
}
159