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() ? job_->request()->context() : NULL; |
| 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* sdch_manager(request()->context()->sdch_manager()); |
317 SdchManager::Global()->IsInSupportedDomain(request_->url())) { | 309 if (sdch_manager && sdch_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 | |
329 // alternate copy. | |
330 DCHECK_EQ(request_->url(), request_info_.url); | |
331 // Resolve suggested URL relative to request url. | 320 // Resolve suggested URL relative to request url. |
332 sdch_dictionary_url_ = request_info_.url.Resolve(url_text); | 321 GURL sdch_dictionary_url = request_->url().Resolve(url_text); |
| 322 if (sdch_dictionary_url.is_valid()) { |
| 323 sdch_manager->FetchDictionary(request_->url(), sdch_dictionary_url); |
| 324 } |
333 } | 325 } |
334 } | 326 } |
335 | 327 |
336 // The HTTP transaction may be restarted several times for the purposes | 328 // The HTTP transaction may be restarted several times for the purposes |
337 // of sending authorization information. Each time it restarts, we get | 329 // of sending authorization information. Each time it restarts, we get |
338 // notified of the headers completion so that we can update the cookie store. | 330 // notified of the headers completion so that we can update the cookie store. |
339 if (transaction_->IsReadyToRestartForAuth()) { | 331 if (transaction_->IsReadyToRestartForAuth()) { |
340 DCHECK(!response_info_->auth_challenge.get()); | 332 DCHECK(!response_info_->auth_challenge.get()); |
341 // TODO(battre): This breaks the webrequest API for | 333 // TODO(battre): This breaks the webrequest API for |
342 // URLRequestTestHTTP.BasicAuthWithCookies | 334 // URLRequestTestHTTP.BasicAuthWithCookies |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 | 448 |
457 // The transaction started synchronously, but we need to notify the | 449 // The transaction started synchronously, but we need to notify the |
458 // URLRequest delegate via the message loop. | 450 // URLRequest delegate via the message loop. |
459 base::MessageLoop::current()->PostTask( | 451 base::MessageLoop::current()->PostTask( |
460 FROM_HERE, | 452 FROM_HERE, |
461 base::Bind(&URLRequestHttpJob::OnStartCompleted, | 453 base::Bind(&URLRequestHttpJob::OnStartCompleted, |
462 weak_factory_.GetWeakPtr(), rv)); | 454 weak_factory_.GetWeakPtr(), rv)); |
463 } | 455 } |
464 | 456 |
465 void URLRequestHttpJob::AddExtraHeaders() { | 457 void URLRequestHttpJob::AddExtraHeaders() { |
| 458 SdchManager* sdch_manager = request()->context()->sdch_manager(); |
| 459 |
466 // Supply Accept-Encoding field only if it is not already provided. | 460 // 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 | 461 // It should be provided IF the content is known to have restrictions on |
468 // potential encoding, such as streaming multi-media. | 462 // potential encoding, such as streaming multi-media. |
469 // For details see bug 47381. | 463 // For details see bug 47381. |
470 // TODO(jar, enal): jpeg files etc. should set up a request header if | 464 // 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 | 465 // possible. Right now it is done only by buffered_resource_loader and |
472 // simple_data_source. | 466 // simple_data_source. |
473 if (!request_info_.extra_headers.HasHeader( | 467 if (!request_info_.extra_headers.HasHeader( |
474 HttpRequestHeaders::kAcceptEncoding)) { | 468 HttpRequestHeaders::kAcceptEncoding)) { |
475 bool advertise_sdch = SdchManager::Global() && | 469 bool advertise_sdch = sdch_manager && |
476 // We don't support SDCH responses to POST as there is a possibility | 470 // We don't support SDCH responses to POST as there is a possibility |
477 // of having SDCH encoded responses returned (e.g. by the cache) | 471 // of having SDCH encoded responses returned (e.g. by the cache) |
478 // which we cannot decode, and in those situations, we will need | 472 // which we cannot decode, and in those situations, we will need |
479 // to retransmit the request without SDCH, which is illegal for a POST. | 473 // to retransmit the request without SDCH, which is illegal for a POST. |
480 request()->method() != "POST" && | 474 request()->method() != "POST" && |
481 SdchManager::Global()->IsInSupportedDomain(request_->url()); | 475 sdch_manager->IsInSupportedDomain(request_->url()); |
482 std::string avail_dictionaries; | 476 std::string avail_dictionaries; |
483 if (advertise_sdch) { | 477 if (advertise_sdch) { |
484 SdchManager::Global()->GetAvailDictionaryList(request_->url(), | 478 sdch_manager->GetAvailDictionaryList(request_->url(), |
485 &avail_dictionaries); | 479 &avail_dictionaries); |
486 | 480 |
487 // The AllowLatencyExperiment() is only true if we've successfully done a | 481 // The AllowLatencyExperiment() is only true if we've successfully done a |
488 // full SDCH compression recently in this browser session for this host. | 482 // full SDCH compression recently in this browser session for this host. |
489 // Note that for this path, there might be no applicable dictionaries, | 483 // Note that for this path, there might be no applicable dictionaries, |
490 // and hence we can't participate in the experiment. | 484 // and hence we can't participate in the experiment. |
491 if (!avail_dictionaries.empty() && | 485 if (!avail_dictionaries.empty() && |
492 SdchManager::Global()->AllowLatencyExperiment(request_->url())) { | 486 sdch_manager->AllowLatencyExperiment(request_->url())) { |
493 // 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 |
494 // eventually record statistics via either SDCH_EXPERIMENT_DECODE or | 488 // eventually record statistics via either SDCH_EXPERIMENT_DECODE or |
495 // SDCH_EXPERIMENT_HOLDBACK, and we'll need some packet timing data. | 489 // SDCH_EXPERIMENT_HOLDBACK, and we'll need some packet timing data. |
496 packet_timing_enabled_ = true; | 490 packet_timing_enabled_ = true; |
497 if (base::RandDouble() < .01) { | 491 if (base::RandDouble() < .01) { |
498 sdch_test_control_ = true; // 1% probability. | 492 sdch_test_control_ = true; // 1% probability. |
499 advertise_sdch = false; | 493 advertise_sdch = false; |
500 } else { | 494 } else { |
501 sdch_test_activated_ = true; | 495 sdch_test_activated_ = true; |
502 } | 496 } |
(...skipping 1005 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1508 return override_response_headers_.get() ? | 1502 return override_response_headers_.get() ? |
1509 override_response_headers_.get() : | 1503 override_response_headers_.get() : |
1510 transaction_->GetResponseInfo()->headers.get(); | 1504 transaction_->GetResponseInfo()->headers.get(); |
1511 } | 1505 } |
1512 | 1506 |
1513 void URLRequestHttpJob::NotifyURLRequestDestroyed() { | 1507 void URLRequestHttpJob::NotifyURLRequestDestroyed() { |
1514 awaiting_callback_ = false; | 1508 awaiting_callback_ = false; |
1515 } | 1509 } |
1516 | 1510 |
1517 } // namespace net | 1511 } // namespace net |
OLD | NEW |