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