Rfc7230   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 164
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 43
c 1
b 0
f 0
dl 0
loc 164
ccs 16
cts 16
cp 1
rs 10
wmc 8

1 Method

Rating   Name   Duplication   Size   Complexity  
B hashRule() 0 28 8
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stadly\Http\Utilities;
6
7
use InvalidArgumentException;
8
9
/**
10
 * Regular expressions for matching rules in RFC 7230:
11
 * Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing
12
 *
13
 * Specification: https://tools.ietf.org/html/rfc7230
14
 */
15
final class Rfc7230
16
{
17
    /**
18
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2 (header-field)
19
     */
20
    public const HEADER_FIELD = '(?:' . self::FIELD_NAME . ':' . self::OWS . self::FIELD_VALUE . self::OWS . ')';
21
22
    /**
23
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2 (header-field)
24
     */
25
    public const HEADER_FIELD_CAPTURE
26
        = '(?:' . self::FIELD_NAME_CAPTURE . ':' . self::OWS . self::FIELD_VALUE_CAPTURE . self::OWS . ')';
27
28
    /**
29
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2 (field-name)
30
     */
31
    public const FIELD_NAME = self::TOKEN;
32
33
    /**
34
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2 (field-name)
35
     */
36
    public const FIELD_NAME_CAPTURE = '(?<FIELD_NAME>' . self::TOKEN . ')';
37
38
    /**
39
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2 (field-value)
40
     */
41
    public const FIELD_VALUE = '(?:(?:' . self::FIELD_CONTENT . '|' . self::OBS_FOLD . ')*)';
42
43
    /**
44
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2 (field-value)
45
     */
46
    public const FIELD_VALUE_CAPTURE = '(?<FIELD_VALUE>(?:' . self::FIELD_CONTENT . '|' . self::OBS_FOLD . ')*)';
47
48
    /**
49
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2 (field-content)
50
     *
51
     * This rule has been updated by an erratum: https://www.rfc-editor.org/errata/eid4189
52
     * Original: field-vchar [ 1*( SP / HTAB ) field-vchar ]
53
     * Updated: field-vchar [ 1*( SP / HTAB / field-vchar ) field-vchar ]
54
     */
55
    public const FIELD_CONTENT
56
        = '(?:' . self::FIELD_VCHAR
57
        . '(?:(?:' . Rfc5234::SP . '|' . Rfc5234::HTAB . '|' . self::FIELD_VCHAR . ')+' . self::FIELD_VCHAR . ')?)';
58
59
    /**
60
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2 (field-vchar)
61
     */
62
    public const FIELD_VCHAR = '(?:' . Rfc5234::VCHAR . '|' . self::OBS_TEXT . ')';
63
64
    /**
65
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2 (obs-fold)
66
     *
67
     * This rule has been updated by an erratum: https://www.rfc-editor.org/errata/eid4189
68
     * Original: CRLF 1*( SP / HTAB )
69
     * Updated: OWS CRLF 1*( SP / HTAB )
70
     */
71
    public const OBS_FOLD = '(?:' . self::OWS . Rfc5234::CRLF . '(?:' . Rfc5234::SP . '|' . Rfc5234::HTAB . ')+)';
72
73
    /**
74
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2.3 (OWS)
75
     */
76
    public const OWS = '(?:(?:' . Rfc5234::SP . '|' . Rfc5234::HTAB . ')*)';
77
78
    /**
79
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2.3 (RWS)
80
     */
81
    public const RWS = '(?:(?:' . Rfc5234::SP . '|' . Rfc5234::HTAB . ')+)';
82
83
    /**
84
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2.3 (BWS)
85
     */
86
    public const BWS = self::OWS;
87
88
    /**
89
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2.6 (token)
90
     */
91
    public const TOKEN = '(?:' . self::TCHAR . '+)';
92
93
    /**
94
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2.6 (tchar)
95
     */
96
    public const TCHAR = "(?:[!#$%&'*+\\-.\\^_`|~]|" . Rfc5234::DIGIT . '|' . Rfc5234::ALPHA . ')';
97
98
    /**
99
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2.6 (quoted-string)
100
     */
101
    public const QUOTED_STRING
102
        = '(?:' . Rfc5234::DQUOTE . '(?:' . self::QDTEXT . '|' . self::QUOTED_PAIR . ')*' . Rfc5234::DQUOTE . ')';
103
104
    /**
105
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2.6 (qdtext)
106
     */
107
    public const QDTEXT
108
        = '(?:' . Rfc5234::HTAB . '|' . Rfc5234::SP . "|[\x21\x23-\x5B\\\x5D-\x7E]|" . self::OBS_TEXT . ')';
109
110
    /**
111
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2.6 (obs-text)
112
     */
113
    public const OBS_TEXT = "[\x80-\xFF]";
114
115
    /**
116
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2.6 (comment)
117
     */
118
    public const COMMENT = '(?:\\((?:' . self::CTEXT . '|' . self::QUOTED_PAIR . '|(?R))*\\))';
119
120
    /**
121
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2.6 (ctext)
122
     */
123
    public const CTEXT
124
        = '(?:' . Rfc5234::HTAB . '|' . Rfc5234::SP . '|[\x21-\x27\x2A-\x5B\x5D-\x7E]|' . self::OBS_TEXT . ')';
125
126
    /**
127
     * Specification: https://tools.ietf.org/html/rfc7230#section-3.2.6 (quoted-pair)
128
     */
129
    public const QUOTED_PAIR
130
        = '(?:\\\\(?:' . Rfc5234::HTAB . '|' . Rfc5234::SP . '|' . Rfc5234::VCHAR . '|' . self::OBS_TEXT . '))';
131
132
    /**
133
     * Specification: https://tools.ietf.org/html/rfc7230#section-7 (#rule)
134
     *
135
     * This function produces the following rules:
136
     * 0# element => [ OWS *( "," OWS ) element *( 1*( OWS "," ) OWS element ) ] OWS *( "," OWS )
137
     * x# element => OWS *( "," OWS ) element <x-1>*( 1*( OWS "," ) OWS element ) OWS *( "," OWS )
138
     *
139
     * 0#0 element => OWS *( "," OWS )
140
     * 0#1 element => [ OWS *( "," OWS ) element ] OWS *( "," OWS )
141
     * 0#y element => [ OWS *( "," OWS ) element *<y-1>( 1*( OWS "," ) OWS element ) ] OWS *( "," OWS )
142
     *
143
     * 1#1 element => OWS *( "," OWS ) element OWS *( "," OWS )
144
     * x#y element => OWS *( "," OWS ) element <x-1>*<y-1>( 1*( OWS "," ) OWS element ) OWS *( "," OWS )
145
     *
146
     * @param string $element Regular expression for the list element.
147
     * @param int $min Minimum number of elements in list.
148
     * @param int|null $max Maximum number of elements in list.
149
     * @return string Regular expression for the list.
150
     */
151 146
    public static function hashRule(string $element, int $min = 0, ?int $max = null): string
152
    {
153 146
        if ($min < 0) {
154 1
            throw new InvalidArgumentException('Min number of elements must be non-negative.');
155
        }
156 145
        if ($max !== null && $min > $max) {
157 1
            throw new InvalidArgumentException('Max number of elements must be greater than or equal to min.');
158
        }
159
160 144
        $regEx = '';
161
162 144
        if ($max !== 0) {
163 128
            $regEx = self::OWS . '(?:,' . self::OWS . ')*' . $element;
164
165 128
            if ($max !== 1) {
166 96
                $minRepeat = max(0, $min - 1);
167 96
                $maxRepeat = $max === null ? '' : $max - 1;
168
169 96
                $regEx
170 96
                    .= '(?:(?:' . self::OWS . ',)+' . self::OWS . $element . '){' . $minRepeat . ',' . $maxRepeat . '}';
171
            }
172
173 128
            if ($min === 0) {
174 48
                $regEx = '(?:' . $regEx . ')?';
175
            }
176
        }
177
178 144
        return $regEx . self::OWS . '(?:,' . self::OWS . ')*';
179
    }
180
}
181