1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An implementation of WebURLLoader in terms of ResourceLoaderBridge.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/child/web_url_loader_impl.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/child/ftp_directory_listing_response_delegate.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/child/multipart_response_delegate.h"
17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/child/request_extra_data.h"
18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/child/request_info.h"
19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/resource_dispatcher.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/child/resource_loader_bridge.h"
214ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch#include "content/child/sync_load_response.h"
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/child/web_url_request_util.h"
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/child/weburlresponse_extradata_impl.h"
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/common/resource_request_body.h"
25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/public/child/request_peer.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/data_url.h"
27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "net/base/filename_util.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/mime_util.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_util.h"
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "net/url_request/redirect_info.h"
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/url_request/url_request_data_job.h"
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebHTTPLoadInfo.h"
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURL.h"
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLError.h"
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLLoadTiming.h"
40ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLRequest.h"
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLResponse.h"
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeTicks;
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebData;
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebHTTPBody;
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebHTTPHeaderVisitor;
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebHTTPLoadInfo;
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebReferrerPolicy;
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebSecurityPolicy;
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebString;
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURL;
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLError;
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLLoadTiming;
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLLoader;
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLLoaderClient;
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLRequest;
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLResponse;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace content {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Utilities ------------------------------------------------------------------
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kThrottledErrorDescription[] =
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Request throttled. Visit http://dev.chromium.org/throttling for more "
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "information.";
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HeaderFlattener : public WebHTTPHeaderVisitor {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  HeaderFlattener() : has_accept_header_(false) {}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void visitHeader(const WebString& name, const WebString& value) {
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Headers are latin1.
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& name_latin1 = name.latin1();
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& value_latin1 = value.latin1();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Skip over referrer headers found in the header map because we already
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // pulled it out as a separate parameter.
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (LowerCaseEqualsASCII(name_latin1, "referer"))
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (LowerCaseEqualsASCII(name_latin1, "accept"))
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      has_accept_header_ = true;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!buffer_.empty())
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      buffer_.append("\r\n");
9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    buffer_.append(name_latin1 + ": " + value_latin1);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string& GetBuffer() {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // In some cases, WebKit doesn't add an Accept header, but not having the
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // header confuses some web servers.  See bug 808613.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!has_accept_header_) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!buffer_.empty())
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        buffer_.append("\r\n");
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      buffer_.append("Accept: */*");
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      has_accept_header_ = true;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return buffer_;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string buffer_;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_accept_header_;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef ResourceDevToolsInfo::HeadersVector HeadersVector;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Converts timing data from |load_timing| to the format used by WebKit.
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PopulateURLLoadTiming(const net::LoadTimingInfo& load_timing,
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           WebURLLoadTiming* url_timing) {
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!load_timing.request_start.is_null());
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const TimeTicks kNullTicks;
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  url_timing->initialize();
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  url_timing->setRequestTime(
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (load_timing.request_start - kNullTicks).InSecondsF());
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  url_timing->setProxyStart(
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (load_timing.proxy_resolve_start - kNullTicks).InSecondsF());
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  url_timing->setProxyEnd(
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (load_timing.proxy_resolve_end - kNullTicks).InSecondsF());
12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  url_timing->setDNSStart(
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (load_timing.connect_timing.dns_start - kNullTicks).InSecondsF());
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  url_timing->setDNSEnd(
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (load_timing.connect_timing.dns_end - kNullTicks).InSecondsF());
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  url_timing->setConnectStart(
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (load_timing.connect_timing.connect_start - kNullTicks).InSecondsF());
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  url_timing->setConnectEnd(
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (load_timing.connect_timing.connect_end - kNullTicks).InSecondsF());
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  url_timing->setSSLStart(
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (load_timing.connect_timing.ssl_start - kNullTicks).InSecondsF());
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  url_timing->setSSLEnd(
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (load_timing.connect_timing.ssl_end - kNullTicks).InSecondsF());
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  url_timing->setSendStart(
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (load_timing.send_start - kNullTicks).InSecondsF());
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  url_timing->setSendEnd(
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (load_timing.send_end - kNullTicks).InSecondsF());
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  url_timing->setReceiveHeadersEnd(
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (load_timing.receive_headers_end - kNullTicks).InSecondsF());
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)net::RequestPriority ConvertWebKitPriorityToNetPriority(
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const WebURLRequest::Priority& priority) {
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (priority) {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case WebURLRequest::PriorityVeryHigh:
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return net::HIGHEST;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case WebURLRequest::PriorityHigh:
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return net::MEDIUM;
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case WebURLRequest::PriorityMedium:
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return net::LOW;
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case WebURLRequest::PriorityLow:
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return net::LOWEST;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case WebURLRequest::PriorityVeryLow:
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return net::IDLE;
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case WebURLRequest::PriorityUnresolved:
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return net::LOW;
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Extracts info from a data scheme URL into |info| and |data|. Returns net::OK
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// if successful. Returns a net error code otherwise. Exported only for testing.
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint GetInfoFromDataURL(const GURL& url,
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       ResourceResponseInfo* info,
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       std::string* data) {
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Assure same time for all time fields of data: URLs.
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Time now = Time::Now();
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  info->load_timing.request_start = TimeTicks::Now();
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  info->load_timing.request_start_time = now;
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  info->request_time = now;
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  info->response_time = now;
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string mime_type;
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string charset;
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<net::HttpResponseHeaders> headers(
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new net::HttpResponseHeaders(std::string()));
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int result = net::URLRequestDataJob::BuildResponse(
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url, &mime_type, &charset, data, headers.get());
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (result != net::OK)
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return result;
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  info->headers = headers;
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  info->mime_type.swap(mime_type);
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  info->charset.swap(charset);
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  info->security_info.clear();
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  info->content_length = data->length();
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  info->encoded_data_length = 0;
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return net::OK;
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WebURLLoaderImpl::Context --------------------------------------------------
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This inner class exists since the WebURLLoader may be deleted while inside a
207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// call to WebURLLoaderClient.  Refcounting is to keep the context from being
208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// deleted if it may have work to do after calling into the client.
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WebURLLoaderImpl::Context : public base::RefCounted<Context>,
210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                  public RequestPeer {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Context(WebURLLoaderImpl* loader, ResourceDispatcher* resource_dispatcher);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLLoaderClient* client() const { return client_; }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_client(WebURLLoaderClient* client) { client_ = client; }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Cancel();
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetDefersLoading(bool value);
219c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  void DidChangePriority(WebURLRequest::Priority new_priority,
220c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                         int intra_priority_value);
221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bool AttachThreadedDataReceiver(
222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      blink::WebThreadedDataReceiver* threaded_data_receiver);
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void Start(const WebURLRequest& request,
2244ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch             SyncLoadResponse* sync_load_response);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
226c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // RequestPeer methods:
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnUploadProgress(uint64 position, uint64 size) OVERRIDE;
2286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual bool OnReceivedRedirect(const net::RedirectInfo& redirect_info,
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  const ResourceResponseInfo& info) OVERRIDE;
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnReceivedResponse(const ResourceResponseInfo& info) OVERRIDE;
23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void OnDownloadedData(int len, int encoded_data_length) OVERRIDE;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnReceivedData(const char* data,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              int data_length,
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              int encoded_data_length) OVERRIDE;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnReceivedCachedMetadata(const char* data, int len) OVERRIDE;
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnCompletedRequest(
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int error_code,
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool was_ignored_by_handler,
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bool stale_copy_in_cache,
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& security_info,
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const base::TimeTicks& completion_time,
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int64 total_transfer_size) OVERRIDE;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCounted<Context>;
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~Context() {}
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We can optimize the handling of data URLs in most cases.
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool CanHandleDataURLRequestLocally() const;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleDataURL();
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLLoaderImpl* loader_;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLRequest request_;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLLoaderClient* client_;
255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ResourceDispatcher* resource_dispatcher_;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebReferrerPolicy referrer_policy_;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ResourceLoaderBridge> bridge_;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MultipartResponseDelegate> multipart_delegate_;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ResourceLoaderBridge> completed_bridge_;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
263116680a4aac90f2aa7413d9095a592090648e557Ben MurdochWebURLLoaderImpl::Context::Context(WebURLLoaderImpl* loader,
264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   ResourceDispatcher* resource_dispatcher)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : loader_(loader),
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_(NULL),
267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      resource_dispatcher_(resource_dispatcher),
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      referrer_policy_(blink::WebReferrerPolicyDefault) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebURLLoaderImpl::Context::Cancel() {
272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (bridge_) {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bridge_->Cancel();
274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bridge_.reset();
275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we do not notify the multipart delegate anymore as it has
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // its own pointer to the client.
279b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (multipart_delegate_)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    multipart_delegate_->Cancel();
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Ditto for the ftp delegate.
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (ftp_listing_delegate_)
283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ftp_listing_delegate_->Cancel();
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do not make any further calls to the client.
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_ = NULL;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  loader_ = NULL;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebURLLoaderImpl::Context::SetDefersLoading(bool value) {
291b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (bridge_)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bridge_->SetDefersLoading(value);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebURLLoaderImpl::Context::DidChangePriority(
296c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    WebURLRequest::Priority new_priority, int intra_priority_value) {
297b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (bridge_)
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bridge_->DidChangePriority(
299c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        ConvertWebKitPriorityToNetPriority(new_priority), intra_priority_value);
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool WebURLLoaderImpl::Context::AttachThreadedDataReceiver(
303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    blink::WebThreadedDataReceiver* threaded_data_receiver) {
304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (bridge_)
305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return bridge_->AttachThreadedDataReceiver(threaded_data_receiver);
306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return false;
308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3104ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdochvoid WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
3114ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch                                      SyncLoadResponse* sync_load_response) {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!bridge_.get());
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_ = request;  // Save the request.
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url = request.url();
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (CanHandleDataURLRequestLocally()) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sync_load_response) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This is a sync load. Do the work now.
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sync_load_response->url = url;
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      sync_load_response->error_code =
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          GetInfoFromDataURL(sync_load_response->url, sync_load_response,
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             &sync_load_response->data);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
325b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::MessageLoop::current()->PostTask(
326b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          FROM_HERE, base::Bind(&Context::HandleDataURL, this));
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL referrer_url(
33258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      request.httpHeaderField(WebString::fromUTF8("Referer")).latin1());
33358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const std::string& method = request.httpMethod().latin1();
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  int load_flags = net::LOAD_NORMAL;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (request.cachePolicy()) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebURLRequest::ReloadIgnoringCacheData:
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Required by LayoutTests/http/tests/misc/refresh-headers.php
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      load_flags |= net::LOAD_VALIDATE_CACHE;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
34146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case WebURLRequest::ReloadBypassingCache:
34246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      load_flags |= net::LOAD_BYPASS_CACHE;
34346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebURLRequest::ReturnCacheDataElseLoad:
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      load_flags |= net::LOAD_PREFERRING_CACHE;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebURLRequest::ReturnCacheDataDontLoad:
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      load_flags |= net::LOAD_ONLY_FROM_CACHE;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebURLRequest::UseProtocolCachePolicy:
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
35246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    default:
35346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      NOTREACHED();
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request.reportUploadProgress())
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    load_flags |= net::LOAD_ENABLE_UPLOAD_PROGRESS;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request.reportRawHeaders())
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    load_flags |= net::LOAD_REPORT_RAW_HEADERS;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!request.allowStoredCredentials()) {
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    load_flags |= net::LOAD_DO_NOT_SAVE_COOKIES;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    load_flags |= net::LOAD_DO_NOT_SEND_COOKIES;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!request.allowStoredCredentials())
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    load_flags |= net::LOAD_DO_NOT_SEND_AUTH_DATA;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (request.requestContext() == WebURLRequest::RequestContextXMLHttpRequest &&
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      (url.has_username() || url.has_password())) {
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    load_flags |= net::LOAD_DO_NOT_PROMPT_FOR_LOGIN;
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  HeaderFlattener flattener;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.visitHTTPHeaderFields(&flattener);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(brettw) this should take parameter encoding into account when
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // creating the GURLs.
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
380effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  RequestInfo request_info;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.method = method;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.url = url;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.first_party_for_cookies = request.firstPartyForCookies();
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.referrer = referrer_url;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.headers = flattener.GetBuffer();
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.load_flags = load_flags;
3876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  request_info.enable_load_timing = true;
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requestor_pid only needs to be non-zero if the request originates outside
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the render process, so we can use requestorProcessID even for requests
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from in-process plugins.
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.requestor_pid = request.requestorProcessID();
3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  request_info.request_type = WebURLRequestToResourceType(request);
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request_info.priority =
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ConvertWebKitPriorityToNetPriority(request.priority());
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.appcache_host_id = request.appCacheHostID();
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.routing_id = request.requestorID();
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.download_to_file = request.downloadToFile();
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.has_user_gesture = request.hasUserGesture();
3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  request_info.skip_service_worker = request.skipServiceWorker();
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.extra_data = request.extraData();
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  referrer_policy_ = request.referrerPolicy();
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request_info.referrer_policy = request.referrerPolicy();
403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bridge_.reset(resource_dispatcher_->CreateBridge(request_info));
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!request.httpBody().isNull()) {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // GET and HEAD requests shouldn't have http bodies.
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(method != "GET" && method != "HEAD");
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebHTTPBody& httpBody = request.httpBody();
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t i = 0;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebHTTPBody::Element element;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (httpBody.elementAt(i++, element)) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switch (element.type) {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WebHTTPBody::Element::TypeData:
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (!element.data.isEmpty()) {
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // WebKit sometimes gives up empty data to append. These aren't
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // necessary so we just optimize those out here.
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            request_body->AppendBytes(
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                element.data.data(), static_cast<int>(element.data.size()));
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WebHTTPBody::Element::TypeFile:
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (element.fileLength == -1) {
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            request_body->AppendFileRange(
425eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                base::FilePath::FromUTF16Unsafe(element.filePath),
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                0, kuint64max, base::Time());
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          } else {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            request_body->AppendFileRange(
429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                base::FilePath::FromUTF16Unsafe(element.filePath),
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                static_cast<uint64>(element.fileStart),
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                static_cast<uint64>(element.fileLength),
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                base::Time::FromDoubleT(element.modificationTime));
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
43558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        case WebHTTPBody::Element::TypeFileSystemURL: {
43668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          GURL file_system_url = element.fileSystemURL;
43768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          DCHECK(file_system_url.SchemeIsFileSystem());
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          request_body->AppendFileSystemFileRange(
43968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)              file_system_url,
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              static_cast<uint64>(element.fileStart),
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              static_cast<uint64>(element.fileLength),
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              base::Time::FromDoubleT(element.modificationTime));
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WebHTTPBody::Element::TypeBlob:
44668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          request_body->AppendBlob(element.blobUUID.utf8());
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        default:
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          NOTREACHED();
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_body->set_identifier(request.httpBody().identifier());
453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bridge_->SetRequestBody(request_body.get());
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (sync_load_response) {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bridge_->SyncLoad(sync_load_response);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TODO(mmenke):  This case probably never happens, anyways.  Probably should
462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // not handle this case at all.  If it's worth handling, this code currently
463116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // results in the request just hanging, which should be fixed.
464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!bridge_->Start(this))
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bridge_.reset();
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebURLLoaderImpl::Context::OnUploadProgress(uint64 position, uint64 size) {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (client_)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_->didSendData(loader_, position, size);
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebURLLoaderImpl::Context::OnReceivedRedirect(
4746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const net::RedirectInfo& redirect_info,
475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ResourceResponseInfo& info) {
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!client_)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response;
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.initialize();
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PopulateURLResponse(request_.url(), info, &response);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(darin): We lack sufficient information to construct the actual
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // request that resulted from the redirect.
4856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  WebURLRequest new_request(redirect_info.new_url);
4866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  new_request.setFirstPartyForCookies(
4876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      redirect_info.new_first_party_for_cookies);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_request.setDownloadToFile(request_.downloadToFile());
48929b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  new_request.setRequestContext(request_.requestContext());
49029b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  new_request.setFrameType(request_.frameType());
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  new_request.setHTTPReferrer(WebString::fromUTF8(redirect_info.new_referrer),
4936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                              referrer_policy_);
4946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::string old_method = request_.httpMethod().utf8();
4966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  new_request.setHTTPMethod(WebString::fromUTF8(redirect_info.new_method));
4976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (redirect_info.new_method == old_method)
4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    new_request.setHTTPBody(request_.httpBody());
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
500116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Protect from deletion during call to willSendRequest.
501116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<Context> protect(this);
502116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_->willSendRequest(loader_, new_request, response);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_ = new_request;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only follow the redirect if WebKit left the URL unmodified.
5076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (redirect_info.new_url == GURL(new_request.url())) {
508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // First-party cookie logic moved from DocumentLoader in Blink to
5096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // net::URLRequest in the browser. Assert that Blink didn't try to change it
5106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // to something else.
5116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    DCHECK_EQ(redirect_info.new_first_party_for_cookies.spec(),
512cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)              request_.firstPartyForCookies().string().utf8());
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We assume that WebKit only changes the URL to suppress a redirect, and we
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // assume that it does so by setting it to be invalid.
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!new_request.url().isValid());
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebURLLoaderImpl::Context::OnReceivedResponse(
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ResourceResponseInfo& info) {
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!client_)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response;
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.initialize();
5295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Updates the request url if the response was fetched by a ServiceWorker,
5305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // and it was not generated inside the ServiceWorker.
5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (info.was_fetched_via_service_worker &&
5325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      !info.original_url_via_service_worker.is_empty()) {
5335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    request_.setURL(info.original_url_via_service_worker);
5345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PopulateURLResponse(request_.url(), info, &response);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool show_raw_listing = (GURL(request_.url()).query() == "raw");
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (info.mime_type == "text/vnd.chromium.ftp-dir") {
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (show_raw_listing) {
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Set the MIME type to plain text to prevent any active content.
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response.setMIMEType("text/plain");
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We're going to produce a parsed listing in HTML.
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response.setMIMEType("text/html");
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
549116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Prevent |this| from being destroyed if the client destroys the loader,
550116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // ether in didReceiveResponse, or when the multipart/ftp delegate calls into
551116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // it.
552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<Context> protect(this);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_->didReceiveResponse(loader_, response);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We may have been cancelled after didReceiveResponse, which would leave us
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // without a client and therefore without much need to do further handling.
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!client_)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!ftp_listing_delegate_.get());
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!multipart_delegate_.get());
562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (info.headers.get() && info.mime_type == "multipart/x-mixed-replace") {
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string content_type;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.headers->EnumerateHeader(NULL, "content-type", &content_type);
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string mime_type;
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string charset;
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool had_charset = false;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string boundary;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpUtil::ParseContentType(content_type, &mime_type, &charset,
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    &had_charset, &boundary);
572a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::TrimString(boundary, " \"", &boundary);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If there's no boundary, just handle the request normally.  In the gecko
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // code, nsMultiMixedConv::OnStartRequest throws an exception.
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!boundary.empty()) {
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      multipart_delegate_.reset(
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          new MultipartResponseDelegate(client_, loader_, response, boundary));
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (info.mime_type == "text/vnd.chromium.ftp-dir" &&
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             !show_raw_listing) {
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ftp_listing_delegate_.reset(
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new FtpDirectoryListingResponseDelegate(client_, loader_, response));
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void WebURLLoaderImpl::Context::OnDownloadedData(int len,
58858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                 int encoded_data_length) {
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (client_)
59058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    client_->didDownloadData(loader_, len, encoded_data_length);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebURLLoaderImpl::Context::OnReceivedData(const char* data,
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               int data_length,
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               int encoded_data_length) {
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!client_)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
599b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (ftp_listing_delegate_) {
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The FTP listing delegate will make the appropriate calls to
601116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // client_->didReceiveData and client_->didReceiveResponse.  Since the
602116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // delegate may want to do work after sending data to the delegate, keep
603116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // |this| and the delegate alive until it's finished handling the data.
604116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_refptr<Context> protect(this);
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ftp_listing_delegate_->OnReceivedData(data, data_length);
606b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  } else if (multipart_delegate_) {
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The multipart delegate will make the appropriate calls to
608116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // client_->didReceiveData and client_->didReceiveResponse.  Since the
609116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // delegate may want to do work after sending data to the delegate, keep
610116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // |this| and the delegate alive until it's finished handling the data.
611116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_refptr<Context> protect(this);
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    multipart_delegate_->OnReceivedData(data, data_length, encoded_data_length);
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_->didReceiveData(loader_, data, data_length, encoded_data_length);
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebURLLoaderImpl::Context::OnReceivedCachedMetadata(
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* data, int len) {
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (client_)
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_->didReceiveCachedMetadata(loader_, data, len);
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebURLLoaderImpl::Context::OnCompletedRequest(
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int error_code,
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool was_ignored_by_handler,
6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool stale_copy_in_cache,
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& security_info,
6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::TimeTicks& completion_time,
6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int64 total_transfer_size) {
631116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The WebURLLoaderImpl may be deleted in any of the calls to the client or
632116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // the delegates below (As they also may call in to the client).  Keep |this|
633116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // alive in that case, to avoid a crash.  If that happens, the request will be
634116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // cancelled and |client_| will be set to NULL.
635116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<Context> protect(this);
636116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
637b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (ftp_listing_delegate_) {
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ftp_listing_delegate_->OnCompletedRequest();
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ftp_listing_delegate_.reset(NULL);
640b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  } else if (multipart_delegate_) {
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    multipart_delegate_->OnCompletedRequest();
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    multipart_delegate_.reset(NULL);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Prevent any further IPC to the browser now that we're complete, but
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // don't delete it to keep any downloaded temp files alive.
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!completed_bridge_.get());
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  completed_bridge_.swap(bridge_);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (client_) {
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (error_code != net::OK) {
6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      client_->didFail(loader_, CreateError(request_.url(),
6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            stale_copy_in_cache,
6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            error_code));
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_->didFinishLoading(
6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          loader_, (completion_time - TimeTicks()).InSecondsF(),
6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          total_transfer_size);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool WebURLLoaderImpl::Context::CanHandleDataURLRequestLocally() const {
6641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GURL url = request_.url();
6651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!url.SchemeIs(url::kDataScheme))
6661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
6671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The fast paths for data URL, Start() and HandleDataURL(), don't support
6691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the downloadToFile option.
6701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (request_.downloadToFile())
6711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Optimize for the case where we can handle a data URL locally.  We must
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // skip this for data URLs targetted at frames since those could trigger a
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // download.
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: We special case MIME types we can render both for performance
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reasons as well as to support unit tests, which do not have an underlying
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ResourceLoaderBridge implementation.
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID)
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For compatibility reasons on Android we need to expose top-level data://
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to the browser.
6845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (request_.frameType() == WebURLRequest::FrameTypeTopLevel)
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (request_.frameType() != WebURLRequest::FrameTypeTopLevel &&
6895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      request_.frameType() != WebURLRequest::FrameTypeNested)
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string mime_type, unused_charset;
6931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (net::DataURL::Parse(request_.url(), &mime_type, &unused_charset, NULL) &&
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::IsSupportedMimeType(mime_type))
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebURLLoaderImpl::Context::HandleDataURL() {
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceResponseInfo info;
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string data;
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int error_code = GetInfoFromDataURL(request_.url(), &info, &data);
7051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
7061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (error_code == net::OK) {
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnReceivedResponse(info);
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!data.empty())
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OnReceivedData(data.data(), data.size(), 0);
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  OnCompletedRequest(error_code, false, false, info.security_info,
7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     base::TimeTicks::Now(), 0);
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WebURLLoaderImpl -----------------------------------------------------------
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
718116680a4aac90f2aa7413d9095a592090648e557Ben MurdochWebURLLoaderImpl::WebURLLoaderImpl(ResourceDispatcher* resource_dispatcher)
719116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : context_(new Context(this, resource_dispatcher)) {
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebURLLoaderImpl::~WebURLLoaderImpl() {
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cancel();
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)WebURLError WebURLLoaderImpl::CreateError(const WebURL& unreachable_url,
7275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          bool stale_copy_in_cache,
728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                          int reason) {
729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  WebURLError error;
730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  error.domain = WebString::fromUTF8(net::kErrorDomain);
731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  error.reason = reason;
732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  error.unreachableURL = unreachable_url;
7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  error.staleCopyInCache = stale_copy_in_cache;
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (reason == net::ERR_ABORTED) {
735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error.isCancellation = true;
736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (reason == net::ERR_TEMPORARILY_THROTTLED) {
737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error.localizedDescription = WebString::fromUTF8(
738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        kThrottledErrorDescription);
739f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
740f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    error.localizedDescription = WebString::fromUTF8(
741f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        net::ErrorToString(reason));
742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return error;
744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
746d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void WebURLLoaderImpl::PopulateURLResponse(const GURL& url,
747d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                           const ResourceResponseInfo& info,
748d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                           WebURLResponse* response) {
749d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setURL(url);
750d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setResponseTime(info.response_time.ToDoubleT());
751d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setMIMEType(WebString::fromUTF8(info.mime_type));
752d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setTextEncodingName(WebString::fromUTF8(info.charset));
753d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setExpectedContentLength(info.content_length);
754d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setSecurityInfo(info.security_info);
755d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setAppCacheID(info.appcache_id);
756d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setAppCacheManifestURL(info.appcache_manifest_url);
757d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setWasCached(!info.load_timing.request_start_time.is_null() &&
758d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      info.response_time < info.load_timing.request_start_time);
759d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setRemoteIPAddress(
760d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      WebString::fromUTF8(info.socket_address.host()));
761d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setRemotePort(info.socket_address.port());
762d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setConnectionID(info.load_timing.socket_log_id);
763d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setConnectionReused(info.load_timing.socket_reused);
764d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setDownloadFilePath(info.download_file_path.AsUTF16Unsafe());
7655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  response->setWasFetchedViaServiceWorker(info.was_fetched_via_service_worker);
766d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  WebURLResponseExtraDataImpl* extra_data =
767d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      new WebURLResponseExtraDataImpl(info.npn_negotiated_protocol);
768d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setExtraData(extra_data);
769d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  extra_data->set_was_fetched_via_spdy(info.was_fetched_via_spdy);
770d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  extra_data->set_was_npn_negotiated(info.was_npn_negotiated);
771d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  extra_data->set_was_alternate_protocol_available(
772d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      info.was_alternate_protocol_available);
773d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  extra_data->set_connection_info(info.connection_info);
774d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  extra_data->set_was_fetched_via_proxy(info.was_fetched_via_proxy);
775d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
776d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // If there's no received headers end time, don't set load timing.  This is
777d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // the case for non-HTTP requests, requests that don't go over the wire, and
778d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // certain error cases.
779d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!info.load_timing.receive_headers_end.is_null()) {
780d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    WebURLLoadTiming timing;
781d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    PopulateURLLoadTiming(info.load_timing, &timing);
7821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const TimeTicks kNullTicks;
7831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    timing.setServiceWorkerFetchStart(
7841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        (info.service_worker_fetch_start - kNullTicks).InSecondsF());
7851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    timing.setServiceWorkerFetchReady(
7861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        (info.service_worker_fetch_ready - kNullTicks).InSecondsF());
7871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    timing.setServiceWorkerFetchEnd(
7881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        (info.service_worker_fetch_end - kNullTicks).InSecondsF());
789d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    response->setLoadTiming(timing);
790d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
791d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
792d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (info.devtools_info.get()) {
793d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    WebHTTPLoadInfo load_info;
794d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
795d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    load_info.setHTTPStatusCode(info.devtools_info->http_status_code);
796d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    load_info.setHTTPStatusText(WebString::fromLatin1(
797d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        info.devtools_info->http_status_text));
798d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    load_info.setEncodedDataLength(info.encoded_data_length);
799d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
800d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    load_info.setRequestHeadersText(WebString::fromLatin1(
801d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        info.devtools_info->request_headers_text));
802d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    load_info.setResponseHeadersText(WebString::fromLatin1(
803d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        info.devtools_info->response_headers_text));
804d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const HeadersVector& request_headers = info.devtools_info->request_headers;
805d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    for (HeadersVector::const_iterator it = request_headers.begin();
806d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)         it != request_headers.end(); ++it) {
807d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      load_info.addRequestHeader(WebString::fromLatin1(it->first),
808d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          WebString::fromLatin1(it->second));
809d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
810d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const HeadersVector& response_headers =
811d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        info.devtools_info->response_headers;
812d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    for (HeadersVector::const_iterator it = response_headers.begin();
813d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)         it != response_headers.end(); ++it) {
814d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      load_info.addResponseHeader(WebString::fromLatin1(it->first),
815d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          WebString::fromLatin1(it->second));
816d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
817d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    response->setHTTPLoadInfo(load_info);
818d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
819d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
820d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const net::HttpResponseHeaders* headers = info.headers.get();
821d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!headers)
822d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
823d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
824d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  WebURLResponse::HTTPVersion version = WebURLResponse::Unknown;
825d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (headers->GetHttpVersion() == net::HttpVersion(0, 9))
826d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    version = WebURLResponse::HTTP_0_9;
827d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  else if (headers->GetHttpVersion() == net::HttpVersion(1, 0))
828d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    version = WebURLResponse::HTTP_1_0;
829d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  else if (headers->GetHttpVersion() == net::HttpVersion(1, 1))
830d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    version = WebURLResponse::HTTP_1_1;
831d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setHTTPVersion(version);
832d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setHTTPStatusCode(headers->response_code());
833d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setHTTPStatusText(WebString::fromLatin1(headers->GetStatusText()));
834d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
835d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // TODO(darin): We should leverage HttpResponseHeaders for this, and this
836d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // should be using the same code as ResourceDispatcherHost.
837d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // TODO(jungshik): Figure out the actual value of the referrer charset and
838d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // pass it to GetSuggestedFilename.
839d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  std::string value;
840d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  headers->EnumerateHeader(NULL, "content-disposition", &value);
841d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  response->setSuggestedFileName(
842d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      net::GetSuggestedFilename(url,
843d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                value,
844d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                std::string(),  // referrer_charset
845d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                std::string(),  // suggested_name
846d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                std::string(),  // mime_type
847d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                std::string()));  // default_name
848d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
849d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  Time time_val;
850d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (headers->GetLastModifiedValue(&time_val))
851d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    response->setLastModifiedDate(time_val.ToDoubleT());
852d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
853d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Build up the header map.
854d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void* iter = NULL;
855d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  std::string name;
856d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
857d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    response->addHTTPHeaderField(WebString::fromLatin1(name),
858d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                 WebString::fromLatin1(value));
859d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
860d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
861d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebURLLoaderImpl::loadSynchronously(const WebURLRequest& request,
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         WebURLResponse& response,
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         WebURLError& error,
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         WebData& data) {
8664ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  SyncLoadResponse sync_load_response;
867effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  context_->Start(request, &sync_load_response);
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& final_url = sync_load_response.url;
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(tc): For file loads, we may want to include a more descriptive
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // status code or status text.
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int error_code = sync_load_response.error_code;
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error_code != net::OK) {
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response.setURL(final_url);
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error.domain = WebString::fromUTF8(net::kErrorDomain);
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error.reason = error_code;
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error.unreachableURL = final_url;
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PopulateURLResponse(final_url, sync_load_response, &response);
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.assign(sync_load_response.data.data(),
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              sync_load_response.data.size());
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebURLLoaderImpl::loadAsynchronously(const WebURLRequest& request,
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          WebURLLoaderClient* client) {
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!context_->client());
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->set_client(client);
893effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  context_->Start(request, NULL);
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebURLLoaderImpl::cancel() {
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->Cancel();
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebURLLoaderImpl::setDefersLoading(bool value) {
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->SetDefersLoading(value);
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
904c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid WebURLLoaderImpl::didChangePriority(WebURLRequest::Priority new_priority,
905c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                         int intra_priority_value) {
906c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  context_->DidChangePriority(new_priority, intra_priority_value);
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
909f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool WebURLLoaderImpl::attachThreadedDataReceiver(
910f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    blink::WebThreadedDataReceiver* threaded_data_receiver) {
911f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return context_->AttachThreadedDataReceiver(threaded_data_receiver);
912f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
913f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
914a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace content
915