Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: third_party/WebKit/Source/core/fetch/FetchUtils.cpp

Issue 2584423002: Loading: move core/fetch to platform/loader/fetch (Closed)
Patch Set: another try Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 "core/fetch/FetchUtils.h"
6
7 #include "platform/HTTPNames.h"
8 #include "platform/network/HTTPHeaderMap.h"
9 #include "platform/network/HTTPParsers.h"
10 #include "wtf/HashSet.h"
11 #include "wtf/Threading.h"
12 #include "wtf/text/AtomicString.h"
13 #include "wtf/text/WTFString.h"
14
15 namespace blink {
16
17 namespace {
18
19 bool isHTTPWhitespace(UChar chr) {
20 return chr == ' ' || chr == '\n' || chr == '\t' || chr == '\r';
21 }
22
23 class ForbiddenHeaderNames {
24 WTF_MAKE_NONCOPYABLE(ForbiddenHeaderNames);
25 USING_FAST_MALLOC(ForbiddenHeaderNames);
26
27 public:
28 bool has(const String& name) const {
29 return m_fixedNames.contains(name) ||
30 name.startsWith(m_proxyHeaderPrefix, TextCaseASCIIInsensitive) ||
31 name.startsWith(m_secHeaderPrefix, TextCaseASCIIInsensitive);
32 }
33
34 static const ForbiddenHeaderNames& get();
35
36 private:
37 ForbiddenHeaderNames();
38
39 String m_proxyHeaderPrefix;
40 String m_secHeaderPrefix;
41 HashSet<String, CaseFoldingHash> m_fixedNames;
42 };
43
44 ForbiddenHeaderNames::ForbiddenHeaderNames()
45 : m_proxyHeaderPrefix("proxy-"), m_secHeaderPrefix("sec-") {
46 m_fixedNames = {
47 "accept-charset",
48 "accept-encoding",
49 "access-control-request-headers",
50 "access-control-request-method",
51 "connection",
52 "content-length",
53 "cookie",
54 "cookie2",
55 "date",
56 "dnt",
57 "expect",
58 "host",
59 "keep-alive",
60 "origin",
61 "referer",
62 "te",
63 "trailer",
64 "transfer-encoding",
65 "upgrade",
66 "user-agent",
67 "via",
68 };
69 }
70
71 const ForbiddenHeaderNames& ForbiddenHeaderNames::get() {
72 DEFINE_THREAD_SAFE_STATIC_LOCAL(const ForbiddenHeaderNames, instance,
73 new ForbiddenHeaderNames);
74 return instance;
75 }
76
77 } // namespace
78
79 bool FetchUtils::isSimpleMethod(const String& method) {
80 // http://fetch.spec.whatwg.org/#simple-method
81 // "A simple method is a method that is `GET`, `HEAD`, or `POST`."
82 return method == "GET" || method == "HEAD" || method == "POST";
83 }
84
85 bool FetchUtils::isSimpleHeader(const AtomicString& name,
86 const AtomicString& value) {
87 // http://fetch.spec.whatwg.org/#simple-header
88 // "A simple header is a header whose name is either one of `Accept`,
89 // `Accept-Language`, and `Content-Language`, or whose name is
90 // `Content-Type` and value, once parsed, is one of
91 // `application/x-www-form-urlencoded`, `multipart/form-data`, and
92 // `text/plain`."
93 // Treat 'Save-Data' as a simple header, since it is added by Chrome when
94 // Data Saver feature is enabled.
95 // Treat inspector header as a simple header, since it is added by blink when
96 // inspector is open.
97
98 if (equalIgnoringCase(name, "accept") ||
99 equalIgnoringCase(name, "accept-language") ||
100 equalIgnoringCase(name, "content-language") ||
101 equalIgnoringCase(
102 name, HTTPNames::X_DevTools_Emulate_Network_Conditions_Client_Id) ||
103 equalIgnoringCase(name, "save-data"))
104 return true;
105
106 if (equalIgnoringCase(name, "content-type"))
107 return isSimpleContentType(value);
108
109 return false;
110 }
111
112 bool FetchUtils::isSimpleContentType(const AtomicString& mediaType) {
113 AtomicString mimeType = extractMIMETypeFromMediaType(mediaType);
114 return equalIgnoringCase(mimeType, "application/x-www-form-urlencoded") ||
115 equalIgnoringCase(mimeType, "multipart/form-data") ||
116 equalIgnoringCase(mimeType, "text/plain");
117 }
118
119 bool FetchUtils::isSimpleRequest(const String& method,
120 const HTTPHeaderMap& headerMap) {
121 if (!isSimpleMethod(method))
122 return false;
123
124 for (const auto& header : headerMap) {
125 // Preflight is required for MIME types that can not be sent via form
126 // submission.
127 if (!isSimpleHeader(header.key, header.value))
128 return false;
129 }
130
131 return true;
132 }
133
134 bool FetchUtils::isForbiddenMethod(const String& method) {
135 // http://fetch.spec.whatwg.org/#forbidden-method
136 // "A forbidden method is a method that is a byte case-insensitive match"
137 // for one of `CONNECT`, `TRACE`, and `TRACK`."
138 return equalIgnoringCase(method, "TRACE") ||
139 equalIgnoringCase(method, "TRACK") ||
140 equalIgnoringCase(method, "CONNECT");
141 }
142
143 bool FetchUtils::isForbiddenHeaderName(const String& name) {
144 // http://fetch.spec.whatwg.org/#forbidden-header-name
145 // "A forbidden header name is a header names that is one of:
146 // `Accept-Charset`, `Accept-Encoding`, `Access-Control-Request-Headers`,
147 // `Access-Control-Request-Method`, `Connection`,
148 // `Content-Length, Cookie`, `Cookie2`, `Date`, `DNT`, `Expect`, `Host`,
149 // `Keep-Alive`, `Origin`, `Referer`, `TE`, `Trailer`,
150 // `Transfer-Encoding`, `Upgrade`, `User-Agent`, `Via`
151 // or starts with `Proxy-` or `Sec-` (including when it is just `Proxy-` or
152 // `Sec-`)."
153
154 return ForbiddenHeaderNames::get().has(name);
155 }
156
157 bool FetchUtils::isForbiddenResponseHeaderName(const String& name) {
158 // http://fetch.spec.whatwg.org/#forbidden-response-header-name
159 // "A forbidden response header name is a header name that is one of:
160 // `Set-Cookie`, `Set-Cookie2`"
161
162 return equalIgnoringCase(name, "set-cookie") ||
163 equalIgnoringCase(name, "set-cookie2");
164 }
165
166 bool FetchUtils::isSimpleOrForbiddenRequest(const String& method,
167 const HTTPHeaderMap& headerMap) {
168 if (!isSimpleMethod(method))
169 return false;
170
171 for (const auto& header : headerMap) {
172 if (!isSimpleHeader(header.key, header.value) &&
173 !isForbiddenHeaderName(header.key))
174 return false;
175 }
176
177 return true;
178 }
179
180 AtomicString FetchUtils::normalizeMethod(const AtomicString& method) {
181 // https://fetch.spec.whatwg.org/#concept-method-normalize
182
183 // We place GET and POST first because they are more commonly used than
184 // others.
185 const char* const methods[] = {
186 "GET", "POST", "DELETE", "HEAD", "OPTIONS", "PUT",
187 };
188
189 for (const auto& known : methods) {
190 if (equalIgnoringCase(method, known)) {
191 // Don't bother allocating a new string if it's already all
192 // uppercase.
193 return method == known ? method : known;
194 }
195 }
196 return method;
197 }
198
199 String FetchUtils::normalizeHeaderValue(const String& value) {
200 // https://fetch.spec.whatwg.org/#concept-header-value-normalize
201 // Strip leading and trailing whitespace from header value.
202 // HTTP whitespace bytes are 0x09, 0x0A, 0x0D, and 0x20.
203
204 return value.stripWhiteSpace(isHTTPWhitespace);
205 }
206
207 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/fetch/FetchUtils.h ('k') | third_party/WebKit/Source/core/fetch/FetchUtilsTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698