Passed
Pull Request — master (#372)
by
unknown
21:21
created

Header::fromRawText()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Qiniu\Http;
4
5
/**
6
 * field name case-insensitive Header
7
 */
8
class Header implements \ArrayAccess, \IteratorAggregate, \Countable
9
{
10
    /** @var array normalized key name map */
11
    private $data;
12
13
    /**
14
     * @param array $obj non-normalized header object
15
     */
16
    public function __construct($obj = array())
17
    {
18
        foreach ($obj as $key => $value) {
19
            $normalizedKey = self::normalizeKey($key);
20
            $this->data[$normalizedKey] = self::normalizeValue($value);
21
        }
22
        return $this;
23
    }
24
25
    /**
26
     * return origin headers, which is field name case-sensitive
27
     *
28
     * @param string $raw
29
     *
30
     * @return array
31
     */
32
    public static function parseRawText($raw)
33
    {
34
        $headers = array();
35
        $headerLines = explode("\r\n", $raw);
36
        foreach ($headerLines as $line) {
37
            $headerLine = trim($line);
38
            $kv = explode(':', $headerLine);
39
            if (count($kv) <= 1) {
40
                continue;
41
            }
42
            // for http2 [Pseudo-Header Fields](https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.1)
43
            if ($kv[0] == "") {
44
                $fieldName = ":" . $kv[1];
45
            } else {
46
                $fieldName = $kv[0];
47
            }
48
            $fieldValue = trim(substr($headerLine, strlen($fieldName.":")));
49
            $headers[$fieldName] = $fieldValue;
50
        }
51
        return $headers;
52
    }
53
54
    /**
55
     * @param string $raw
56
     *
57
     * @return Header
58
     */
59
    public static function fromRawText($raw)
60
    {
61
        return new Header(self::parseRawText($raw));
62
    }
63
64
    /**
65
     * @param string $key
66
     *
67
     * @return string
68
     */
69
    public static function normalizeKey($key)
70
    {
71
        $key = trim($key);
72
73
        if (!self::isValidKeyName($key)) {
74
            return $key;
75
        }
76
77
        return ucwords(strtolower($key), '-');
78
    }
79
80
    /**
81
     * @param string | numeric $value
0 ignored issues
show
Bug introduced by
The type Qiniu\Http\numeric was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
82
     *
83
     * @return string | numeric
84
     */
85
    public static function normalizeValue($value)
86
    {
87
        if (is_numeric($value)) {
88
            return $value + 0;
89
        }
90
        return trim($value);
91
    }
92
93
    public function offsetExists($offset)
94
    {
95
        $key = self::normalizeKey($offset);
96
        return isset($this->data[$key]);
97
    }
98
99
    public function offsetGet($offset)
100
    {
101
        $key = self::normalizeKey($offset);
102
        return $this->data[$key];
103
    }
104
105
    public function offsetSet($offset, $value)
106
    {
107
        $key = self::normalizeKey($offset);
108
        $this->data[$key] = self::normalizeValue($value);
109
    }
110
111
    public function offsetUnset($offset)
112
    {
113
        $key = self::normalizeKey($offset);
114
        unset($this->data[$key]);
115
    }
116
117
    public function getIterator()
118
    {
119
        return new \ArrayIterator($this->data);
120
    }
121
122
    public function count()
123
    {
124
        return count($this->data);
125
    }
126
127
128
    private static $isTokenTable = array(
129
        '!' => true,
130
        '#' => true,
131
        '$' => true,
132
        '%' => true,
133
        '&' => true,
134
        '\'' => true,
135
        '*' => true,
136
        '+' => true,
137
        '-' => true,
138
        '.' => true,
139
        '0' => true,
140
        '1' => true,
141
        '2' => true,
142
        '3' => true,
143
        '4' => true,
144
        '5' => true,
145
        '6' => true,
146
        '7' => true,
147
        '8' => true,
148
        '9' => true,
149
        'A' => true,
150
        'B' => true,
151
        'C' => true,
152
        'D' => true,
153
        'E' => true,
154
        'F' => true,
155
        'G' => true,
156
        'H' => true,
157
        'I' => true,
158
        'J' => true,
159
        'K' => true,
160
        'L' => true,
161
        'M' => true,
162
        'N' => true,
163
        'O' => true,
164
        'P' => true,
165
        'Q' => true,
166
        'R' => true,
167
        'S' => true,
168
        'T' => true,
169
        'U' => true,
170
        'W' => true,
171
        'V' => true,
172
        'X' => true,
173
        'Y' => true,
174
        'Z' => true,
175
        '^' => true,
176
        '_' => true,
177
        '`' => true,
178
        'a' => true,
179
        'b' => true,
180
        'c' => true,
181
        'd' => true,
182
        'e' => true,
183
        'f' => true,
184
        'g' => true,
185
        'h' => true,
186
        'i' => true,
187
        'j' => true,
188
        'k' => true,
189
        'l' => true,
190
        'm' => true,
191
        'n' => true,
192
        'o' => true,
193
        'p' => true,
194
        'q' => true,
195
        'r' => true,
196
        's' => true,
197
        't' => true,
198
        'u' => true,
199
        'v' => true,
200
        'w' => true,
201
        'x' => true,
202
        'y' => true,
203
        'z' => true,
204
        '|' => true,
205
        '~' => true,
206
    );
207
208
    /**
209
     * @param string $str
210
     *
211
     * @return boolean
212
     */
213
    private static function isValidKeyName($str)
214
    {
215
        for ($i = 0; $i < count($str); $i += 1) {
0 ignored issues
show
Bug introduced by
$str of type string is incompatible with the type Countable|array expected by parameter $value of count(). ( Ignorable by Annotation )

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

215
        for ($i = 0; $i < count(/** @scrutinizer ignore-type */ $str); $i += 1) {
Loading history...
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
216
            if (!isset(self::$isTokenTable[$str[$i]])) {
217
                return false;
218
            }
219
        }
220
        return true;
221
    }
222
}
223