| 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 15 matching lines...) Expand all  Loading... | 
| 26 #include "net/base/load_flags.h" | 26 #include "net/base/load_flags.h" | 
| 27 #include "net/base/net_errors.h" | 27 #include "net/base/net_errors.h" | 
| 28 #include "net/base/network_delegate.h" | 28 #include "net/base/network_delegate.h" | 
| 29 #include "net/base/network_quality_estimator.h" | 29 #include "net/base/network_quality_estimator.h" | 
| 30 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 30 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 
| 31 #include "net/base/sdch_manager.h" | 31 #include "net/base/sdch_manager.h" | 
| 32 #include "net/base/sdch_net_log_params.h" | 32 #include "net/base/sdch_net_log_params.h" | 
| 33 #include "net/base/url_util.h" | 33 #include "net/base/url_util.h" | 
| 34 #include "net/cert/cert_status_flags.h" | 34 #include "net/cert/cert_status_flags.h" | 
| 35 #include "net/cookies/cookie_store.h" | 35 #include "net/cookies/cookie_store.h" | 
|  | 36 #include "net/filter/stream_source_util.h" | 
| 36 #include "net/http/http_content_disposition.h" | 37 #include "net/http/http_content_disposition.h" | 
| 37 #include "net/http/http_network_session.h" | 38 #include "net/http/http_network_session.h" | 
| 38 #include "net/http/http_request_headers.h" | 39 #include "net/http/http_request_headers.h" | 
| 39 #include "net/http/http_response_headers.h" | 40 #include "net/http/http_response_headers.h" | 
| 40 #include "net/http/http_response_info.h" | 41 #include "net/http/http_response_info.h" | 
| 41 #include "net/http/http_status_code.h" | 42 #include "net/http/http_status_code.h" | 
| 42 #include "net/http/http_transaction.h" | 43 #include "net/http/http_transaction.h" | 
| 43 #include "net/http/http_transaction_factory.h" | 44 #include "net/http/http_transaction_factory.h" | 
| 44 #include "net/http/http_util.h" | 45 #include "net/http/http_util.h" | 
| 45 #include "net/proxy/proxy_info.h" | 46 #include "net/proxy/proxy_info.h" | 
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 154     ephemerality = PERSISTENT_MISMATCH; | 155     ephemerality = PERSISTENT_MISMATCH; | 
| 155   } | 156   } | 
| 156   UMA_HISTOGRAM_ENUMERATION("Net.TokenBinding.StoreEphemerality", ephemerality, | 157   UMA_HISTOGRAM_ENUMERATION("Net.TokenBinding.StoreEphemerality", ephemerality, | 
| 157                             EPHEMERALITY_MAX); | 158                             EPHEMERALITY_MAX); | 
| 158 } | 159 } | 
| 159 | 160 | 
| 160 }  // namespace | 161 }  // namespace | 
| 161 | 162 | 
| 162 namespace net { | 163 namespace net { | 
| 163 | 164 | 
| 164 class URLRequestHttpJob::HttpFilterContext : public FilterContext { |  | 
| 165  public: |  | 
| 166   explicit HttpFilterContext(URLRequestHttpJob* job); |  | 
| 167   ~HttpFilterContext() override; |  | 
| 168 |  | 
| 169   // FilterContext implementation. |  | 
| 170   bool GetMimeType(std::string* mime_type) const override; |  | 
| 171   bool GetURL(GURL* gurl) const override; |  | 
| 172   base::Time GetRequestTime() const override; |  | 
| 173   bool IsCachedContent() const override; |  | 
| 174   SdchManager::DictionarySet* SdchDictionariesAdvertised() const override; |  | 
| 175   int64_t GetByteReadCount() const override; |  | 
| 176   int GetResponseCode() const override; |  | 
| 177   const URLRequestContext* GetURLRequestContext() const override; |  | 
| 178   void RecordPacketStats(StatisticSelector statistic) const override; |  | 
| 179   const BoundNetLog& GetNetLog() const override; |  | 
| 180 |  | 
| 181  private: |  | 
| 182   URLRequestHttpJob* job_; |  | 
| 183 |  | 
| 184   // URLRequestHttpJob may be detached from URLRequest, but we still need to |  | 
| 185   // return something. |  | 
| 186   BoundNetLog dummy_log_; |  | 
| 187 |  | 
| 188   DISALLOW_COPY_AND_ASSIGN(HttpFilterContext); |  | 
| 189 }; |  | 
| 190 |  | 
| 191 URLRequestHttpJob::HttpFilterContext::HttpFilterContext(URLRequestHttpJob* job) |  | 
| 192     : job_(job) { |  | 
| 193   DCHECK(job_); |  | 
| 194 } |  | 
| 195 |  | 
| 196 URLRequestHttpJob::HttpFilterContext::~HttpFilterContext() { |  | 
| 197 } |  | 
| 198 |  | 
| 199 bool URLRequestHttpJob::HttpFilterContext::GetMimeType( |  | 
| 200     std::string* mime_type) const { |  | 
| 201   return job_->GetMimeType(mime_type); |  | 
| 202 } |  | 
| 203 |  | 
| 204 bool URLRequestHttpJob::HttpFilterContext::GetURL(GURL* gurl) const { |  | 
| 205   if (!job_->request()) |  | 
| 206     return false; |  | 
| 207   *gurl = job_->request()->url(); |  | 
| 208   return true; |  | 
| 209 } |  | 
| 210 |  | 
| 211 base::Time URLRequestHttpJob::HttpFilterContext::GetRequestTime() const { |  | 
| 212   return job_->request() ? job_->request()->request_time() : base::Time(); |  | 
| 213 } |  | 
| 214 |  | 
| 215 bool URLRequestHttpJob::HttpFilterContext::IsCachedContent() const { |  | 
| 216   return job_->is_cached_content_; |  | 
| 217 } |  | 
| 218 |  | 
| 219 SdchManager::DictionarySet* |  | 
| 220 URLRequestHttpJob::HttpFilterContext::SdchDictionariesAdvertised() const { |  | 
| 221   return job_->dictionaries_advertised_.get(); |  | 
| 222 } |  | 
| 223 |  | 
| 224 int64_t URLRequestHttpJob::HttpFilterContext::GetByteReadCount() const { |  | 
| 225   return job_->prefilter_bytes_read(); |  | 
| 226 } |  | 
| 227 |  | 
| 228 int URLRequestHttpJob::HttpFilterContext::GetResponseCode() const { |  | 
| 229   return job_->GetResponseCode(); |  | 
| 230 } |  | 
| 231 |  | 
| 232 const URLRequestContext* |  | 
| 233 URLRequestHttpJob::HttpFilterContext::GetURLRequestContext() const { |  | 
| 234   return job_->request() ? job_->request()->context() : NULL; |  | 
| 235 } |  | 
| 236 |  | 
| 237 void URLRequestHttpJob::HttpFilterContext::RecordPacketStats( |  | 
| 238     StatisticSelector statistic) const { |  | 
| 239   job_->RecordPacketStats(statistic); |  | 
| 240 } |  | 
| 241 |  | 
| 242 const BoundNetLog& URLRequestHttpJob::HttpFilterContext::GetNetLog() const { |  | 
| 243   return job_->request() ? job_->request()->net_log() : dummy_log_; |  | 
| 244 } |  | 
| 245 |  | 
| 246 // TODO(darin): make sure the port blocking code is not lost | 165 // TODO(darin): make sure the port blocking code is not lost | 
| 247 // static | 166 // static | 
| 248 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, | 167 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, | 
| 249                                           NetworkDelegate* network_delegate, | 168                                           NetworkDelegate* network_delegate, | 
| 250                                           const std::string& scheme) { | 169                                           const std::string& scheme) { | 
| 251   DCHECK(scheme == "http" || scheme == "https" || scheme == "ws" || | 170   DCHECK(scheme == "http" || scheme == "https" || scheme == "ws" || | 
| 252          scheme == "wss"); | 171          scheme == "wss"); | 
| 253 | 172 | 
| 254   if (!request->context()->http_transaction_factory()) { | 173   if (!request->context()->http_transaction_factory()) { | 
| 255     NOTREACHED() << "requires a valid context"; | 174     NOTREACHED() << "requires a valid context"; | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 287       throttling_entry_(nullptr), | 206       throttling_entry_(nullptr), | 
| 288       sdch_test_activated_(false), | 207       sdch_test_activated_(false), | 
| 289       sdch_test_control_(false), | 208       sdch_test_control_(false), | 
| 290       is_cached_content_(false), | 209       is_cached_content_(false), | 
| 291       request_creation_time_(), | 210       request_creation_time_(), | 
| 292       packet_timing_enabled_(false), | 211       packet_timing_enabled_(false), | 
| 293       done_(false), | 212       done_(false), | 
| 294       bytes_observed_in_packets_(0), | 213       bytes_observed_in_packets_(0), | 
| 295       request_time_snapshot_(), | 214       request_time_snapshot_(), | 
| 296       final_packet_time_(), | 215       final_packet_time_(), | 
| 297       filter_context_(new HttpFilterContext(this)), |  | 
| 298       on_headers_received_callback_( | 216       on_headers_received_callback_( | 
| 299           base::Bind(&URLRequestHttpJob::OnHeadersReceivedCallback, | 217           base::Bind(&URLRequestHttpJob::OnHeadersReceivedCallback, | 
| 300                      base::Unretained(this))), | 218                      base::Unretained(this))), | 
| 301       awaiting_callback_(false), | 219       awaiting_callback_(false), | 
| 302       http_user_agent_settings_(http_user_agent_settings), | 220       http_user_agent_settings_(http_user_agent_settings), | 
| 303       backoff_manager_(request->context()->backoff_manager()), | 221       backoff_manager_(request->context()->backoff_manager()), | 
| 304       total_received_bytes_from_previous_transactions_(0), | 222       total_received_bytes_from_previous_transactions_(0), | 
| 305       total_sent_bytes_from_previous_transactions_(0), | 223       total_sent_bytes_from_previous_transactions_(0), | 
| 306       weak_factory_(this) { | 224       weak_factory_(this) { | 
| 307   URLRequestThrottlerManager* manager = request->context()->throttler_manager(); | 225   URLRequestThrottlerManager* manager = request->context()->throttler_manager(); | 
| 308   if (manager) | 226   if (manager) | 
| 309     throttling_entry_ = manager->RegisterRequestUrl(request->url()); | 227     throttling_entry_ = manager->RegisterRequestUrl(request->url()); | 
| 310 | 228 | 
| 311   ResetTimer(); | 229   ResetTimer(); | 
| 312 } | 230 } | 
| 313 | 231 | 
| 314 URLRequestHttpJob::~URLRequestHttpJob() { | 232 URLRequestHttpJob::~URLRequestHttpJob() { | 
| 315   CHECK(!awaiting_callback_); | 233   CHECK(!awaiting_callback_); | 
| 316 | 234 | 
|  | 235 // FIXME: FilterContext is gone. How should we handle SDCH stats??? | 
|  | 236 #if 0 | 
| 317   DCHECK(!sdch_test_control_ || !sdch_test_activated_); | 237   DCHECK(!sdch_test_control_ || !sdch_test_activated_); | 
| 318   if (!is_cached_content_) { | 238   if (!is_cached_content_) { | 
| 319     if (sdch_test_control_) | 239     if (sdch_test_control_) | 
| 320       RecordPacketStats(FilterContext::SDCH_EXPERIMENT_HOLDBACK); | 240       RecordPacketStats(FilterContext::SDCH_EXPERIMENT_HOLDBACK); | 
| 321     if (sdch_test_activated_) | 241     if (sdch_test_activated_) | 
| 322       RecordPacketStats(FilterContext::SDCH_EXPERIMENT_DECODE); | 242       RecordPacketStats(FilterContext::SDCH_EXPERIMENT_DECODE); | 
| 323   } | 243   } | 
|  | 244 #endif | 
| 324   // Make sure SDCH filters are told to emit histogram data while | 245   // Make sure SDCH filters are told to emit histogram data while | 
| 325   // filter_context_ is still alive. | 246   // filter_context_ is still alive. | 
| 326   DestroyFilters(); | 247   // DestroyFilters(); | 
| 327 | 248 | 
| 328   DoneWithRequest(ABORTED); | 249   DoneWithRequest(ABORTED); | 
| 329 } | 250 } | 
| 330 | 251 | 
| 331 void URLRequestHttpJob::SetPriority(RequestPriority priority) { | 252 void URLRequestHttpJob::SetPriority(RequestPriority priority) { | 
| 332   priority_ = priority; | 253   priority_ = priority; | 
| 333   if (transaction_) | 254   if (transaction_) | 
| 334     transaction_->SetPriority(priority_); | 255     transaction_->SetPriority(priority_); | 
| 335 } | 256 } | 
| 336 | 257 | 
| (...skipping 884 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1221   return GetResponseHeaders()->response_code(); | 1142   return GetResponseHeaders()->response_code(); | 
| 1222 } | 1143 } | 
| 1223 | 1144 | 
| 1224 void URLRequestHttpJob::PopulateNetErrorDetails( | 1145 void URLRequestHttpJob::PopulateNetErrorDetails( | 
| 1225     NetErrorDetails* details) const { | 1146     NetErrorDetails* details) const { | 
| 1226   if (!transaction_) | 1147   if (!transaction_) | 
| 1227     return; | 1148     return; | 
| 1228   return transaction_->PopulateNetErrorDetails(details); | 1149   return transaction_->PopulateNetErrorDetails(details); | 
| 1229 } | 1150 } | 
| 1230 | 1151 | 
| 1231 Filter* URLRequestHttpJob::SetupFilter() const { | 1152 std::unique_ptr<StreamSource> URLRequestHttpJob::SetupSource() { | 
| 1232   DCHECK(transaction_.get()); | 1153   DCHECK(transaction_.get()); | 
| 1233   if (!response_info_) | 1154   if (!response_info_) | 
| 1234     return NULL; | 1155     return nullptr; | 
| 1235 | 1156 | 
| 1236   std::vector<Filter::FilterType> encoding_types; | 1157   return StreamSourceUtil::BuildSourceChain(URLRequestJob::SetupSource(), | 
| 1237   std::string encoding_type; | 1158                                             GetResponseHeaders()); | 
| 1238   HttpResponseHeaders* headers = GetResponseHeaders(); |  | 
| 1239   size_t iter = 0; |  | 
| 1240   while (headers->EnumerateHeader(&iter, "Content-Encoding", &encoding_type)) { |  | 
| 1241     encoding_types.push_back(Filter::ConvertEncodingToType(encoding_type)); |  | 
| 1242   } |  | 
| 1243 |  | 
| 1244   // Even if encoding types are empty, there is a chance that we need to add |  | 
| 1245   // some decoding, as some proxies strip encoding completely. In such cases, |  | 
| 1246   // we may need to add (for example) SDCH filtering (when the context suggests |  | 
| 1247   // it is appropriate). |  | 
| 1248   Filter::FixupEncodingTypes(*filter_context_, &encoding_types); |  | 
| 1249 |  | 
| 1250   return !encoding_types.empty() |  | 
| 1251       ? Filter::Factory(encoding_types, *filter_context_) : NULL; |  | 
| 1252 } | 1159 } | 
| 1253 | 1160 | 
| 1254 bool URLRequestHttpJob::CopyFragmentOnRedirect(const GURL& location) const { | 1161 bool URLRequestHttpJob::CopyFragmentOnRedirect(const GURL& location) const { | 
| 1255   // Allow modification of reference fragments by default, unless | 1162   // Allow modification of reference fragments by default, unless | 
| 1256   // |allowed_unsafe_redirect_url_| is set and equal to the redirect URL. | 1163   // |allowed_unsafe_redirect_url_| is set and equal to the redirect URL. | 
| 1257   // When this is the case, we assume that the network delegate has set the | 1164   // When this is the case, we assume that the network delegate has set the | 
| 1258   // desired redirect URL (with or without fragment), so it must not be changed | 1165   // desired redirect URL (with or without fragment), so it must not be changed | 
| 1259   // any more. | 1166   // any more. | 
| 1260   return !allowed_unsafe_redirect_url_.is_valid() || | 1167   return !allowed_unsafe_redirect_url_.is_valid() || | 
| 1261        allowed_unsafe_redirect_url_ != location; | 1168        allowed_unsafe_redirect_url_ != location; | 
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1536   DCHECK_GT(prefilter_bytes_read(), bytes_observed_in_packets_); | 1443   DCHECK_GT(prefilter_bytes_read(), bytes_observed_in_packets_); | 
| 1537 | 1444 | 
| 1538   base::Time now(base::Time::Now()); | 1445   base::Time now(base::Time::Now()); | 
| 1539   if (!bytes_observed_in_packets_) | 1446   if (!bytes_observed_in_packets_) | 
| 1540     request_time_snapshot_ = now; | 1447     request_time_snapshot_ = now; | 
| 1541   final_packet_time_ = now; | 1448   final_packet_time_ = now; | 
| 1542 | 1449 | 
| 1543   bytes_observed_in_packets_ = prefilter_bytes_read(); | 1450   bytes_observed_in_packets_ = prefilter_bytes_read(); | 
| 1544 } | 1451 } | 
| 1545 | 1452 | 
| 1546 void URLRequestHttpJob::RecordPacketStats( |  | 
| 1547     FilterContext::StatisticSelector statistic) const { |  | 
| 1548   if (!packet_timing_enabled_ || (final_packet_time_ == base::Time())) |  | 
| 1549     return; |  | 
| 1550 |  | 
| 1551   base::TimeDelta duration = final_packet_time_ - request_time_snapshot_; |  | 
| 1552   switch (statistic) { |  | 
| 1553     case FilterContext::SDCH_DECODE: { |  | 
| 1554       UMA_HISTOGRAM_CUSTOM_COUNTS("Sdch3.Network_Decode_Bytes_Processed_b", |  | 
| 1555           static_cast<int>(bytes_observed_in_packets_), 500, 100000, 100); |  | 
| 1556       return; |  | 
| 1557     } |  | 
| 1558     case FilterContext::SDCH_PASSTHROUGH: { |  | 
| 1559       // Despite advertising a dictionary, we handled non-sdch compressed |  | 
| 1560       // content. |  | 
| 1561       return; |  | 
| 1562     } |  | 
| 1563 |  | 
| 1564     case FilterContext::SDCH_EXPERIMENT_DECODE: { |  | 
| 1565       UMA_HISTOGRAM_CUSTOM_TIMES("Sdch3.Experiment3_Decode", |  | 
| 1566                                   duration, |  | 
| 1567                                   base::TimeDelta::FromMilliseconds(20), |  | 
| 1568                                   base::TimeDelta::FromMinutes(10), 100); |  | 
| 1569       return; |  | 
| 1570     } |  | 
| 1571     case FilterContext::SDCH_EXPERIMENT_HOLDBACK: { |  | 
| 1572       UMA_HISTOGRAM_CUSTOM_TIMES("Sdch3.Experiment3_Holdback", |  | 
| 1573                                   duration, |  | 
| 1574                                   base::TimeDelta::FromMilliseconds(20), |  | 
| 1575                                   base::TimeDelta::FromMinutes(10), 100); |  | 
| 1576       return; |  | 
| 1577     } |  | 
| 1578     default: |  | 
| 1579       NOTREACHED(); |  | 
| 1580       return; |  | 
| 1581   } |  | 
| 1582 } |  | 
| 1583 |  | 
| 1584 void URLRequestHttpJob::RecordPerfHistograms(CompletionCause reason) { | 1453 void URLRequestHttpJob::RecordPerfHistograms(CompletionCause reason) { | 
| 1585   if (start_time_.is_null()) | 1454   if (start_time_.is_null()) | 
| 1586     return; | 1455     return; | 
| 1587 | 1456 | 
| 1588   base::TimeDelta total_time = base::TimeTicks::Now() - start_time_; | 1457   base::TimeDelta total_time = base::TimeTicks::Now() - start_time_; | 
| 1589   UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTime", total_time); | 1458   UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTime", total_time); | 
| 1590 | 1459 | 
| 1591   if (reason == FINISHED) { | 1460   if (reason == FINISHED) { | 
| 1592     UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeSuccess", total_time); | 1461     UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeSuccess", total_time); | 
| 1593   } else { | 1462   } else { | 
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1665   return override_response_headers_.get() ? | 1534   return override_response_headers_.get() ? | 
| 1666              override_response_headers_.get() : | 1535              override_response_headers_.get() : | 
| 1667              transaction_->GetResponseInfo()->headers.get(); | 1536              transaction_->GetResponseInfo()->headers.get(); | 
| 1668 } | 1537 } | 
| 1669 | 1538 | 
| 1670 void URLRequestHttpJob::NotifyURLRequestDestroyed() { | 1539 void URLRequestHttpJob::NotifyURLRequestDestroyed() { | 
| 1671   awaiting_callback_ = false; | 1540   awaiting_callback_ = false; | 
| 1672 } | 1541 } | 
| 1673 | 1542 | 
| 1674 }  // namespace net | 1543 }  // namespace net | 
| OLD | NEW | 
|---|