Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/aphront/headerparser/AphrontHTTPHeaderParser.php
12241 views
1
<?php
2
3
final class AphrontHTTPHeaderParser extends Phobject {
4
5
private $name;
6
private $content;
7
private $pairs;
8
9
public function parseRawHeader($raw_header) {
10
$this->name = null;
11
$this->content = null;
12
13
$parts = explode(':', $raw_header, 2);
14
$this->name = trim($parts[0]);
15
if (count($parts) > 1) {
16
$this->content = trim($parts[1]);
17
}
18
19
$this->pairs = null;
20
21
return $this;
22
}
23
24
public function getHeaderName() {
25
$this->requireParse();
26
return $this->name;
27
}
28
29
public function getHeaderContent() {
30
$this->requireParse();
31
return $this->content;
32
}
33
34
public function getHeaderContentAsPairs() {
35
$content = $this->getHeaderContent();
36
37
38
$state = 'prekey';
39
$length = strlen($content);
40
41
$pair_name = null;
42
$pair_value = null;
43
44
$pairs = array();
45
$ii = 0;
46
while ($ii < $length) {
47
$c = $content[$ii];
48
49
switch ($state) {
50
case 'prekey';
51
// We're eating space in front of a key.
52
if ($c == ' ') {
53
$ii++;
54
break;
55
}
56
$pair_name = '';
57
$state = 'key';
58
break;
59
case 'key';
60
// We're parsing a key name until we find "=" or ";".
61
if ($c == ';') {
62
$state = 'done';
63
break;
64
}
65
66
if ($c == '=') {
67
$ii++;
68
$state = 'value';
69
break;
70
}
71
72
$ii++;
73
$pair_name .= $c;
74
break;
75
case 'value':
76
// We found an "=", so now figure out if the value is quoted
77
// or not.
78
if ($c == '"') {
79
$ii++;
80
$state = 'quoted';
81
break;
82
}
83
$state = 'unquoted';
84
break;
85
case 'quoted':
86
// We're in a quoted string, parse until we find the closing quote.
87
if ($c == '"') {
88
$ii++;
89
$state = 'done';
90
break;
91
}
92
93
$ii++;
94
$pair_value .= $c;
95
break;
96
case 'unquoted':
97
// We're in an unquoted string, parse until we find a space or a
98
// semicolon.
99
if ($c == ' ' || $c == ';') {
100
$state = 'done';
101
break;
102
}
103
$ii++;
104
$pair_value .= $c;
105
break;
106
case 'done':
107
// We parsed something, so eat any trailing whitespace and semicolons
108
// and look for a new value.
109
if ($c == ' ' || $c == ';') {
110
$ii++;
111
break;
112
}
113
114
$pairs[] = array(
115
$pair_name,
116
$pair_value,
117
);
118
119
$pair_name = null;
120
$pair_value = null;
121
122
$state = 'prekey';
123
break;
124
}
125
}
126
127
if ($state == 'quoted') {
128
throw new Exception(
129
pht(
130
'Header has unterminated double quote for key "%s".',
131
$pair_name));
132
}
133
134
if ($pair_name !== null) {
135
$pairs[] = array(
136
$pair_name,
137
$pair_value,
138
);
139
}
140
141
return $pairs;
142
}
143
144
private function requireParse() {
145
if ($this->name === null) {
146
throw new PhutilInvalidStateException('parseRawHeader');
147
}
148
}
149
150
}
151
152