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