Linux: Depend on liberation-fonts package for RPMs.
[chromium-blink-merge.git] / content / child / web_url_request_util.cc
blobc51e2ea07084c0d4a4f873f750d421a2f0cb0df0
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.
5 #include "content/child/web_url_request_util.h"
7 #include "base/logging.h"
8 #include "base/strings/string_util.h"
9 #include "net/base/load_flags.h"
10 #include "net/base/net_errors.h"
11 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
12 #include "third_party/WebKit/public/platform/WebString.h"
13 #include "third_party/WebKit/public/platform/WebURL.h"
14 #include "third_party/WebKit/public/platform/WebURLError.h"
15 #include "third_party/WebKit/public/platform/WebURLRequest.h"
17 using blink::WebHTTPBody;
18 using blink::WebString;
19 using blink::WebURLRequest;
21 namespace content {
23 namespace {
25 const char kThrottledErrorDescription[] =
26 "Request throttled. Visit http://dev.chromium.org/throttling for more "
27 "information.";
29 class HeaderFlattener : public blink::WebHTTPHeaderVisitor {
30 public:
31 HeaderFlattener() : has_accept_header_(false) {}
33 virtual void visitHeader(const WebString& name, const WebString& value) {
34 // Headers are latin1.
35 const std::string& name_latin1 = name.latin1();
36 const std::string& value_latin1 = value.latin1();
38 // Skip over referrer headers found in the header map because we already
39 // pulled it out as a separate parameter.
40 if (base::LowerCaseEqualsASCII(name_latin1, "referer"))
41 return;
43 if (base::LowerCaseEqualsASCII(name_latin1, "accept"))
44 has_accept_header_ = true;
46 if (!buffer_.empty())
47 buffer_.append("\r\n");
48 buffer_.append(name_latin1 + ": " + value_latin1);
51 const std::string& GetBuffer() {
52 // In some cases, WebKit doesn't add an Accept header, but not having the
53 // header confuses some web servers. See bug 808613.
54 if (!has_accept_header_) {
55 if (!buffer_.empty())
56 buffer_.append("\r\n");
57 buffer_.append("Accept: */*");
58 has_accept_header_ = true;
60 return buffer_;
63 private:
64 std::string buffer_;
65 bool has_accept_header_;
68 } // namespace
70 ResourceType WebURLRequestToResourceType(const WebURLRequest& request) {
71 WebURLRequest::RequestContext requestContext = request.requestContext();
72 if (request.frameType() != WebURLRequest::FrameTypeNone) {
73 DCHECK(requestContext == WebURLRequest::RequestContextForm ||
74 requestContext == WebURLRequest::RequestContextFrame ||
75 requestContext == WebURLRequest::RequestContextHyperlink ||
76 requestContext == WebURLRequest::RequestContextIframe ||
77 requestContext == WebURLRequest::RequestContextInternal ||
78 requestContext == WebURLRequest::RequestContextLocation);
79 if (request.frameType() == WebURLRequest::FrameTypeTopLevel ||
80 request.frameType() == WebURLRequest::FrameTypeAuxiliary) {
81 return RESOURCE_TYPE_MAIN_FRAME;
83 if (request.frameType() == WebURLRequest::FrameTypeNested)
84 return RESOURCE_TYPE_SUB_FRAME;
85 NOTREACHED();
86 return RESOURCE_TYPE_SUB_RESOURCE;
89 switch (requestContext) {
90 // Favicon
91 case WebURLRequest::RequestContextFavicon:
92 return RESOURCE_TYPE_FAVICON;
94 // Font
95 case WebURLRequest::RequestContextFont:
96 return RESOURCE_TYPE_FONT_RESOURCE;
98 // Image
99 case WebURLRequest::RequestContextImage:
100 case WebURLRequest::RequestContextImageSet:
101 return RESOURCE_TYPE_IMAGE;
103 // Media
104 case WebURLRequest::RequestContextAudio:
105 case WebURLRequest::RequestContextVideo:
106 return RESOURCE_TYPE_MEDIA;
108 // Object
109 case WebURLRequest::RequestContextEmbed:
110 case WebURLRequest::RequestContextObject:
111 return RESOURCE_TYPE_OBJECT;
113 // Ping
114 case WebURLRequest::RequestContextBeacon:
115 case WebURLRequest::RequestContextCSPReport:
116 case WebURLRequest::RequestContextPing:
117 return RESOURCE_TYPE_PING;
119 // Prefetch
120 case WebURLRequest::RequestContextPrefetch:
121 return RESOURCE_TYPE_PREFETCH;
123 // Script
124 case WebURLRequest::RequestContextImport:
125 case WebURLRequest::RequestContextScript:
126 return RESOURCE_TYPE_SCRIPT;
128 // Style
129 case WebURLRequest::RequestContextXSLT:
130 case WebURLRequest::RequestContextStyle:
131 return RESOURCE_TYPE_STYLESHEET;
133 // Subresource
134 case WebURLRequest::RequestContextDownload:
135 case WebURLRequest::RequestContextManifest:
136 case WebURLRequest::RequestContextSubresource:
137 case WebURLRequest::RequestContextPlugin:
138 return RESOURCE_TYPE_SUB_RESOURCE;
140 // TextTrack
141 case WebURLRequest::RequestContextTrack:
142 return RESOURCE_TYPE_MEDIA;
144 // Workers
145 case WebURLRequest::RequestContextServiceWorker:
146 return RESOURCE_TYPE_SERVICE_WORKER;
147 case WebURLRequest::RequestContextSharedWorker:
148 return RESOURCE_TYPE_SHARED_WORKER;
149 case WebURLRequest::RequestContextWorker:
150 return RESOURCE_TYPE_WORKER;
152 // Unspecified
153 case WebURLRequest::RequestContextInternal:
154 case WebURLRequest::RequestContextUnspecified:
155 return RESOURCE_TYPE_SUB_RESOURCE;
157 // XHR
158 case WebURLRequest::RequestContextEventSource:
159 case WebURLRequest::RequestContextFetch:
160 case WebURLRequest::RequestContextXMLHttpRequest:
161 return RESOURCE_TYPE_XHR;
163 // These should be handled by the FrameType checks at the top of the
164 // function.
165 case WebURLRequest::RequestContextForm:
166 case WebURLRequest::RequestContextHyperlink:
167 case WebURLRequest::RequestContextLocation:
168 case WebURLRequest::RequestContextFrame:
169 case WebURLRequest::RequestContextIframe:
170 NOTREACHED();
171 return RESOURCE_TYPE_SUB_RESOURCE;
173 default:
174 NOTREACHED();
175 return RESOURCE_TYPE_SUB_RESOURCE;
179 std::string GetWebURLRequestHeaders(const blink::WebURLRequest& request) {
180 HeaderFlattener flattener;
181 request.visitHTTPHeaderFields(&flattener);
182 return flattener.GetBuffer();
185 int GetLoadFlagsForWebURLRequest(const blink::WebURLRequest& request) {
186 int load_flags = net::LOAD_NORMAL;
187 GURL url = request.url();
188 switch (request.cachePolicy()) {
189 case WebURLRequest::ReloadIgnoringCacheData:
190 // Required by LayoutTests/http/tests/misc/refresh-headers.php
191 load_flags |= net::LOAD_VALIDATE_CACHE;
192 break;
193 case WebURLRequest::ReloadBypassingCache:
194 load_flags |= net::LOAD_BYPASS_CACHE;
195 break;
196 case WebURLRequest::ReturnCacheDataElseLoad:
197 load_flags |= net::LOAD_PREFERRING_CACHE;
198 break;
199 case WebURLRequest::ReturnCacheDataDontLoad:
200 load_flags |= net::LOAD_ONLY_FROM_CACHE;
201 break;
202 case WebURLRequest::UseProtocolCachePolicy:
203 break;
204 default:
205 NOTREACHED();
208 if (!request.allowStoredCredentials()) {
209 load_flags |= net::LOAD_DO_NOT_SAVE_COOKIES;
210 load_flags |= net::LOAD_DO_NOT_SEND_COOKIES;
213 if (!request.allowStoredCredentials())
214 load_flags |= net::LOAD_DO_NOT_SEND_AUTH_DATA;
216 return load_flags;
219 scoped_refptr<ResourceRequestBody> GetRequestBodyForWebURLRequest(
220 const blink::WebURLRequest& request) {
221 scoped_refptr<ResourceRequestBody> request_body;
223 if (request.httpBody().isNull()) {
224 return request_body;
227 const std::string& method = request.httpMethod().latin1();
228 // GET and HEAD requests shouldn't have http bodies.
229 DCHECK(method != "GET" && method != "HEAD");
231 const WebHTTPBody& httpBody = request.httpBody();
232 request_body = new ResourceRequestBody();
233 size_t i = 0;
234 WebHTTPBody::Element element;
235 while (httpBody.elementAt(i++, element)) {
236 switch (element.type) {
237 case WebHTTPBody::Element::TypeData:
238 if (!element.data.isEmpty()) {
239 // Blink sometimes gives empty data to append. These aren't
240 // necessary so they are just optimized out here.
241 request_body->AppendBytes(
242 element.data.data(), static_cast<int>(element.data.size()));
244 break;
245 case WebHTTPBody::Element::TypeFile:
246 if (element.fileLength == -1) {
247 request_body->AppendFileRange(
248 base::FilePath::FromUTF16Unsafe(element.filePath),
249 0, kuint64max, base::Time());
250 } else {
251 request_body->AppendFileRange(
252 base::FilePath::FromUTF16Unsafe(element.filePath),
253 static_cast<uint64>(element.fileStart),
254 static_cast<uint64>(element.fileLength),
255 base::Time::FromDoubleT(element.modificationTime));
257 break;
258 case WebHTTPBody::Element::TypeFileSystemURL: {
259 GURL file_system_url = element.fileSystemURL;
260 DCHECK(file_system_url.SchemeIsFileSystem());
261 request_body->AppendFileSystemFileRange(
262 file_system_url,
263 static_cast<uint64>(element.fileStart),
264 static_cast<uint64>(element.fileLength),
265 base::Time::FromDoubleT(element.modificationTime));
266 break;
268 case WebHTTPBody::Element::TypeBlob:
269 request_body->AppendBlob(element.blobUUID.utf8());
270 break;
271 default:
272 NOTREACHED();
275 request_body->set_identifier(request.httpBody().identifier());
276 return request_body;
279 #define STATIC_ASSERT_MATCHING_ENUMS(content_name, blink_name) \
280 static_assert( \
281 static_cast<int>(content_name) == static_cast<int>(blink_name), \
282 "mismatching enums: " #content_name)
284 STATIC_ASSERT_MATCHING_ENUMS(FETCH_REQUEST_MODE_SAME_ORIGIN,
285 WebURLRequest::FetchRequestModeSameOrigin);
286 STATIC_ASSERT_MATCHING_ENUMS(FETCH_REQUEST_MODE_NO_CORS,
287 WebURLRequest::FetchRequestModeNoCORS);
288 STATIC_ASSERT_MATCHING_ENUMS(FETCH_REQUEST_MODE_CORS,
289 WebURLRequest::FetchRequestModeCORS);
290 STATIC_ASSERT_MATCHING_ENUMS(
291 FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT,
292 WebURLRequest::FetchRequestModeCORSWithForcedPreflight);
294 FetchRequestMode GetFetchRequestModeForWebURLRequest(
295 const blink::WebURLRequest& request) {
296 return static_cast<FetchRequestMode>(request.fetchRequestMode());
299 STATIC_ASSERT_MATCHING_ENUMS(FETCH_CREDENTIALS_MODE_OMIT,
300 WebURLRequest::FetchCredentialsModeOmit);
301 STATIC_ASSERT_MATCHING_ENUMS(FETCH_CREDENTIALS_MODE_SAME_ORIGIN,
302 WebURLRequest::FetchCredentialsModeSameOrigin);
303 STATIC_ASSERT_MATCHING_ENUMS(FETCH_CREDENTIALS_MODE_INCLUDE,
304 WebURLRequest::FetchCredentialsModeInclude);
306 FetchCredentialsMode GetFetchCredentialsModeForWebURLRequest(
307 const blink::WebURLRequest& request) {
308 return static_cast<FetchCredentialsMode>(request.fetchCredentialsMode());
311 STATIC_ASSERT_MATCHING_ENUMS(FetchRedirectMode::FOLLOW_MODE,
312 WebURLRequest::FetchRedirectModeFollow);
313 STATIC_ASSERT_MATCHING_ENUMS(FetchRedirectMode::ERROR_MODE,
314 WebURLRequest::FetchRedirectModeError);
315 STATIC_ASSERT_MATCHING_ENUMS(FetchRedirectMode::MANUAL_MODE,
316 WebURLRequest::FetchRedirectModeManual);
318 FetchRedirectMode GetFetchRedirectModeForWebURLRequest(
319 const blink::WebURLRequest& request) {
320 return static_cast<FetchRedirectMode>(request.fetchRedirectMode());
323 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_FRAME_TYPE_AUXILIARY,
324 WebURLRequest::FrameTypeAuxiliary);
325 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_FRAME_TYPE_NESTED,
326 WebURLRequest::FrameTypeNested);
327 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_FRAME_TYPE_NONE,
328 WebURLRequest::FrameTypeNone);
329 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL,
330 WebURLRequest::FrameTypeTopLevel);
332 RequestContextFrameType GetRequestContextFrameTypeForWebURLRequest(
333 const blink::WebURLRequest& request) {
334 return static_cast<RequestContextFrameType>(request.frameType());
337 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_UNSPECIFIED,
338 WebURLRequest::RequestContextUnspecified);
339 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_AUDIO,
340 WebURLRequest::RequestContextAudio);
341 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_BEACON,
342 WebURLRequest::RequestContextBeacon);
343 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_CSP_REPORT,
344 WebURLRequest::RequestContextCSPReport);
345 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_DOWNLOAD,
346 WebURLRequest::RequestContextDownload);
347 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_EMBED,
348 WebURLRequest::RequestContextEmbed);
349 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_EVENT_SOURCE,
350 WebURLRequest::RequestContextEventSource);
351 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_FAVICON,
352 WebURLRequest::RequestContextFavicon);
353 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_FETCH,
354 WebURLRequest::RequestContextFetch);
355 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_FONT,
356 WebURLRequest::RequestContextFont);
357 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_FORM,
358 WebURLRequest::RequestContextForm);
359 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_FRAME,
360 WebURLRequest::RequestContextFrame);
361 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_HYPERLINK,
362 WebURLRequest::RequestContextHyperlink);
363 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_IFRAME,
364 WebURLRequest::RequestContextIframe);
365 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_IMAGE,
366 WebURLRequest::RequestContextImage);
367 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_IMAGE_SET,
368 WebURLRequest::RequestContextImageSet);
369 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_IMPORT,
370 WebURLRequest::RequestContextImport);
371 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_INTERNAL,
372 WebURLRequest::RequestContextInternal);
373 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_LOCATION,
374 WebURLRequest::RequestContextLocation);
375 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_MANIFEST,
376 WebURLRequest::RequestContextManifest);
377 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_OBJECT,
378 WebURLRequest::RequestContextObject);
379 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_PING,
380 WebURLRequest::RequestContextPing);
381 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_PLUGIN,
382 WebURLRequest::RequestContextPlugin);
383 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_PREFETCH,
384 WebURLRequest::RequestContextPrefetch);
385 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_SCRIPT,
386 WebURLRequest::RequestContextScript);
387 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_SERVICE_WORKER,
388 WebURLRequest::RequestContextServiceWorker);
389 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_SHARED_WORKER,
390 WebURLRequest::RequestContextSharedWorker);
391 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_SUBRESOURCE,
392 WebURLRequest::RequestContextSubresource);
393 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_STYLE,
394 WebURLRequest::RequestContextStyle);
395 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_TRACK,
396 WebURLRequest::RequestContextTrack);
397 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_VIDEO,
398 WebURLRequest::RequestContextVideo);
399 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_WORKER,
400 WebURLRequest::RequestContextWorker);
401 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_XML_HTTP_REQUEST,
402 WebURLRequest::RequestContextXMLHttpRequest);
403 STATIC_ASSERT_MATCHING_ENUMS(REQUEST_CONTEXT_TYPE_XSLT,
404 WebURLRequest::RequestContextXSLT);
406 RequestContextType GetRequestContextTypeForWebURLRequest(
407 const blink::WebURLRequest& request) {
408 return static_cast<RequestContextType>(request.requestContext());
411 blink::WebURLError CreateWebURLError(const blink::WebURL& unreachable_url,
412 bool stale_copy_in_cache,
413 int reason) {
414 blink::WebURLError error;
415 error.domain = WebString::fromUTF8(net::kErrorDomain);
416 error.reason = reason;
417 error.unreachableURL = unreachable_url;
418 error.staleCopyInCache = stale_copy_in_cache;
419 if (reason == net::ERR_ABORTED) {
420 error.isCancellation = true;
421 } else if (reason == net::ERR_TEMPORARILY_THROTTLED) {
422 error.localizedDescription =
423 WebString::fromUTF8(kThrottledErrorDescription);
424 } else {
425 error.localizedDescription =
426 WebString::fromUTF8(net::ErrorToString(reason));
428 return error;
431 blink::WebURLError CreateWebURLError(const blink::WebURL& unreachable_url,
432 bool stale_copy_in_cache,
433 int reason,
434 bool was_ignored_by_handler) {
435 blink::WebURLError error =
436 CreateWebURLError(unreachable_url, stale_copy_in_cache, reason);
437 error.wasIgnoredByHandler = was_ignored_by_handler;
438 return error;
441 } // namespace content