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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 // Privacy mode could still be disabled in OnCookiesLoaded if we are going | 257 // Privacy mode could still be disabled in OnCookiesLoaded if we are going |
267 // to send previously saved cookies. | 258 // to send previously saved cookies. |
268 request_info_.privacy_mode = enable_privacy_mode ? | 259 request_info_.privacy_mode = enable_privacy_mode ? |
269 PRIVACY_MODE_ENABLED : PRIVACY_MODE_DISABLED; | 260 PRIVACY_MODE_ENABLED : PRIVACY_MODE_DISABLED; |
270 | 261 |
271 // Strip Referer from request_info_.extra_headers to prevent, e.g., plugins | 262 // Strip Referer from request_info_.extra_headers to prevent, e.g., plugins |
272 // from overriding headers that are controlled using other means. Otherwise a | 263 // from overriding headers that are controlled using other means. Otherwise a |
273 // plugin could set a referrer although sending the referrer is inhibited. | 264 // plugin could set a referrer although sending the referrer is inhibited. |
274 request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer); | 265 request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer); |
275 | 266 |
276 // Our consumer should have made sure that this is a safe referrer. See for | 267 // Our consumer should have made sure that this is a safe referrer. See for |
277 // instance WebCore::FrameLoader::HideReferrer. | 268 // instance WebCore::FrameLoader::HideReferrer. |
278 if (referrer.is_valid()) { | 269 if (referrer.is_valid()) { |
279 request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer, | 270 request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer, |
280 referrer.spec()); | 271 referrer.spec()); |
281 } | 272 } |
282 | 273 |
283 request_info_.extra_headers.SetHeaderIfMissing( | 274 request_info_.extra_headers.SetHeaderIfMissing( |
284 HttpRequestHeaders::kUserAgent, | 275 HttpRequestHeaders::kUserAgent, |
285 http_user_agent_settings_ ? | 276 http_user_agent_settings_ ? |
286 http_user_agent_settings_->GetUserAgent() : std::string()); | 277 http_user_agent_settings_->GetUserAgent() : std::string()); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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_) { |
| 368 // We are wary of proxies that discard or damage SDCH encoding. If a server |
| 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 Loading... |
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_ && |
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_) { |
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 |
587 if (http_user_agent_settings_) { | 596 if (http_user_agent_settings_) { |
588 // Only add default Accept-Language if the request didn't have it | 597 // Only add default Accept-Language if the request didn't have it |
589 // specified. | 598 // specified. |
590 std::string accept_language = | 599 std::string accept_language = |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1022 | 1031 |
1023 *info = *response_info_; | 1032 *info = *response_info_; |
1024 if (override_response_headers_.get()) | 1033 if (override_response_headers_.get()) |
1025 info->headers = override_response_headers_; | 1034 info->headers = override_response_headers_; |
1026 } | 1035 } |
1027 } | 1036 } |
1028 | 1037 |
1029 void URLRequestHttpJob::GetLoadTimingInfo( | 1038 void URLRequestHttpJob::GetLoadTimingInfo( |
1030 LoadTimingInfo* load_timing_info) const { | 1039 LoadTimingInfo* load_timing_info) const { |
1031 // If haven't made it far enough to receive any headers, don't return | 1040 // If haven't made it far enough to receive any headers, don't return |
1032 // anything. This makes for more consistent behavior in the case of errors. | 1041 // anything. This makes for more consistent behavior in the case of errors. |
1033 if (!transaction_ || receive_headers_end_.is_null()) | 1042 if (!transaction_ || receive_headers_end_.is_null()) |
1034 return; | 1043 return; |
1035 if (transaction_->GetLoadTimingInfo(load_timing_info)) | 1044 if (transaction_->GetLoadTimingInfo(load_timing_info)) |
1036 load_timing_info->receive_headers_end = receive_headers_end_; | 1045 load_timing_info->receive_headers_end = receive_headers_end_; |
1037 } | 1046 } |
1038 | 1047 |
1039 bool URLRequestHttpJob::GetResponseCookies(std::vector<std::string>* cookies) { | 1048 bool URLRequestHttpJob::GetResponseCookies(std::vector<std::string>* cookies) { |
1040 DCHECK(transaction_.get()); | 1049 DCHECK(transaction_.get()); |
1041 | 1050 |
1042 if (!response_info_) | 1051 if (!response_info_) |
(...skipping 22 matching lines...) Expand all Loading... |
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 23 matching lines...) Expand all Loading... |
1125 // redirect to. | 1117 // redirect to. |
1126 return request_->context()->job_factory() && | 1118 return request_->context()->job_factory() && |
1127 request_->context()->job_factory()->IsSafeRedirectTarget(location); | 1119 request_->context()->job_factory()->IsSafeRedirectTarget(location); |
1128 } | 1120 } |
1129 | 1121 |
1130 bool URLRequestHttpJob::NeedsAuth() { | 1122 bool URLRequestHttpJob::NeedsAuth() { |
1131 int code = GetResponseCode(); | 1123 int code = GetResponseCode(); |
1132 if (code == -1) | 1124 if (code == -1) |
1133 return false; | 1125 return false; |
1134 | 1126 |
1135 // Check if we need either Proxy or WWW Authentication. This could happen | 1127 // Check if we need either Proxy or WWW Authentication. This could happen |
1136 // because we either provided no auth info, or provided incorrect info. | 1128 // because we either provided no auth info, or provided incorrect info. |
1137 switch (code) { | 1129 switch (code) { |
1138 case 407: | 1130 case 407: |
1139 if (proxy_auth_state_ == AUTH_STATE_CANCELED) | 1131 if (proxy_auth_state_ == AUTH_STATE_CANCELED) |
1140 return false; | 1132 return false; |
1141 proxy_auth_state_ = AUTH_STATE_NEED_AUTH; | 1133 proxy_auth_state_ = AUTH_STATE_NEED_AUTH; |
1142 return true; | 1134 return true; |
1143 case 401: | 1135 case 401: |
1144 if (server_auth_state_ == AUTH_STATE_CANCELED) | 1136 if (server_auth_state_ == AUTH_STATE_CANCELED) |
1145 return false; | 1137 return false; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1259 weak_factory_.GetWeakPtr(), rv)); | 1251 weak_factory_.GetWeakPtr(), rv)); |
1260 } | 1252 } |
1261 | 1253 |
1262 void URLRequestHttpJob::ResumeNetworkStart() { | 1254 void URLRequestHttpJob::ResumeNetworkStart() { |
1263 DCHECK(transaction_.get()); | 1255 DCHECK(transaction_.get()); |
1264 transaction_->ResumeNetworkStart(); | 1256 transaction_->ResumeNetworkStart(); |
1265 } | 1257 } |
1266 | 1258 |
1267 bool URLRequestHttpJob::ShouldFixMismatchedContentLength(int rv) const { | 1259 bool URLRequestHttpJob::ShouldFixMismatchedContentLength(int rv) const { |
1268 // Some servers send the body compressed, but specify the content length as | 1260 // Some servers send the body compressed, but specify the content length as |
1269 // the uncompressed size. Although this violates the HTTP spec we want to | 1261 // the uncompressed size. Although this violates the HTTP spec we want to |
1270 // support it (as IE and FireFox do), but *only* for an exact match. | 1262 // support it (as IE and FireFox do), but *only* for an exact match. |
1271 // See http://crbug.com/79694. | 1263 // See http://crbug.com/79694. |
1272 if (rv == net::ERR_CONTENT_LENGTH_MISMATCH || | 1264 if (rv == net::ERR_CONTENT_LENGTH_MISMATCH || |
1273 rv == net::ERR_INCOMPLETE_CHUNKED_ENCODING) { | 1265 rv == net::ERR_INCOMPLETE_CHUNKED_ENCODING) { |
1274 if (request_ && request_->response_headers()) { | 1266 if (request_ && request_->response_headers()) { |
1275 int64 expected_length = request_->response_headers()->GetContentLength(); | 1267 int64 expected_length = request_->response_headers()->GetContentLength(); |
1276 VLOG(1) << __FUNCTION__ << "() " | 1268 VLOG(1) << __FUNCTION__ << "() " |
1277 << "\"" << request_->url().spec() << "\"" | 1269 << "\"" << request_->url().spec() << "\"" |
1278 << " content-length = " << expected_length | 1270 << " content-length = " << expected_length |
1279 << " pre total = " << prefilter_bytes_read() | 1271 << " pre total = " << prefilter_bytes_read() |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1454 DCHECK(request_); | 1446 DCHECK(request_); |
1455 if (!request_) | 1447 if (!request_) |
1456 return; | 1448 return; |
1457 | 1449 |
1458 if (is_cached_content_ || // Don't record cached content | 1450 if (is_cached_content_ || // Don't record cached content |
1459 !GetStatus().is_success() || // Don't record failed content | 1451 !GetStatus().is_success() || // Don't record failed content |
1460 !IsCompressibleContent() || // Only record compressible content | 1452 !IsCompressibleContent() || // Only record compressible content |
1461 !prefilter_bytes_read()) // Zero-byte responses aren't useful. | 1453 !prefilter_bytes_read()) // Zero-byte responses aren't useful. |
1462 return; | 1454 return; |
1463 | 1455 |
1464 // Miniature requests aren't really compressible. Don't count them. | 1456 // Miniature requests aren't really compressible. Don't count them. |
1465 const int kMinSize = 16; | 1457 const int kMinSize = 16; |
1466 if (prefilter_bytes_read() < kMinSize) | 1458 if (prefilter_bytes_read() < kMinSize) |
1467 return; | 1459 return; |
1468 | 1460 |
1469 // Only record for http or https urls. | 1461 // Only record for http or https urls. |
1470 bool is_http = request_->url().SchemeIs("http"); | 1462 bool is_http = request_->url().SchemeIs("http"); |
1471 bool is_https = request_->url().SchemeIs("https"); | 1463 bool is_https = request_->url().SchemeIs("https"); |
1472 if (!is_http && !is_https) | 1464 if (!is_http && !is_https) |
1473 return; | 1465 return; |
1474 | 1466 |
1475 int compressed_B = prefilter_bytes_read(); | 1467 int compressed_B = prefilter_bytes_read(); |
1476 int decompressed_B = postfilter_bytes_read(); | 1468 int decompressed_B = postfilter_bytes_read(); |
1477 bool was_filtered = HasFilter(); | 1469 bool was_filtered = HasFilter(); |
1478 | 1470 |
1479 // We want to record how often downloaded resources are compressed. | 1471 // We want to record how often downloaded resources are compressed. |
1480 // But, we recognize that different protocols may have different | 1472 // But, we recognize that different protocols may have different |
1481 // properties. So, for each request, we'll put it into one of 3 | 1473 // properties. So, for each request, we'll put it into one of 3 |
1482 // groups: | 1474 // groups: |
1483 // a) SSL resources | 1475 // a) SSL resources |
1484 // Proxies cannot tamper with compression headers with SSL. | 1476 // Proxies cannot tamper with compression headers with SSL. |
1485 // b) Non-SSL, loaded-via-proxy resources | 1477 // b) Non-SSL, loaded-via-proxy resources |
1486 // In this case, we know a proxy might have interfered. | 1478 // In this case, we know a proxy might have interfered. |
1487 // c) Non-SSL, loaded-without-proxy resources | 1479 // c) Non-SSL, loaded-without-proxy resources |
1488 // In this case, we know there was no explicit proxy. However, | 1480 // In this case, we know there was no explicit proxy. However, |
1489 // it is possible that a transparent proxy was still interfering. | 1481 // it is possible that a transparent proxy was still interfering. |
1490 // | 1482 // |
1491 // For each group, we record the same 3 histograms. | 1483 // For each group, we record the same 3 histograms. |
1492 | 1484 |
1493 if (is_https) { | 1485 if (is_https) { |
1494 if (was_filtered) { | 1486 if (was_filtered) { |
1495 COMPRESSION_HISTOGRAM("SSL.BytesBeforeCompression", compressed_B); | 1487 COMPRESSION_HISTOGRAM("SSL.BytesBeforeCompression", compressed_B); |
1496 COMPRESSION_HISTOGRAM("SSL.BytesAfterCompression", decompressed_B); | 1488 COMPRESSION_HISTOGRAM("SSL.BytesAfterCompression", decompressed_B); |
1497 } else { | 1489 } else { |
1498 COMPRESSION_HISTOGRAM("SSL.ShouldHaveBeenCompressed", decompressed_B); | 1490 COMPRESSION_HISTOGRAM("SSL.ShouldHaveBeenCompressed", decompressed_B); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 |
OLD | NEW |