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