- add sources.
[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/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
40 using base::Time;
41 using std::string;
42
43 namespace net {
44
45 namespace {
46
47 // Max number of http redirects to follow.  Same number as gecko.
48 const int kMaxRedirects = 20;
49
50 // Discard headers which have meaning in POST (Content-Length, Content-Type,
51 // Origin).
52 void 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.
62 uint64 g_next_url_request_identifier = 1;
63
64 // This lock protects g_next_url_request_identifier.
65 base::LazyInstance<base::Lock>::Leaky
66     g_next_url_request_identifier_lock = LAZY_INSTANCE_INITIALIZER;
67
68 // Returns an prior unused identifier for URL requests.
69 uint64 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.
75 bool g_url_requests_started = false;
76
77 // True if cookies are accepted by default.
78 bool 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.
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 URLRequest::ProtocolFactory*
145 URLRequest::Deprecated::RegisterProtocolFactory(const std::string& scheme,
146                                                 ProtocolFactory* factory) {
147   return URLRequest::RegisterProtocolFactory(scheme, factory);
148 }
149
150 void URLRequest::Deprecated::RegisterRequestInterceptor(
151     Interceptor* interceptor) {
152   URLRequest::RegisterRequestInterceptor(interceptor);
153 }
154
155 void URLRequest::Deprecated::UnregisterRequestInterceptor(
156     Interceptor* interceptor) {
157   URLRequest::UnregisterRequestInterceptor(interceptor);
158 }
159
160 ///////////////////////////////////////////////////////////////////////////////
161 // URLRequest::Interceptor
162
163 URLRequestJob* URLRequest::Interceptor::MaybeInterceptRedirect(
164     URLRequest* request,
165     NetworkDelegate* network_delegate,
166     const GURL& location) {
167   return NULL;
168 }
169
170 URLRequestJob* URLRequest::Interceptor::MaybeInterceptResponse(
171     URLRequest* request, NetworkDelegate* network_delegate) {
172   return NULL;
173 }
174
175 ///////////////////////////////////////////////////////////////////////////////
176 // URLRequest::Delegate
177
178 void URLRequest::Delegate::OnReceivedRedirect(URLRequest* request,
179                                               const GURL& new_url,
180                                               bool* defer_redirect) {
181 }
182
183 void URLRequest::Delegate::OnAuthRequired(URLRequest* request,
184                                           AuthChallengeInfo* auth_info) {
185   request->CancelAuth();
186 }
187
188 void URLRequest::Delegate::OnCertificateRequested(
189     URLRequest* request,
190     SSLCertRequestInfo* cert_request_info) {
191   request->Cancel();
192 }
193
194 void URLRequest::Delegate::OnSSLCertificateError(URLRequest* request,
195                                                  const SSLInfo& ssl_info,
196                                                  bool is_hsts_ok) {
197   request->Cancel();
198 }
199
200 ///////////////////////////////////////////////////////////////////////////////
201 // URLRequest
202
203 URLRequest::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       delegate_info_usage_(DELEGATE_INFO_DEBUG_ONLY),
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
240 URLRequest::~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
264 URLRequest::ProtocolFactory* URLRequest::RegisterProtocolFactory(
265     const string& scheme, ProtocolFactory* factory) {
266   return URLRequestJobManager::GetInstance()->RegisterProtocolFactory(scheme,
267                                                                       factory);
268 }
269
270 // static
271 void URLRequest::RegisterRequestInterceptor(Interceptor* interceptor) {
272   URLRequestJobManager::GetInstance()->RegisterRequestInterceptor(interceptor);
273 }
274
275 // static
276 void URLRequest::UnregisterRequestInterceptor(Interceptor* interceptor) {
277   URLRequestJobManager::GetInstance()->UnregisterRequestInterceptor(
278       interceptor);
279 }
280
281 void 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
289 void 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
298 void URLRequest::set_upload(scoped_ptr<UploadDataStream> upload) {
299   DCHECK(!upload->is_chunked());
300   upload_data_stream_ = upload.Pass();
301 }
302
303 const UploadDataStream* URLRequest::get_upload() const {
304   return upload_data_stream_.get();
305 }
306
307 bool URLRequest::has_upload() const {
308   return upload_data_stream_.get() != NULL;
309 }
310
311 void URLRequest::SetExtraRequestHeaderById(int id, const string& value,
312                                            bool overwrite) {
313   DCHECK(!is_pending_ || is_redirecting_);
314   NOTREACHED() << "implement me!";
315 }
316
317 void 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
328 void URLRequest::RemoveRequestHeaderByName(const string& name) {
329   DCHECK(!is_pending_ || is_redirecting_);
330   extra_request_headers_.RemoveHeader(name);
331 }
332
333 void 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
342 bool URLRequest::GetFullRequestHeaders(HttpRequestHeaders* headers) const {
343   if (!job_.get())
344     return false;
345
346   return job_->GetFullRequestHeaders(headers);
347 }
348
349 LoadStateWithParam URLRequest::GetLoadState() const {
350   // The delegate_info_.empty() check allows |this| to report it's blocked on
351   // a delegate before it has been started.
352   if (calling_delegate_ || !delegate_info_.empty()) {
353     return LoadStateWithParam(
354         LOAD_STATE_WAITING_FOR_DELEGATE,
355         delegate_info_usage_ == DELEGATE_INFO_DISPLAY_TO_USER ?
356             UTF8ToUTF16(delegate_info_) : base::string16());
357   }
358   return LoadStateWithParam(job_.get() ? job_->GetLoadState() : LOAD_STATE_IDLE,
359                             base::string16());
360 }
361
362 base::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 (!delegate_info_.empty())
382     dict->SetString("delegate_info", delegate_info_);
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
410 void URLRequest::SetDelegateInfo(const char* delegate_info,
411                                  DelegateInfoUsage delegate_info_usage) {
412   // Only log delegate information to NetLog during startup and certain
413   // deferring calls to delegates.  For all reads but the first, delegate info
414   // is currently ignored.
415   if (!calling_delegate_ && !response_info_.request_time.is_null())
416     return;
417
418   if (!delegate_info_.empty()) {
419     delegate_info_.clear();
420     net_log_.EndEvent(NetLog::TYPE_DELEGATE_INFO);
421   }
422   if (delegate_info) {
423     delegate_info_ = delegate_info;
424     delegate_info_usage_ = delegate_info_usage;
425     net_log_.BeginEvent(
426         NetLog::TYPE_DELEGATE_INFO,
427         NetLog::StringCallback("delegate_info", &delegate_info_));
428   }
429 }
430
431 UploadProgress URLRequest::GetUploadProgress() const {
432   if (!job_.get()) {
433     // We haven't started or the request was cancelled
434     return UploadProgress();
435   }
436   if (final_upload_progress_.position()) {
437     // The first job completed and none of the subsequent series of
438     // GETs when following redirects will upload anything, so we return the
439     // cached results from the initial job, the POST.
440     return final_upload_progress_;
441   }
442   return job_->GetUploadProgress();
443 }
444
445 void URLRequest::GetResponseHeaderById(int id, string* value) {
446   DCHECK(job_.get());
447   NOTREACHED() << "implement me!";
448 }
449
450 void URLRequest::GetResponseHeaderByName(const string& name, string* value) {
451   DCHECK(value);
452   if (response_info_.headers.get()) {
453     response_info_.headers->GetNormalizedHeader(name, value);
454   } else {
455     value->clear();
456   }
457 }
458
459 void URLRequest::GetAllResponseHeaders(string* headers) {
460   DCHECK(headers);
461   if (response_info_.headers.get()) {
462     response_info_.headers->GetNormalizedHeaders(headers);
463   } else {
464     headers->clear();
465   }
466 }
467
468 HostPortPair URLRequest::GetSocketAddress() const {
469   DCHECK(job_.get());
470   return job_->GetSocketAddress();
471 }
472
473 HttpResponseHeaders* URLRequest::response_headers() const {
474   return response_info_.headers.get();
475 }
476
477 void URLRequest::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const {
478   *load_timing_info = load_timing_info_;
479 }
480
481 bool URLRequest::GetResponseCookies(ResponseCookies* cookies) {
482   DCHECK(job_.get());
483   return job_->GetResponseCookies(cookies);
484 }
485
486 void URLRequest::GetMimeType(string* mime_type) {
487   DCHECK(job_.get());
488   job_->GetMimeType(mime_type);
489 }
490
491 void URLRequest::GetCharset(string* charset) {
492   DCHECK(job_.get());
493   job_->GetCharset(charset);
494 }
495
496 int URLRequest::GetResponseCode() const {
497   DCHECK(job_.get());
498   return job_->GetResponseCode();
499 }
500
501 // static
502 void URLRequest::SetDefaultCookiePolicyToBlock() {
503   CHECK(!g_url_requests_started);
504   g_default_can_use_cookies = false;
505 }
506
507 // static
508 bool URLRequest::IsHandledProtocol(const std::string& scheme) {
509   return URLRequestJobManager::GetInstance()->SupportsScheme(scheme);
510 }
511
512 // static
513 bool URLRequest::IsHandledURL(const GURL& url) {
514   if (!url.is_valid()) {
515     // We handle error cases.
516     return true;
517   }
518
519   return IsHandledProtocol(url.scheme());
520 }
521
522 void URLRequest::set_first_party_for_cookies(
523     const GURL& first_party_for_cookies) {
524   first_party_for_cookies_ = first_party_for_cookies;
525 }
526
527 void URLRequest::set_method(const std::string& method) {
528   DCHECK(!is_pending_);
529   method_ = method;
530 }
531
532 // static
533 std::string URLRequest::ComputeMethodForRedirect(
534     const std::string& method,
535     int http_status_code) {
536   // For 303 redirects, all request methods except HEAD are converted to GET,
537   // as per the latest httpbis draft.  The draft also allows POST requests to
538   // be converted to GETs when following 301/302 redirects, for historical
539   // reasons. Most major browsers do this and so shall we.  Both RFC 2616 and
540   // the httpbis draft say to prompt the user to confirm the generation of new
541   // requests, other than GET and HEAD requests, but IE omits these prompts and
542   // so shall we.
543   // See:  https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-17#section-7.3
544   if ((http_status_code == 303 && method != "HEAD") ||
545       ((http_status_code == 301 || http_status_code == 302) &&
546        method == "POST")) {
547     return "GET";
548   }
549   return method;
550 }
551
552 void URLRequest::SetReferrer(const std::string& referrer) {
553   DCHECK(!is_pending_);
554   referrer_ = referrer;
555   // Ensure that we do not send URL fragment, username and password
556   // fields in the referrer.
557   GURL referrer_url(referrer);
558   UMA_HISTOGRAM_BOOLEAN("Net.URLRequest_SetReferrer_IsEmptyOrValid",
559                         referrer_url.is_empty() || referrer_url.is_valid());
560   if (referrer_url.is_valid() && (referrer_url.has_ref() ||
561       referrer_url.has_username() ||  referrer_url.has_password())) {
562     GURL::Replacements referrer_mods;
563     referrer_mods.ClearRef();
564     referrer_mods.ClearUsername();
565     referrer_mods.ClearPassword();
566     referrer_url = referrer_url.ReplaceComponents(referrer_mods);
567     referrer_ = referrer_url.spec();
568   }
569 }
570
571 void URLRequest::set_referrer_policy(ReferrerPolicy referrer_policy) {
572   DCHECK(!is_pending_);
573   referrer_policy_ = referrer_policy;
574 }
575
576 void URLRequest::set_delegate(Delegate* delegate) {
577   delegate_ = delegate;
578 }
579
580 void URLRequest::Start() {
581   DCHECK_EQ(network_delegate_, context_->network_delegate());
582   // Anything that set delegate information before start should have cleaned up
583   // after itself.
584   DCHECK(delegate_info_.empty());
585
586   g_url_requests_started = true;
587   response_info_.request_time = base::Time::Now();
588
589   load_timing_info_ = LoadTimingInfo();
590   load_timing_info_.request_start_time = response_info_.request_time;
591   load_timing_info_.request_start = base::TimeTicks::Now();
592
593   // Only notify the delegate for the initial request.
594   if (network_delegate_) {
595     OnCallToDelegate();
596     int error = network_delegate_->NotifyBeforeURLRequest(
597         this, before_request_callback_, &delegate_redirect_url_);
598     // If ERR_IO_PENDING is returned, the delegate will invoke
599     // |before_request_callback_| later.
600     if (error != ERR_IO_PENDING)
601       BeforeRequestComplete(error);
602     return;
603   }
604
605   StartJob(URLRequestJobManager::GetInstance()->CreateJob(
606       this, network_delegate_));
607 }
608
609 ///////////////////////////////////////////////////////////////////////////////
610
611 void URLRequest::BeforeRequestComplete(int error) {
612   DCHECK(!job_.get());
613   DCHECK_NE(ERR_IO_PENDING, error);
614   DCHECK_EQ(network_delegate_, context_->network_delegate());
615
616   // Check that there are no callbacks to already canceled requests.
617   DCHECK_NE(URLRequestStatus::CANCELED, status_.status());
618
619   OnCallToDelegateComplete();
620
621   if (error != OK) {
622     std::string source("delegate");
623     net_log_.AddEvent(NetLog::TYPE_CANCELLED,
624                       NetLog::StringCallback("source", &source));
625     StartJob(new URLRequestErrorJob(this, network_delegate_, error));
626   } else if (!delegate_redirect_url_.is_empty()) {
627     GURL new_url;
628     new_url.Swap(&delegate_redirect_url_);
629
630     URLRequestRedirectJob* job = new URLRequestRedirectJob(
631         this, network_delegate_, new_url,
632         // Use status code 307 to preserve the method, so POST requests work.
633         URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT);
634     StartJob(job);
635   } else {
636     StartJob(URLRequestJobManager::GetInstance()->CreateJob(
637         this, network_delegate_));
638   }
639 }
640
641 void URLRequest::StartJob(URLRequestJob* job) {
642   DCHECK(!is_pending_);
643   DCHECK(!job_.get());
644
645   net_log_.BeginEvent(
646       NetLog::TYPE_URL_REQUEST_START_JOB,
647       base::Bind(&NetLogURLRequestStartCallback,
648                  &url(), &method_, load_flags_, priority_,
649                  upload_data_stream_ ? upload_data_stream_->identifier() : -1));
650
651   job_ = job;
652   job_->SetExtraRequestHeaders(extra_request_headers_);
653   job_->SetPriority(priority_);
654
655   if (upload_data_stream_.get())
656     job_->SetUpload(upload_data_stream_.get());
657
658   is_pending_ = true;
659   is_redirecting_ = false;
660
661   response_info_.was_cached = false;
662
663   // Don't allow errors to be sent from within Start().
664   // TODO(brettw) this may cause NotifyDone to be sent synchronously,
665   // we probably don't want this: they should be sent asynchronously so
666   // the caller does not get reentered.
667   job_->Start();
668 }
669
670 void URLRequest::Restart() {
671   // Should only be called if the original job didn't make any progress.
672   DCHECK(job_.get() && !job_->has_response_started());
673   RestartWithJob(
674       URLRequestJobManager::GetInstance()->CreateJob(this, network_delegate_));
675 }
676
677 void URLRequest::RestartWithJob(URLRequestJob *job) {
678   DCHECK(job->request() == this);
679   PrepareToRestart();
680   StartJob(job);
681 }
682
683 void URLRequest::Cancel() {
684   DoCancel(ERR_ABORTED, SSLInfo());
685 }
686
687 void URLRequest::CancelWithError(int error) {
688   DoCancel(error, SSLInfo());
689 }
690
691 void URLRequest::CancelWithSSLError(int error, const SSLInfo& ssl_info) {
692   // This should only be called on a started request.
693   if (!is_pending_ || !job_.get() || job_->has_response_started()) {
694     NOTREACHED();
695     return;
696   }
697   DoCancel(error, ssl_info);
698 }
699
700 void URLRequest::DoCancel(int error, const SSLInfo& ssl_info) {
701   DCHECK(error < 0);
702   // If cancelled while calling a delegate, clear delegate info.
703   if (calling_delegate_) {
704     SetDelegateInfo(NULL, DELEGATE_INFO_DEBUG_ONLY);
705     OnCallToDelegateComplete();
706   }
707
708   // If the URL request already has an error status, then canceling is a no-op.
709   // Plus, we don't want to change the error status once it has been set.
710   if (status_.is_success()) {
711     status_.set_status(URLRequestStatus::CANCELED);
712     status_.set_error(error);
713     response_info_.ssl_info = ssl_info;
714
715     // If the request hasn't already been completed, log a cancellation event.
716     if (!has_notified_completion_) {
717       // Don't log an error code on ERR_ABORTED, since that's redundant.
718       net_log_.AddEventWithNetErrorCode(NetLog::TYPE_CANCELLED,
719                                         error == ERR_ABORTED ? OK : error);
720     }
721   }
722
723   if (is_pending_ && job_.get())
724     job_->Kill();
725
726   // We need to notify about the end of this job here synchronously. The
727   // Job sends an asynchronous notification but by the time this is processed,
728   // our |context_| is NULL.
729   NotifyRequestCompleted();
730
731   // The Job will call our NotifyDone method asynchronously.  This is done so
732   // that the Delegate implementation can call Cancel without having to worry
733   // about being called recursively.
734 }
735
736 bool URLRequest::Read(IOBuffer* dest, int dest_size, int* bytes_read) {
737   DCHECK(job_.get());
738   DCHECK(bytes_read);
739   *bytes_read = 0;
740
741   // If this is the first read, end the delegate call that may have started in
742   // OnResponseStarted.
743   OnCallToDelegateComplete();
744
745   // This handles a cancel that happens while paused.
746   // TODO(ahendrickson): DCHECK() that it is not done after
747   // http://crbug.com/115705 is fixed.
748   if (job_->is_done())
749     return false;
750
751   if (dest_size == 0) {
752     // Caller is not too bright.  I guess we've done what they asked.
753     return true;
754   }
755
756   // Once the request fails or is cancelled, read will just return 0 bytes
757   // to indicate end of stream.
758   if (!status_.is_success()) {
759     return true;
760   }
761
762   bool rv = job_->Read(dest, dest_size, bytes_read);
763   // If rv is false, the status cannot be success.
764   DCHECK(rv || status_.status() != URLRequestStatus::SUCCESS);
765   if (rv && *bytes_read <= 0 && status_.is_success())
766     NotifyRequestCompleted();
767   return rv;
768 }
769
770 void URLRequest::StopCaching() {
771   DCHECK(job_.get());
772   job_->StopCaching();
773 }
774
775 void URLRequest::NotifyReceivedRedirect(const GURL& location,
776                                         bool* defer_redirect) {
777   is_redirecting_ = true;
778
779   URLRequestJob* job =
780       URLRequestJobManager::GetInstance()->MaybeInterceptRedirect(
781           this, network_delegate_, location);
782   if (job) {
783     RestartWithJob(job);
784   } else if (delegate_) {
785     OnCallToDelegate();
786     delegate_->OnReceivedRedirect(this, location, defer_redirect);
787     // |this| may be have been destroyed here.
788   }
789 }
790
791 void URLRequest::NotifyResponseStarted() {
792   int net_error = OK;
793   if (!status_.is_success())
794     net_error = status_.error();
795   net_log_.EndEventWithNetErrorCode(NetLog::TYPE_URL_REQUEST_START_JOB,
796                                     net_error);
797
798   URLRequestJob* job =
799       URLRequestJobManager::GetInstance()->MaybeInterceptResponse(
800           this, network_delegate_);
801   if (job) {
802     RestartWithJob(job);
803   } else {
804     if (delegate_) {
805       // In some cases (e.g. an event was canceled), we might have sent the
806       // completion event and receive a NotifyResponseStarted() later.
807       if (!has_notified_completion_ && status_.is_success()) {
808         if (network_delegate_)
809           network_delegate_->NotifyResponseStarted(this);
810       }
811
812       // Notify in case the entire URL Request has been finished.
813       if (!has_notified_completion_ && !status_.is_success())
814         NotifyRequestCompleted();
815
816       OnCallToDelegate();
817       delegate_->OnResponseStarted(this);
818       // Nothing may appear below this line as OnResponseStarted may delete
819       // |this|.
820     }
821   }
822 }
823
824 void URLRequest::FollowDeferredRedirect() {
825   CHECK(job_.get());
826   CHECK(status_.is_success());
827
828   job_->FollowDeferredRedirect();
829 }
830
831 void URLRequest::SetAuth(const AuthCredentials& credentials) {
832   DCHECK(job_.get());
833   DCHECK(job_->NeedsAuth());
834
835   job_->SetAuth(credentials);
836 }
837
838 void URLRequest::CancelAuth() {
839   DCHECK(job_.get());
840   DCHECK(job_->NeedsAuth());
841
842   job_->CancelAuth();
843 }
844
845 void URLRequest::ContinueWithCertificate(X509Certificate* client_cert) {
846   DCHECK(job_.get());
847
848   job_->ContinueWithCertificate(client_cert);
849 }
850
851 void URLRequest::ContinueDespiteLastError() {
852   DCHECK(job_.get());
853
854   job_->ContinueDespiteLastError();
855 }
856
857 void URLRequest::PrepareToRestart() {
858   DCHECK(job_.get());
859
860   // Close the current URL_REQUEST_START_JOB, since we will be starting a new
861   // one.
862   net_log_.EndEvent(NetLog::TYPE_URL_REQUEST_START_JOB);
863
864   OrphanJob();
865
866   response_info_ = HttpResponseInfo();
867   response_info_.request_time = base::Time::Now();
868
869   load_timing_info_ = LoadTimingInfo();
870   load_timing_info_.request_start_time = response_info_.request_time;
871   load_timing_info_.request_start = base::TimeTicks::Now();
872
873   status_ = URLRequestStatus();
874   is_pending_ = false;
875 }
876
877 void URLRequest::OrphanJob() {
878   // When calling this function, please check that URLRequestHttpJob is
879   // not in between calling NetworkDelegate::NotifyHeadersReceived receiving
880   // the call back. This is currently guaranteed by the following strategies:
881   // - OrphanJob is called on JobRestart, in this case the URLRequestJob cannot
882   //   be receiving any headers at that time.
883   // - OrphanJob is called in ~URLRequest, in this case
884   //   NetworkDelegate::NotifyURLRequestDestroyed notifies the NetworkDelegate
885   //   that the callback becomes invalid.
886   job_->Kill();
887   job_->DetachRequest();  // ensures that the job will not call us again
888   job_ = NULL;
889 }
890
891 int URLRequest::Redirect(const GURL& location, int http_status_code) {
892   // Matches call in NotifyReceivedRedirect.
893   OnCallToDelegateComplete();
894   if (net_log_.IsLoggingAllEvents()) {
895     net_log_.AddEvent(
896         NetLog::TYPE_URL_REQUEST_REDIRECTED,
897         NetLog::StringCallback("location", &location.possibly_invalid_spec()));
898   }
899
900   if (network_delegate_)
901     network_delegate_->NotifyBeforeRedirect(this, location);
902
903   if (redirect_limit_ <= 0) {
904     DVLOG(1) << "disallowing redirect: exceeds limit";
905     return ERR_TOO_MANY_REDIRECTS;
906   }
907
908   if (!location.is_valid())
909     return ERR_INVALID_URL;
910
911   if (!job_->IsSafeRedirect(location)) {
912     DVLOG(1) << "disallowing redirect: unsafe protocol";
913     return ERR_UNSAFE_REDIRECT;
914   }
915
916   if (!final_upload_progress_.position())
917     final_upload_progress_ = job_->GetUploadProgress();
918   PrepareToRestart();
919
920   std::string new_method(ComputeMethodForRedirect(method_, http_status_code));
921   if (new_method != method_) {
922     if (method_ == "POST") {
923       // If being switched from POST, must remove headers that were specific to
924       // the POST and don't have meaning in other methods. For example the
925       // inclusion of a multipart Content-Type header in GET can cause problems
926       // with some servers:
927       // http://code.google.com/p/chromium/issues/detail?id=843
928       StripPostSpecificHeaders(&extra_request_headers_);
929     }
930     upload_data_stream_.reset();
931     method_.swap(new_method);
932   }
933
934   // Suppress the referrer if we're redirecting out of https.
935   if (referrer_policy_ ==
936           CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE &&
937       GURL(referrer_).SchemeIsSecure() && !location.SchemeIsSecure()) {
938     referrer_.clear();
939   }
940
941   url_chain_.push_back(location);
942   --redirect_limit_;
943
944   Start();
945   return OK;
946 }
947
948 const URLRequestContext* URLRequest::context() const {
949   return context_;
950 }
951
952 int64 URLRequest::GetExpectedContentSize() const {
953   int64 expected_content_size = -1;
954   if (job_.get())
955     expected_content_size = job_->expected_content_size();
956
957   return expected_content_size;
958 }
959
960 void URLRequest::SetPriority(RequestPriority priority) {
961   DCHECK_GE(priority, MINIMUM_PRIORITY);
962   DCHECK_LE(priority, MAXIMUM_PRIORITY);
963   if (priority_ == priority)
964     return;
965
966   priority_ = priority;
967   if (job_.get()) {
968     net_log_.AddEvent(NetLog::TYPE_URL_REQUEST_SET_PRIORITY,
969                       NetLog::IntegerCallback("priority", priority_));
970     job_->SetPriority(priority_);
971   }
972 }
973
974 bool URLRequest::GetHSTSRedirect(GURL* redirect_url) const {
975   const GURL& url = this->url();
976   if (!url.SchemeIs("http"))
977     return false;
978   TransportSecurityState::DomainState domain_state;
979   if (context()->transport_security_state() &&
980       context()->transport_security_state()->GetDomainState(
981           url.host(),
982           SSLConfigService::IsSNIAvailable(context()->ssl_config_service()),
983           &domain_state) &&
984       domain_state.ShouldUpgradeToSSL()) {
985     url_canon::Replacements<char> replacements;
986     const char kNewScheme[] = "https";
987     replacements.SetScheme(kNewScheme,
988                            url_parse::Component(0, strlen(kNewScheme)));
989     *redirect_url = url.ReplaceComponents(replacements);
990     return true;
991   }
992   return false;
993 }
994
995 void URLRequest::NotifyAuthRequired(AuthChallengeInfo* auth_info) {
996   NetworkDelegate::AuthRequiredResponse rv =
997       NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION;
998   auth_info_ = auth_info;
999   if (network_delegate_) {
1000     OnCallToDelegate();
1001     rv = network_delegate_->NotifyAuthRequired(
1002         this,
1003         *auth_info,
1004         base::Bind(&URLRequest::NotifyAuthRequiredComplete,
1005                    base::Unretained(this)),
1006         &auth_credentials_);
1007     if (rv == NetworkDelegate::AUTH_REQUIRED_RESPONSE_IO_PENDING)
1008       return;
1009   }
1010
1011   NotifyAuthRequiredComplete(rv);
1012 }
1013
1014 void URLRequest::NotifyAuthRequiredComplete(
1015     NetworkDelegate::AuthRequiredResponse result) {
1016   OnCallToDelegateComplete();
1017
1018   // Check that there are no callbacks to already canceled requests.
1019   DCHECK_NE(URLRequestStatus::CANCELED, status_.status());
1020
1021   // NotifyAuthRequired may be called multiple times, such as
1022   // when an authentication attempt fails. Clear out the data
1023   // so it can be reset on another round.
1024   AuthCredentials credentials = auth_credentials_;
1025   auth_credentials_ = AuthCredentials();
1026   scoped_refptr<AuthChallengeInfo> auth_info;
1027   auth_info.swap(auth_info_);
1028
1029   switch (result) {
1030     case NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION:
1031       // Defer to the URLRequest::Delegate, since the NetworkDelegate
1032       // didn't take an action.
1033       if (delegate_)
1034         delegate_->OnAuthRequired(this, auth_info.get());
1035       break;
1036
1037     case NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH:
1038       SetAuth(credentials);
1039       break;
1040
1041     case NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH:
1042       CancelAuth();
1043       break;
1044
1045     case NetworkDelegate::AUTH_REQUIRED_RESPONSE_IO_PENDING:
1046       NOTREACHED();
1047       break;
1048   }
1049 }
1050
1051 void URLRequest::NotifyCertificateRequested(
1052     SSLCertRequestInfo* cert_request_info) {
1053   if (delegate_)
1054     delegate_->OnCertificateRequested(this, cert_request_info);
1055 }
1056
1057 void URLRequest::NotifySSLCertificateError(const SSLInfo& ssl_info,
1058                                            bool fatal) {
1059   if (delegate_)
1060     delegate_->OnSSLCertificateError(this, ssl_info, fatal);
1061 }
1062
1063 bool URLRequest::CanGetCookies(const CookieList& cookie_list) const {
1064   DCHECK(!(load_flags_ & LOAD_DO_NOT_SEND_COOKIES));
1065   if (network_delegate_) {
1066     return network_delegate_->CanGetCookies(*this, cookie_list);
1067   }
1068   return g_default_can_use_cookies;
1069 }
1070
1071 bool URLRequest::CanSetCookie(const std::string& cookie_line,
1072                               CookieOptions* options) const {
1073   DCHECK(!(load_flags_ & LOAD_DO_NOT_SAVE_COOKIES));
1074   if (network_delegate_) {
1075     return network_delegate_->CanSetCookie(*this, cookie_line, options);
1076   }
1077   return g_default_can_use_cookies;
1078 }
1079
1080 bool URLRequest::CanEnablePrivacyMode() const {
1081   if (network_delegate_) {
1082     return network_delegate_->CanEnablePrivacyMode(url(),
1083                                                    first_party_for_cookies_);
1084   }
1085   return !g_default_can_use_cookies;
1086 }
1087
1088
1089 void URLRequest::NotifyReadCompleted(int bytes_read) {
1090   // Notify in case the entire URL Request has been finished.
1091   if (bytes_read <= 0)
1092     NotifyRequestCompleted();
1093
1094   // Notify NetworkChangeNotifier that we just received network data.
1095   // This is to identify cases where the NetworkChangeNotifier thinks we
1096   // are off-line but we are still receiving network data (crbug.com/124069),
1097   // and to get rough network connection measurements.
1098   if (bytes_read > 0 && !was_cached())
1099     NetworkChangeNotifier::NotifyDataReceived(*this, bytes_read);
1100
1101   if (delegate_)
1102     delegate_->OnReadCompleted(this, bytes_read);
1103
1104   // Nothing below this line as OnReadCompleted may delete |this|.
1105 }
1106
1107 void URLRequest::OnHeadersComplete() {
1108   // Cache load timing information now, as information will be lost once the
1109   // socket is closed and the ClientSocketHandle is Reset, which will happen
1110   // once the body is complete.  The start times should already be populated.
1111   if (job_.get()) {
1112     // Keep a copy of the two times the URLRequest sets.
1113     base::TimeTicks request_start = load_timing_info_.request_start;
1114     base::Time request_start_time = load_timing_info_.request_start_time;
1115
1116     // Clear load times.  Shouldn't be neded, but gives the GetLoadTimingInfo a
1117     // consistent place to start from.
1118     load_timing_info_ = LoadTimingInfo();
1119     job_->GetLoadTimingInfo(&load_timing_info_);
1120
1121     load_timing_info_.request_start = request_start;
1122     load_timing_info_.request_start_time = request_start_time;
1123
1124     ConvertRealLoadTimesToBlockingTimes(&load_timing_info_);
1125   }
1126 }
1127
1128 void URLRequest::NotifyRequestCompleted() {
1129   // TODO(battre): Get rid of this check, according to willchan it should
1130   // not be needed.
1131   if (has_notified_completion_)
1132     return;
1133
1134   is_pending_ = false;
1135   is_redirecting_ = false;
1136   has_notified_completion_ = true;
1137   if (network_delegate_)
1138     network_delegate_->NotifyCompleted(this, job_.get() != NULL);
1139 }
1140
1141 void URLRequest::OnCallToDelegate() {
1142   DCHECK(!calling_delegate_);
1143   DCHECK(delegate_info_.empty());
1144   calling_delegate_ = true;
1145   net_log_.BeginEvent(NetLog::TYPE_URL_REQUEST_DELEGATE);
1146 }
1147
1148 void URLRequest::OnCallToDelegateComplete() {
1149   // Delegates should clear their info when it becomes outdated.
1150   DCHECK(delegate_info_.empty());
1151   if (!calling_delegate_)
1152     return;
1153   calling_delegate_ = false;
1154   net_log_.EndEvent(NetLog::TYPE_URL_REQUEST_DELEGATE);
1155 }
1156
1157 void URLRequest::set_stack_trace(const base::debug::StackTrace& stack_trace) {
1158   base::debug::StackTrace* stack_trace_copy =
1159       new base::debug::StackTrace(NULL, 0);
1160   *stack_trace_copy = stack_trace;
1161   stack_trace_.reset(stack_trace_copy);
1162 }
1163
1164 const base::debug::StackTrace* URLRequest::stack_trace() const {
1165   return stack_trace_.get();
1166 }
1167
1168 }  // namespace net