| 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 // FilterContext implementation. | 59 // FilterContext implementation. |
| 60 virtual bool GetMimeType(std::string* mime_type) const OVERRIDE; | 60 virtual bool GetMimeType(std::string* mime_type) const OVERRIDE; |
| 61 virtual bool GetURL(GURL* gurl) const OVERRIDE; | 61 virtual bool GetURL(GURL* gurl) const OVERRIDE; |
| 62 virtual bool GetContentDisposition(std::string* disposition) const OVERRIDE; | 62 virtual bool GetContentDisposition(std::string* disposition) const OVERRIDE; |
| 63 virtual base::Time GetRequestTime() const OVERRIDE; | 63 virtual base::Time GetRequestTime() const OVERRIDE; |
| 64 virtual bool IsCachedContent() const OVERRIDE; | 64 virtual bool IsCachedContent() const OVERRIDE; |
| 65 virtual bool IsDownload() const OVERRIDE; | 65 virtual bool IsDownload() const OVERRIDE; |
| 66 virtual bool IsSdchResponse() const OVERRIDE; | 66 virtual bool IsSdchResponse() const OVERRIDE; |
| 67 virtual int64 GetByteReadCount() const OVERRIDE; | 67 virtual int64 GetByteReadCount() const OVERRIDE; |
| 68 virtual int GetResponseCode() const OVERRIDE; | 68 virtual int GetResponseCode() const OVERRIDE; |
| 69 virtual const URLRequestContext* GetURLRequestContext() const OVERRIDE; |
| 69 virtual void RecordPacketStats(StatisticSelector statistic) const OVERRIDE; | 70 virtual void RecordPacketStats(StatisticSelector statistic) const OVERRIDE; |
| 70 | 71 |
| 71 // Method to allow us to reset filter context for a response that should have | 72 // Method to allow us to reset filter context for a response that should have |
| 72 // been SDCH encoded when there is an update due to an explicit HTTP header. | 73 // been SDCH encoded when there is an update due to an explicit HTTP header. |
| 73 void ResetSdchResponseToFalse(); | 74 void ResetSdchResponseToFalse(); |
| 74 | 75 |
| 75 private: | 76 private: |
| 76 URLRequestHttpJob* job_; | 77 URLRequestHttpJob* job_; |
| 77 | 78 |
| 78 DISALLOW_COPY_AND_ASSIGN(HttpFilterContext); | 79 DISALLOW_COPY_AND_ASSIGN(HttpFilterContext); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 } | 128 } |
| 128 | 129 |
| 129 int64 URLRequestHttpJob::HttpFilterContext::GetByteReadCount() const { | 130 int64 URLRequestHttpJob::HttpFilterContext::GetByteReadCount() const { |
| 130 return job_->filter_input_byte_count(); | 131 return job_->filter_input_byte_count(); |
| 131 } | 132 } |
| 132 | 133 |
| 133 int URLRequestHttpJob::HttpFilterContext::GetResponseCode() const { | 134 int URLRequestHttpJob::HttpFilterContext::GetResponseCode() const { |
| 134 return job_->GetResponseCode(); | 135 return job_->GetResponseCode(); |
| 135 } | 136 } |
| 136 | 137 |
| 138 const URLRequestContext* |
| 139 URLRequestHttpJob::HttpFilterContext::GetURLRequestContext() const { |
| 140 return job_->request()->context(); |
| 141 } |
| 142 |
| 137 void URLRequestHttpJob::HttpFilterContext::RecordPacketStats( | 143 void URLRequestHttpJob::HttpFilterContext::RecordPacketStats( |
| 138 StatisticSelector statistic) const { | 144 StatisticSelector statistic) const { |
| 139 job_->RecordPacketStats(statistic); | 145 job_->RecordPacketStats(statistic); |
| 140 } | 146 } |
| 141 | 147 |
| 142 // TODO(darin): make sure the port blocking code is not lost | 148 // TODO(darin): make sure the port blocking code is not lost |
| 143 // static | 149 // static |
| 144 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, | 150 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, |
| 145 NetworkDelegate* network_delegate, | 151 NetworkDelegate* network_delegate, |
| 146 const std::string& scheme) { | 152 const std::string& scheme) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 if (!is_cached_content_) { | 219 if (!is_cached_content_) { |
| 214 if (sdch_test_control_) | 220 if (sdch_test_control_) |
| 215 RecordPacketStats(FilterContext::SDCH_EXPERIMENT_HOLDBACK); | 221 RecordPacketStats(FilterContext::SDCH_EXPERIMENT_HOLDBACK); |
| 216 if (sdch_test_activated_) | 222 if (sdch_test_activated_) |
| 217 RecordPacketStats(FilterContext::SDCH_EXPERIMENT_DECODE); | 223 RecordPacketStats(FilterContext::SDCH_EXPERIMENT_DECODE); |
| 218 } | 224 } |
| 219 // Make sure SDCH filters are told to emit histogram data while | 225 // Make sure SDCH filters are told to emit histogram data while |
| 220 // filter_context_ is still alive. | 226 // filter_context_ is still alive. |
| 221 DestroyFilters(); | 227 DestroyFilters(); |
| 222 | 228 |
| 223 if (sdch_dictionary_url_.is_valid()) { | |
| 224 // Prior to reaching the destructor, request_ has been set to a NULL | |
| 225 // pointer, so request_->url() is no longer valid in the destructor, and we | |
| 226 // use an alternate copy |request_info_.url|. | |
| 227 SdchManager* manager = SdchManager::Global(); | |
| 228 // To be extra safe, since this is a "different time" from when we decided | |
| 229 // to get the dictionary, we'll validate that an SdchManager is available. | |
| 230 // At shutdown time, care is taken to be sure that we don't delete this | |
| 231 // globally useful instance "too soon," so this check is just defensive | |
| 232 // coding to assure that IF the system is shutting down, we don't have any | |
| 233 // problem if the manager was deleted ahead of time. | |
| 234 if (manager) // Defensive programming. | |
| 235 manager->FetchDictionary(request_info_.url, sdch_dictionary_url_); | |
| 236 } | |
| 237 DoneWithRequest(ABORTED); | 229 DoneWithRequest(ABORTED); |
| 238 } | 230 } |
| 239 | 231 |
| 240 void URLRequestHttpJob::SetPriority(RequestPriority priority) { | 232 void URLRequestHttpJob::SetPriority(RequestPriority priority) { |
| 241 priority_ = priority; | 233 priority_ = priority; |
| 242 if (transaction_) | 234 if (transaction_) |
| 243 transaction_->SetPriority(priority_); | 235 transaction_->SetPriority(priority_); |
| 244 } | 236 } |
| 245 | 237 |
| 246 void URLRequestHttpJob::Start() { | 238 void URLRequestHttpJob::Start() { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 if (!is_cached_content_ && throttling_entry_.get()) { | 298 if (!is_cached_content_ && throttling_entry_.get()) { |
| 307 URLRequestThrottlerHeaderAdapter response_adapter(GetResponseHeaders()); | 299 URLRequestThrottlerHeaderAdapter response_adapter(GetResponseHeaders()); |
| 308 throttling_entry_->UpdateWithResponse(request_info_.url.host(), | 300 throttling_entry_->UpdateWithResponse(request_info_.url.host(), |
| 309 &response_adapter); | 301 &response_adapter); |
| 310 } | 302 } |
| 311 | 303 |
| 312 // The ordering of these calls is not important. | 304 // The ordering of these calls is not important. |
| 313 ProcessStrictTransportSecurityHeader(); | 305 ProcessStrictTransportSecurityHeader(); |
| 314 ProcessPublicKeyPinsHeader(); | 306 ProcessPublicKeyPinsHeader(); |
| 315 | 307 |
| 316 if (SdchManager::Global() && | 308 SdchManager* manager(request()->context()->sdch_manager()); |
| 317 SdchManager::Global()->IsInSupportedDomain(request_->url())) { | 309 if (manager && manager->IsInSupportedDomain(request_->url())) { |
| 318 const std::string name = "Get-Dictionary"; | 310 const std::string name = "Get-Dictionary"; |
| 319 std::string url_text; | 311 std::string url_text; |
| 320 void* iter = NULL; | 312 void* iter = NULL; |
| 321 // TODO(jar): We need to not fetch dictionaries the first time they are | 313 // TODO(jar): We need to not fetch dictionaries the first time they are |
| 322 // seen, but rather wait until we can justify their usefulness. | 314 // seen, but rather wait until we can justify their usefulness. |
| 323 // For now, we will only fetch the first dictionary, which will at least | 315 // For now, we will only fetch the first dictionary, which will at least |
| 324 // require multiple suggestions before we get additional ones for this site. | 316 // require multiple suggestions before we get additional ones for this site. |
| 325 // Eventually we should wait until a dictionary is requested several times | 317 // Eventually we should wait until a dictionary is requested several times |
| 326 // before we even download it (so that we don't waste memory or bandwidth). | 318 // before we even download it (so that we don't waste memory or bandwidth). |
| 327 if (GetResponseHeaders()->EnumerateHeader(&iter, name, &url_text)) { | 319 if (GetResponseHeaders()->EnumerateHeader(&iter, name, &url_text)) { |
| 328 // request_->url() won't be valid in the destructor, so we use an | 320 // request_->url() won't be valid in the destructor, so we use an |
| 329 // alternate copy. | 321 // alternate copy. |
| 330 DCHECK_EQ(request_->url(), request_info_.url); | 322 DCHECK_EQ(request_->url(), request_info_.url); |
| 331 // Resolve suggested URL relative to request url. | 323 // Resolve suggested URL relative to request url. |
| 332 sdch_dictionary_url_ = request_info_.url.Resolve(url_text); | 324 GURL sdch_dictionary_url = request_info_.url.Resolve(url_text); |
| 325 if (sdch_dictionary_url.is_valid()) { |
| 326 SdchManager* manager = request()->context()->sdch_manager(); |
| 327 if (manager) |
| 328 manager->FetchDictionary(request_info_.url, sdch_dictionary_url); |
| 329 } |
| 333 } | 330 } |
| 334 } | 331 } |
| 335 | 332 |
| 336 // The HTTP transaction may be restarted several times for the purposes | 333 // The HTTP transaction may be restarted several times for the purposes |
| 337 // of sending authorization information. Each time it restarts, we get | 334 // of sending authorization information. Each time it restarts, we get |
| 338 // notified of the headers completion so that we can update the cookie store. | 335 // notified of the headers completion so that we can update the cookie store. |
| 339 if (transaction_->IsReadyToRestartForAuth()) { | 336 if (transaction_->IsReadyToRestartForAuth()) { |
| 340 DCHECK(!response_info_->auth_challenge.get()); | 337 DCHECK(!response_info_->auth_challenge.get()); |
| 341 // TODO(battre): This breaks the webrequest API for | 338 // TODO(battre): This breaks the webrequest API for |
| 342 // URLRequestTestHTTP.BasicAuthWithCookies | 339 // URLRequestTestHTTP.BasicAuthWithCookies |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 | 453 |
| 457 // The transaction started synchronously, but we need to notify the | 454 // The transaction started synchronously, but we need to notify the |
| 458 // URLRequest delegate via the message loop. | 455 // URLRequest delegate via the message loop. |
| 459 base::MessageLoop::current()->PostTask( | 456 base::MessageLoop::current()->PostTask( |
| 460 FROM_HERE, | 457 FROM_HERE, |
| 461 base::Bind(&URLRequestHttpJob::OnStartCompleted, | 458 base::Bind(&URLRequestHttpJob::OnStartCompleted, |
| 462 weak_factory_.GetWeakPtr(), rv)); | 459 weak_factory_.GetWeakPtr(), rv)); |
| 463 } | 460 } |
| 464 | 461 |
| 465 void URLRequestHttpJob::AddExtraHeaders() { | 462 void URLRequestHttpJob::AddExtraHeaders() { |
| 463 SdchManager* sdch_manager = request()->context()->sdch_manager(); |
| 464 |
| 466 // Supply Accept-Encoding field only if it is not already provided. | 465 // Supply Accept-Encoding field only if it is not already provided. |
| 467 // It should be provided IF the content is known to have restrictions on | 466 // It should be provided IF the content is known to have restrictions on |
| 468 // potential encoding, such as streaming multi-media. | 467 // potential encoding, such as streaming multi-media. |
| 469 // For details see bug 47381. | 468 // For details see bug 47381. |
| 470 // TODO(jar, enal): jpeg files etc. should set up a request header if | 469 // TODO(jar, enal): jpeg files etc. should set up a request header if |
| 471 // possible. Right now it is done only by buffered_resource_loader and | 470 // possible. Right now it is done only by buffered_resource_loader and |
| 472 // simple_data_source. | 471 // simple_data_source. |
| 473 if (!request_info_.extra_headers.HasHeader( | 472 if (!request_info_.extra_headers.HasHeader( |
| 474 HttpRequestHeaders::kAcceptEncoding)) { | 473 HttpRequestHeaders::kAcceptEncoding)) { |
| 475 bool advertise_sdch = SdchManager::Global() && | 474 bool advertise_sdch = sdch_manager && |
| 476 SdchManager::Global()->IsInSupportedDomain(request_->url()); | 475 sdch_manager->IsInSupportedDomain(request_->url()); |
| 477 std::string avail_dictionaries; | 476 std::string avail_dictionaries; |
| 478 if (advertise_sdch) { | 477 if (advertise_sdch) { |
| 479 SdchManager::Global()->GetAvailDictionaryList(request_->url(), | 478 sdch_manager->GetAvailDictionaryList(request_->url(), |
| 480 &avail_dictionaries); | 479 &avail_dictionaries); |
| 481 | 480 |
| 482 // The AllowLatencyExperiment() is only true if we've successfully done a | 481 // The AllowLatencyExperiment() is only true if we've successfully done a |
| 483 // full SDCH compression recently in this browser session for this host. | 482 // full SDCH compression recently in this browser session for this host. |
| 484 // Note that for this path, there might be no applicable dictionaries, | 483 // Note that for this path, there might be no applicable dictionaries, |
| 485 // and hence we can't participate in the experiment. | 484 // and hence we can't participate in the experiment. |
| 486 if (!avail_dictionaries.empty() && | 485 if (!avail_dictionaries.empty() && |
| 487 SdchManager::Global()->AllowLatencyExperiment(request_->url())) { | 486 sdch_manager->AllowLatencyExperiment(request_->url())) { |
| 488 // We are participating in the test (or control), and hence we'll | 487 // We are participating in the test (or control), and hence we'll |
| 489 // eventually record statistics via either SDCH_EXPERIMENT_DECODE or | 488 // eventually record statistics via either SDCH_EXPERIMENT_DECODE or |
| 490 // SDCH_EXPERIMENT_HOLDBACK, and we'll need some packet timing data. | 489 // SDCH_EXPERIMENT_HOLDBACK, and we'll need some packet timing data. |
| 491 packet_timing_enabled_ = true; | 490 packet_timing_enabled_ = true; |
| 492 if (base::RandDouble() < .01) { | 491 if (base::RandDouble() < .01) { |
| 493 sdch_test_control_ = true; // 1% probability. | 492 sdch_test_control_ = true; // 1% probability. |
| 494 advertise_sdch = false; | 493 advertise_sdch = false; |
| 495 } else { | 494 } else { |
| 496 sdch_test_activated_ = true; | 495 sdch_test_activated_ = true; |
| 497 } | 496 } |
| (...skipping 1006 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1504 return override_response_headers_.get() ? | 1503 return override_response_headers_.get() ? |
| 1505 override_response_headers_.get() : | 1504 override_response_headers_.get() : |
| 1506 transaction_->GetResponseInfo()->headers.get(); | 1505 transaction_->GetResponseInfo()->headers.get(); |
| 1507 } | 1506 } |
| 1508 | 1507 |
| 1509 void URLRequestHttpJob::NotifyURLRequestDestroyed() { | 1508 void URLRequestHttpJob::NotifyURLRequestDestroyed() { |
| 1510 awaiting_callback_ = false; | 1509 awaiting_callback_ = false; |
| 1511 } | 1510 } |
| 1512 | 1511 |
| 1513 } // namespace net | 1512 } // namespace net |
| OLD | NEW |