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