Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: net/url_request/url_request_http_job.cc

Issue 711753003: Pin dictionaries from being deleted while request is outstanding. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Incorporated comments. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 explicit HttpFilterContext(URLRequestHttpJob* job); 59 explicit HttpFilterContext(URLRequestHttpJob* job);
60 ~HttpFilterContext() override; 60 ~HttpFilterContext() override;
61 61
62 // FilterContext implementation. 62 // FilterContext implementation.
63 bool GetMimeType(std::string* mime_type) const override; 63 bool GetMimeType(std::string* mime_type) const override;
64 bool GetURL(GURL* gurl) const override; 64 bool GetURL(GURL* gurl) const override;
65 bool GetContentDisposition(std::string* disposition) const override; 65 bool GetContentDisposition(std::string* disposition) const override;
66 base::Time GetRequestTime() const override; 66 base::Time GetRequestTime() const override;
67 bool IsCachedContent() const override; 67 bool IsCachedContent() const override;
68 bool IsDownload() const override; 68 bool IsDownload() const override;
69 bool SdchResponseExpected() const override; 69 SdchManager::DictionarySet* SdchDictionariesAdvertised() const override;
70 int64 GetByteReadCount() const override; 70 int64 GetByteReadCount() const override;
71 int GetResponseCode() const override; 71 int GetResponseCode() const override;
72 const URLRequestContext* GetURLRequestContext() const override; 72 const URLRequestContext* GetURLRequestContext() const override;
73 void RecordPacketStats(StatisticSelector statistic) const override; 73 void RecordPacketStats(StatisticSelector statistic) const override;
74 const BoundNetLog& GetNetLog() const override; 74 const BoundNetLog& GetNetLog() const override;
75 75
76 // Method to allow us to reset filter context for a response that should have
77 // been SDCH encoded when there is an update due to an explicit HTTP header.
78 void ResetSdchResponseToFalse();
79
80 private: 76 private:
81 URLRequestHttpJob* job_; 77 URLRequestHttpJob* job_;
82 78
83 // URLRequestHttpJob may be detached from URLRequest, but we still need to 79 // URLRequestHttpJob may be detached from URLRequest, but we still need to
84 // return something. 80 // return something.
85 BoundNetLog dummy_log_; 81 BoundNetLog dummy_log_;
86 82
87 DISALLOW_COPY_AND_ASSIGN(HttpFilterContext); 83 DISALLOW_COPY_AND_ASSIGN(HttpFilterContext);
88 }; 84 };
89 85
(...skipping 29 matching lines...) Expand all
119 } 115 }
120 116
121 bool URLRequestHttpJob::HttpFilterContext::IsCachedContent() const { 117 bool URLRequestHttpJob::HttpFilterContext::IsCachedContent() const {
122 return job_->is_cached_content_; 118 return job_->is_cached_content_;
123 } 119 }
124 120
125 bool URLRequestHttpJob::HttpFilterContext::IsDownload() const { 121 bool URLRequestHttpJob::HttpFilterContext::IsDownload() const {
126 return (job_->request_info_.load_flags & LOAD_IS_DOWNLOAD) != 0; 122 return (job_->request_info_.load_flags & LOAD_IS_DOWNLOAD) != 0;
127 } 123 }
128 124
129 void URLRequestHttpJob::HttpFilterContext::ResetSdchResponseToFalse() { 125 SdchManager::DictionarySet*
130 DCHECK(job_->sdch_dictionary_advertised_); 126 URLRequestHttpJob::HttpFilterContext::SdchDictionariesAdvertised() const {
131 job_->sdch_dictionary_advertised_ = false; 127 return job_->dictionaries_advertised_.get();
132 }
133
134 bool URLRequestHttpJob::HttpFilterContext::SdchResponseExpected() const {
135 return job_->sdch_dictionary_advertised_;
136 } 128 }
137 129
138 int64 URLRequestHttpJob::HttpFilterContext::GetByteReadCount() const { 130 int64 URLRequestHttpJob::HttpFilterContext::GetByteReadCount() const {
139 return job_->filter_input_byte_count(); 131 return job_->filter_input_byte_count();
140 } 132 }
141 133
142 int URLRequestHttpJob::HttpFilterContext::GetResponseCode() const { 134 int URLRequestHttpJob::HttpFilterContext::GetResponseCode() const {
143 return job_->GetResponseCode(); 135 return job_->GetResponseCode();
144 } 136 }
145 137
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 response_cookies_save_index_(0), 185 response_cookies_save_index_(0),
194 proxy_auth_state_(AUTH_STATE_DONT_NEED_AUTH), 186 proxy_auth_state_(AUTH_STATE_DONT_NEED_AUTH),
195 server_auth_state_(AUTH_STATE_DONT_NEED_AUTH), 187 server_auth_state_(AUTH_STATE_DONT_NEED_AUTH),
196 start_callback_(base::Bind(&URLRequestHttpJob::OnStartCompleted, 188 start_callback_(base::Bind(&URLRequestHttpJob::OnStartCompleted,
197 base::Unretained(this))), 189 base::Unretained(this))),
198 notify_before_headers_sent_callback_( 190 notify_before_headers_sent_callback_(
199 base::Bind(&URLRequestHttpJob::NotifyBeforeSendHeadersCallback, 191 base::Bind(&URLRequestHttpJob::NotifyBeforeSendHeadersCallback,
200 base::Unretained(this))), 192 base::Unretained(this))),
201 read_in_progress_(false), 193 read_in_progress_(false),
202 throttling_entry_(NULL), 194 throttling_entry_(NULL),
203 sdch_dictionary_advertised_(false),
204 sdch_test_activated_(false), 195 sdch_test_activated_(false),
205 sdch_test_control_(false), 196 sdch_test_control_(false),
206 is_cached_content_(false), 197 is_cached_content_(false),
207 request_creation_time_(), 198 request_creation_time_(),
208 packet_timing_enabled_(false), 199 packet_timing_enabled_(false),
209 done_(false), 200 done_(false),
210 bytes_observed_in_packets_(0), 201 bytes_observed_in_packets_(0),
211 request_time_snapshot_(), 202 request_time_snapshot_(),
212 final_packet_time_(), 203 final_packet_time_(),
213 filter_context_(new HttpFilterContext(this)), 204 filter_context_(new HttpFilterContext(this)),
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 if (!is_cached_content_ && throttling_entry_.get()) { 314 if (!is_cached_content_ && throttling_entry_.get()) {
324 URLRequestThrottlerHeaderAdapter response_adapter(GetResponseHeaders()); 315 URLRequestThrottlerHeaderAdapter response_adapter(GetResponseHeaders());
325 throttling_entry_->UpdateWithResponse(request_info_.url.host(), 316 throttling_entry_->UpdateWithResponse(request_info_.url.host(),
326 &response_adapter); 317 &response_adapter);
327 } 318 }
328 319
329 // The ordering of these calls is not important. 320 // The ordering of these calls is not important.
330 ProcessStrictTransportSecurityHeader(); 321 ProcessStrictTransportSecurityHeader();
331 ProcessPublicKeyPinsHeader(); 322 ProcessPublicKeyPinsHeader();
332 323
324 // Handle the server notification of a new SDCH dictionary.
333 SdchManager* sdch_manager(request()->context()->sdch_manager()); 325 SdchManager* sdch_manager(request()->context()->sdch_manager());
334 if (sdch_manager) { 326 if (sdch_manager) {
335 SdchProblemCode rv = sdch_manager->IsInSupportedDomain(request()->url()); 327 SdchProblemCode rv = sdch_manager->IsInSupportedDomain(request()->url());
336 if (rv != SDCH_OK) { 328 if (rv != SDCH_OK) {
337 // If SDCH is just disabled, it is not a real error. 329 // If SDCH is just disabled, it is not a real error.
338 if (rv != SDCH_DISABLED && rv != SDCH_SECURE_SCHEME_NOT_SUPPORTED) { 330 if (rv != SDCH_DISABLED && rv != SDCH_SECURE_SCHEME_NOT_SUPPORTED) {
339 SdchManager::SdchErrorRecovery(rv); 331 SdchManager::SdchErrorRecovery(rv);
340 request()->net_log().AddEvent( 332 request()->net_log().AddEvent(
341 NetLog::TYPE_SDCH_DECODING_ERROR, 333 NetLog::TYPE_SDCH_DECODING_ERROR,
342 base::Bind(&NetLogSdchResourceProblemCallback, rv)); 334 base::Bind(&NetLogSdchResourceProblemCallback, rv));
(...skipping 21 matching lines...) Expand all
364 request_->net_log().AddEvent( 356 request_->net_log().AddEvent(
365 NetLog::TYPE_SDCH_DICTIONARY_ERROR, 357 NetLog::TYPE_SDCH_DICTIONARY_ERROR,
366 base::Bind(&NetLogSdchDictionaryFetchProblemCallback, rv, 358 base::Bind(&NetLogSdchDictionaryFetchProblemCallback, rv,
367 sdch_dictionary_url, false)); 359 sdch_dictionary_url, false));
368 } 360 }
369 } 361 }
370 } 362 }
371 } 363 }
372 } 364 }
373 365
366 // Handle the server signalling no SDCH encoding.
367 if (dictionaries_advertised_.get()) {
Ryan Sleevi 2014/11/20 22:50:30 scoped_ptr implements Testable (it's only scoped_r
Randy Smith (Not in Mondays) 2014/11/20 23:44:29 Done.
368 // We are wary of proxies that discard or damage SDCH encoding. If a server
Ryan Sleevi 2014/11/20 22:50:30 *cough* s/. If/. If/
Randy Smith (Not in Mondays) 2014/11/20 23:44:29 *embarrassed amused look* Done. (Throughout CL.)
369 // explicitly states that this is not SDCH content, then we can correct our
370 // assumption that this is an SDCH response, and avoid the need to recover
371 // as though the content is corrupted (when we discover it is not SDCH
372 // encoded).
373 std::string sdch_response_status;
374 void* iter = NULL;
375 while (GetResponseHeaders()->EnumerateHeader(&iter, "X-Sdch-Encode",
376 &sdch_response_status)) {
377 if (sdch_response_status == "0") {
378 dictionaries_advertised_.reset();
379 break;
380 }
381 }
382 }
383
374 // The HTTP transaction may be restarted several times for the purposes 384 // The HTTP transaction may be restarted several times for the purposes
375 // of sending authorization information. Each time it restarts, we get 385 // of sending authorization information. Each time it restarts, we get
376 // notified of the headers completion so that we can update the cookie store. 386 // notified of the headers completion so that we can update the cookie store.
377 if (transaction_->IsReadyToRestartForAuth()) { 387 if (transaction_->IsReadyToRestartForAuth()) {
378 DCHECK(!response_info_->auth_challenge.get()); 388 DCHECK(!response_info_->auth_challenge.get());
379 // TODO(battre): This breaks the webrequest API for 389 // TODO(battre): This breaks the webrequest API for
380 // URLRequestTestHTTP.BasicAuthWithCookies 390 // URLRequestTestHTTP.BasicAuthWithCookies
381 // where OnBeforeSendHeaders -> OnSendHeaders -> OnBeforeSendHeaders 391 // where OnBeforeSendHeaders -> OnSendHeaders -> OnBeforeSendHeaders
382 // occurs. 392 // occurs.
383 RestartTransactionWithAuth(AuthCredentials()); 393 RestartTransactionWithAuth(AuthCredentials());
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 advertise_sdch = false; 535 advertise_sdch = false;
526 // If SDCH is just disabled, it is not a real error. 536 // If SDCH is just disabled, it is not a real error.
527 if (rv != SDCH_DISABLED && rv != SDCH_SECURE_SCHEME_NOT_SUPPORTED) { 537 if (rv != SDCH_DISABLED && rv != SDCH_SECURE_SCHEME_NOT_SUPPORTED) {
528 SdchManager::SdchErrorRecovery(rv); 538 SdchManager::SdchErrorRecovery(rv);
529 request()->net_log().AddEvent( 539 request()->net_log().AddEvent(
530 NetLog::TYPE_SDCH_DECODING_ERROR, 540 NetLog::TYPE_SDCH_DECODING_ERROR,
531 base::Bind(&NetLogSdchResourceProblemCallback, rv)); 541 base::Bind(&NetLogSdchResourceProblemCallback, rv));
532 } 542 }
533 } 543 }
534 } 544 }
535 std::string avail_dictionaries;
536 if (advertise_sdch) { 545 if (advertise_sdch) {
537 sdch_manager->GetAvailDictionaryList(request_->url(), 546 dictionaries_advertised_ =
538 &avail_dictionaries); 547 sdch_manager->GetDictionarySet(request_->url());
548 }
539 549
540 // The AllowLatencyExperiment() is only true if we've successfully done a 550 // The AllowLatencyExperiment() is only true if we've successfully done a
541 // full SDCH compression recently in this browser session for this host. 551 // full SDCH compression recently in this browser session for this host.
542 // Note that for this path, there might be no applicable dictionaries, 552 // Note that for this path, there might be no applicable dictionaries,
543 // and hence we can't participate in the experiment. 553 // and hence we can't participate in the experiment.
544 if (!avail_dictionaries.empty() && 554 if (dictionaries_advertised_.get() &&
Ryan Sleevi 2014/11/20 22:50:30 ditto testability
Randy Smith (Not in Mondays) 2014/11/20 23:44:29 Done.
545 sdch_manager->AllowLatencyExperiment(request_->url())) { 555 sdch_manager->AllowLatencyExperiment(request_->url())) {
546 // We are participating in the test (or control), and hence we'll 556 // We are participating in the test (or control), and hence we'll
547 // eventually record statistics via either SDCH_EXPERIMENT_DECODE or 557 // eventually record statistics via either SDCH_EXPERIMENT_DECODE or
548 // SDCH_EXPERIMENT_HOLDBACK, and we'll need some packet timing data. 558 // SDCH_EXPERIMENT_HOLDBACK, and we'll need some packet timing data.
549 packet_timing_enabled_ = true; 559 packet_timing_enabled_ = true;
550 if (base::RandDouble() < .01) { 560 if (base::RandDouble() < .01) {
551 sdch_test_control_ = true; // 1% probability. 561 sdch_test_control_ = true; // 1% probability.
552 advertise_sdch = false; 562 dictionaries_advertised_.reset();
553 } else { 563 advertise_sdch = false;
554 sdch_test_activated_ = true; 564 } else {
555 } 565 sdch_test_activated_ = true;
556 } 566 }
557 } 567 }
558 568
559 // Supply Accept-Encoding headers first so that it is more likely that they 569 // Supply Accept-Encoding headers first so that it is more likely that they
560 // will be in the first transmitted packet. This can sometimes make it 570 // will be in the first transmitted packet. This can sometimes make it
561 // easier to filter and analyze the streams to assure that a proxy has not 571 // easier to filter and analyze the streams to assure that a proxy has not
562 // damaged these headers. Some proxies deliberately corrupt Accept-Encoding 572 // damaged these headers. Some proxies deliberately corrupt Accept-Encoding
563 // headers. 573 // headers.
564 if (!advertise_sdch) { 574 if (!advertise_sdch) {
565 // Tell the server what compression formats we support (other than SDCH). 575 // Tell the server what compression formats we support (other than SDCH).
566 request_info_.extra_headers.SetHeader( 576 request_info_.extra_headers.SetHeader(
567 HttpRequestHeaders::kAcceptEncoding, "gzip, deflate"); 577 HttpRequestHeaders::kAcceptEncoding, "gzip, deflate");
568 } else { 578 } else {
569 // Include SDCH in acceptable list. 579 // Include SDCH in acceptable list.
570 request_info_.extra_headers.SetHeader( 580 request_info_.extra_headers.SetHeader(
571 HttpRequestHeaders::kAcceptEncoding, "gzip, deflate, sdch"); 581 HttpRequestHeaders::kAcceptEncoding, "gzip, deflate, sdch");
572 if (!avail_dictionaries.empty()) { 582 if (dictionaries_advertised_.get()) {
Ryan Sleevi 2014/11/20 22:50:30 ditto Testability
Randy Smith (Not in Mondays) 2014/11/20 23:44:29 You realize that by not just saying also "elsewher
573 request_info_.extra_headers.SetHeader( 583 request_info_.extra_headers.SetHeader(
574 kAvailDictionaryHeader, 584 kAvailDictionaryHeader,
575 avail_dictionaries); 585 dictionaries_advertised_->GetDictionaryClientHashList());
576 sdch_dictionary_advertised_ = true;
577 // Since we're tagging this transaction as advertising a dictionary, 586 // Since we're tagging this transaction as advertising a dictionary,
578 // we'll definitely employ an SDCH filter (or tentative sdch filter) 587 // we'll definitely employ an SDCH filter (or tentative sdch filter)
579 // when we get a response. When done, we'll record histograms via 588 // when we get a response. When done, we'll record histograms via
580 // SDCH_DECODE or SDCH_PASSTHROUGH. Hence we need to record packet 589 // SDCH_DECODE or SDCH_PASSTHROUGH. Hence we need to record packet
581 // arrival times. 590 // arrival times.
582 packet_timing_enabled_ = true; 591 packet_timing_enabled_ = true;
583 } 592 }
584 } 593 }
585 } 594 }
586 595
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 return NULL; 1074 return NULL;
1066 1075
1067 std::vector<Filter::FilterType> encoding_types; 1076 std::vector<Filter::FilterType> encoding_types;
1068 std::string encoding_type; 1077 std::string encoding_type;
1069 HttpResponseHeaders* headers = GetResponseHeaders(); 1078 HttpResponseHeaders* headers = GetResponseHeaders();
1070 void* iter = NULL; 1079 void* iter = NULL;
1071 while (headers->EnumerateHeader(&iter, "Content-Encoding", &encoding_type)) { 1080 while (headers->EnumerateHeader(&iter, "Content-Encoding", &encoding_type)) {
1072 encoding_types.push_back(Filter::ConvertEncodingToType(encoding_type)); 1081 encoding_types.push_back(Filter::ConvertEncodingToType(encoding_type));
1073 } 1082 }
1074 1083
1075 if (filter_context_->SdchResponseExpected()) {
1076 // We are wary of proxies that discard or damage SDCH encoding. If a server
1077 // explicitly states that this is not SDCH content, then we can correct our
1078 // assumption that this is an SDCH response, and avoid the need to recover
1079 // as though the content is corrupted (when we discover it is not SDCH
1080 // encoded).
1081 std::string sdch_response_status;
1082 iter = NULL;
1083 while (headers->EnumerateHeader(&iter, "X-Sdch-Encode",
1084 &sdch_response_status)) {
1085 if (sdch_response_status == "0") {
1086 filter_context_->ResetSdchResponseToFalse();
1087 break;
1088 }
1089 }
1090 }
1091
1092 // Even if encoding types are empty, there is a chance that we need to add 1084 // Even if encoding types are empty, there is a chance that we need to add
1093 // some decoding, as some proxies strip encoding completely. In such cases, 1085 // some decoding, as some proxies strip encoding completely. In such cases,
1094 // we may need to add (for example) SDCH filtering (when the context suggests 1086 // we may need to add (for example) SDCH filtering (when the context suggests
1095 // it is appropriate). 1087 // it is appropriate).
1096 Filter::FixupEncodingTypes(*filter_context_, &encoding_types); 1088 Filter::FixupEncodingTypes(*filter_context_, &encoding_types);
1097 1089
1098 return !encoding_types.empty() 1090 return !encoding_types.empty()
1099 ? Filter::Factory(encoding_types, *filter_context_) : NULL; 1091 ? Filter::Factory(encoding_types, *filter_context_) : NULL;
1100 } 1092 }
1101 1093
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
1570 return override_response_headers_.get() ? 1562 return override_response_headers_.get() ?
1571 override_response_headers_.get() : 1563 override_response_headers_.get() :
1572 transaction_->GetResponseInfo()->headers.get(); 1564 transaction_->GetResponseInfo()->headers.get();
1573 } 1565 }
1574 1566
1575 void URLRequestHttpJob::NotifyURLRequestDestroyed() { 1567 void URLRequestHttpJob::NotifyURLRequestDestroyed() {
1576 awaiting_callback_ = false; 1568 awaiting_callback_ = false;
1577 } 1569 }
1578 1570
1579 } // namespace net 1571 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698