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