url_request.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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)#include "net/url_request/url_request.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/stack_trace.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/stats_counters.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/auth.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/host_port_pair.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/network_change_notifier.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/network_delegate.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/ssl_cert_request_info.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/upload_data.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_util.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_error_job.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_job.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_job_manager.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_netlog_params.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_redirect_job.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::string;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Max number of http redirects to follow.  Same number as gecko.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxRedirects = 20;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Discard headers which have meaning in POST (Content-Length, Content-Type,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Origin).
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StripPostSpecificHeaders(HttpRequestHeaders* headers) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These are headers that may be attached to a POST.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers->RemoveHeader(HttpRequestHeaders::kContentLength);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers->RemoveHeader(HttpRequestHeaders::kContentType);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers->RemoveHeader(HttpRequestHeaders::kOrigin);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(battre): Delete this, see http://crbug.com/89321:
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This counter keeps track of the identifiers used for URL requests so far.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 0 is reserved to represent an invalid ID.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint64 g_next_url_request_identifier = 1;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This lock protects g_next_url_request_identifier.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<base::Lock>::Leaky
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_next_url_request_identifier_lock = LAZY_INSTANCE_INITIALIZER;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns an prior unused identifier for URL requests.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint64 GenerateURLRequestIdentifier() {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(g_next_url_request_identifier_lock.Get());
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_next_url_request_identifier++;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// True once the first URLRequest was started.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_url_requests_started = false;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// True if cookies are accepted by default.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_default_can_use_cookies = true;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequest::ProtocolFactory*
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequest::Deprecated::RegisterProtocolFactory(const std::string& scheme,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                ProtocolFactory* factory) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return URLRequest::RegisterProtocolFactory(scheme, factory);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::Deprecated::RegisterRequestInterceptor(
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Interceptor* interceptor) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequest::RegisterRequestInterceptor(interceptor);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::Deprecated::UnregisterRequestInterceptor(
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Interceptor* interceptor) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequest::UnregisterRequestInterceptor(interceptor);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URLRequest::Interceptor
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestJob* URLRequest::Interceptor::MaybeInterceptRedirect(
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLRequest* request,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetworkDelegate* network_delegate,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& location) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestJob* URLRequest::Interceptor::MaybeInterceptResponse(
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLRequest* request, NetworkDelegate* network_delegate) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URLRequest::Delegate
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::Delegate::OnReceivedRedirect(URLRequest* request,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              const GURL& new_url,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              bool* defer_redirect) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::Delegate::OnAuthRequired(URLRequest* request,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          AuthChallengeInfo* auth_info) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request->CancelAuth();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::Delegate::OnCertificateRequested(
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLRequest* request,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSLCertRequestInfo* cert_request_info) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request->Cancel();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::Delegate::OnSSLCertificateError(URLRequest* request,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 const SSLInfo& ssl_info,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 bool is_hsts_ok) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request->Cancel();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URLRequest
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(shalev): Get rid of this constructor in favour of the one below it.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequest::URLRequest(const GURL& url,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       Delegate* delegate,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const URLRequestContext* context)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : context_(context),
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      network_delegate_(context->network_delegate()),
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net_log_(BoundNetLog::Make(context->net_log(),
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NetLog::SOURCE_URL_REQUEST)),
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url_chain_(1, url),
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      method_("GET"),
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      referrer_policy_(CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE),
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      load_flags_(LOAD_NORMAL),
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(delegate),
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_pending_(false),
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_redirecting_(false),
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      redirect_limit_(kMaxRedirects),
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      priority_(LOWEST),
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      identifier_(GenerateURLRequestIdentifier()),
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      blocked_on_delegate_(false),
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ALLOW_THIS_IN_INITIALIZER_LIST(before_request_callback_(
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&URLRequest::BeforeRequestComplete,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(this)))),
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      has_notified_completion_(false),
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      received_response_content_length_(0),
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      creation_time_(base::TimeTicks::Now()) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SIMPLE_STATS_COUNTER("URLRequestCount");
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sanity check out environment.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(MessageLoop::current()) << "The current MessageLoop must exist";
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(MessageLoop::current()->IsType(MessageLoop::TYPE_IO)) << ""
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "The current MessageLoop must be TYPE_IO";
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(context);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context->url_requests()->insert(this);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net_log_.BeginEvent(NetLog::TYPE_REQUEST_ALIVE);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequest::URLRequest(const GURL& url,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       Delegate* delegate,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const URLRequestContext* context,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NetworkDelegate* network_delegate)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : context_(context),
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      network_delegate_(network_delegate),
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net_log_(BoundNetLog::Make(context->net_log(),
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NetLog::SOURCE_URL_REQUEST)),
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url_chain_(1, url),
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      method_("GET"),
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      referrer_policy_(CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE),
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      load_flags_(LOAD_NORMAL),
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(delegate),
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_pending_(false),
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_redirecting_(false),
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      redirect_limit_(kMaxRedirects),
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      priority_(LOWEST),
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      identifier_(GenerateURLRequestIdentifier()),
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      blocked_on_delegate_(false),
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ALLOW_THIS_IN_INITIALIZER_LIST(before_request_callback_(
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&URLRequest::BeforeRequestComplete,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(this)))),
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      has_notified_completion_(false),
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      received_response_content_length_(0),
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      creation_time_(base::TimeTicks::Now()) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SIMPLE_STATS_COUNTER("URLRequestCount");
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sanity check out environment.
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(MessageLoop::current()) << "The current MessageLoop must exist";
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(MessageLoop::current()->IsType(MessageLoop::TYPE_IO)) << ""
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "The current MessageLoop must be TYPE_IO";
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(context);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context->url_requests()->insert(this);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net_log_.BeginEvent(NetLog::TYPE_REQUEST_ALIVE);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequest::~URLRequest() {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cancel();
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (network_delegate_) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    network_delegate_->NotifyURLRequestDestroyed(this);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (job_)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      job_->NotifyURLRequestDestroyed();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (job_)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OrphanJob();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int deleted = context_->url_requests()->erase(this);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(1, deleted);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int net_error = OK;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Log error only on failure, not cancellation, as even successful requests
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are "cancelled" on destruction.
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status_.status() == URLRequestStatus::FAILED)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net_error = status_.error();
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net_log_.EndEventWithNetErrorCode(NetLog::TYPE_REQUEST_ALIVE, net_error);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequest::ProtocolFactory* URLRequest::RegisterProtocolFactory(
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string& scheme, ProtocolFactory* factory) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return URLRequestJobManager::GetInstance()->RegisterProtocolFactory(scheme,
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                                      factory);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::RegisterRequestInterceptor(Interceptor* interceptor) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestJobManager::GetInstance()->RegisterRequestInterceptor(interceptor);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::UnregisterRequestInterceptor(Interceptor* interceptor) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestJobManager::GetInstance()->UnregisterRequestInterceptor(
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      interceptor);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::AppendBytesToUpload(const char* bytes, int bytes_len) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bytes_len > 0 && bytes);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!upload_)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    upload_ = new UploadData();
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  upload_->AppendBytes(bytes, bytes_len);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::EnableChunkedUpload() {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!upload_ || upload_->is_chunked());
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!upload_) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    upload_ = new UploadData();
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    upload_->set_is_chunked(true);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::AppendChunkToUpload(const char* bytes,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     int bytes_len,
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     bool is_last_chunk) {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(upload_);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(upload_->is_chunked());
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(bytes_len, 0);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  upload_->AppendChunk(bytes, bytes_len, is_last_chunk);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::set_upload(UploadData* upload) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  upload_ = upload;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get the upload data directly.
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const UploadData* URLRequest::get_upload() const {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return upload_.get();
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UploadData* URLRequest::get_upload_mutable() {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return upload_.get();
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequest::has_upload() const {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return upload_ != NULL;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::SetExtraRequestHeaderById(int id, const string& value,
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           bool overwrite) {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_pending_ || is_redirecting_);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED() << "implement me!";
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::SetExtraRequestHeaderByName(const string& name,
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             const string& value,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             bool overwrite) {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_pending_ || is_redirecting_);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (overwrite) {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extra_request_headers_.SetHeader(name, value);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extra_request_headers_.SetHeaderIfMissing(name, value);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::SetExtraRequestHeaders(
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpRequestHeaders& headers) {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_pending_);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extra_request_headers_ = headers;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: This method will likely become non-trivial once the other setters
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for request headers are implemented.
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoadStateWithParam URLRequest::GetLoadState() const {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (blocked_on_delegate_) {
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return LoadStateWithParam(LOAD_STATE_WAITING_FOR_DELEGATE,
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              load_state_param_);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return LoadStateWithParam(job_ ? job_->GetLoadState() : LOAD_STATE_IDLE,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            string16());
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UploadProgress URLRequest::GetUploadProgress() const {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!job_) {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We haven't started or the request was cancelled
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return UploadProgress();
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (final_upload_progress_.position()) {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The first job completed and none of the subsequent series of
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // GETs when following redirects will upload anything, so we return the
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // cached results from the initial job, the POST.
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return final_upload_progress_;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return job_->GetUploadProgress();
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::GetResponseHeaderById(int id, string* value) {
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED() << "implement me!";
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::GetResponseHeaderByName(const string& name, string* value) {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(value);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response_info_.headers) {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_info_.headers->GetNormalizedHeader(name, value);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value->clear();
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::GetAllResponseHeaders(string* headers) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(headers);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response_info_.headers) {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_info_.headers->GetNormalizedHeaders(headers);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers->clear();
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostPortPair URLRequest::GetSocketAddress() const {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return job_->GetSocketAddress();
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpResponseHeaders* URLRequest::response_headers() const {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return response_info_.headers.get();
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequest::GetResponseCookies(ResponseCookies* cookies) {
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return job_->GetResponseCookies(cookies);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::GetMimeType(string* mime_type) {
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  job_->GetMimeType(mime_type);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::GetCharset(string* charset) {
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  job_->GetCharset(charset);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLRequest::GetResponseCode() {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return job_->GetResponseCode();
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::SetDefaultCookiePolicyToBlock() {
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!g_url_requests_started);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_default_can_use_cookies = false;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequest::IsHandledProtocol(const std::string& scheme) {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return URLRequestJobManager::GetInstance()->SupportsScheme(scheme);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequest::IsHandledURL(const GURL& url) {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!url.is_valid()) {
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We handle error cases.
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return IsHandledProtocol(url.scheme());
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::set_first_party_for_cookies(
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& first_party_for_cookies) {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_party_for_cookies_ = first_party_for_cookies;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::set_method(const std::string& method) {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_pending_);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  method_ = method;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::set_referrer(const std::string& referrer) {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_pending_);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  referrer_ = referrer;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL URLRequest::GetSanitizedReferrer() const {
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL ret(referrer());
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we do not send username and password fields in the referrer.
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ret.has_username() || ret.has_password()) {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL::Replacements referrer_mods;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    referrer_mods.ClearUsername();
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    referrer_mods.ClearPassword();
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = ret.ReplaceComponents(referrer_mods);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::set_referrer_policy(ReferrerPolicy referrer_policy) {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_pending_);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  referrer_policy_ = referrer_policy;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::set_delegate(Delegate* delegate) {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_ = delegate;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::Start() {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(network_delegate_, context_->network_delegate());
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_url_requests_started = true;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_info_.request_time = Time::Now();
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only notify the delegate for the initial request.
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (network_delegate_) {
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int error = network_delegate_->NotifyBeforeURLRequest(
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this, before_request_callback_, &delegate_redirect_url_);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (error == net::ERR_IO_PENDING) {
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Paused on the delegate, will invoke |before_request_callback_| later.
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetBlockedOnDelegate();
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BeforeRequestComplete(error);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartJob(URLRequestJobManager::GetInstance()->CreateJob(
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, network_delegate_));
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::BeforeRequestComplete(int error) {
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!job_);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(ERR_IO_PENDING, error);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(network_delegate_, context_->network_delegate());
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that there are no callbacks to already canceled requests.
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(URLRequestStatus::CANCELED, status_.status());
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (blocked_on_delegate_)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetUnblockedOnDelegate();
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error != OK) {
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string source("delegate");
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net_log_.AddEvent(NetLog::TYPE_CANCELLED,
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      NetLog::StringCallback("source", &source));
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StartJob(new URLRequestErrorJob(this, network_delegate_, error));
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (!delegate_redirect_url_.is_empty()) {
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL new_url;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_url.Swap(&delegate_redirect_url_);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLRequestRedirectJob* job = new URLRequestRedirectJob(
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this, network_delegate_, new_url);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Use status code 307 to preserve the method, so POST requests work.
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->set_redirect_code(
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StartJob(job);
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StartJob(URLRequestJobManager::GetInstance()->CreateJob(
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this, network_delegate_));
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::StartJob(URLRequestJob* job) {
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_pending_);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!job_);
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net_log_.BeginEvent(
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_URL_REQUEST_START_JOB,
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&NetLogURLRequestStartCallback,
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 &url(), &method_, load_flags_, priority_,
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 upload_.get() ? upload_->identifier() : -1));
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  job_ = job;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  job_->SetExtraRequestHeaders(extra_request_headers_);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (upload_.get())
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job_->SetUpload(upload_.get());
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_pending_ = true;
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_redirecting_ = false;
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_info_.was_cached = false;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't allow errors to be sent from within Start().
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(brettw) this may cause NotifyDone to be sent synchronously,
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we probably don't want this: they should be sent asynchronously so
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the caller does not get reentered.
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  job_->Start();
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::Restart() {
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should only be called if the original job didn't make any progress.
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_ && !job_->has_response_started());
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RestartWithJob(URLRequestJobManager::GetInstance()->CreateJob(
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, network_delegate_));
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::RestartWithJob(URLRequestJob *job) {
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job->request() == this);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrepareToRestart();
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartJob(job);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::Cancel() {
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoCancel(ERR_ABORTED, SSLInfo());
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::CancelWithError(int error) {
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoCancel(error, SSLInfo());
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::CancelWithSSLError(int error, const SSLInfo& ssl_info) {
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should only be called on a started request.
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_pending_ || !job_ || job_->has_response_started()) {
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoCancel(error, ssl_info);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::DoCancel(int error, const SSLInfo& ssl_info) {
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(error < 0);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the URL request already has an error status, then canceling is a no-op.
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Plus, we don't want to change the error status once it has been set.
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status_.is_success()) {
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_.set_status(URLRequestStatus::CANCELED);
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_.set_error(error);
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_info_.ssl_info = ssl_info;
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the request hasn't already been completed, log a cancellation event.
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!has_notified_completion_) {
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Don't log an error code on ERR_ABORTED, since that's redundant.
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net_log_.AddEventWithNetErrorCode(NetLog::TYPE_CANCELLED,
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        error == ERR_ABORTED ? OK : error);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_pending_ && job_)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job_->Kill();
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We need to notify about the end of this job here synchronously. The
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Job sends an asynchronous notification but by the time this is processed,
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // our |context_| is NULL.
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyRequestCompleted();
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The Job will call our NotifyDone method asynchronously.  This is done so
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that the Delegate implementation can call Cancel without having to worry
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // about being called recursively.
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequest::Read(IOBuffer* dest, int dest_size, int* bytes_read) {
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_);
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bytes_read);
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *bytes_read = 0;
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This handles a cancel that happens while paused.
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ahendrickson): DCHECK() that it is not done after
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // http://crbug.com/115705 is fixed.
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (job_->is_done())
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (dest_size == 0) {
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Caller is not too bright.  I guess we've done what they asked.
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Once the request fails or is cancelled, read will just return 0 bytes
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to indicate end of stream.
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!status_.is_success()) {
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool rv = job_->Read(dest, dest_size, bytes_read);
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If rv is false, the status cannot be success.
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(rv || status_.status() != URLRequestStatus::SUCCESS);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv && *bytes_read <= 0 && status_.is_success())
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyRequestCompleted();
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rv;
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::StopCaching() {
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  job_->StopCaching();
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::NotifyReceivedRedirect(const GURL& location,
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        bool* defer_redirect) {
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_redirecting_ = true;
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestJob* job =
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      URLRequestJobManager::GetInstance()->MaybeInterceptRedirect(
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          this, network_delegate_, location);
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (job) {
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RestartWithJob(job);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (delegate_) {
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnReceivedRedirect(this, location, defer_redirect);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::NotifyResponseStarted() {
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int net_error = OK;
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!status_.is_success())
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net_error = status_.error();
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net_log_.EndEventWithNetErrorCode(NetLog::TYPE_URL_REQUEST_START_JOB,
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    net_error);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestJob* job =
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      URLRequestJobManager::GetInstance()->MaybeInterceptResponse(
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          this, network_delegate_);
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (job) {
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RestartWithJob(job);
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate_) {
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // In some cases (e.g. an event was canceled), we might have sent the
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // completion event and receive a NotifyResponseStarted() later.
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!has_notified_completion_ && status_.is_success()) {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (network_delegate_)
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          network_delegate_->NotifyResponseStarted(this);
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Notify in case the entire URL Request has been finished.
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!has_notified_completion_ && !status_.is_success())
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NotifyRequestCompleted();
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->OnResponseStarted(this);
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Nothing may appear below this line as OnResponseStarted may delete
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // |this|.
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::FollowDeferredRedirect() {
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(job_);
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(status_.is_success());
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  job_->FollowDeferredRedirect();
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::SetAuth(const AuthCredentials& credentials) {
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_);
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_->NeedsAuth());
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  job_->SetAuth(credentials);
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::CancelAuth() {
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_);
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_->NeedsAuth());
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  job_->CancelAuth();
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::ContinueWithCertificate(X509Certificate* client_cert) {
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  job_->ContinueWithCertificate(client_cert);
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::ContinueDespiteLastError() {
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_);
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  job_->ContinueDespiteLastError();
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::PrepareToRestart() {
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_);
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Close the current URL_REQUEST_START_JOB, since we will be starting a new
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // one.
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net_log_.EndEvent(NetLog::TYPE_URL_REQUEST_START_JOB);
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrphanJob();
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_info_ = HttpResponseInfo();
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_info_.request_time = Time::Now();
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  status_ = URLRequestStatus();
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_pending_ = false;
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::OrphanJob() {
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When calling this function, please check that URLRequestHttpJob is
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not in between calling NetworkDelegate::NotifyHeadersReceived receiving
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the call back. This is currently guaranteed by the following strategies:
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // - OrphanJob is called on JobRestart, in this case the URLRequestJob cannot
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   be receiving any headers at that time.
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // - OrphanJob is called in ~URLRequest, in this case
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   NetworkDelegate::NotifyURLRequestDestroyed notifies the NetworkDelegate
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   that the callback becomes invalid.
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  job_->Kill();
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  job_->DetachRequest();  // ensures that the job will not call us again
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  job_ = NULL;
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLRequest::Redirect(const GURL& location, int http_status_code) {
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (net_log_.IsLoggingAllEvents()) {
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net_log_.AddEvent(
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NetLog::TYPE_URL_REQUEST_REDIRECTED,
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NetLog::StringCallback("location", &location.possibly_invalid_spec()));
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (network_delegate_)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    network_delegate_->NotifyBeforeRedirect(this, location);
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (redirect_limit_ <= 0) {
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "disallowing redirect: exceeds limit";
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_TOO_MANY_REDIRECTS;
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!location.is_valid())
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_INVALID_URL;
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!job_->IsSafeRedirect(location)) {
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "disallowing redirect: unsafe protocol";
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_UNSAFE_REDIRECT;
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For 303 redirects, all request methods except HEAD are converted to GET,
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as per the latest httpbis draft.  The draft also allows POST requests to
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be converted to GETs when following 301/302 redirects, for historical
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reasons. Most major browsers do this and so shall we.  Both RFC 2616 and
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the httpbis draft say to prompt the user to confirm the generation of new
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requests, other than GET and HEAD requests, but IE omits these prompts and
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so shall we.
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See:  https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-17#section-7.3
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool was_post = method_ == "POST";
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((http_status_code == 303 && method_ != "HEAD") ||
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ((http_status_code == 301 || http_status_code == 302) && was_post)) {
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    method_ = "GET";
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    upload_ = NULL;
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (was_post) {
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If being switched from POST to GET, must remove headers that were
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // specific to the POST and don't have meaning in GET. For example
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // the inclusion of a multipart Content-Type header in GET can cause
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // problems with some servers:
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // http://code.google.com/p/chromium/issues/detail?id=843
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StripPostSpecificHeaders(&extra_request_headers_);
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Suppress the referrer if we're redirecting out of https.
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (referrer_policy_ ==
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE &&
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL(referrer_).SchemeIsSecure() && !location.SchemeIsSecure()) {
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    referrer_.clear();
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_chain_.push_back(location);
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --redirect_limit_;
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!final_upload_progress_.position())
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    final_upload_progress_ = job_->GetUploadProgress();
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrepareToRestart();
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Start();
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return OK;
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const URLRequestContext* URLRequest::context() const {
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return context_;
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 URLRequest::GetExpectedContentSize() const {
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 expected_content_size = -1;
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (job_)
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expected_content_size = job_->expected_content_size();
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return expected_content_size;
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequest::GetHSTSRedirect(GURL* redirect_url) const {
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& url = this->url();
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!url.SchemeIs("http"))
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportSecurityState::DomainState domain_state;
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (context()->transport_security_state() &&
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context()->transport_security_state()->GetDomainState(
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          url.host(),
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          SSLConfigService::IsSNIAvailable(context()->ssl_config_service()),
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &domain_state) &&
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      domain_state.ShouldRedirectHTTPToHTTPS()) {
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_canon::Replacements<char> replacements;
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kNewScheme[] = "https";
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    replacements.SetScheme(kNewScheme,
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           url_parse::Component(0, strlen(kNewScheme)));
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *redirect_url = url.ReplaceComponents(replacements);
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::NotifyAuthRequired(AuthChallengeInfo* auth_info) {
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NetworkDelegate::AuthRequiredResponse rv =
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION;
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_info_ = auth_info;
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (network_delegate_) {
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = network_delegate_->NotifyAuthRequired(
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this,
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *auth_info,
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&URLRequest::NotifyAuthRequiredComplete,
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)),
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &auth_credentials_);
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == NetworkDelegate::AUTH_REQUIRED_RESPONSE_IO_PENDING) {
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetBlockedOnDelegate();
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyAuthRequiredComplete(rv);
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::NotifyAuthRequiredComplete(
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetworkDelegate::AuthRequiredResponse result) {
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetUnblockedOnDelegate();
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that there are no callbacks to already canceled requests.
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(URLRequestStatus::CANCELED, status_.status());
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NotifyAuthRequired may be called multiple times, such as
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when an authentication attempt fails. Clear out the data
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so it can be reset on another round.
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AuthCredentials credentials = auth_credentials_;
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_credentials_ = AuthCredentials();
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<AuthChallengeInfo> auth_info;
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_info.swap(auth_info_);
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (result) {
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION:
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Defer to the URLRequest::Delegate, since the NetworkDelegate
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // didn't take an action.
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (delegate_)
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnAuthRequired(this, auth_info.get());
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH:
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetAuth(credentials);
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH:
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CancelAuth();
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NetworkDelegate::AUTH_REQUIRED_RESPONSE_IO_PENDING:
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::NotifyCertificateRequested(
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSLCertRequestInfo* cert_request_info) {
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnCertificateRequested(this, cert_request_info);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::NotifySSLCertificateError(const SSLInfo& ssl_info,
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           bool fatal) {
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnSSLCertificateError(this, ssl_info, fatal);
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequest::CanGetCookies(const CookieList& cookie_list) const {
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!(load_flags_ & LOAD_DO_NOT_SEND_COOKIES));
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (network_delegate_) {
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return network_delegate_->CanGetCookies(*this, cookie_list);
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_default_can_use_cookies;
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequest::CanSetCookie(const std::string& cookie_line,
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              CookieOptions* options) const {
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!(load_flags_ & LOAD_DO_NOT_SAVE_COOKIES));
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (network_delegate_) {
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return network_delegate_->CanSetCookie(*this, cookie_line, options);
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_default_can_use_cookies;
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::NotifyReadCompleted(int bytes_read) {
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notify in case the entire URL Request has been finished.
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bytes_read <= 0)
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyRequestCompleted();
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notify NetworkChangeNotifier that we just received network data.
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is to identify cases where the NetworkChangeNotifier thinks we
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are off-line but we are still receiving network data (crbug.com/124069).
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bytes_read > 0 && !was_cached())
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetworkChangeNotifier::NotifyDataReceived(url());
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnReadCompleted(this, bytes_read);
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing below this line as OnReadCompleted may delete |this|.
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::NotifyRequestCompleted() {
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(battre): Get rid of this check, according to willchan it should
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not be needed.
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_notified_completion_)
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_pending_ = false;
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_redirecting_ = false;
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_notified_completion_ = true;
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (network_delegate_)
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    network_delegate_->NotifyCompleted(this, job_ != NULL);
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::SetBlockedOnDelegate() {
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blocked_on_delegate_ = true;
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net_log_.BeginEvent(NetLog::TYPE_URL_REQUEST_BLOCKED_ON_DELEGATE);
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::SetUnblockedOnDelegate() {
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!blocked_on_delegate_)
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blocked_on_delegate_ = false;
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_state_param_.clear();
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net_log_.EndEvent(NetLog::TYPE_URL_REQUEST_BLOCKED_ON_DELEGATE);
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequest::set_stack_trace(const base::debug::StackTrace& stack_trace) {
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::debug::StackTrace* stack_trace_copy =
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new base::debug::StackTrace(NULL, 0);
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *stack_trace_copy = stack_trace;
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  stack_trace_.reset(stack_trace_copy);
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const base::debug::StackTrace* URLRequest::stack_trace() const {
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return stack_trace_.get();
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
985