Chromium Code Reviews| 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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 StatisticSelector statistic) const { | 127 StatisticSelector statistic) const { |
| 128 job_->RecordPacketStats(statistic); | 128 job_->RecordPacketStats(statistic); |
| 129 } | 129 } |
| 130 | 130 |
| 131 // TODO(darin): make sure the port blocking code is not lost | 131 // TODO(darin): make sure the port blocking code is not lost |
| 132 // static | 132 // static |
| 133 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, | 133 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, |
| 134 const std::string& scheme) { | 134 const std::string& scheme) { |
| 135 DCHECK(scheme == "http" || scheme == "https"); | 135 DCHECK(scheme == "http" || scheme == "https"); |
| 136 | 136 |
| 137 if (!request->context() || | 137 if (!request->context()->http_transaction_factory()) { |
| 138 !request->context()->http_transaction_factory()) { | |
| 139 NOTREACHED() << "requires a valid context"; | 138 NOTREACHED() << "requires a valid context"; |
| 140 return new URLRequestErrorJob(request, ERR_INVALID_ARGUMENT); | 139 return new URLRequestErrorJob(request, ERR_INVALID_ARGUMENT); |
| 141 } | 140 } |
| 142 | 141 |
| 143 GURL redirect_url; | 142 GURL redirect_url; |
| 144 if (request->GetHSTSRedirect(&redirect_url)) | 143 if (request->GetHSTSRedirect(&redirect_url)) |
| 145 return new URLRequestRedirectJob(request, redirect_url); | 144 return new URLRequestRedirectJob(request, redirect_url); |
| 146 return new URLRequestHttpJob(request); | 145 return new URLRequestHttpJob( |
| 146 request, | |
| 147 request->context()->http_transaction_factory(), | |
| 148 request->context()->network_delegate(), | |
| 149 request->context()->throttler_manager(), | |
| 150 request->context()->accept_language(), | |
| 151 request->context()->accept_charset(), | |
| 152 request->context()->cookie_store(), | |
| 153 request->context()->fraudulent_certificate_reporter(), | |
| 154 request->context()->ssl_config_service(), | |
| 155 request->context()->transport_security_state()); | |
|
mmenke
2012/07/18 16:21:53
nit: 4-space indent.
shalev
2012/07/23 21:00:21
Done.
| |
| 147 } | 156 } |
| 148 | 157 |
| 149 | 158 |
| 150 URLRequestHttpJob::URLRequestHttpJob(URLRequest* request) | 159 URLRequestHttpJob::URLRequestHttpJob( |
| 151 : URLRequestJob(request, request->context()->network_delegate()), | 160 URLRequest* request, |
| 161 HttpTransactionFactory* http_transaction_factory, | |
| 162 NetworkDelegate* network_delegate, | |
| 163 URLRequestThrottlerManager* throttler_manager, | |
| 164 const std::string& accept_language, | |
| 165 const std::string& accept_charset, | |
| 166 CookieStore* cookie_store, | |
| 167 FraudulentCertificateReporter* fraudulent_certificate_reporter, | |
| 168 SSLConfigService* ssl_config_service, | |
| 169 TransportSecurityState* transport_security_state) | |
| 170 : URLRequestJob(request, network_delegate), | |
| 152 response_info_(NULL), | 171 response_info_(NULL), |
| 153 response_cookies_save_index_(0), | 172 response_cookies_save_index_(0), |
| 154 proxy_auth_state_(AUTH_STATE_DONT_NEED_AUTH), | 173 proxy_auth_state_(AUTH_STATE_DONT_NEED_AUTH), |
| 155 server_auth_state_(AUTH_STATE_DONT_NEED_AUTH), | 174 server_auth_state_(AUTH_STATE_DONT_NEED_AUTH), |
| 156 ALLOW_THIS_IN_INITIALIZER_LIST(start_callback_( | 175 ALLOW_THIS_IN_INITIALIZER_LIST(start_callback_( |
| 157 base::Bind(&URLRequestHttpJob::OnStartCompleted, | 176 base::Bind(&URLRequestHttpJob::OnStartCompleted, |
| 158 base::Unretained(this)))), | 177 base::Unretained(this)))), |
| 159 ALLOW_THIS_IN_INITIALIZER_LIST(notify_before_headers_sent_callback_( | 178 ALLOW_THIS_IN_INITIALIZER_LIST(notify_before_headers_sent_callback_( |
| 160 base::Bind(&URLRequestHttpJob::NotifyBeforeSendHeadersCallback, | 179 base::Bind(&URLRequestHttpJob::NotifyBeforeSendHeadersCallback, |
| 161 base::Unretained(this)))), | 180 base::Unretained(this)))), |
| 162 read_in_progress_(false), | 181 read_in_progress_(false), |
| 163 transaction_(NULL), | 182 transaction_(NULL), |
| 164 throttling_entry_(NULL), | 183 throttling_entry_(NULL), |
| 165 sdch_dictionary_advertised_(false), | 184 sdch_dictionary_advertised_(false), |
| 166 sdch_test_activated_(false), | 185 sdch_test_activated_(false), |
| 167 sdch_test_control_(false), | 186 sdch_test_control_(false), |
| 168 is_cached_content_(false), | 187 is_cached_content_(false), |
| 169 request_creation_time_(), | 188 request_creation_time_(), |
| 170 packet_timing_enabled_(false), | 189 packet_timing_enabled_(false), |
| 171 done_(false), | 190 done_(false), |
| 172 bytes_observed_in_packets_(0), | 191 bytes_observed_in_packets_(0), |
| 173 request_time_snapshot_(), | 192 request_time_snapshot_(), |
| 174 final_packet_time_(), | 193 final_packet_time_(), |
| 175 ALLOW_THIS_IN_INITIALIZER_LIST( | 194 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 176 filter_context_(new HttpFilterContext(this))), | 195 filter_context_(new HttpFilterContext(this))), |
| 177 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 196 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
| 178 ALLOW_THIS_IN_INITIALIZER_LIST(on_headers_received_callback_( | 197 ALLOW_THIS_IN_INITIALIZER_LIST(on_headers_received_callback_( |
| 179 base::Bind(&URLRequestHttpJob::OnHeadersReceivedCallback, | 198 base::Bind(&URLRequestHttpJob::OnHeadersReceivedCallback, |
| 180 base::Unretained(this)))), | 199 base::Unretained(this)))), |
| 181 awaiting_callback_(false) { | 200 awaiting_callback_(false), |
| 182 URLRequestThrottlerManager* manager = request->context()->throttler_manager(); | 201 http_transaction_factory_(http_transaction_factory), |
| 183 if (manager) | 202 network_delegate_(network_delegate), |
| 184 throttling_entry_ = manager->RegisterRequestUrl(request->url()); | 203 accept_language_(accept_language), |
| 204 accept_charset_(accept_charset), | |
| 205 cookie_store_(cookie_store), | |
| 206 fraudulent_certificate_reporter_(fraudulent_certificate_reporter), | |
| 207 ssl_config_service_(ssl_config_service), | |
| 208 transport_security_state_(transport_security_state) { | |
| 209 DCHECK(http_transaction_factory_); | |
| 210 if (throttler_manager) | |
| 211 throttling_entry_ = throttler_manager->RegisterRequestUrl(request->url()); | |
| 185 | 212 |
| 186 ResetTimer(); | 213 ResetTimer(); |
| 187 } | 214 } |
| 188 | 215 |
| 189 void URLRequestHttpJob::NotifyHeadersComplete() { | 216 void URLRequestHttpJob::NotifyHeadersComplete() { |
| 190 DCHECK(!response_info_); | 217 DCHECK(!response_info_); |
| 191 | 218 |
| 192 response_info_ = transaction_->GetResponseInfo(); | 219 response_info_ = transaction_->GetResponseInfo(); |
| 193 | 220 |
| 194 // Save boolean, as we'll need this info at destruction time, and filters may | 221 // Save boolean, as we'll need this info at destruction time, and filters may |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 248 | 275 |
| 249 void URLRequestHttpJob::DestroyTransaction() { | 276 void URLRequestHttpJob::DestroyTransaction() { |
| 250 DCHECK(transaction_.get()); | 277 DCHECK(transaction_.get()); |
| 251 | 278 |
| 252 DoneWithRequest(ABORTED); | 279 DoneWithRequest(ABORTED); |
| 253 transaction_.reset(); | 280 transaction_.reset(); |
| 254 response_info_ = NULL; | 281 response_info_ = NULL; |
| 255 } | 282 } |
| 256 | 283 |
| 257 void URLRequestHttpJob::StartTransaction() { | 284 void URLRequestHttpJob::StartTransaction() { |
| 258 if (request_->context() && request_->context()->network_delegate()) { | 285 if (network_delegate_) { |
| 259 int rv = request_->context()->network_delegate()->NotifyBeforeSendHeaders( | 286 int rv = network_delegate_->NotifyBeforeSendHeaders( |
| 260 request_, notify_before_headers_sent_callback_, | 287 request_, notify_before_headers_sent_callback_, |
| 261 &request_info_.extra_headers); | 288 &request_info_.extra_headers); |
| 262 // If an extension blocks the request, we rely on the callback to | 289 // If an extension blocks the request, we rely on the callback to |
| 263 // StartTransactionInternal(). | 290 // StartTransactionInternal(). |
| 264 if (rv == ERR_IO_PENDING) { | 291 if (rv == ERR_IO_PENDING) { |
| 265 SetBlockedOnDelegate(); | 292 SetBlockedOnDelegate(); |
| 266 return; | 293 return; |
| 267 } | 294 } |
| 268 } | 295 } |
| 269 StartTransactionInternal(); | 296 StartTransactionInternal(); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 286 } | 313 } |
| 287 | 314 |
| 288 void URLRequestHttpJob::StartTransactionInternal() { | 315 void URLRequestHttpJob::StartTransactionInternal() { |
| 289 // NOTE: This method assumes that request_info_ is already setup properly. | 316 // NOTE: This method assumes that request_info_ is already setup properly. |
| 290 | 317 |
| 291 // If we already have a transaction, then we should restart the transaction | 318 // If we already have a transaction, then we should restart the transaction |
| 292 // with auth provided by auth_credentials_. | 319 // with auth provided by auth_credentials_. |
| 293 | 320 |
| 294 int rv; | 321 int rv; |
| 295 | 322 |
| 296 if (request_->context() && request_->context()->network_delegate()) { | 323 if (network_delegate_) |
| 297 request_->context()->network_delegate()->NotifySendHeaders( | 324 network_delegate_->NotifySendHeaders(request_, request_info_.extra_headers); |
| 298 request_, request_info_.extra_headers); | |
| 299 } | |
| 300 | 325 |
| 301 if (transaction_.get()) { | 326 if (transaction_.get()) { |
| 302 rv = transaction_->RestartWithAuth(auth_credentials_, start_callback_); | 327 rv = transaction_->RestartWithAuth(auth_credentials_, start_callback_); |
| 303 auth_credentials_ = AuthCredentials(); | 328 auth_credentials_ = AuthCredentials(); |
| 304 } else { | 329 } else { |
| 305 DCHECK(request_->context()); | 330 rv = http_transaction_factory_->CreateTransaction(&transaction_); |
| 306 DCHECK(request_->context()->http_transaction_factory()); | |
| 307 | |
| 308 rv = request_->context()->http_transaction_factory()->CreateTransaction( | |
| 309 &transaction_); | |
| 310 if (rv == OK) { | 331 if (rv == OK) { |
| 311 if (!throttling_entry_ || | 332 if (!throttling_entry_ || |
| 312 !throttling_entry_->ShouldRejectRequest(*request_)) { | 333 !throttling_entry_->ShouldRejectRequest(*request_)) { |
| 313 rv = transaction_->Start( | 334 rv = transaction_->Start( |
| 314 &request_info_, start_callback_, request_->net_log()); | 335 &request_info_, start_callback_, request_->net_log()); |
| 315 start_time_ = base::TimeTicks::Now(); | 336 start_time_ = base::TimeTicks::Now(); |
| 316 } else { | 337 } else { |
| 317 // Special error code for the exponential back-off module. | 338 // Special error code for the exponential back-off module. |
| 318 rv = ERR_TEMPORARILY_THROTTLED; | 339 rv = ERR_TEMPORARILY_THROTTLED; |
| 319 } | 340 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 388 // Since we're tagging this transaction as advertising a dictionary, | 409 // Since we're tagging this transaction as advertising a dictionary, |
| 389 // we'll definitely employ an SDCH filter (or tentative sdch filter) | 410 // we'll definitely employ an SDCH filter (or tentative sdch filter) |
| 390 // when we get a response. When done, we'll record histograms via | 411 // when we get a response. When done, we'll record histograms via |
| 391 // SDCH_DECODE or SDCH_PASSTHROUGH. Hence we need to record packet | 412 // SDCH_DECODE or SDCH_PASSTHROUGH. Hence we need to record packet |
| 392 // arrival times. | 413 // arrival times. |
| 393 packet_timing_enabled_ = true; | 414 packet_timing_enabled_ = true; |
| 394 } | 415 } |
| 395 } | 416 } |
| 396 } | 417 } |
| 397 | 418 |
| 398 const URLRequestContext* context = request_->context(); | 419 // Only add default Accept-Language and Accept-Charset if the request |
| 399 if (context) { | 420 // didn't have them specified. |
| 400 // Only add default Accept-Language and Accept-Charset if the request | 421 if (!accept_language_.empty()) { |
| 401 // didn't have them specified. | 422 request_info_.extra_headers.SetHeaderIfMissing( |
| 402 if (!context->accept_language().empty()) { | 423 HttpRequestHeaders::kAcceptLanguage, |
| 403 request_info_.extra_headers.SetHeaderIfMissing( | 424 accept_language_); |
| 404 HttpRequestHeaders::kAcceptLanguage, | 425 } |
| 405 context->accept_language()); | 426 if (!accept_charset_.empty()) { |
| 406 } | 427 request_info_.extra_headers.SetHeaderIfMissing( |
| 407 if (!context->accept_charset().empty()) { | 428 HttpRequestHeaders::kAcceptCharset, |
| 408 request_info_.extra_headers.SetHeaderIfMissing( | 429 accept_charset_); |
| 409 HttpRequestHeaders::kAcceptCharset, | |
| 410 context->accept_charset()); | |
| 411 } | |
| 412 } | 430 } |
| 413 } | 431 } |
| 414 | 432 |
| 415 void URLRequestHttpJob::AddCookieHeaderAndStart() { | 433 void URLRequestHttpJob::AddCookieHeaderAndStart() { |
| 416 // No matter what, we want to report our status as IO pending since we will | 434 // No matter what, we want to report our status as IO pending since we will |
| 417 // be notifying our consumer asynchronously via OnStartCompleted. | 435 // be notifying our consumer asynchronously via OnStartCompleted. |
| 418 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); | 436 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
| 419 | 437 |
| 420 // If the request was destroyed, then there is no more work to do. | 438 // If the request was destroyed, then there is no more work to do. |
| 421 if (!request_) | 439 if (!request_) |
| 422 return; | 440 return; |
| 423 | 441 |
| 424 CookieStore* cookie_store = | 442 if (cookie_store_ && !(request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES)) { |
| 425 request_->context()->cookie_store(); | 443 net::CookieMonster* cookie_monster = cookie_store_->GetCookieMonster(); |
| 426 if (cookie_store && !(request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES)) { | |
| 427 net::CookieMonster* cookie_monster = cookie_store->GetCookieMonster(); | |
| 428 if (cookie_monster) { | 444 if (cookie_monster) { |
| 429 cookie_monster->GetAllCookiesForURLAsync( | 445 cookie_monster->GetAllCookiesForURLAsync( |
| 430 request_->url(), | 446 request_->url(), |
| 431 base::Bind(&URLRequestHttpJob::CheckCookiePolicyAndLoad, | 447 base::Bind(&URLRequestHttpJob::CheckCookiePolicyAndLoad, |
| 432 weak_factory_.GetWeakPtr())); | 448 weak_factory_.GetWeakPtr())); |
| 433 } else { | 449 } else { |
| 434 DoLoadCookies(); | 450 DoLoadCookies(); |
| 435 } | 451 } |
| 436 } else { | 452 } else { |
| 437 DoStartTransaction(); | 453 DoStartTransaction(); |
| 438 } | 454 } |
| 439 } | 455 } |
| 440 | 456 |
| 441 void URLRequestHttpJob::DoLoadCookies() { | 457 void URLRequestHttpJob::DoLoadCookies() { |
| 442 CookieOptions options; | 458 CookieOptions options; |
| 443 options.set_include_httponly(); | 459 options.set_include_httponly(); |
| 444 request_->context()->cookie_store()->GetCookiesWithInfoAsync( | 460 cookie_store_->GetCookiesWithInfoAsync( |
| 445 request_->url(), options, | 461 request_->url(), options, |
| 446 base::Bind(&URLRequestHttpJob::OnCookiesLoaded, | 462 base::Bind(&URLRequestHttpJob::OnCookiesLoaded, |
| 447 weak_factory_.GetWeakPtr())); | 463 weak_factory_.GetWeakPtr())); |
| 448 } | 464 } |
| 449 | 465 |
| 450 void URLRequestHttpJob::CheckCookiePolicyAndLoad( | 466 void URLRequestHttpJob::CheckCookiePolicyAndLoad( |
| 451 const CookieList& cookie_list) { | 467 const CookieList& cookie_list) { |
| 452 if (CanGetCookies(cookie_list)) | 468 if (CanGetCookies(cookie_list)) |
| 453 DoLoadCookies(); | 469 DoLoadCookies(); |
| 454 else | 470 else |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 511 // be notifying our consumer asynchronously via OnStartCompleted. | 527 // be notifying our consumer asynchronously via OnStartCompleted. |
| 512 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); | 528 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
| 513 | 529 |
| 514 // Used to communicate with the callback. See the implementation of | 530 // Used to communicate with the callback. See the implementation of |
| 515 // OnCookieSaved. | 531 // OnCookieSaved. |
| 516 scoped_refptr<SharedBoolean> callback_pending = new SharedBoolean(false); | 532 scoped_refptr<SharedBoolean> callback_pending = new SharedBoolean(false); |
| 517 scoped_refptr<SharedBoolean> save_next_cookie_running = | 533 scoped_refptr<SharedBoolean> save_next_cookie_running = |
| 518 new SharedBoolean(true); | 534 new SharedBoolean(true); |
| 519 | 535 |
| 520 if (!(request_info_.load_flags & LOAD_DO_NOT_SAVE_COOKIES) && | 536 if (!(request_info_.load_flags & LOAD_DO_NOT_SAVE_COOKIES) && |
| 521 request_->context()->cookie_store() && | 537 cookie_store_ && |
| 522 response_cookies_.size() > 0) { | 538 response_cookies_.size() > 0) { |
| 523 CookieOptions options; | 539 CookieOptions options; |
| 524 options.set_include_httponly(); | 540 options.set_include_httponly(); |
| 525 options.set_server_time(response_date_); | 541 options.set_server_time(response_date_); |
| 526 | 542 |
| 527 net::CookieStore::SetCookiesCallback callback( | 543 net::CookieStore::SetCookiesCallback callback( |
| 528 base::Bind(&URLRequestHttpJob::OnCookieSaved, | 544 base::Bind(&URLRequestHttpJob::OnCookieSaved, |
| 529 weak_factory_.GetWeakPtr(), | 545 weak_factory_.GetWeakPtr(), |
| 530 save_next_cookie_running, | 546 save_next_cookie_running, |
| 531 callback_pending)); | 547 callback_pending)); |
| 532 | 548 |
| 533 // Loop through the cookies as long as SetCookieWithOptionsAsync completes | 549 // Loop through the cookies as long as SetCookieWithOptionsAsync completes |
| 534 // synchronously. | 550 // synchronously. |
| 535 while (!callback_pending->data && | 551 while (!callback_pending->data && |
| 536 response_cookies_save_index_ < response_cookies_.size()) { | 552 response_cookies_save_index_ < response_cookies_.size()) { |
| 537 if (CanSetCookie( | 553 if (CanSetCookie( |
| 538 response_cookies_[response_cookies_save_index_], &options)) { | 554 response_cookies_[response_cookies_save_index_], &options)) { |
| 539 callback_pending->data = true; | 555 callback_pending->data = true; |
| 540 request_->context()->cookie_store()->SetCookieWithOptionsAsync( | 556 cookie_store_->SetCookieWithOptionsAsync( |
| 541 request_->url(), response_cookies_[response_cookies_save_index_], | 557 request_->url(), response_cookies_[response_cookies_save_index_], |
| 542 options, callback); | 558 options, callback); |
| 543 } | 559 } |
| 544 ++response_cookies_save_index_; | 560 ++response_cookies_save_index_; |
| 545 } | 561 } |
| 546 } | 562 } |
| 547 | 563 |
| 548 save_next_cookie_running->data = false; | 564 save_next_cookie_running->data = false; |
| 549 | 565 |
| 550 if (!callback_pending->data) { | 566 if (!callback_pending->data) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 598 | 614 |
| 599 // NOTE: |ProcessStrictTransportSecurityHeader| and | 615 // NOTE: |ProcessStrictTransportSecurityHeader| and |
| 600 // |ProcessPublicKeyPinsHeader| have very similar structures, by design. | 616 // |ProcessPublicKeyPinsHeader| have very similar structures, by design. |
| 601 // They manipulate different parts of |TransportSecurityState::DomainState|, | 617 // They manipulate different parts of |TransportSecurityState::DomainState|, |
| 602 // and they must remain complementary. If, in future changes here, there is | 618 // and they must remain complementary. If, in future changes here, there is |
| 603 // any conflict between their policies (such as in |domain_state.mode|), you | 619 // any conflict between their policies (such as in |domain_state.mode|), you |
| 604 // should resolve the conflict in favor of the more strict policy. | 620 // should resolve the conflict in favor of the more strict policy. |
| 605 void URLRequestHttpJob::ProcessStrictTransportSecurityHeader() { | 621 void URLRequestHttpJob::ProcessStrictTransportSecurityHeader() { |
| 606 DCHECK(response_info_); | 622 DCHECK(response_info_); |
| 607 | 623 |
| 608 const URLRequestContext* ctx = request_->context(); | |
| 609 const SSLInfo& ssl_info = response_info_->ssl_info; | 624 const SSLInfo& ssl_info = response_info_->ssl_info; |
| 610 | 625 |
| 611 // Only accept strict transport security headers on HTTPS connections that | 626 // Only accept strict transport security headers on HTTPS connections that |
| 612 // have no certificate errors. | 627 // have no certificate errors. |
| 613 if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || | 628 if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || |
| 614 !ctx || !ctx->transport_security_state()) { | 629 !transport_security_state_) { |
| 615 return; | 630 return; |
| 616 } | 631 } |
| 617 | 632 |
| 618 TransportSecurityState* security_state = ctx->transport_security_state(); | |
| 619 TransportSecurityState::DomainState domain_state; | 633 TransportSecurityState::DomainState domain_state; |
| 620 const std::string& host = request_info_.url.host(); | 634 const std::string& host = request_info_.url.host(); |
| 621 | 635 |
| 622 bool sni_available = | 636 bool sni_available = |
| 623 SSLConfigService::IsSNIAvailable(ctx->ssl_config_service()); | 637 SSLConfigService::IsSNIAvailable(ssl_config_service_); |
| 624 if (!security_state->GetDomainState(host, sni_available, &domain_state)) | 638 if (!transport_security_state_->GetDomainState( |
| 639 host, sni_available, &domain_state)) { | |
|
mmenke
2012/07/18 16:21:53
nit: Since this is a continuation of the function
shalev
2012/07/23 21:00:21
Done.
| |
| 625 // |GetDomainState| may have altered |domain_state| while searching. If | 640 // |GetDomainState| may have altered |domain_state| while searching. If |
| 626 // not found, start with a fresh state. | 641 // not found, start with a fresh state. |
| 627 domain_state.upgrade_mode = | 642 domain_state.upgrade_mode = |
| 628 TransportSecurityState::DomainState::MODE_FORCE_HTTPS; | 643 TransportSecurityState::DomainState::MODE_FORCE_HTTPS; |
| 644 } | |
| 629 | 645 |
| 630 HttpResponseHeaders* headers = GetResponseHeaders(); | 646 HttpResponseHeaders* headers = GetResponseHeaders(); |
| 631 std::string value; | 647 std::string value; |
| 632 void* iter = NULL; | 648 void* iter = NULL; |
| 633 base::Time now = base::Time::Now(); | 649 base::Time now = base::Time::Now(); |
| 634 | 650 |
| 635 while (headers->EnumerateHeader(&iter, "Strict-Transport-Security", &value)) { | 651 while (headers->EnumerateHeader(&iter, "Strict-Transport-Security", &value)) { |
| 636 TransportSecurityState::DomainState domain_state; | 652 TransportSecurityState::DomainState domain_state; |
| 637 if (domain_state.ParseSTSHeader(now, value)) | 653 if (domain_state.ParseSTSHeader(now, value)) |
| 638 security_state->EnableHost(host, domain_state); | 654 transport_security_state_->EnableHost(host, domain_state); |
| 639 } | 655 } |
| 640 } | 656 } |
| 641 | 657 |
| 642 void URLRequestHttpJob::ProcessPublicKeyPinsHeader() { | 658 void URLRequestHttpJob::ProcessPublicKeyPinsHeader() { |
| 643 DCHECK(response_info_); | 659 DCHECK(response_info_); |
| 644 | 660 |
| 645 const URLRequestContext* ctx = request_->context(); | |
| 646 const SSLInfo& ssl_info = response_info_->ssl_info; | 661 const SSLInfo& ssl_info = response_info_->ssl_info; |
| 647 | 662 |
| 648 // Only accept public key pins headers on HTTPS connections that have no | 663 // Only accept public key pins headers on HTTPS connections that have no |
| 649 // certificate errors. | 664 // certificate errors. |
| 650 if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || | 665 if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || |
| 651 !ctx || !ctx->transport_security_state()) { | 666 !transport_security_state_) { |
| 652 return; | 667 return; |
| 653 } | 668 } |
| 654 | 669 |
| 655 TransportSecurityState* security_state = ctx->transport_security_state(); | |
| 656 TransportSecurityState::DomainState domain_state; | 670 TransportSecurityState::DomainState domain_state; |
| 657 const std::string& host = request_info_.url.host(); | 671 const std::string& host = request_info_.url.host(); |
| 658 | 672 |
| 659 bool sni_available = | 673 bool sni_available = |
| 660 SSLConfigService::IsSNIAvailable(ctx->ssl_config_service()); | 674 SSLConfigService::IsSNIAvailable(ssl_config_service_); |
| 661 if (!security_state->GetDomainState(host, sni_available, &domain_state)) | 675 if (!transport_security_state_->GetDomainState( |
| 676 host, sni_available, &domain_state)) { | |
| 662 // |GetDomainState| may have altered |domain_state| while searching. If | 677 // |GetDomainState| may have altered |domain_state| while searching. If |
| 663 // not found, start with a fresh state. | 678 // not found, start with a fresh state. |
| 664 domain_state.upgrade_mode = | 679 domain_state.upgrade_mode = |
| 665 TransportSecurityState::DomainState::MODE_DEFAULT; | 680 TransportSecurityState::DomainState::MODE_DEFAULT; |
| 681 } | |
| 666 | 682 |
| 667 HttpResponseHeaders* headers = GetResponseHeaders(); | 683 HttpResponseHeaders* headers = GetResponseHeaders(); |
| 668 void* iter = NULL; | 684 void* iter = NULL; |
| 669 std::string value; | 685 std::string value; |
| 670 base::Time now = base::Time::Now(); | 686 base::Time now = base::Time::Now(); |
| 671 | 687 |
| 672 while (headers->EnumerateHeader(&iter, "Public-Key-Pins", &value)) { | 688 while (headers->EnumerateHeader(&iter, "Public-Key-Pins", &value)) { |
| 673 // Note that ParsePinsHeader updates |domain_state| (iff the header parses | 689 // Note that ParsePinsHeader updates |domain_state| (iff the header parses |
| 674 // correctly), but does not completely overwrite it. It just updates the | 690 // correctly), but does not completely overwrite it. It just updates the |
| 675 // dynamic pinning metadata. | 691 // dynamic pinning metadata. |
| 676 if (domain_state.ParsePinsHeader(now, value, ssl_info)) | 692 if (domain_state.ParsePinsHeader(now, value, ssl_info)) |
| 677 security_state->EnableHost(host, domain_state); | 693 transport_security_state_->EnableHost(host, domain_state); |
| 678 } | 694 } |
| 679 } | 695 } |
| 680 | 696 |
| 681 void URLRequestHttpJob::OnStartCompleted(int result) { | 697 void URLRequestHttpJob::OnStartCompleted(int result) { |
| 682 RecordTimer(); | 698 RecordTimer(); |
| 683 | 699 |
| 684 // If the request was destroyed, then there is no more work to do. | 700 // If the request was destroyed, then there is no more work to do. |
| 685 if (!request_) | 701 if (!request_) |
| 686 return; | 702 return; |
| 687 | 703 |
| 688 // If the transaction was destroyed, then the job was cancelled, and | 704 // If the transaction was destroyed, then the job was cancelled, and |
| 689 // we can just ignore this notification. | 705 // we can just ignore this notification. |
| 690 if (!transaction_.get()) | 706 if (!transaction_.get()) |
| 691 return; | 707 return; |
| 692 | 708 |
| 693 // Clear the IO_PENDING status | 709 // Clear the IO_PENDING status |
| 694 SetStatus(URLRequestStatus()); | 710 SetStatus(URLRequestStatus()); |
| 695 | 711 |
| 696 const URLRequestContext* context = request_->context(); | |
| 697 | 712 |
| 698 if (result == ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN && | 713 if (result == ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN && |
| 699 transaction_->GetResponseInfo() != NULL) { | 714 transaction_->GetResponseInfo() != NULL) { |
| 700 FraudulentCertificateReporter* reporter = | 715 if (fraudulent_certificate_reporter_) { |
| 701 context->fraudulent_certificate_reporter(); | |
| 702 if (reporter != NULL) { | |
| 703 const SSLInfo& ssl_info = transaction_->GetResponseInfo()->ssl_info; | 716 const SSLInfo& ssl_info = transaction_->GetResponseInfo()->ssl_info; |
| 704 bool sni_available = SSLConfigService::IsSNIAvailable( | 717 bool sni_available = SSLConfigService::IsSNIAvailable( |
| 705 context->ssl_config_service()); | 718 ssl_config_service_); |
| 706 const std::string& host = request_->url().host(); | 719 const std::string& host = request_->url().host(); |
| 707 | 720 |
| 708 reporter->SendReport(host, ssl_info, sni_available); | 721 fraudulent_certificate_reporter_->SendReport( |
| 722 host, ssl_info, sni_available); | |
| 709 } | 723 } |
| 710 } | 724 } |
| 711 | 725 |
| 712 if (result == OK) { | 726 if (result == OK) { |
| 713 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); | 727 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); |
| 714 if (context && context->network_delegate()) { | 728 if (network_delegate_) { |
| 715 // Note that |this| may not be deleted until | 729 // Note that |this| may not be deleted until |
| 716 // |on_headers_received_callback_| or | 730 // |on_headers_received_callback_| or |
| 717 // |NetworkDelegate::URLRequestDestroyed()| has been called. | 731 // |NetworkDelegate::URLRequestDestroyed()| has been called. |
| 718 int error = context->network_delegate()-> | 732 int error = network_delegate_-> |
| 719 NotifyHeadersReceived(request_, on_headers_received_callback_, | 733 NotifyHeadersReceived(request_, on_headers_received_callback_, |
| 720 headers, &override_response_headers_); | 734 headers, &override_response_headers_); |
| 721 if (error != net::OK) { | 735 if (error != net::OK) { |
| 722 if (error == net::ERR_IO_PENDING) { | 736 if (error == net::ERR_IO_PENDING) { |
| 723 awaiting_callback_ = true; | 737 awaiting_callback_ = true; |
| 724 request_->net_log().BeginEvent( | 738 request_->net_log().BeginEvent( |
| 725 NetLog::TYPE_URL_REQUEST_BLOCKED_ON_DELEGATE); | 739 NetLog::TYPE_URL_REQUEST_BLOCKED_ON_DELEGATE); |
| 726 } else { | 740 } else { |
| 727 std::string source("delegate"); | 741 std::string source("delegate"); |
| 728 request_->net_log().AddEvent(NetLog::TYPE_CANCELLED, | 742 request_->net_log().AddEvent(NetLog::TYPE_CANCELLED, |
| 729 NetLog::StringCallback("source", | 743 NetLog::StringCallback("source", |
| 730 &source)); | 744 &source)); |
| 731 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, error)); | 745 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, error)); |
| 732 } | 746 } |
| 733 return; | 747 return; |
| 734 } | 748 } |
| 735 } | 749 } |
| 736 | 750 |
| 737 SaveCookiesAndNotifyHeadersComplete(net::OK); | 751 SaveCookiesAndNotifyHeadersComplete(net::OK); |
| 738 } else if (IsCertificateError(result)) { | 752 } else if (IsCertificateError(result)) { |
| 739 // We encountered an SSL certificate error. Ask our delegate to decide | 753 // We encountered an SSL certificate error. Ask our delegate to decide |
| 740 // what we should do. | 754 // what we should do. |
| 741 | 755 |
| 742 TransportSecurityState::DomainState domain_state; | 756 TransportSecurityState::DomainState domain_state; |
| 743 const URLRequestContext* context = request_->context(); | |
| 744 const bool fatal = | 757 const bool fatal = |
| 745 context->transport_security_state() && | 758 transport_security_state_ && |
| 746 context->transport_security_state()->GetDomainState( | 759 transport_security_state_->GetDomainState( |
| 747 request_info_.url.host(), | 760 request_info_.url.host(), |
| 748 SSLConfigService::IsSNIAvailable(context->ssl_config_service()), | 761 SSLConfigService::IsSNIAvailable(ssl_config_service_), |
| 749 &domain_state); | 762 &domain_state); |
| 750 NotifySSLCertificateError(transaction_->GetResponseInfo()->ssl_info, fatal); | 763 NotifySSLCertificateError(transaction_->GetResponseInfo()->ssl_info, fatal); |
| 751 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 764 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
| 752 NotifyCertificateRequested( | 765 NotifyCertificateRequested( |
| 753 transaction_->GetResponseInfo()->cert_request_info); | 766 transaction_->GetResponseInfo()->cert_request_info); |
| 754 } else { | 767 } else { |
| 755 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); | 768 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); |
| 756 } | 769 } |
| 757 } | 770 } |
| 758 | 771 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 830 // plugin could set a referrer although sending the referrer is inhibited. | 843 // plugin could set a referrer although sending the referrer is inhibited. |
| 831 request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer); | 844 request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer); |
| 832 | 845 |
| 833 // Our consumer should have made sure that this is a safe referrer. See for | 846 // Our consumer should have made sure that this is a safe referrer. See for |
| 834 // instance WebCore::FrameLoader::HideReferrer. | 847 // instance WebCore::FrameLoader::HideReferrer. |
| 835 if (referrer.is_valid()) { | 848 if (referrer.is_valid()) { |
| 836 request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer, | 849 request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer, |
| 837 referrer.spec()); | 850 referrer.spec()); |
| 838 } | 851 } |
| 839 | 852 |
| 840 if (request_->context()) { | 853 // TODO(shalev): Fix this to not go through URLRequestContext. |
| 841 request_info_.extra_headers.SetHeaderIfMissing( | 854 request_info_.extra_headers.SetHeaderIfMissing( |
| 842 HttpRequestHeaders::kUserAgent, | 855 HttpRequestHeaders::kUserAgent, |
| 843 request_->context()->GetUserAgent(request_->url())); | 856 request_->context()->GetUserAgent(request_->url())); |
| 844 } | |
| 845 | 857 |
| 846 AddExtraHeaders(); | 858 AddExtraHeaders(); |
| 847 AddCookieHeaderAndStart(); | 859 AddCookieHeaderAndStart(); |
| 848 } | 860 } |
| 849 | 861 |
| 850 void URLRequestHttpJob::Kill() { | 862 void URLRequestHttpJob::Kill() { |
| 851 if (!transaction_.get()) | 863 if (!transaction_.get()) |
| 852 return; | 864 return; |
| 853 | 865 |
| 854 weak_factory_.InvalidateWeakPtrs(); | 866 weak_factory_.InvalidateWeakPtrs(); |
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1431 return override_response_headers_.get() ? | 1443 return override_response_headers_.get() ? |
| 1432 override_response_headers_ : | 1444 override_response_headers_ : |
| 1433 transaction_->GetResponseInfo()->headers; | 1445 transaction_->GetResponseInfo()->headers; |
| 1434 } | 1446 } |
| 1435 | 1447 |
| 1436 void URLRequestHttpJob::NotifyURLRequestDestroyed() { | 1448 void URLRequestHttpJob::NotifyURLRequestDestroyed() { |
| 1437 awaiting_callback_ = false; | 1449 awaiting_callback_ = false; |
| 1438 } | 1450 } |
| 1439 | 1451 |
| 1440 } // namespace net | 1452 } // namespace net |
| OLD | NEW |