Home | History | Annotate | Download | only in url_request
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/url_request/url_request.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/bind_helpers.h"
      9 #include "base/callback.h"
     10 #include "base/compiler_specific.h"
     11 #include "base/debug/stack_trace.h"
     12 #include "base/lazy_instance.h"
     13 #include "base/memory/singleton.h"
     14 #include "base/message_loop/message_loop.h"
     15 #include "base/metrics/histogram.h"
     16 #include "base/metrics/stats_counters.h"
     17 #include "base/stl_util.h"
     18 #include "base/synchronization/lock.h"
     19 #include "net/base/auth.h"
     20 #include "net/base/host_port_pair.h"
     21 #include "net/base/load_flags.h"
     22 #include "net/base/load_timing_info.h"
     23 #include "net/base/net_errors.h"
     24 #include "net/base/net_log.h"
     25 #include "net/base/network_change_notifier.h"
     26 #include "net/base/network_delegate.h"
     27 #include "net/base/upload_data_stream.h"
     28 #include "net/http/http_response_headers.h"
     29 #include "net/http/http_util.h"
     30 #include "net/ssl/ssl_cert_request_info.h"
     31 #include "net/url_request/url_request_context.h"
     32 #include "net/url_request/url_request_error_job.h"
     33 #include "net/url_request/url_request_job.h"
     34 #include "net/url_request/url_request_job_manager.h"
     35 #include "net/url_request/url_request_netlog_params.h"
     36 #include "net/url_request/url_request_redirect_job.h"
     37 
     38 using base::Time;
     39 using std::string;
     40 
     41 namespace net {
     42 
     43 namespace {
     44 
     45 // Max number of http redirects to follow.  Same number as gecko.
     46 const int kMaxRedirects = 20;
     47 
     48 // Discard headers which have meaning in POST (Content-Length, Content-Type,
     49 // Origin).
     50 void StripPostSpecificHeaders(HttpRequestHeaders* headers) {
     51   // These are headers that may be attached to a POST.
     52   headers->RemoveHeader(HttpRequestHeaders::kContentLength);
     53   headers->RemoveHeader(HttpRequestHeaders::kContentType);
     54   headers->RemoveHeader(HttpRequestHeaders::kOrigin);
     55 }
     56 
     57 // TODO(battre): Delete this, see http://crbug.com/89321:
     58 // This counter keeps track of the identifiers used for URL requests so far.
     59 // 0 is reserved to represent an invalid ID.
     60 uint64 g_next_url_request_identifier = 1;
     61 
     62 // This lock protects g_next_url_request_identifier.
     63 base::LazyInstance<base::Lock>::Leaky
     64     g_next_url_request_identifier_lock = LAZY_INSTANCE_INITIALIZER;
     65 
     66 // Returns an prior unused identifier for URL requests.
     67 uint64 GenerateURLRequestIdentifier() {
     68   base::AutoLock lock(g_next_url_request_identifier_lock.Get());
     69   return g_next_url_request_identifier++;
     70 }
     71 
     72 // True once the first URLRequest was started.
     73 bool g_url_requests_started = false;
     74 
     75 // True if cookies are accepted by default.
     76 bool g_default_can_use_cookies = true;
     77 
     78 // When the URLRequest first assempts load timing information, it has the times
     79 // at which each event occurred.  The API requires the time which the request
     80 // was blocked on each phase.  This function handles the conversion.
     81 //
     82 // In the case of reusing a SPDY session or HTTP pipeline, old proxy results may
     83 // have been reused, so proxy resolution times may be before the request was
     84 // started.
     85 //
     86 // Due to preconnect and late binding, it is also possible for the connection
     87 // attempt to start before a request has been started, or proxy resolution
     88 // completed.
     89 //
     90 // This functions fixes both those cases.
     91 void ConvertRealLoadTimesToBlockingTimes(
     92     net::LoadTimingInfo* load_timing_info) {
     93   DCHECK(!load_timing_info->request_start.is_null());
     94 
     95   // Earliest time possible for the request to be blocking on connect events.
     96   base::TimeTicks block_on_connect = load_timing_info->request_start;
     97 
     98   if (!load_timing_info->proxy_resolve_start.is_null()) {
     99     DCHECK(!load_timing_info->proxy_resolve_end.is_null());
    100 
    101     // Make sure the proxy times are after request start.
    102     if (load_timing_info->proxy_resolve_start < load_timing_info->request_start)
    103       load_timing_info->proxy_resolve_start = load_timing_info->request_start;
    104     if (load_timing_info->proxy_resolve_end < load_timing_info->request_start)
    105       load_timing_info->proxy_resolve_end = load_timing_info->request_start;
    106 
    107     // Connect times must also be after the proxy times.
    108     block_on_connect = load_timing_info->proxy_resolve_end;
    109   }
    110 
    111   // Make sure connection times are after start and proxy times.
    112 
    113   net::LoadTimingInfo::ConnectTiming* connect_timing =
    114       &load_timing_info->connect_timing;
    115   if (!connect_timing->dns_start.is_null()) {
    116     DCHECK(!connect_timing->dns_end.is_null());
    117     if (connect_timing->dns_start < block_on_connect)
    118       connect_timing->dns_start = block_on_connect;
    119     if (connect_timing->dns_end < block_on_connect)
    120       connect_timing->dns_end = block_on_connect;
    121   }
    122 
    123   if (!connect_timing->connect_start.is_null()) {
    124     DCHECK(!connect_timing->connect_end.is_null());
    125     if (connect_timing->connect_start < block_on_connect)
    126       connect_timing->connect_start = block_on_connect;
    127     if (connect_timing->connect_end < block_on_connect)
    128       connect_timing->connect_end = block_on_connect;
    129   }
    130 
    131   if (!connect_timing->ssl_start.is_null()) {
    132     DCHECK(!connect_timing->ssl_end.is_null());
    133     if (connect_timing->ssl_start < block_on_connect)
    134       connect_timing->ssl_start = block_on_connect;
    135     if (connect_timing->ssl_end < block_on_connect)
    136       connect_timing->ssl_end = block_on_connect;
    137   }
    138 }
    139 
    140 }  // namespace
    141 
    142 URLRequest::ProtocolFactory*
    143 URLRequest::Deprecated::RegisterProtocolFactory(const std::string& scheme,
    144                                                 ProtocolFactory* factory) {
    145   return URLRequest::RegisterProtocolFactory(scheme, factory);
    146 }
    147 
    148 void URLRequest::Deprecated::RegisterRequestInterceptor(
    149     Interceptor* interceptor) {
    150   URLRequest::RegisterRequestInterceptor(interceptor);
    151 }
    152 
    153 void URLRequest::Deprecated::UnregisterRequestInterceptor(
    154     Interceptor* interceptor) {
    155   URLRequest::UnregisterRequestInterceptor(interceptor);
    156 }
    157 
    158 ///////////////////////////////////////////////////////////////////////////////
    159 // URLRequest::Interceptor
    160 
    161 URLRequestJob* URLRequest::Interceptor::MaybeInterceptRedirect(
    162     URLRequest* request,
    163     NetworkDelegate* network_delegate,
    164     const GURL& location) {
    165   return NULL;
    166 }
    167 
    168 URLRequestJob* URLRequest::Interceptor::MaybeInterceptResponse(
    169     URLRequest* request, NetworkDelegate* network_delegate) {
    170   return NULL;
    171 }
    172 
    173 ///////////////////////////////////////////////////////////////////////////////
    174 // URLRequest::Delegate
    175 
    176 void URLRequest::Delegate::OnReceivedRedirect(URLRequest* request,
    177                                               const GURL& new_url,
    178                                               bool* defer_redirect) {
    179 }
    180 
    181 void URLRequest::Delegate::OnAuthRequired(URLRequest* request,
    182                                           AuthChallengeInfo* auth_info) {
    183   request->CancelAuth();
    184 }
    185 
    186 void URLRequest::Delegate::OnCertificateRequested(
    187     URLRequest* request,
    188     SSLCertRequestInfo* cert_request_info) {
    189   request->Cancel();
    190 }
    191 
    192 void URLRequest::Delegate::OnSSLCertificateError(URLRequest* request,
    193                                                  const SSLInfo& ssl_info,
    194                                                  bool is_hsts_ok) {
    195   request->Cancel();
    196 }
    197 
    198 ///////////////////////////////////////////////////////////////////////////////
    199 // URLRequest
    200 
    201 // TODO(shalev): Get rid of this constructor in favour of the one below it.
    202 URLRequest::URLRequest(const GURL& url,
    203                        Delegate* delegate,
    204                        const URLRequestContext* context)
    205     : context_(context),
    206       network_delegate_(context->network_delegate()),
    207       net_log_(BoundNetLog::Make(context->net_log(),
    208                                  NetLog::SOURCE_URL_REQUEST)),
    209       url_chain_(1, url),
    210       method_("GET"),
    211       referrer_policy_(CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE),
    212       load_flags_(LOAD_NORMAL),
    213       delegate_(delegate),
    214       is_pending_(false),
    215       is_redirecting_(false),
    216       redirect_limit_(kMaxRedirects),
    217       priority_(DEFAULT_PRIORITY),
    218       identifier_(GenerateURLRequestIdentifier()),
    219       blocked_on_delegate_(false),
    220       before_request_callback_(base::Bind(&URLRequest::BeforeRequestComplete,
    221                                           base::Unretained(this))),
    222       has_notified_completion_(false),
    223       received_response_content_length_(0),
    224       creation_time_(base::TimeTicks::Now()) {
    225   SIMPLE_STATS_COUNTER("URLRequestCount");
    226 
    227   // Sanity check out environment.
    228   DCHECK(base::MessageLoop::current())
    229       << "The current base::MessageLoop must exist";
    230 
    231   CHECK(context);
    232   context->url_requests()->insert(this);
    233 
    234   net_log_.BeginEvent(NetLog::TYPE_REQUEST_ALIVE);
    235 }
    236 
    237 URLRequest::URLRequest(const GURL& url,
    238                        Delegate* delegate,
    239                        const URLRequestContext* context,
    240                        NetworkDelegate* network_delegate)
    241     : context_(context),
    242       network_delegate_(network_delegate),
    243       net_log_(BoundNetLog::Make(context->net_log(),
    244                                  NetLog::SOURCE_URL_REQUEST)),
    245       url_chain_(1, url),
    246       method_("GET"),
    247       referrer_policy_(CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE),
    248       load_flags_(LOAD_NORMAL),
    249       delegate_(delegate),
    250       is_pending_(false),
    251       is_redirecting_(false),
    252       redirect_limit_(kMaxRedirects),
    253       priority_(DEFAULT_PRIORITY),
    254       identifier_(GenerateURLRequestIdentifier()),
    255       blocked_on_delegate_(false),
    256       before_request_callback_(base::Bind(&URLRequest::BeforeRequestComplete,
    257                                           base::Unretained(this))),
    258       has_notified_completion_(false),
    259       received_response_content_length_(0),
    260       creation_time_(base::TimeTicks::Now()) {
    261   SIMPLE_STATS_COUNTER("URLRequestCount");
    262 
    263   // Sanity check out environment.
    264   DCHECK(base::MessageLoop::current())
    265       << "The current base::MessageLoop must exist";
    266 
    267   CHECK(context);
    268   context->url_requests()->insert(this);
    269 
    270   net_log_.BeginEvent(NetLog::TYPE_REQUEST_ALIVE);
    271 }
    272 
    273 URLRequest::~URLRequest() {
    274   Cancel();
    275 
    276   if (network_delegate_) {
    277     network_delegate_->NotifyURLRequestDestroyed(this);
    278     if (job_.get())
    279       job_->NotifyURLRequestDestroyed();
    280   }
    281 
    282   if (job_.get())
    283     OrphanJob();
    284 
    285   int deleted = context_->url_requests()->erase(this);
    286   CHECK_EQ(1, deleted);
    287 
    288   int net_error = OK;
    289   // Log error only on failure, not cancellation, as even successful requests
    290   // are "cancelled" on destruction.
    291   if (status_.status() == URLRequestStatus::FAILED)
    292     net_error = status_.error();
    293   net_log_.EndEventWithNetErrorCode(NetLog::TYPE_REQUEST_ALIVE, net_error);
    294 }
    295 
    296 // static
    297 URLRequest::ProtocolFactory* URLRequest::RegisterProtocolFactory(
    298     const string& scheme, ProtocolFactory* factory) {
    299   return URLRequestJobManager::GetInstance()->RegisterProtocolFactory(scheme,
    300                                                                       factory);
    301 }
    302 
    303 // static
    304 void URLRequest::RegisterRequestInterceptor(Interceptor* interceptor) {
    305   URLRequestJobManager::GetInstance()->RegisterRequestInterceptor(interceptor);
    306 }
    307 
    308 // static
    309 void URLRequest::UnregisterRequestInterceptor(Interceptor* interceptor) {
    310   URLRequestJobManager::GetInstance()->UnregisterRequestInterceptor(
    311       interceptor);
    312 }
    313 
    314 void URLRequest::EnableChunkedUpload() {
    315   DCHECK(!upload_data_stream_ || upload_data_stream_->is_chunked());
    316   if (!upload_data_stream_) {
    317     upload_data_stream_.reset(
    318         new UploadDataStream(UploadDataStream::CHUNKED, 0));
    319   }
    320 }
    321 
    322 void URLRequest::AppendChunkToUpload(const char* bytes,
    323                                      int bytes_len,
    324                                      bool is_last_chunk) {
    325   DCHECK(upload_data_stream_);
    326   DCHECK(upload_data_stream_->is_chunked());
    327   DCHECK_GT(bytes_len, 0);
    328   upload_data_stream_->AppendChunk(bytes, bytes_len, is_last_chunk);
    329 }
    330 
    331 void URLRequest::set_upload(scoped_ptr<UploadDataStream> upload) {
    332   DCHECK(!upload->is_chunked());
    333   upload_data_stream_ = upload.Pass();
    334 }
    335 
    336 const UploadDataStream* URLRequest::get_upload() const {
    337   return upload_data_stream_.get();
    338 }
    339 
    340 bool URLRequest::has_upload() const {
    341   return upload_data_stream_.get() != NULL;
    342 }
    343 
    344 void URLRequest::SetExtraRequestHeaderById(int id, const string& value,
    345                                            bool overwrite) {
    346   DCHECK(!is_pending_ || is_redirecting_);
    347   NOTREACHED() << "implement me!";
    348 }
    349 
    350 void URLRequest::SetExtraRequestHeaderByName(const string& name,
    351                                              const string& value,
    352                                              bool overwrite) {
    353   DCHECK(!is_pending_ || is_redirecting_);
    354   if (overwrite) {
    355     extra_request_headers_.SetHeader(name, value);
    356   } else {
    357     extra_request_headers_.SetHeaderIfMissing(name, value);
    358   }
    359 }
    360 
    361 void URLRequest::RemoveRequestHeaderByName(const string& name) {
    362   DCHECK(!is_pending_ || is_redirecting_);
    363   extra_request_headers_.RemoveHeader(name);
    364 }
    365 
    366 void URLRequest::SetExtraRequestHeaders(
    367     const HttpRequestHeaders& headers) {
    368   DCHECK(!is_pending_);
    369   extra_request_headers_ = headers;
    370 
    371   // NOTE: This method will likely become non-trivial once the other setters
    372   // for request headers are implemented.
    373 }
    374 
    375 bool URLRequest::GetFullRequestHeaders(HttpRequestHeaders* headers) const {
    376   if (!job_.get())
    377     return false;
    378 
    379   return job_->GetFullRequestHeaders(headers);
    380 }
    381 
    382 LoadStateWithParam URLRequest::GetLoadState() const {
    383   if (blocked_on_delegate_) {
    384     return LoadStateWithParam(LOAD_STATE_WAITING_FOR_DELEGATE,
    385                               load_state_param_);
    386   }
    387   return LoadStateWithParam(job_.get() ? job_->GetLoadState() : LOAD_STATE_IDLE,
    388                             base::string16());
    389 }
    390 
    391 UploadProgress URLRequest::GetUploadProgress() const {
    392   if (!job_.get()) {
    393     // We haven't started or the request was cancelled
    394     return UploadProgress();
    395   }
    396   if (final_upload_progress_.position()) {
    397     // The first job completed and none of the subsequent series of
    398     // GETs when following redirects will upload anything, so we return the
    399     // cached results from the initial job, the POST.
    400     return final_upload_progress_;
    401   }
    402   return job_->GetUploadProgress();
    403 }
    404 
    405 void URLRequest::GetResponseHeaderById(int id, string* value) {
    406   DCHECK(job_.get());
    407   NOTREACHED() << "implement me!";
    408 }
    409 
    410 void URLRequest::GetResponseHeaderByName(const string& name, string* value) {
    411   DCHECK(value);
    412   if (response_info_.headers.get()) {
    413     response_info_.headers->GetNormalizedHeader(name, value);
    414   } else {
    415     value->clear();
    416   }
    417 }
    418 
    419 void URLRequest::GetAllResponseHeaders(string* headers) {
    420   DCHECK(headers);
    421   if (response_info_.headers.get()) {
    422     response_info_.headers->GetNormalizedHeaders(headers);
    423   } else {
    424     headers->clear();
    425   }
    426 }
    427 
    428 HostPortPair URLRequest::GetSocketAddress() const {
    429   DCHECK(job_.get());
    430   return job_->GetSocketAddress();
    431 }
    432 
    433 HttpResponseHeaders* URLRequest::response_headers() const {
    434   return response_info_.headers.get();
    435 }
    436 
    437 void URLRequest::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const {
    438   *load_timing_info = load_timing_info_;
    439 }
    440 
    441 bool URLRequest::GetResponseCookies(ResponseCookies* cookies) {
    442   DCHECK(job_.get());
    443   return job_->GetResponseCookies(cookies);
    444 }
    445 
    446 void URLRequest::GetMimeType(string* mime_type) {
    447   DCHECK(job_.get());
    448   job_->GetMimeType(mime_type);
    449 }
    450 
    451 void URLRequest::GetCharset(string* charset) {
    452   DCHECK(job_.get());
    453   job_->GetCharset(charset);
    454 }
    455 
    456 int URLRequest::GetResponseCode() {
    457   DCHECK(job_.get());
    458   return job_->GetResponseCode();
    459 }
    460 
    461 // static
    462 void URLRequest::SetDefaultCookiePolicyToBlock() {
    463   CHECK(!g_url_requests_started);
    464   g_default_can_use_cookies = false;
    465 }
    466 
    467 // static
    468 bool URLRequest::IsHandledProtocol(const std::string& scheme) {
    469   return URLRequestJobManager::GetInstance()->SupportsScheme(scheme);
    470 }
    471 
    472 // static
    473 bool URLRequest::IsHandledURL(const GURL& url) {
    474   if (!url.is_valid()) {
    475     // We handle error cases.
    476     return true;
    477   }
    478 
    479   return IsHandledProtocol(url.scheme());
    480 }
    481 
    482 void URLRequest::set_first_party_for_cookies(
    483     const GURL& first_party_for_cookies) {
    484   first_party_for_cookies_ = first_party_for_cookies;
    485 }
    486 
    487 void URLRequest::set_method(const std::string& method) {
    488   DCHECK(!is_pending_);
    489   method_ = method;
    490 }
    491 
    492 // static
    493 std::string URLRequest::ComputeMethodForRedirect(
    494     const std::string& method,
    495     int http_status_code) {
    496   // For 303 redirects, all request methods except HEAD are converted to GET,
    497   // as per the latest httpbis draft.  The draft also allows POST requests to
    498   // be converted to GETs when following 301/302 redirects, for historical
    499   // reasons. Most major browsers do this and so shall we.  Both RFC 2616 and
    500   // the httpbis draft say to prompt the user to confirm the generation of new
    501   // requests, other than GET and HEAD requests, but IE omits these prompts and
    502   // so shall we.
    503   // See:  https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-17#section-7.3
    504   if ((http_status_code == 303 && method != "HEAD") ||
    505       ((http_status_code == 301 || http_status_code == 302) &&
    506        method == "POST")) {
    507     return "GET";
    508   }
    509   return method;
    510 }
    511 
    512 void URLRequest::SetReferrer(const std::string& referrer) {
    513   DCHECK(!is_pending_);
    514   referrer_ = referrer;
    515   // Ensure that we do not send URL fragment, username and password
    516   // fields in the referrer.
    517   GURL referrer_url(referrer);
    518   UMA_HISTOGRAM_BOOLEAN("Net.URLRequest_SetReferrer_IsEmptyOrValid",
    519                         referrer_url.is_empty() || referrer_url.is_valid());
    520   if (referrer_url.is_valid() && (referrer_url.has_ref() ||
    521       referrer_url.has_username() ||  referrer_url.has_password())) {
    522     GURL::Replacements referrer_mods;
    523     referrer_mods.ClearRef();
    524     referrer_mods.ClearUsername();
    525     referrer_mods.ClearPassword();
    526     referrer_url = referrer_url.ReplaceComponents(referrer_mods);
    527     referrer_ = referrer_url.spec();
    528   }
    529 }
    530 
    531 void URLRequest::set_referrer_policy(ReferrerPolicy referrer_policy) {
    532   DCHECK(!is_pending_);
    533   referrer_policy_ = referrer_policy;
    534 }
    535 
    536 void URLRequest::set_delegate(Delegate* delegate) {
    537   delegate_ = delegate;
    538 }
    539 
    540 void URLRequest::Start() {
    541   DCHECK_EQ(network_delegate_, context_->network_delegate());
    542 
    543   g_url_requests_started = true;
    544   response_info_.request_time = base::Time::Now();
    545 
    546   load_timing_info_ = LoadTimingInfo();
    547   load_timing_info_.request_start_time = response_info_.request_time;
    548   load_timing_info_.request_start = base::TimeTicks::Now();
    549 
    550   // Only notify the delegate for the initial request.
    551   if (network_delegate_) {
    552     int error = network_delegate_->NotifyBeforeURLRequest(
    553         this, before_request_callback_, &delegate_redirect_url_);
    554     if (error == net::ERR_IO_PENDING) {
    555       // Paused on the delegate, will invoke |before_request_callback_| later.
    556       SetBlockedOnDelegate();
    557     } else {
    558       BeforeRequestComplete(error);
    559     }
    560     return;
    561   }
    562 
    563   StartJob(URLRequestJobManager::GetInstance()->CreateJob(
    564       this, network_delegate_));
    565 }
    566 
    567 ///////////////////////////////////////////////////////////////////////////////
    568 
    569 void URLRequest::BeforeRequestComplete(int error) {
    570   DCHECK(!job_.get());
    571   DCHECK_NE(ERR_IO_PENDING, error);
    572   DCHECK_EQ(network_delegate_, context_->network_delegate());
    573 
    574   // Check that there are no callbacks to already canceled requests.
    575   DCHECK_NE(URLRequestStatus::CANCELED, status_.status());
    576 
    577   if (blocked_on_delegate_)
    578     SetUnblockedOnDelegate();
    579 
    580   if (error != OK) {
    581     std::string source("delegate");
    582     net_log_.AddEvent(NetLog::TYPE_CANCELLED,
    583                       NetLog::StringCallback("source", &source));
    584     StartJob(new URLRequestErrorJob(this, network_delegate_, error));
    585   } else if (!delegate_redirect_url_.is_empty()) {
    586     GURL new_url;
    587     new_url.Swap(&delegate_redirect_url_);
    588 
    589     URLRequestRedirectJob* job = new URLRequestRedirectJob(
    590         this, network_delegate_, new_url,
    591         // Use status code 307 to preserve the method, so POST requests work.
    592         URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT);
    593     StartJob(job);
    594   } else {
    595     StartJob(URLRequestJobManager::GetInstance()->CreateJob(
    596         this, network_delegate_));
    597   }
    598 }
    599 
    600 void URLRequest::StartJob(URLRequestJob* job) {
    601   DCHECK(!is_pending_);
    602   DCHECK(!job_.get());
    603 
    604   net_log_.BeginEvent(
    605       NetLog::TYPE_URL_REQUEST_START_JOB,
    606       base::Bind(&NetLogURLRequestStartCallback,
    607                  &url(), &method_, load_flags_, priority_,
    608                  upload_data_stream_ ? upload_data_stream_->identifier() : -1));
    609 
    610   job_ = job;
    611   job_->SetExtraRequestHeaders(extra_request_headers_);
    612   job_->SetPriority(priority_);
    613 
    614   if (upload_data_stream_.get())
    615     job_->SetUpload(upload_data_stream_.get());
    616 
    617   is_pending_ = true;
    618   is_redirecting_ = false;
    619 
    620   response_info_.was_cached = false;
    621 
    622   // Don't allow errors to be sent from within Start().
    623   // TODO(brettw) this may cause NotifyDone to be sent synchronously,
    624   // we probably don't want this: they should be sent asynchronously so
    625   // the caller does not get reentered.
    626   job_->Start();
    627 }
    628 
    629 void URLRequest::Restart() {
    630   // Should only be called if the original job didn't make any progress.
    631   DCHECK(job_.get() && !job_->has_response_started());
    632   RestartWithJob(
    633       URLRequestJobManager::GetInstance()->CreateJob(this, network_delegate_));
    634 }
    635 
    636 void URLRequest::RestartWithJob(URLRequestJob *job) {
    637   DCHECK(job->request() == this);
    638   PrepareToRestart();
    639   StartJob(job);
    640 }
    641 
    642 void URLRequest::Cancel() {
    643   DoCancel(ERR_ABORTED, SSLInfo());
    644 }
    645 
    646 void URLRequest::CancelWithError(int error) {
    647   DoCancel(error, SSLInfo());
    648 }
    649 
    650 void URLRequest::CancelWithSSLError(int error, const SSLInfo& ssl_info) {
    651   // This should only be called on a started request.
    652   if (!is_pending_ || !job_.get() || job_->has_response_started()) {
    653     NOTREACHED();
    654     return;
    655   }
    656   DoCancel(error, ssl_info);
    657 }
    658 
    659 void URLRequest::DoCancel(int error, const SSLInfo& ssl_info) {
    660   DCHECK(error < 0);
    661 
    662   // If the URL request already has an error status, then canceling is a no-op.
    663   // Plus, we don't want to change the error status once it has been set.
    664   if (status_.is_success()) {
    665     status_.set_status(URLRequestStatus::CANCELED);
    666     status_.set_error(error);
    667     response_info_.ssl_info = ssl_info;
    668 
    669     // If the request hasn't already been completed, log a cancellation event.
    670     if (!has_notified_completion_) {
    671       // Don't log an error code on ERR_ABORTED, since that's redundant.
    672       net_log_.AddEventWithNetErrorCode(NetLog::TYPE_CANCELLED,
    673                                         error == ERR_ABORTED ? OK : error);
    674     }
    675   }
    676 
    677   if (is_pending_ && job_.get())
    678     job_->Kill();
    679 
    680   // We need to notify about the end of this job here synchronously. The
    681   // Job sends an asynchronous notification but by the time this is processed,
    682   // our |context_| is NULL.
    683   NotifyRequestCompleted();
    684 
    685   // The Job will call our NotifyDone method asynchronously.  This is done so
    686   // that the Delegate implementation can call Cancel without having to worry
    687   // about being called recursively.
    688 }
    689 
    690 bool URLRequest::Read(IOBuffer* dest, int dest_size, int* bytes_read) {
    691   DCHECK(job_.get());
    692   DCHECK(bytes_read);
    693   *bytes_read = 0;
    694 
    695   // This handles a cancel that happens while paused.
    696   // TODO(ahendrickson): DCHECK() that it is not done after
    697   // http://crbug.com/115705 is fixed.
    698   if (job_->is_done())
    699     return false;
    700 
    701   if (dest_size == 0) {
    702     // Caller is not too bright.  I guess we've done what they asked.
    703     return true;
    704   }
    705 
    706   // Once the request fails or is cancelled, read will just return 0 bytes
    707   // to indicate end of stream.
    708   if (!status_.is_success()) {
    709     return true;
    710   }
    711 
    712   bool rv = job_->Read(dest, dest_size, bytes_read);
    713   // If rv is false, the status cannot be success.
    714   DCHECK(rv || status_.status() != URLRequestStatus::SUCCESS);
    715   if (rv && *bytes_read <= 0 && status_.is_success())
    716     NotifyRequestCompleted();
    717   return rv;
    718 }
    719 
    720 void URLRequest::StopCaching() {
    721   DCHECK(job_.get());
    722   job_->StopCaching();
    723 }
    724 
    725 void URLRequest::NotifyReceivedRedirect(const GURL& location,
    726                                         bool* defer_redirect) {
    727   is_redirecting_ = true;
    728 
    729   URLRequestJob* job =
    730       URLRequestJobManager::GetInstance()->MaybeInterceptRedirect(
    731           this, network_delegate_, location);
    732   if (job) {
    733     RestartWithJob(job);
    734   } else if (delegate_) {
    735     delegate_->OnReceivedRedirect(this, location, defer_redirect);
    736     // |this| may be have been destroyed here.
    737   }
    738 }
    739 
    740 void URLRequest::NotifyResponseStarted() {
    741   int net_error = OK;
    742   if (!status_.is_success())
    743     net_error = status_.error();
    744   net_log_.EndEventWithNetErrorCode(NetLog::TYPE_URL_REQUEST_START_JOB,
    745                                     net_error);
    746 
    747   URLRequestJob* job =
    748       URLRequestJobManager::GetInstance()->MaybeInterceptResponse(
    749           this, network_delegate_);
    750   if (job) {
    751     RestartWithJob(job);
    752   } else {
    753     if (delegate_) {
    754       // In some cases (e.g. an event was canceled), we might have sent the
    755       // completion event and receive a NotifyResponseStarted() later.
    756       if (!has_notified_completion_ && status_.is_success()) {
    757         if (network_delegate_)
    758           network_delegate_->NotifyResponseStarted(this);
    759       }
    760 
    761       // Notify in case the entire URL Request has been finished.
    762       if (!has_notified_completion_ && !status_.is_success())
    763         NotifyRequestCompleted();
    764 
    765       delegate_->OnResponseStarted(this);
    766       // Nothing may appear below this line as OnResponseStarted may delete
    767       // |this|.
    768     }
    769   }
    770 }
    771 
    772 void URLRequest::FollowDeferredRedirect() {
    773   CHECK(job_.get());
    774   CHECK(status_.is_success());
    775 
    776   job_->FollowDeferredRedirect();
    777 }
    778 
    779 void URLRequest::SetAuth(const AuthCredentials& credentials) {
    780   DCHECK(job_.get());
    781   DCHECK(job_->NeedsAuth());
    782 
    783   job_->SetAuth(credentials);
    784 }
    785 
    786 void URLRequest::CancelAuth() {
    787   DCHECK(job_.get());
    788   DCHECK(job_->NeedsAuth());
    789 
    790   job_->CancelAuth();
    791 }
    792 
    793 void URLRequest::ContinueWithCertificate(X509Certificate* client_cert) {
    794   DCHECK(job_.get());
    795 
    796   job_->ContinueWithCertificate(client_cert);
    797 }
    798 
    799 void URLRequest::ContinueDespiteLastError() {
    800   DCHECK(job_.get());
    801 
    802   job_->ContinueDespiteLastError();
    803 }
    804 
    805 void URLRequest::PrepareToRestart() {
    806   DCHECK(job_.get());
    807 
    808   // Close the current URL_REQUEST_START_JOB, since we will be starting a new
    809   // one.
    810   net_log_.EndEvent(NetLog::TYPE_URL_REQUEST_START_JOB);
    811 
    812   OrphanJob();
    813 
    814   response_info_ = HttpResponseInfo();
    815   response_info_.request_time = base::Time::Now();
    816 
    817   load_timing_info_ = LoadTimingInfo();
    818   load_timing_info_.request_start_time = response_info_.request_time;
    819   load_timing_info_.request_start = base::TimeTicks::Now();
    820 
    821   status_ = URLRequestStatus();
    822   is_pending_ = false;
    823 }
    824 
    825 void URLRequest::OrphanJob() {
    826   // When calling this function, please check that URLRequestHttpJob is
    827   // not in between calling NetworkDelegate::NotifyHeadersReceived receiving
    828   // the call back. This is currently guaranteed by the following strategies:
    829   // - OrphanJob is called on JobRestart, in this case the URLRequestJob cannot
    830   //   be receiving any headers at that time.
    831   // - OrphanJob is called in ~URLRequest, in this case
    832   //   NetworkDelegate::NotifyURLRequestDestroyed notifies the NetworkDelegate
    833   //   that the callback becomes invalid.
    834   job_->Kill();
    835   job_->DetachRequest();  // ensures that the job will not call us again
    836   job_ = NULL;
    837 }
    838 
    839 int URLRequest::Redirect(const GURL& location, int http_status_code) {
    840   if (net_log_.IsLoggingAllEvents()) {
    841     net_log_.AddEvent(
    842         NetLog::TYPE_URL_REQUEST_REDIRECTED,
    843         NetLog::StringCallback("location", &location.possibly_invalid_spec()));
    844   }
    845 
    846   if (network_delegate_)
    847     network_delegate_->NotifyBeforeRedirect(this, location);
    848 
    849   if (redirect_limit_ <= 0) {
    850     DVLOG(1) << "disallowing redirect: exceeds limit";
    851     return ERR_TOO_MANY_REDIRECTS;
    852   }
    853 
    854   if (!location.is_valid())
    855     return ERR_INVALID_URL;
    856 
    857   if (!job_->IsSafeRedirect(location)) {
    858     DVLOG(1) << "disallowing redirect: unsafe protocol";
    859     return ERR_UNSAFE_REDIRECT;
    860   }
    861 
    862   if (!final_upload_progress_.position())
    863     final_upload_progress_ = job_->GetUploadProgress();
    864   PrepareToRestart();
    865 
    866   std::string new_method(ComputeMethodForRedirect(method_, http_status_code));
    867   if (new_method != method_) {
    868     if (method_ == "POST") {
    869       // If being switched from POST, must remove headers that were specific to
    870       // the POST and don't have meaning in other methods. For example the
    871       // inclusion of a multipart Content-Type header in GET can cause problems
    872       // with some servers:
    873       // http://code.google.com/p/chromium/issues/detail?id=843
    874       StripPostSpecificHeaders(&extra_request_headers_);
    875     }
    876     upload_data_stream_.reset();
    877     method_.swap(new_method);
    878   }
    879 
    880   // Suppress the referrer if we're redirecting out of https.
    881   if (referrer_policy_ ==
    882           CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE &&
    883       GURL(referrer_).SchemeIsSecure() && !location.SchemeIsSecure()) {
    884     referrer_.clear();
    885   }
    886 
    887   url_chain_.push_back(location);
    888   --redirect_limit_;
    889 
    890   Start();
    891   return OK;
    892 }
    893 
    894 const URLRequestContext* URLRequest::context() const {
    895   return context_;
    896 }
    897 
    898 int64 URLRequest::GetExpectedContentSize() const {
    899   int64 expected_content_size = -1;
    900   if (job_.get())
    901     expected_content_size = job_->expected_content_size();
    902 
    903   return expected_content_size;
    904 }
    905 
    906 void URLRequest::SetPriority(RequestPriority priority) {
    907   DCHECK_GE(priority, MINIMUM_PRIORITY);
    908   DCHECK_LT(priority, NUM_PRIORITIES);
    909   if (priority_ == priority)
    910     return;
    911 
    912   priority_ = priority;
    913   if (job_.get()) {
    914     net_log_.AddEvent(NetLog::TYPE_URL_REQUEST_SET_PRIORITY,
    915                       NetLog::IntegerCallback("priority", priority_));
    916     job_->SetPriority(priority_);
    917   }
    918 }
    919 
    920 bool URLRequest::GetHSTSRedirect(GURL* redirect_url) const {
    921   const GURL& url = this->url();
    922   if (!url.SchemeIs("http"))
    923     return false;
    924   TransportSecurityState::DomainState domain_state;
    925   if (context()->transport_security_state() &&
    926       context()->transport_security_state()->GetDomainState(
    927           url.host(),
    928           SSLConfigService::IsSNIAvailable(context()->ssl_config_service()),
    929           &domain_state) &&
    930       domain_state.ShouldUpgradeToSSL()) {
    931     url_canon::Replacements<char> replacements;
    932     const char kNewScheme[] = "https";
    933     replacements.SetScheme(kNewScheme,
    934                            url_parse::Component(0, strlen(kNewScheme)));
    935     *redirect_url = url.ReplaceComponents(replacements);
    936     return true;
    937   }
    938   return false;
    939 }
    940 
    941 void URLRequest::NotifyAuthRequired(AuthChallengeInfo* auth_info) {
    942   NetworkDelegate::AuthRequiredResponse rv =
    943       NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION;
    944   auth_info_ = auth_info;
    945   if (network_delegate_) {
    946     rv = network_delegate_->NotifyAuthRequired(
    947         this,
    948         *auth_info,
    949         base::Bind(&URLRequest::NotifyAuthRequiredComplete,
    950                    base::Unretained(this)),
    951         &auth_credentials_);
    952   }
    953 
    954   if (rv == NetworkDelegate::AUTH_REQUIRED_RESPONSE_IO_PENDING) {
    955     SetBlockedOnDelegate();
    956   } else {
    957     NotifyAuthRequiredComplete(rv);
    958   }
    959 }
    960 
    961 void URLRequest::NotifyAuthRequiredComplete(
    962     NetworkDelegate::AuthRequiredResponse result) {
    963   SetUnblockedOnDelegate();
    964 
    965   // Check that there are no callbacks to already canceled requests.
    966   DCHECK_NE(URLRequestStatus::CANCELED, status_.status());
    967 
    968   // NotifyAuthRequired may be called multiple times, such as
    969   // when an authentication attempt fails. Clear out the data
    970   // so it can be reset on another round.
    971   AuthCredentials credentials = auth_credentials_;
    972   auth_credentials_ = AuthCredentials();
    973   scoped_refptr<AuthChallengeInfo> auth_info;
    974   auth_info.swap(auth_info_);
    975 
    976   switch (result) {
    977     case NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION:
    978       // Defer to the URLRequest::Delegate, since the NetworkDelegate
    979       // didn't take an action.
    980       if (delegate_)
    981         delegate_->OnAuthRequired(this, auth_info.get());
    982       break;
    983 
    984     case NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH:
    985       SetAuth(credentials);
    986       break;
    987 
    988     case NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH:
    989       CancelAuth();
    990       break;
    991 
    992     case NetworkDelegate::AUTH_REQUIRED_RESPONSE_IO_PENDING:
    993       NOTREACHED();
    994       break;
    995   }
    996 }
    997 
    998 void URLRequest::NotifyCertificateRequested(
    999     SSLCertRequestInfo* cert_request_info) {
   1000   if (delegate_)
   1001     delegate_->OnCertificateRequested(this, cert_request_info);
   1002 }
   1003 
   1004 void URLRequest::NotifySSLCertificateError(const SSLInfo& ssl_info,
   1005                                            bool fatal) {
   1006   if (delegate_)
   1007     delegate_->OnSSLCertificateError(this, ssl_info, fatal);
   1008 }
   1009 
   1010 bool URLRequest::CanGetCookies(const CookieList& cookie_list) const {
   1011   DCHECK(!(load_flags_ & LOAD_DO_NOT_SEND_COOKIES));
   1012   if (network_delegate_) {
   1013     return network_delegate_->CanGetCookies(*this, cookie_list);
   1014   }
   1015   return g_default_can_use_cookies;
   1016 }
   1017 
   1018 bool URLRequest::CanSetCookie(const std::string& cookie_line,
   1019                               CookieOptions* options) const {
   1020   DCHECK(!(load_flags_ & LOAD_DO_NOT_SAVE_COOKIES));
   1021   if (network_delegate_) {
   1022     return network_delegate_->CanSetCookie(*this, cookie_line, options);
   1023   }
   1024   return g_default_can_use_cookies;
   1025 }
   1026 
   1027 bool URLRequest::CanEnablePrivacyMode() const {
   1028   if (network_delegate_) {
   1029     return network_delegate_->CanEnablePrivacyMode(url(),
   1030                                                    first_party_for_cookies_);
   1031   }
   1032   return !g_default_can_use_cookies;
   1033 }
   1034 
   1035 
   1036 void URLRequest::NotifyReadCompleted(int bytes_read) {
   1037   // Notify in case the entire URL Request has been finished.
   1038   if (bytes_read <= 0)
   1039     NotifyRequestCompleted();
   1040 
   1041   // Notify NetworkChangeNotifier that we just received network data.
   1042   // This is to identify cases where the NetworkChangeNotifier thinks we
   1043   // are off-line but we are still receiving network data (crbug.com/124069),
   1044   // and to get rough network connection measurements.
   1045   if (bytes_read > 0 && !was_cached())
   1046     NetworkChangeNotifier::NotifyDataReceived(*this, bytes_read);
   1047 
   1048   if (delegate_)
   1049     delegate_->OnReadCompleted(this, bytes_read);
   1050 
   1051   // Nothing below this line as OnReadCompleted may delete |this|.
   1052 }
   1053 
   1054 void URLRequest::OnHeadersComplete() {
   1055   // Cache load timing information now, as information will be lost once the
   1056   // socket is closed and the ClientSocketHandle is Reset, which will happen
   1057   // once the body is complete.  The start times should already be populated.
   1058   if (job_.get()) {
   1059     // Keep a copy of the two times the URLRequest sets.
   1060     base::TimeTicks request_start = load_timing_info_.request_start;
   1061     base::Time request_start_time = load_timing_info_.request_start_time;
   1062 
   1063     // Clear load times.  Shouldn't be neded, but gives the GetLoadTimingInfo a
   1064     // consistent place to start from.
   1065     load_timing_info_ = LoadTimingInfo();
   1066     job_->GetLoadTimingInfo(&load_timing_info_);
   1067 
   1068     load_timing_info_.request_start = request_start;
   1069     load_timing_info_.request_start_time = request_start_time;
   1070 
   1071     ConvertRealLoadTimesToBlockingTimes(&load_timing_info_);
   1072   }
   1073 }
   1074 
   1075 void URLRequest::NotifyRequestCompleted() {
   1076   // TODO(battre): Get rid of this check, according to willchan it should
   1077   // not be needed.
   1078   if (has_notified_completion_)
   1079     return;
   1080 
   1081   is_pending_ = false;
   1082   is_redirecting_ = false;
   1083   has_notified_completion_ = true;
   1084   if (network_delegate_)
   1085     network_delegate_->NotifyCompleted(this, job_.get() != NULL);
   1086 }
   1087 
   1088 void URLRequest::SetBlockedOnDelegate() {
   1089   blocked_on_delegate_ = true;
   1090   if (!load_state_param_.empty()) {
   1091     net_log_.BeginEvent(NetLog::TYPE_URL_REQUEST_BLOCKED_ON_DELEGATE,
   1092                         NetLog::StringCallback("delegate", &load_state_param_));
   1093   } else {
   1094     net_log_.BeginEvent(NetLog::TYPE_URL_REQUEST_BLOCKED_ON_DELEGATE);
   1095   }
   1096 }
   1097 
   1098 void URLRequest::SetUnblockedOnDelegate() {
   1099   if (!blocked_on_delegate_)
   1100     return;
   1101   blocked_on_delegate_ = false;
   1102   load_state_param_.clear();
   1103   net_log_.EndEvent(NetLog::TYPE_URL_REQUEST_BLOCKED_ON_DELEGATE);
   1104 }
   1105 
   1106 void URLRequest::set_stack_trace(const base::debug::StackTrace& stack_trace) {
   1107   base::debug::StackTrace* stack_trace_copy =
   1108       new base::debug::StackTrace(NULL, 0);
   1109   *stack_trace_copy = stack_trace;
   1110   stack_trace_.reset(stack_trace_copy);
   1111 }
   1112 
   1113 const base::debug::StackTrace* URLRequest::stack_trace() const {
   1114   return stack_trace_.get();
   1115 }
   1116 
   1117 }  // namespace net
   1118