| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/url_request/url_request_http_job.h" | 5 #include "net/url_request/url_request_http_job.h" |
| 6 | 6 |
| 7 #include "base/base_switches.h" | 7 #include "base/base_switches.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 StatisticSelector statistic) const { | 165 StatisticSelector statistic) const { |
| 166 job_->RecordPacketStats(statistic); | 166 job_->RecordPacketStats(statistic); |
| 167 } | 167 } |
| 168 | 168 |
| 169 // TODO(darin): make sure the port blocking code is not lost | 169 // TODO(darin): make sure the port blocking code is not lost |
| 170 // static | 170 // static |
| 171 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, | 171 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, |
| 172 const std::string& scheme) { | 172 const std::string& scheme) { |
| 173 DCHECK(scheme == "http" || scheme == "https"); | 173 DCHECK(scheme == "http" || scheme == "https"); |
| 174 | 174 |
| 175 if (!request->context() || | 175 if (!request->context()->http_transaction_factory()) { |
| 176 !request->context()->http_transaction_factory()) { | |
| 177 NOTREACHED() << "requires a valid context"; | 176 NOTREACHED() << "requires a valid context"; |
| 178 return new URLRequestErrorJob(request, ERR_INVALID_ARGUMENT); | 177 return new URLRequestErrorJob(request, ERR_INVALID_ARGUMENT); |
| 179 } | 178 } |
| 180 | 179 |
| 181 GURL redirect_url; | 180 GURL redirect_url; |
| 182 if (request->GetHSTSRedirect(&redirect_url)) | 181 if (request->GetHSTSRedirect(&redirect_url)) |
| 183 return new URLRequestRedirectJob(request, redirect_url); | 182 return new URLRequestRedirectJob(request, redirect_url); |
| 184 return new URLRequestHttpJob(request); | 183 return new URLRequestHttpJob( |
| 184 request, |
| 185 request->context()->http_transaction_factory(), |
| 186 request->context()->network_delegate(), |
| 187 request->context()->throttler_manager(), |
| 188 request->context()->accept_language(), |
| 189 request->context()->accept_charset(), |
| 190 request->context()->cookie_store(), |
| 191 request->context()->fraudulent_certificate_reporter(), |
| 192 request->context()->ssl_config_service(), |
| 193 request->context()->transport_security_state()); |
| 185 } | 194 } |
| 186 | 195 |
| 187 | 196 |
| 188 URLRequestHttpJob::URLRequestHttpJob(URLRequest* request) | 197 URLRequestHttpJob::URLRequestHttpJob( |
| 189 : URLRequestJob(request, request->context()->network_delegate()), | 198 URLRequest* request, |
| 199 HttpTransactionFactory* http_transaction_factory, |
| 200 NetworkDelegate* network_delegate, |
| 201 URLRequestThrottlerManager* throttler_manager, |
| 202 const std::string& accept_language, |
| 203 const std::string& accept_charset, |
| 204 CookieStore* cookie_store, |
| 205 FraudulentCertificateReporter* fraudulent_certificate_reporter, |
| 206 SSLConfigService* ssl_config_service, |
| 207 TransportSecurityState* transport_security_state) |
| 208 : URLRequestJob(request, network_delegate), |
| 190 response_info_(NULL), | 209 response_info_(NULL), |
| 191 response_cookies_save_index_(0), | 210 response_cookies_save_index_(0), |
| 192 proxy_auth_state_(AUTH_STATE_DONT_NEED_AUTH), | 211 proxy_auth_state_(AUTH_STATE_DONT_NEED_AUTH), |
| 193 server_auth_state_(AUTH_STATE_DONT_NEED_AUTH), | 212 server_auth_state_(AUTH_STATE_DONT_NEED_AUTH), |
| 194 ALLOW_THIS_IN_INITIALIZER_LIST(start_callback_( | 213 ALLOW_THIS_IN_INITIALIZER_LIST(start_callback_( |
| 195 base::Bind(&URLRequestHttpJob::OnStartCompleted, | 214 base::Bind(&URLRequestHttpJob::OnStartCompleted, |
| 196 base::Unretained(this)))), | 215 base::Unretained(this)))), |
| 197 ALLOW_THIS_IN_INITIALIZER_LIST(notify_before_headers_sent_callback_( | 216 ALLOW_THIS_IN_INITIALIZER_LIST(notify_before_headers_sent_callback_( |
| 198 base::Bind(&URLRequestHttpJob::NotifyBeforeSendHeadersCallback, | 217 base::Bind(&URLRequestHttpJob::NotifyBeforeSendHeadersCallback, |
| 199 base::Unretained(this)))), | 218 base::Unretained(this)))), |
| (...skipping 10 matching lines...) Expand all Loading... |
| 210 bytes_observed_in_packets_(0), | 229 bytes_observed_in_packets_(0), |
| 211 request_time_snapshot_(), | 230 request_time_snapshot_(), |
| 212 final_packet_time_(), | 231 final_packet_time_(), |
| 213 ALLOW_THIS_IN_INITIALIZER_LIST( | 232 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 214 filter_context_(new HttpFilterContext(this))), | 233 filter_context_(new HttpFilterContext(this))), |
| 215 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 234 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
| 216 ALLOW_THIS_IN_INITIALIZER_LIST(on_headers_received_callback_( | 235 ALLOW_THIS_IN_INITIALIZER_LIST(on_headers_received_callback_( |
| 217 base::Bind(&URLRequestHttpJob::OnHeadersReceivedCallback, | 236 base::Bind(&URLRequestHttpJob::OnHeadersReceivedCallback, |
| 218 base::Unretained(this)))), | 237 base::Unretained(this)))), |
| 219 awaiting_callback_(false), | 238 awaiting_callback_(false), |
| 220 http_transaction_delegate_(new HttpTransactionDelegateImpl(request)) { | 239 http_transaction_delegate_(new HttpTransactionDelegateImpl(request)), |
| 240 http_transaction_factory_(http_transaction_factory), |
| 241 network_delegate_(network_delegate), |
| 242 accept_language_(accept_language), |
| 243 accept_charset_(accept_charset), |
| 244 cookie_store_(cookie_store), |
| 245 fraudulent_certificate_reporter_(fraudulent_certificate_reporter), |
| 246 ssl_config_service_(ssl_config_service), |
| 247 transport_security_state_(transport_security_state) { |
| 248 DCHECK(http_transaction_factory_); |
| 221 URLRequestThrottlerManager* manager = request->context()->throttler_manager(); | 249 URLRequestThrottlerManager* manager = request->context()->throttler_manager(); |
| 222 if (manager) | 250 if (manager) |
| 223 throttling_entry_ = manager->RegisterRequestUrl(request->url()); | 251 throttling_entry_ = manager->RegisterRequestUrl(request->url()); |
| 224 | 252 |
| 225 ResetTimer(); | 253 ResetTimer(); |
| 226 } | 254 } |
| 227 | 255 |
| 228 void URLRequestHttpJob::NotifyHeadersComplete() { | 256 void URLRequestHttpJob::NotifyHeadersComplete() { |
| 229 DCHECK(!response_info_); | 257 DCHECK(!response_info_); |
| 230 | 258 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 | 315 |
| 288 void URLRequestHttpJob::DestroyTransaction() { | 316 void URLRequestHttpJob::DestroyTransaction() { |
| 289 DCHECK(transaction_.get()); | 317 DCHECK(transaction_.get()); |
| 290 | 318 |
| 291 DoneWithRequest(ABORTED); | 319 DoneWithRequest(ABORTED); |
| 292 transaction_.reset(); | 320 transaction_.reset(); |
| 293 response_info_ = NULL; | 321 response_info_ = NULL; |
| 294 } | 322 } |
| 295 | 323 |
| 296 void URLRequestHttpJob::StartTransaction() { | 324 void URLRequestHttpJob::StartTransaction() { |
| 297 if (request_->context() && request_->context()->network_delegate()) { | 325 if (network_delegate_) { |
| 298 int rv = request_->context()->network_delegate()->NotifyBeforeSendHeaders( | 326 int rv = network_delegate_->NotifyBeforeSendHeaders( |
| 299 request_, notify_before_headers_sent_callback_, | 327 request_, notify_before_headers_sent_callback_, |
| 300 &request_info_.extra_headers); | 328 &request_info_.extra_headers); |
| 301 // If an extension blocks the request, we rely on the callback to | 329 // If an extension blocks the request, we rely on the callback to |
| 302 // StartTransactionInternal(). | 330 // StartTransactionInternal(). |
| 303 if (rv == ERR_IO_PENDING) { | 331 if (rv == ERR_IO_PENDING) { |
| 304 SetBlockedOnDelegate(); | 332 SetBlockedOnDelegate(); |
| 305 return; | 333 return; |
| 306 } | 334 } |
| 307 } | 335 } |
| 308 StartTransactionInternal(); | 336 StartTransactionInternal(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 325 } | 353 } |
| 326 | 354 |
| 327 void URLRequestHttpJob::StartTransactionInternal() { | 355 void URLRequestHttpJob::StartTransactionInternal() { |
| 328 // NOTE: This method assumes that request_info_ is already setup properly. | 356 // NOTE: This method assumes that request_info_ is already setup properly. |
| 329 | 357 |
| 330 // If we already have a transaction, then we should restart the transaction | 358 // If we already have a transaction, then we should restart the transaction |
| 331 // with auth provided by auth_credentials_. | 359 // with auth provided by auth_credentials_. |
| 332 | 360 |
| 333 int rv; | 361 int rv; |
| 334 | 362 |
| 335 if (request_->context() && request_->context()->network_delegate()) { | 363 if (network_delegate_) |
| 336 request_->context()->network_delegate()->NotifySendHeaders( | 364 network_delegate_->NotifySendHeaders(request_, request_info_.extra_headers); |
| 337 request_, request_info_.extra_headers); | |
| 338 } | |
| 339 | 365 |
| 340 if (transaction_.get()) { | 366 if (transaction_.get()) { |
| 341 rv = transaction_->RestartWithAuth(auth_credentials_, start_callback_); | 367 rv = transaction_->RestartWithAuth(auth_credentials_, start_callback_); |
| 342 auth_credentials_ = AuthCredentials(); | 368 auth_credentials_ = AuthCredentials(); |
| 343 } else { | 369 } else { |
| 344 DCHECK(request_->context()); | 370 rv = http_transaction_factory_->CreateTransaction( |
| 345 DCHECK(request_->context()->http_transaction_factory()); | |
| 346 | |
| 347 rv = request_->context()->http_transaction_factory()->CreateTransaction( | |
| 348 &transaction_, http_transaction_delegate_.get()); | 371 &transaction_, http_transaction_delegate_.get()); |
| 349 if (rv == OK) { | 372 if (rv == OK) { |
| 350 if (!throttling_entry_ || | 373 if (!throttling_entry_ || |
| 351 !throttling_entry_->ShouldRejectRequest(*request_)) { | 374 !throttling_entry_->ShouldRejectRequest(*request_)) { |
| 352 rv = transaction_->Start( | 375 rv = transaction_->Start( |
| 353 &request_info_, start_callback_, request_->net_log()); | 376 &request_info_, start_callback_, request_->net_log()); |
| 354 start_time_ = base::TimeTicks::Now(); | 377 start_time_ = base::TimeTicks::Now(); |
| 355 } else { | 378 } else { |
| 356 // Special error code for the exponential back-off module. | 379 // Special error code for the exponential back-off module. |
| 357 rv = ERR_TEMPORARILY_THROTTLED; | 380 rv = ERR_TEMPORARILY_THROTTLED; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 // Since we're tagging this transaction as advertising a dictionary, | 450 // Since we're tagging this transaction as advertising a dictionary, |
| 428 // we'll definitely employ an SDCH filter (or tentative sdch filter) | 451 // we'll definitely employ an SDCH filter (or tentative sdch filter) |
| 429 // when we get a response. When done, we'll record histograms via | 452 // when we get a response. When done, we'll record histograms via |
| 430 // SDCH_DECODE or SDCH_PASSTHROUGH. Hence we need to record packet | 453 // SDCH_DECODE or SDCH_PASSTHROUGH. Hence we need to record packet |
| 431 // arrival times. | 454 // arrival times. |
| 432 packet_timing_enabled_ = true; | 455 packet_timing_enabled_ = true; |
| 433 } | 456 } |
| 434 } | 457 } |
| 435 } | 458 } |
| 436 | 459 |
| 437 const URLRequestContext* context = request_->context(); | 460 // Only add default Accept-Language and Accept-Charset if the request |
| 438 if (context) { | 461 // didn't have them specified. |
| 439 // Only add default Accept-Language and Accept-Charset if the request | 462 if (!accept_language_.empty()) { |
| 440 // didn't have them specified. | 463 request_info_.extra_headers.SetHeaderIfMissing( |
| 441 if (!context->accept_language().empty()) { | 464 HttpRequestHeaders::kAcceptLanguage, |
| 442 request_info_.extra_headers.SetHeaderIfMissing( | 465 accept_language_); |
| 443 HttpRequestHeaders::kAcceptLanguage, | 466 } |
| 444 context->accept_language()); | 467 if (!accept_charset_.empty()) { |
| 445 } | 468 request_info_.extra_headers.SetHeaderIfMissing( |
| 446 if (!context->accept_charset().empty()) { | 469 HttpRequestHeaders::kAcceptCharset, |
| 447 request_info_.extra_headers.SetHeaderIfMissing( | 470 accept_charset_); |
| 448 HttpRequestHeaders::kAcceptCharset, | |
| 449 context->accept_charset()); | |
| 450 } | |
| 451 } | 471 } |
| 452 } | 472 } |
| 453 | 473 |
| 454 void URLRequestHttpJob::AddCookieHeaderAndStart() { | 474 void URLRequestHttpJob::AddCookieHeaderAndStart() { |
| 455 // No matter what, we want to report our status as IO pending since we will | 475 // No matter what, we want to report our status as IO pending since we will |
| 456 // be notifying our consumer asynchronously via OnStartCompleted. | 476 // be notifying our consumer asynchronously via OnStartCompleted. |
| 457 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); | 477 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
| 458 | 478 |
| 459 // If the request was destroyed, then there is no more work to do. | 479 // If the request was destroyed, then there is no more work to do. |
| 460 if (!request_) | 480 if (!request_) |
| 461 return; | 481 return; |
| 462 | 482 |
| 463 CookieStore* cookie_store = | 483 if (cookie_store_ && !(request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES)) { |
| 464 request_->context()->cookie_store(); | 484 net::CookieMonster* cookie_monster = cookie_store_->GetCookieMonster(); |
| 465 if (cookie_store && !(request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES)) { | |
| 466 net::CookieMonster* cookie_monster = cookie_store->GetCookieMonster(); | |
| 467 if (cookie_monster) { | 485 if (cookie_monster) { |
| 468 cookie_monster->GetAllCookiesForURLAsync( | 486 cookie_monster->GetAllCookiesForURLAsync( |
| 469 request_->url(), | 487 request_->url(), |
| 470 base::Bind(&URLRequestHttpJob::CheckCookiePolicyAndLoad, | 488 base::Bind(&URLRequestHttpJob::CheckCookiePolicyAndLoad, |
| 471 weak_factory_.GetWeakPtr())); | 489 weak_factory_.GetWeakPtr())); |
| 472 } else { | 490 } else { |
| 473 DoLoadCookies(); | 491 DoLoadCookies(); |
| 474 } | 492 } |
| 475 } else { | 493 } else { |
| 476 DoStartTransaction(); | 494 DoStartTransaction(); |
| 477 } | 495 } |
| 478 } | 496 } |
| 479 | 497 |
| 480 void URLRequestHttpJob::DoLoadCookies() { | 498 void URLRequestHttpJob::DoLoadCookies() { |
| 481 CookieOptions options; | 499 CookieOptions options; |
| 482 options.set_include_httponly(); | 500 options.set_include_httponly(); |
| 483 request_->context()->cookie_store()->GetCookiesWithInfoAsync( | 501 cookie_store_->GetCookiesWithInfoAsync( |
| 484 request_->url(), options, | 502 request_->url(), options, |
| 485 base::Bind(&URLRequestHttpJob::OnCookiesLoaded, | 503 base::Bind(&URLRequestHttpJob::OnCookiesLoaded, |
| 486 weak_factory_.GetWeakPtr())); | 504 weak_factory_.GetWeakPtr())); |
| 487 } | 505 } |
| 488 | 506 |
| 489 void URLRequestHttpJob::CheckCookiePolicyAndLoad( | 507 void URLRequestHttpJob::CheckCookiePolicyAndLoad( |
| 490 const CookieList& cookie_list) { | 508 const CookieList& cookie_list) { |
| 491 if (CanGetCookies(cookie_list)) | 509 if (CanGetCookies(cookie_list)) |
| 492 DoLoadCookies(); | 510 DoLoadCookies(); |
| 493 else | 511 else |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 // be notifying our consumer asynchronously via OnStartCompleted. | 568 // be notifying our consumer asynchronously via OnStartCompleted. |
| 551 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); | 569 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
| 552 | 570 |
| 553 // Used to communicate with the callback. See the implementation of | 571 // Used to communicate with the callback. See the implementation of |
| 554 // OnCookieSaved. | 572 // OnCookieSaved. |
| 555 scoped_refptr<SharedBoolean> callback_pending = new SharedBoolean(false); | 573 scoped_refptr<SharedBoolean> callback_pending = new SharedBoolean(false); |
| 556 scoped_refptr<SharedBoolean> save_next_cookie_running = | 574 scoped_refptr<SharedBoolean> save_next_cookie_running = |
| 557 new SharedBoolean(true); | 575 new SharedBoolean(true); |
| 558 | 576 |
| 559 if (!(request_info_.load_flags & LOAD_DO_NOT_SAVE_COOKIES) && | 577 if (!(request_info_.load_flags & LOAD_DO_NOT_SAVE_COOKIES) && |
| 560 request_->context()->cookie_store() && | 578 cookie_store_ && |
| 561 response_cookies_.size() > 0) { | 579 response_cookies_.size() > 0) { |
| 562 CookieOptions options; | 580 CookieOptions options; |
| 563 options.set_include_httponly(); | 581 options.set_include_httponly(); |
| 564 options.set_server_time(response_date_); | 582 options.set_server_time(response_date_); |
| 565 | 583 |
| 566 net::CookieStore::SetCookiesCallback callback( | 584 net::CookieStore::SetCookiesCallback callback( |
| 567 base::Bind(&URLRequestHttpJob::OnCookieSaved, | 585 base::Bind(&URLRequestHttpJob::OnCookieSaved, |
| 568 weak_factory_.GetWeakPtr(), | 586 weak_factory_.GetWeakPtr(), |
| 569 save_next_cookie_running, | 587 save_next_cookie_running, |
| 570 callback_pending)); | 588 callback_pending)); |
| 571 | 589 |
| 572 // Loop through the cookies as long as SetCookieWithOptionsAsync completes | 590 // Loop through the cookies as long as SetCookieWithOptionsAsync completes |
| 573 // synchronously. | 591 // synchronously. |
| 574 while (!callback_pending->data && | 592 while (!callback_pending->data && |
| 575 response_cookies_save_index_ < response_cookies_.size()) { | 593 response_cookies_save_index_ < response_cookies_.size()) { |
| 576 if (CanSetCookie( | 594 if (CanSetCookie( |
| 577 response_cookies_[response_cookies_save_index_], &options)) { | 595 response_cookies_[response_cookies_save_index_], &options)) { |
| 578 callback_pending->data = true; | 596 callback_pending->data = true; |
| 579 request_->context()->cookie_store()->SetCookieWithOptionsAsync( | 597 cookie_store_->SetCookieWithOptionsAsync( |
| 580 request_->url(), response_cookies_[response_cookies_save_index_], | 598 request_->url(), response_cookies_[response_cookies_save_index_], |
| 581 options, callback); | 599 options, callback); |
| 582 } | 600 } |
| 583 ++response_cookies_save_index_; | 601 ++response_cookies_save_index_; |
| 584 } | 602 } |
| 585 } | 603 } |
| 586 | 604 |
| 587 save_next_cookie_running->data = false; | 605 save_next_cookie_running->data = false; |
| 588 | 606 |
| 589 if (!callback_pending->data) { | 607 if (!callback_pending->data) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 | 655 |
| 638 // NOTE: |ProcessStrictTransportSecurityHeader| and | 656 // NOTE: |ProcessStrictTransportSecurityHeader| and |
| 639 // |ProcessPublicKeyPinsHeader| have very similar structures, by design. | 657 // |ProcessPublicKeyPinsHeader| have very similar structures, by design. |
| 640 // They manipulate different parts of |TransportSecurityState::DomainState|, | 658 // They manipulate different parts of |TransportSecurityState::DomainState|, |
| 641 // and they must remain complementary. If, in future changes here, there is | 659 // and they must remain complementary. If, in future changes here, there is |
| 642 // any conflict between their policies (such as in |domain_state.mode|), you | 660 // any conflict between their policies (such as in |domain_state.mode|), you |
| 643 // should resolve the conflict in favor of the more strict policy. | 661 // should resolve the conflict in favor of the more strict policy. |
| 644 void URLRequestHttpJob::ProcessStrictTransportSecurityHeader() { | 662 void URLRequestHttpJob::ProcessStrictTransportSecurityHeader() { |
| 645 DCHECK(response_info_); | 663 DCHECK(response_info_); |
| 646 | 664 |
| 647 const URLRequestContext* ctx = request_->context(); | |
| 648 const SSLInfo& ssl_info = response_info_->ssl_info; | 665 const SSLInfo& ssl_info = response_info_->ssl_info; |
| 649 | 666 |
| 650 // Only accept strict transport security headers on HTTPS connections that | 667 // Only accept strict transport security headers on HTTPS connections that |
| 651 // have no certificate errors. | 668 // have no certificate errors. |
| 652 if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || | 669 if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || |
| 653 !ctx || !ctx->transport_security_state()) { | 670 !transport_security_state_) { |
| 654 return; | 671 return; |
| 655 } | 672 } |
| 656 | 673 |
| 657 TransportSecurityState* security_state = ctx->transport_security_state(); | |
| 658 TransportSecurityState::DomainState domain_state; | 674 TransportSecurityState::DomainState domain_state; |
| 659 const std::string& host = request_info_.url.host(); | 675 const std::string& host = request_info_.url.host(); |
| 660 | 676 |
| 661 bool sni_available = | 677 bool sni_available = |
| 662 SSLConfigService::IsSNIAvailable(ctx->ssl_config_service()); | 678 SSLConfigService::IsSNIAvailable(ssl_config_service_); |
| 663 if (!security_state->GetDomainState(host, sni_available, &domain_state)) | 679 if (!transport_security_state_->GetDomainState( |
| 680 host, sni_available, &domain_state)) { |
| 664 // |GetDomainState| may have altered |domain_state| while searching. If | 681 // |GetDomainState| may have altered |domain_state| while searching. If |
| 665 // not found, start with a fresh state. | 682 // not found, start with a fresh state. |
| 666 domain_state.upgrade_mode = | 683 domain_state.upgrade_mode = |
| 667 TransportSecurityState::DomainState::MODE_FORCE_HTTPS; | 684 TransportSecurityState::DomainState::MODE_FORCE_HTTPS; |
| 685 } |
| 668 | 686 |
| 669 HttpResponseHeaders* headers = GetResponseHeaders(); | 687 HttpResponseHeaders* headers = GetResponseHeaders(); |
| 670 std::string value; | 688 std::string value; |
| 671 void* iter = NULL; | 689 void* iter = NULL; |
| 672 base::Time now = base::Time::Now(); | 690 base::Time now = base::Time::Now(); |
| 673 | 691 |
| 674 while (headers->EnumerateHeader(&iter, "Strict-Transport-Security", &value)) { | 692 while (headers->EnumerateHeader(&iter, "Strict-Transport-Security", &value)) { |
| 675 TransportSecurityState::DomainState domain_state; | 693 TransportSecurityState::DomainState domain_state; |
| 676 if (domain_state.ParseSTSHeader(now, value)) | 694 if (domain_state.ParseSTSHeader(now, value)) |
| 677 security_state->EnableHost(host, domain_state); | 695 transport_security_state_->EnableHost(host, domain_state); |
| 678 } | 696 } |
| 679 } | 697 } |
| 680 | 698 |
| 681 void URLRequestHttpJob::ProcessPublicKeyPinsHeader() { | 699 void URLRequestHttpJob::ProcessPublicKeyPinsHeader() { |
| 682 DCHECK(response_info_); | 700 DCHECK(response_info_); |
| 683 | 701 |
| 684 const URLRequestContext* ctx = request_->context(); | |
| 685 const SSLInfo& ssl_info = response_info_->ssl_info; | 702 const SSLInfo& ssl_info = response_info_->ssl_info; |
| 686 | 703 |
| 687 // Only accept public key pins headers on HTTPS connections that have no | 704 // Only accept public key pins headers on HTTPS connections that have no |
| 688 // certificate errors. | 705 // certificate errors. |
| 689 if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || | 706 if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || |
| 690 !ctx || !ctx->transport_security_state()) { | 707 !transport_security_state_) { |
| 691 return; | 708 return; |
| 692 } | 709 } |
| 693 | 710 |
| 694 TransportSecurityState* security_state = ctx->transport_security_state(); | |
| 695 TransportSecurityState::DomainState domain_state; | 711 TransportSecurityState::DomainState domain_state; |
| 696 const std::string& host = request_info_.url.host(); | 712 const std::string& host = request_info_.url.host(); |
| 697 | 713 |
| 698 bool sni_available = | 714 bool sni_available = |
| 699 SSLConfigService::IsSNIAvailable(ctx->ssl_config_service()); | 715 SSLConfigService::IsSNIAvailable(ssl_config_service_); |
| 700 if (!security_state->GetDomainState(host, sni_available, &domain_state)) | 716 if (!transport_security_state_->GetDomainState( |
| 717 host, sni_available, &domain_state)) { |
| 701 // |GetDomainState| may have altered |domain_state| while searching. If | 718 // |GetDomainState| may have altered |domain_state| while searching. If |
| 702 // not found, start with a fresh state. | 719 // not found, start with a fresh state. |
| 703 domain_state.upgrade_mode = | 720 domain_state.upgrade_mode = |
| 704 TransportSecurityState::DomainState::MODE_DEFAULT; | 721 TransportSecurityState::DomainState::MODE_DEFAULT; |
| 722 } |
| 705 | 723 |
| 706 HttpResponseHeaders* headers = GetResponseHeaders(); | 724 HttpResponseHeaders* headers = GetResponseHeaders(); |
| 707 void* iter = NULL; | 725 void* iter = NULL; |
| 708 std::string value; | 726 std::string value; |
| 709 base::Time now = base::Time::Now(); | 727 base::Time now = base::Time::Now(); |
| 710 | 728 |
| 711 while (headers->EnumerateHeader(&iter, "Public-Key-Pins", &value)) { | 729 while (headers->EnumerateHeader(&iter, "Public-Key-Pins", &value)) { |
| 712 // Note that ParsePinsHeader updates |domain_state| (iff the header parses | 730 // Note that ParsePinsHeader updates |domain_state| (iff the header parses |
| 713 // correctly), but does not completely overwrite it. It just updates the | 731 // correctly), but does not completely overwrite it. It just updates the |
| 714 // dynamic pinning metadata. | 732 // dynamic pinning metadata. |
| 715 if (domain_state.ParsePinsHeader(now, value, ssl_info)) | 733 if (domain_state.ParsePinsHeader(now, value, ssl_info)) |
| 716 security_state->EnableHost(host, domain_state); | 734 transport_security_state_->EnableHost(host, domain_state); |
| 717 } | 735 } |
| 718 } | 736 } |
| 719 | 737 |
| 720 void URLRequestHttpJob::OnStartCompleted(int result) { | 738 void URLRequestHttpJob::OnStartCompleted(int result) { |
| 721 RecordTimer(); | 739 RecordTimer(); |
| 722 | 740 |
| 723 // If the request was destroyed, then there is no more work to do. | 741 // If the request was destroyed, then there is no more work to do. |
| 724 if (!request_) | 742 if (!request_) |
| 725 return; | 743 return; |
| 726 | 744 |
| 727 // If the transaction was destroyed, then the job was cancelled, and | 745 // If the transaction was destroyed, then the job was cancelled, and |
| 728 // we can just ignore this notification. | 746 // we can just ignore this notification. |
| 729 if (!transaction_.get()) | 747 if (!transaction_.get()) |
| 730 return; | 748 return; |
| 731 | 749 |
| 732 // Clear the IO_PENDING status | 750 // Clear the IO_PENDING status |
| 733 SetStatus(URLRequestStatus()); | 751 SetStatus(URLRequestStatus()); |
| 734 | 752 |
| 735 const URLRequestContext* context = request_->context(); | |
| 736 | |
| 737 if (result == ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN && | 753 if (result == ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN && |
| 738 transaction_->GetResponseInfo() != NULL) { | 754 transaction_->GetResponseInfo() != NULL) { |
| 739 FraudulentCertificateReporter* reporter = | 755 if (fraudulent_certificate_reporter_) { |
| 740 context->fraudulent_certificate_reporter(); | |
| 741 if (reporter != NULL) { | |
| 742 const SSLInfo& ssl_info = transaction_->GetResponseInfo()->ssl_info; | 756 const SSLInfo& ssl_info = transaction_->GetResponseInfo()->ssl_info; |
| 743 bool sni_available = SSLConfigService::IsSNIAvailable( | 757 bool sni_available = SSLConfigService::IsSNIAvailable( |
| 744 context->ssl_config_service()); | 758 ssl_config_service_); |
| 745 const std::string& host = request_->url().host(); | 759 const std::string& host = request_->url().host(); |
| 746 | 760 |
| 747 reporter->SendReport(host, ssl_info, sni_available); | 761 fraudulent_certificate_reporter_->SendReport( |
| 762 host, ssl_info, sni_available); |
| 748 } | 763 } |
| 749 } | 764 } |
| 750 | 765 |
| 751 if (result == OK) { | 766 if (result == OK) { |
| 752 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); | 767 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); |
| 753 if (context && context->network_delegate()) { | 768 if (network_delegate_) { |
| 754 // Note that |this| may not be deleted until | 769 // Note that |this| may not be deleted until |
| 755 // |on_headers_received_callback_| or | 770 // |on_headers_received_callback_| or |
| 756 // |NetworkDelegate::URLRequestDestroyed()| has been called. | 771 // |NetworkDelegate::URLRequestDestroyed()| has been called. |
| 757 int error = context->network_delegate()-> | 772 int error = network_delegate_-> |
| 758 NotifyHeadersReceived(request_, on_headers_received_callback_, | 773 NotifyHeadersReceived(request_, on_headers_received_callback_, |
| 759 headers, &override_response_headers_); | 774 headers, &override_response_headers_); |
| 760 if (error != net::OK) { | 775 if (error != net::OK) { |
| 761 if (error == net::ERR_IO_PENDING) { | 776 if (error == net::ERR_IO_PENDING) { |
| 762 awaiting_callback_ = true; | 777 awaiting_callback_ = true; |
| 763 request_->net_log().BeginEvent( | 778 request_->net_log().BeginEvent( |
| 764 NetLog::TYPE_URL_REQUEST_BLOCKED_ON_DELEGATE); | 779 NetLog::TYPE_URL_REQUEST_BLOCKED_ON_DELEGATE); |
| 765 } else { | 780 } else { |
| 766 std::string source("delegate"); | 781 std::string source("delegate"); |
| 767 request_->net_log().AddEvent(NetLog::TYPE_CANCELLED, | 782 request_->net_log().AddEvent(NetLog::TYPE_CANCELLED, |
| 768 NetLog::StringCallback("source", | 783 NetLog::StringCallback("source", |
| 769 &source)); | 784 &source)); |
| 770 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, error)); | 785 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, error)); |
| 771 } | 786 } |
| 772 return; | 787 return; |
| 773 } | 788 } |
| 774 } | 789 } |
| 775 | 790 |
| 776 SaveCookiesAndNotifyHeadersComplete(net::OK); | 791 SaveCookiesAndNotifyHeadersComplete(net::OK); |
| 777 } else if (IsCertificateError(result)) { | 792 } else if (IsCertificateError(result)) { |
| 778 // We encountered an SSL certificate error. Ask our delegate to decide | 793 // We encountered an SSL certificate error. Ask our delegate to decide |
| 779 // what we should do. | 794 // what we should do. |
| 780 | 795 |
| 781 TransportSecurityState::DomainState domain_state; | 796 TransportSecurityState::DomainState domain_state; |
| 782 const URLRequestContext* context = request_->context(); | |
| 783 const bool fatal = | 797 const bool fatal = |
| 784 context->transport_security_state() && | 798 transport_security_state_ && |
| 785 context->transport_security_state()->GetDomainState( | 799 transport_security_state_->GetDomainState( |
| 786 request_info_.url.host(), | 800 request_info_.url.host(), |
| 787 SSLConfigService::IsSNIAvailable(context->ssl_config_service()), | 801 SSLConfigService::IsSNIAvailable(ssl_config_service_), |
| 788 &domain_state); | 802 &domain_state); |
| 789 NotifySSLCertificateError(transaction_->GetResponseInfo()->ssl_info, fatal); | 803 NotifySSLCertificateError(transaction_->GetResponseInfo()->ssl_info, fatal); |
| 790 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 804 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
| 791 NotifyCertificateRequested( | 805 NotifyCertificateRequested( |
| 792 transaction_->GetResponseInfo()->cert_request_info); | 806 transaction_->GetResponseInfo()->cert_request_info); |
| 793 } else { | 807 } else { |
| 794 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); | 808 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); |
| 795 } | 809 } |
| 796 } | 810 } |
| 797 | 811 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 // plugin could set a referrer although sending the referrer is inhibited. | 883 // plugin could set a referrer although sending the referrer is inhibited. |
| 870 request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer); | 884 request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer); |
| 871 | 885 |
| 872 // Our consumer should have made sure that this is a safe referrer. See for | 886 // Our consumer should have made sure that this is a safe referrer. See for |
| 873 // instance WebCore::FrameLoader::HideReferrer. | 887 // instance WebCore::FrameLoader::HideReferrer. |
| 874 if (referrer.is_valid()) { | 888 if (referrer.is_valid()) { |
| 875 request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer, | 889 request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer, |
| 876 referrer.spec()); | 890 referrer.spec()); |
| 877 } | 891 } |
| 878 | 892 |
| 879 if (request_->context()) { | 893 // TODO(shalev): Fix this to not go through URLRequestContext. |
| 880 request_info_.extra_headers.SetHeaderIfMissing( | 894 request_info_.extra_headers.SetHeaderIfMissing( |
| 881 HttpRequestHeaders::kUserAgent, | 895 HttpRequestHeaders::kUserAgent, |
| 882 request_->context()->GetUserAgent(request_->url())); | 896 request_->context()->GetUserAgent(request_->url())); |
| 883 } | |
| 884 | 897 |
| 885 AddExtraHeaders(); | 898 AddExtraHeaders(); |
| 886 AddCookieHeaderAndStart(); | 899 AddCookieHeaderAndStart(); |
| 887 } | 900 } |
| 888 | 901 |
| 889 void URLRequestHttpJob::Kill() { | 902 void URLRequestHttpJob::Kill() { |
| 890 if (!transaction_.get()) | 903 if (!transaction_.get()) |
| 891 return; | 904 return; |
| 892 | 905 |
| 893 weak_factory_.InvalidateWeakPtrs(); | 906 weak_factory_.InvalidateWeakPtrs(); |
| (...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1474 | 1487 |
| 1475 void URLRequestHttpJob::NotifyURLRequestDestroyed() { | 1488 void URLRequestHttpJob::NotifyURLRequestDestroyed() { |
| 1476 awaiting_callback_ = false; | 1489 awaiting_callback_ = false; |
| 1477 } | 1490 } |
| 1478 | 1491 |
| 1479 void URLRequestHttpJob::OnDetachRequest() { | 1492 void URLRequestHttpJob::OnDetachRequest() { |
| 1480 http_transaction_delegate_->OnDetachRequest(); | 1493 http_transaction_delegate_->OnDetachRequest(); |
| 1481 } | 1494 } |
| 1482 | 1495 |
| 1483 } // namespace net | 1496 } // namespace net |
| OLD | NEW |