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