OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "config.h" | |
6 #include "FetchHeaderList.h" | |
7 | |
8 #include "core/fetch/CrossOriginAccessControl.h" | |
9 #include "core/xml/XMLHttpRequest.h" | |
10 #include "platform/network/HTTPParsers.h" | |
11 #include "wtf/PassOwnPtr.h" | |
12 | |
13 namespace WebCore { | |
14 | |
15 PassRefPtr<FetchHeaderList> FetchHeaderList::create() | |
16 { | |
17 return adoptRef(new FetchHeaderList()); | |
18 } | |
19 | |
20 FetchHeaderList::FetchHeaderList() | |
21 { | |
22 } | |
23 | |
24 FetchHeaderList::~FetchHeaderList() | |
25 { | |
26 } | |
27 | |
28 void FetchHeaderList::append(const String& name, const String& value) | |
29 { | |
30 // To append a name/value (name/value) pair to a header list (list), append | |
31 // a new header whose name is name and value is value, to list. | |
falken
2014/06/27 02:08:06
I didn't realize at first this is a quote from the
horo
2014/06/27 04:19:10
Done.
| |
32 m_headerList.append(adoptPtr(new Header(name, value))); | |
33 } | |
34 | |
35 void FetchHeaderList::set(const String& name, const String& value) | |
36 { | |
37 // To set a name/value (name/value) pair in a header list (list), run these | |
38 // steps: | |
39 // 1. If there are any headers in list whose name is name, set the value of | |
40 // the first such header to value and remove the others. | |
41 // 2. Otherwise, append a new header whose name is name and value is value, | |
42 // to list. | |
43 for (size_t i = 0; i < m_headerList.size(); ++i) { | |
44 if (m_headerList[i]->first == name) { | |
45 m_headerList[i]->second = value; | |
46 for (size_t j = i + 1; j < m_headerList.size(); ) { | |
47 if (m_headerList[j]->first == name) | |
48 m_headerList.remove(j); | |
49 else | |
50 ++j; | |
51 } | |
52 return; | |
53 } | |
54 } | |
55 m_headerList.append(adoptPtr(new Header(name, value))); | |
56 } | |
57 | |
58 size_t FetchHeaderList::size() const | |
59 { | |
60 return m_headerList.size(); | |
61 } | |
62 | |
63 void FetchHeaderList::remove(const String& name) | |
64 { | |
65 for (size_t i = 0; i < m_headerList.size(); ) { | |
66 if (m_headerList[i]->first == name) { | |
67 m_headerList.remove(i); | |
68 } else { | |
69 ++i; | |
70 } | |
falken
2014/06/27 02:08:06
nit: blink code typically omits these braces
horo
2014/06/27 04:19:10
Done.
| |
71 } | |
72 } | |
73 | |
74 bool FetchHeaderList::get(const String& name, String& result) const | |
75 { | |
76 for (size_t i = 0; i < m_headerList.size(); ++i) { | |
77 if (m_headerList[i]->first == name) { | |
78 result = m_headerList[i]->second; | |
79 return true; | |
80 } | |
81 } | |
82 return false; | |
83 } | |
84 | |
85 void FetchHeaderList::getAll(const String& name, Vector<String>& result) const | |
86 { | |
87 result.clear(); | |
88 for (size_t i = 0; i < m_headerList.size(); ++i) { | |
89 if (m_headerList[i]->first == name) | |
90 result.append(m_headerList[i]->second); | |
91 } | |
92 } | |
93 | |
94 bool FetchHeaderList::has(const String& name) const | |
95 { | |
96 for (size_t i = 0; i < m_headerList.size(); ++i) { | |
97 if (m_headerList[i]->first == name) | |
98 return true; | |
99 } | |
100 return false; | |
101 } | |
102 | |
103 void FetchHeaderList::clearList() | |
104 { | |
105 m_headerList.clear(); | |
106 } | |
107 | |
108 bool FetchHeaderList::isValidHeaderName(const String& name) | |
109 { | |
110 // FIXME: According to the spec (http://fetch.spec.whatwg.org/) should we | |
111 // accept all characters in the range 0x00 to 0x7F? | |
112 return isValidHTTPToken(name); | |
113 } | |
114 | |
115 bool FetchHeaderList::isValidHeaderValue(const String& value) | |
116 { | |
117 // A value is a byte sequence that matches the field-value token production | |
118 // and contains no 0x0A or 0x0D bytes. | |
119 return (value.find('\r') == kNotFound) && (value.find('\n') == kNotFound); | |
120 } | |
121 | |
122 bool FetchHeaderList::isSimpleHeader(const String& name, const String& value) | |
123 { | |
124 // A simple header is a header whose name is either one of `Accept`, | |
125 // `Accept-Language`, and `Content-Language`, or whose name is | |
126 // `Content-Type` and value, once parsed, is one of | |
127 // `application/x-www-form-urlencoded`, `multipart/form-data`, and | |
128 // `text/plain`. | |
129 if (equalIgnoringCase(name, "accept") | |
130 || equalIgnoringCase(name, "accept-language") | |
131 || equalIgnoringCase(name, "content-language")) | |
132 return true; | |
133 | |
134 if (equalIgnoringCase(name, "content-type")) { | |
135 AtomicString mimeType = extractMIMETypeFromMediaType(AtomicString(value) ); | |
136 return equalIgnoringCase(mimeType, "application/x-www-form-urlencoded") | |
137 || equalIgnoringCase(mimeType, "multipart/form-data") | |
138 || equalIgnoringCase(mimeType, "text/plain"); | |
139 } | |
140 | |
141 return false; | |
142 } | |
143 | |
144 bool FetchHeaderList::isForbiddenHeaderName(const String& name) | |
145 { | |
146 // A forbidden header name is a header names that is one of: | |
147 // `Accept-Charset`, `Accept-Encoding`, `Access-Control-Request-Headers`, | |
148 // `Access-Control-Request-Method`, `Connection`, | |
149 // `Content-Length, Cookie`, `Cookie2`, `Date`, `DNT`, `Expect`, `Host`, | |
150 // `Keep-Alive`, `Origin`, `Referer`, `TE`, `Trailer`, | |
151 // `Transfer-Encoding`, `Upgrade`, `User-Agent`, `Via` | |
152 // or starts with `Proxy-` or `Sec-` (including when it is just `Proxy-` or | |
153 // `Sec-`). | |
154 return !XMLHttpRequest::isAllowedHTTPHeader(name); | |
155 } | |
156 | |
157 bool FetchHeaderList::isForbiddenResponseHeaderName(const String& name) | |
158 { | |
159 // A forbidden response header name is a header name that is one of: | |
160 // `Set-Cookie`, `Set-Cookie2` | |
161 return equalIgnoringCase(name, "set-cookie") || equalIgnoringCase(name, "set -cookie2"); | |
162 } | |
163 | |
164 } // namespace WebCore | |
OLD | NEW |