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