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" |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "base/file_version_info.h" | 12 #include "base/file_version_info.h" |
13 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
14 #include "base/metrics/field_trial.h" | 14 #include "base/metrics/field_trial.h" |
15 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
16 #include "base/profiler/scoped_tracker.h" | 16 #include "base/profiler/scoped_tracker.h" |
17 #include "base/rand_util.h" | 17 #include "base/rand_util.h" |
18 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
19 #include "base/time/time.h" | 19 #include "base/time/time.h" |
20 #include "net/base/host_port_pair.h" | 20 #include "net/base/host_port_pair.h" |
21 #include "net/base/load_flags.h" | 21 #include "net/base/load_flags.h" |
22 #include "net/base/mime_util.h" | 22 #include "net/base/mime_util.h" |
23 #include "net/base/net_errors.h" | 23 #include "net/base/net_errors.h" |
24 #include "net/base/net_util.h" | 24 #include "net/base/net_util.h" |
25 #include "net/base/network_delegate.h" | 25 #include "net/base/network_delegate.h" |
26 #include "net/base/sdch_manager.h" | 26 #include "net/base/sdch_manager.h" |
| 27 #include "net/base/sdch_net_log_params.h" |
27 #include "net/cert/cert_status_flags.h" | 28 #include "net/cert/cert_status_flags.h" |
28 #include "net/cookies/cookie_store.h" | 29 #include "net/cookies/cookie_store.h" |
29 #include "net/http/http_content_disposition.h" | 30 #include "net/http/http_content_disposition.h" |
30 #include "net/http/http_network_session.h" | 31 #include "net/http/http_network_session.h" |
31 #include "net/http/http_request_headers.h" | 32 #include "net/http/http_request_headers.h" |
32 #include "net/http/http_response_headers.h" | 33 #include "net/http/http_response_headers.h" |
33 #include "net/http/http_response_info.h" | 34 #include "net/http/http_response_info.h" |
34 #include "net/http/http_status_code.h" | 35 #include "net/http/http_status_code.h" |
35 #include "net/http/http_transaction.h" | 36 #include "net/http/http_transaction.h" |
36 #include "net/http/http_transaction_factory.h" | 37 #include "net/http/http_transaction_factory.h" |
(...skipping 26 matching lines...) Expand all Loading... |
63 bool GetURL(GURL* gurl) const override; | 64 bool GetURL(GURL* gurl) const override; |
64 bool GetContentDisposition(std::string* disposition) const override; | 65 bool GetContentDisposition(std::string* disposition) const override; |
65 base::Time GetRequestTime() const override; | 66 base::Time GetRequestTime() const override; |
66 bool IsCachedContent() const override; | 67 bool IsCachedContent() const override; |
67 bool IsDownload() const override; | 68 bool IsDownload() const override; |
68 bool SdchResponseExpected() const override; | 69 bool SdchResponseExpected() const override; |
69 int64 GetByteReadCount() const override; | 70 int64 GetByteReadCount() const override; |
70 int GetResponseCode() const override; | 71 int GetResponseCode() const override; |
71 const URLRequestContext* GetURLRequestContext() const override; | 72 const URLRequestContext* GetURLRequestContext() const override; |
72 void RecordPacketStats(StatisticSelector statistic) const override; | 73 void RecordPacketStats(StatisticSelector statistic) const override; |
| 74 const BoundNetLog& GetNetLog() const override; |
73 | 75 |
74 // Method to allow us to reset filter context for a response that should have | 76 // Method to allow us to reset filter context for a response that should have |
75 // been SDCH encoded when there is an update due to an explicit HTTP header. | 77 // been SDCH encoded when there is an update due to an explicit HTTP header. |
76 void ResetSdchResponseToFalse(); | 78 void ResetSdchResponseToFalse(); |
77 | 79 |
78 private: | 80 private: |
79 URLRequestHttpJob* job_; | 81 URLRequestHttpJob* job_; |
80 | 82 |
| 83 // URLRequestHttpJob may be detached from URLRequest, but we still need to |
| 84 // return something. |
| 85 BoundNetLog dummy_log_; |
| 86 |
81 DISALLOW_COPY_AND_ASSIGN(HttpFilterContext); | 87 DISALLOW_COPY_AND_ASSIGN(HttpFilterContext); |
82 }; | 88 }; |
83 | 89 |
84 URLRequestHttpJob::HttpFilterContext::HttpFilterContext(URLRequestHttpJob* job) | 90 URLRequestHttpJob::HttpFilterContext::HttpFilterContext(URLRequestHttpJob* job) |
85 : job_(job) { | 91 : job_(job) { |
86 DCHECK(job_); | 92 DCHECK(job_); |
87 } | 93 } |
88 | 94 |
89 URLRequestHttpJob::HttpFilterContext::~HttpFilterContext() { | 95 URLRequestHttpJob::HttpFilterContext::~HttpFilterContext() { |
90 } | 96 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 const URLRequestContext* | 146 const URLRequestContext* |
141 URLRequestHttpJob::HttpFilterContext::GetURLRequestContext() const { | 147 URLRequestHttpJob::HttpFilterContext::GetURLRequestContext() const { |
142 return job_->request() ? job_->request()->context() : NULL; | 148 return job_->request() ? job_->request()->context() : NULL; |
143 } | 149 } |
144 | 150 |
145 void URLRequestHttpJob::HttpFilterContext::RecordPacketStats( | 151 void URLRequestHttpJob::HttpFilterContext::RecordPacketStats( |
146 StatisticSelector statistic) const { | 152 StatisticSelector statistic) const { |
147 job_->RecordPacketStats(statistic); | 153 job_->RecordPacketStats(statistic); |
148 } | 154 } |
149 | 155 |
| 156 const BoundNetLog& URLRequestHttpJob::HttpFilterContext::GetNetLog() const { |
| 157 return job_->request() ? job_->request()->net_log() : dummy_log_; |
| 158 } |
| 159 |
150 // TODO(darin): make sure the port blocking code is not lost | 160 // TODO(darin): make sure the port blocking code is not lost |
151 // static | 161 // static |
152 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, | 162 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, |
153 NetworkDelegate* network_delegate, | 163 NetworkDelegate* network_delegate, |
154 const std::string& scheme) { | 164 const std::string& scheme) { |
155 DCHECK(scheme == "http" || scheme == "https" || scheme == "ws" || | 165 DCHECK(scheme == "http" || scheme == "https" || scheme == "ws" || |
156 scheme == "wss"); | 166 scheme == "wss"); |
157 | 167 |
158 if (!request->context()->http_transaction_factory()) { | 168 if (!request->context()->http_transaction_factory()) { |
159 NOTREACHED() << "requires a valid context"; | 169 NOTREACHED() << "requires a valid context"; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 URLRequestThrottlerHeaderAdapter response_adapter(GetResponseHeaders()); | 324 URLRequestThrottlerHeaderAdapter response_adapter(GetResponseHeaders()); |
315 throttling_entry_->UpdateWithResponse(request_info_.url.host(), | 325 throttling_entry_->UpdateWithResponse(request_info_.url.host(), |
316 &response_adapter); | 326 &response_adapter); |
317 } | 327 } |
318 | 328 |
319 // The ordering of these calls is not important. | 329 // The ordering of these calls is not important. |
320 ProcessStrictTransportSecurityHeader(); | 330 ProcessStrictTransportSecurityHeader(); |
321 ProcessPublicKeyPinsHeader(); | 331 ProcessPublicKeyPinsHeader(); |
322 | 332 |
323 SdchManager* sdch_manager(request()->context()->sdch_manager()); | 333 SdchManager* sdch_manager(request()->context()->sdch_manager()); |
324 if (sdch_manager && sdch_manager->IsInSupportedDomain(request_->url())) { | 334 if (sdch_manager) { |
325 const std::string name = "Get-Dictionary"; | 335 SdchProblemCode rv = sdch_manager->IsInSupportedDomain(request()->url()); |
326 std::string url_text; | 336 if (rv != SDCH_OK) { |
327 void* iter = NULL; | 337 // If SDCH is just disabled, it is not a real error. |
328 // TODO(jar): We need to not fetch dictionaries the first time they are | 338 if (rv != SDCH_DISABLED && rv != SDCH_SECURE_SCHEME_NOT_SUPPORTED) { |
329 // seen, but rather wait until we can justify their usefulness. | 339 SdchManager::SdchErrorRecovery(rv); |
330 // For now, we will only fetch the first dictionary, which will at least | 340 request()->net_log().AddEvent( |
331 // require multiple suggestions before we get additional ones for this site. | 341 NetLog::TYPE_SDCH_DECODING_ERROR, |
332 // Eventually we should wait until a dictionary is requested several times | 342 base::Bind(&NetLogSdchResourceProblemCallback, rv)); |
333 // before we even download it (so that we don't waste memory or bandwidth). | 343 } |
334 if (GetResponseHeaders()->EnumerateHeader(&iter, name, &url_text)) { | 344 } else { |
335 // Resolve suggested URL relative to request url. | 345 const std::string name = "Get-Dictionary"; |
336 GURL sdch_dictionary_url = request_->url().Resolve(url_text); | 346 std::string url_text; |
337 if (sdch_dictionary_url.is_valid()) { | 347 void* iter = NULL; |
338 sdch_manager->OnGetDictionary(request_->url(), sdch_dictionary_url); | 348 // TODO(jar): We need to not fetch dictionaries the first time they are |
| 349 // seen, but rather wait until we can justify their usefulness. |
| 350 // For now, we will only fetch the first dictionary, which will at least |
| 351 // require multiple suggestions before we get additional ones for this |
| 352 // site. Eventually we should wait until a dictionary is requested |
| 353 // several times |
| 354 // before we even download it (so that we don't waste memory or |
| 355 // bandwidth). |
| 356 if (GetResponseHeaders()->EnumerateHeader(&iter, name, &url_text)) { |
| 357 // Resolve suggested URL relative to request url. |
| 358 GURL sdch_dictionary_url = request_->url().Resolve(url_text); |
| 359 if (sdch_dictionary_url.is_valid()) { |
| 360 rv = sdch_manager->OnGetDictionary(request_->url(), |
| 361 sdch_dictionary_url); |
| 362 if (rv != SDCH_OK) { |
| 363 SdchManager::SdchErrorRecovery(rv); |
| 364 request_->net_log().AddEvent( |
| 365 NetLog::TYPE_SDCH_DICTIONARY_ERROR, |
| 366 base::Bind(&NetLogSdchDictionaryFetchProblemCallback, rv, |
| 367 sdch_dictionary_url, false)); |
| 368 } |
| 369 } |
339 } | 370 } |
340 } | 371 } |
341 } | 372 } |
342 | 373 |
343 // The HTTP transaction may be restarted several times for the purposes | 374 // The HTTP transaction may be restarted several times for the purposes |
344 // of sending authorization information. Each time it restarts, we get | 375 // of sending authorization information. Each time it restarts, we get |
345 // notified of the headers completion so that we can update the cookie store. | 376 // notified of the headers completion so that we can update the cookie store. |
346 if (transaction_->IsReadyToRestartForAuth()) { | 377 if (transaction_->IsReadyToRestartForAuth()) { |
347 DCHECK(!response_info_->auth_challenge.get()); | 378 DCHECK(!response_info_->auth_challenge.get()); |
348 // TODO(battre): This breaks the webrequest API for | 379 // TODO(battre): This breaks the webrequest API for |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 | 507 |
477 // Supply Accept-Encoding field only if it is not already provided. | 508 // Supply Accept-Encoding field only if it is not already provided. |
478 // It should be provided IF the content is known to have restrictions on | 509 // It should be provided IF the content is known to have restrictions on |
479 // potential encoding, such as streaming multi-media. | 510 // potential encoding, such as streaming multi-media. |
480 // For details see bug 47381. | 511 // For details see bug 47381. |
481 // TODO(jar, enal): jpeg files etc. should set up a request header if | 512 // TODO(jar, enal): jpeg files etc. should set up a request header if |
482 // possible. Right now it is done only by buffered_resource_loader and | 513 // possible. Right now it is done only by buffered_resource_loader and |
483 // simple_data_source. | 514 // simple_data_source. |
484 if (!request_info_.extra_headers.HasHeader( | 515 if (!request_info_.extra_headers.HasHeader( |
485 HttpRequestHeaders::kAcceptEncoding)) { | 516 HttpRequestHeaders::kAcceptEncoding)) { |
486 bool advertise_sdch = sdch_manager && | 517 // We don't support SDCH responses to POST as there is a possibility |
487 // We don't support SDCH responses to POST as there is a possibility | 518 // of having SDCH encoded responses returned (e.g. by the cache) |
488 // of having SDCH encoded responses returned (e.g. by the cache) | 519 // which we cannot decode, and in those situations, we will need |
489 // which we cannot decode, and in those situations, we will need | 520 // to retransmit the request without SDCH, which is illegal for a POST. |
490 // to retransmit the request without SDCH, which is illegal for a POST. | 521 bool advertise_sdch = sdch_manager != NULL && request()->method() != "POST"; |
491 request()->method() != "POST" && | 522 if (advertise_sdch) { |
492 sdch_manager->IsInSupportedDomain(request_->url()); | 523 SdchProblemCode rv = sdch_manager->IsInSupportedDomain(request()->url()); |
| 524 if (rv != SDCH_OK) { |
| 525 advertise_sdch = false; |
| 526 // If SDCH is just disabled, it is not a real error. |
| 527 if (rv != SDCH_DISABLED && rv != SDCH_SECURE_SCHEME_NOT_SUPPORTED) { |
| 528 SdchManager::SdchErrorRecovery(rv); |
| 529 request()->net_log().AddEvent( |
| 530 NetLog::TYPE_SDCH_DECODING_ERROR, |
| 531 base::Bind(&NetLogSdchResourceProblemCallback, rv)); |
| 532 } |
| 533 } |
| 534 } |
493 std::string avail_dictionaries; | 535 std::string avail_dictionaries; |
494 if (advertise_sdch) { | 536 if (advertise_sdch) { |
495 sdch_manager->GetAvailDictionaryList(request_->url(), | 537 sdch_manager->GetAvailDictionaryList(request_->url(), |
496 &avail_dictionaries); | 538 &avail_dictionaries); |
497 | 539 |
498 // The AllowLatencyExperiment() is only true if we've successfully done a | 540 // The AllowLatencyExperiment() is only true if we've successfully done a |
499 // full SDCH compression recently in this browser session for this host. | 541 // full SDCH compression recently in this browser session for this host. |
500 // Note that for this path, there might be no applicable dictionaries, | 542 // Note that for this path, there might be no applicable dictionaries, |
501 // and hence we can't participate in the experiment. | 543 // and hence we can't participate in the experiment. |
502 if (!avail_dictionaries.empty() && | 544 if (!avail_dictionaries.empty() && |
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1528 return override_response_headers_.get() ? | 1570 return override_response_headers_.get() ? |
1529 override_response_headers_.get() : | 1571 override_response_headers_.get() : |
1530 transaction_->GetResponseInfo()->headers.get(); | 1572 transaction_->GetResponseInfo()->headers.get(); |
1531 } | 1573 } |
1532 | 1574 |
1533 void URLRequestHttpJob::NotifyURLRequestDestroyed() { | 1575 void URLRequestHttpJob::NotifyURLRequestDestroyed() { |
1534 awaiting_callback_ = false; | 1576 awaiting_callback_ = false; |
1535 } | 1577 } |
1536 | 1578 |
1537 } // namespace net | 1579 } // namespace net |
OLD | NEW |