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/base64.h" | |
| 7 #include "base/base_switches.h" | 8 #include "base/base_switches.h" |
| 8 #include "base/bind.h" | 9 #include "base/bind.h" |
| 9 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| 10 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 11 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 12 #include "base/file_util.h" | 13 #include "base/file_util.h" |
| 13 #include "base/file_version_info.h" | 14 #include "base/file_version_info.h" |
| 14 #include "base/message_loop.h" | 15 #include "base/message_loop.h" |
| 15 #include "base/metrics/field_trial.h" | 16 #include "base/metrics/field_trial.h" |
| 16 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
| 17 #include "base/rand_util.h" | 18 #include "base/rand_util.h" |
| 18 #include "base/string_util.h" | 19 #include "base/string_util.h" |
| 19 #include "base/time.h" | 20 #include "base/time.h" |
| 20 #include "net/base/cert_status_flags.h" | 21 #include "net/base/cert_status_flags.h" |
| 22 #include "net/base/dns_util.h" | |
| 23 #include "net/base/dnsrr_resolver.h" | |
| 21 #include "net/base/filter.h" | 24 #include "net/base/filter.h" |
| 22 #include "net/base/host_port_pair.h" | 25 #include "net/base/host_port_pair.h" |
| 23 #include "net/base/load_flags.h" | 26 #include "net/base/load_flags.h" |
| 24 #include "net/base/mime_util.h" | 27 #include "net/base/mime_util.h" |
| 25 #include "net/base/net_errors.h" | 28 #include "net/base/net_errors.h" |
| 26 #include "net/base/net_util.h" | 29 #include "net/base/net_util.h" |
| 27 #include "net/base/network_delegate.h" | 30 #include "net/base/network_delegate.h" |
| 31 #include "net/base/public_key_hashes.h" | |
| 28 #include "net/base/sdch_manager.h" | 32 #include "net/base/sdch_manager.h" |
| 29 #include "net/base/ssl_cert_request_info.h" | 33 #include "net/base/ssl_cert_request_info.h" |
| 30 #include "net/base/ssl_config_service.h" | 34 #include "net/base/ssl_config_service.h" |
| 31 #include "net/cookies/cookie_monster.h" | 35 #include "net/cookies/cookie_monster.h" |
| 32 #include "net/http/http_request_headers.h" | 36 #include "net/http/http_request_headers.h" |
| 33 #include "net/http/http_response_headers.h" | 37 #include "net/http/http_response_headers.h" |
| 34 #include "net/http/http_response_info.h" | 38 #include "net/http/http_response_info.h" |
| 35 #include "net/http/http_status_code.h" | 39 #include "net/http/http_status_code.h" |
| 36 #include "net/http/http_transaction.h" | 40 #include "net/http/http_transaction.h" |
| 37 #include "net/http/http_transaction_factory.h" | 41 #include "net/http/http_transaction_factory.h" |
| 38 #include "net/http/http_util.h" | 42 #include "net/http/http_util.h" |
| 39 #include "net/url_request/fraudulent_certificate_reporter.h" | 43 #include "net/url_request/fraudulent_certificate_reporter.h" |
| 40 #include "net/url_request/url_request.h" | 44 #include "net/url_request/url_request.h" |
| 41 #include "net/url_request/url_request_context.h" | 45 #include "net/url_request/url_request_context.h" |
| 42 #include "net/url_request/url_request_error_job.h" | 46 #include "net/url_request/url_request_error_job.h" |
| 43 #include "net/url_request/url_request_redirect_job.h" | 47 #include "net/url_request/url_request_redirect_job.h" |
| 44 #include "net/url_request/url_request_throttler_header_adapter.h" | 48 #include "net/url_request/url_request_throttler_header_adapter.h" |
| 45 #include "net/url_request/url_request_throttler_manager.h" | 49 #include "net/url_request/url_request_throttler_manager.h" |
| 46 | 50 |
| 47 static const char kAvailDictionaryHeader[] = "Avail-Dictionary"; | 51 static const char kAvailDictionaryHeader[] = "Avail-Dictionary"; |
| 48 | 52 |
| 49 namespace net { | 53 namespace net { |
| 50 | 54 |
| 55 namespace { | |
| 56 | |
| 57 const char* const kComodoCerts[] = { | |
| 58 kSPKIHash_AAACertificateServices, | |
| 59 kSPKIHash_AddTrustClass1CARoot, | |
| 60 kSPKIHash_AddTrustExternalCARoot, | |
| 61 kSPKIHash_AddTrustPublicCARoot, | |
| 62 kSPKIHash_AddTrustQualifiedCARoot, | |
| 63 kSPKIHash_COMODOCertificationAuthority, | |
| 64 kSPKIHash_SecureCertificateServices, | |
| 65 kSPKIHash_TrustedCertificateServices, | |
| 66 kSPKIHash_UTNDATACorpSGC, | |
| 67 kSPKIHash_UTNUSERFirstClientAuthenticationandEmail, | |
| 68 kSPKIHash_UTNUSERFirstHardware, | |
| 69 kSPKIHash_UTNUSERFirstObject, | |
| 70 }; | |
| 71 | |
| 72 // IsComodoCertificate returns true if a known Comodo public key appears in | |
| 73 // |public_key_hashes|. | |
| 74 // TODO(agl): remove once experiment is complete, by July 2012. | |
| 75 static bool IsComodoCertificate( | |
| 76 const std::vector<SHA1Fingerprint>& public_key_hashes) { | |
| 77 for (std::vector<SHA1Fingerprint>::const_iterator | |
| 78 i = public_key_hashes.begin(); i != public_key_hashes.end(); i++) { | |
| 79 std::string base64_hash; | |
| 80 base::Base64Encode(base::StringPiece( | |
| 81 reinterpret_cast<const char*>(i->data), sizeof(i->data)), &base64_hash); | |
|
Ryan Sleevi
2012/03/19 18:58:15
nit: Use arraysize() rather than sizeof() - functi
agl
2012/03/19 20:16:48
Done.
| |
| 82 base64_hash = "sha1/" + base64_hash; | |
| 83 | |
| 84 for (size_t j = 0; j < arraysize(kComodoCerts); j++) { | |
| 85 if (base64_hash == kComodoCerts[j]) | |
| 86 return true; | |
| 87 } | |
| 88 } | |
| 89 | |
| 90 return false; | |
| 91 } | |
| 92 | |
| 93 // RecordComodoDNSResult is a callback from a DNS resolution. It records the | |
| 94 // elapsed time in a histogram. | |
| 95 // TODO(agl): remove once experiment is complete, by July 2012. | |
| 96 static void RecordComodoDNSResult(RRResponse* response, | |
| 97 base::TimeTicks start_time, | |
| 98 int result) { | |
| 99 base::TimeDelta total_time = base::TimeTicks::Now() - start_time; | |
| 100 if (total_time.InMilliseconds() > 10) { | |
| 101 // If the reply took > 10 ms there's a good chance that it didn't come from | |
| 102 // a local DNS cache. | |
| 103 if (result == OK && | |
| 104 response->rrdatas.size() && | |
| 105 response->rrdatas[0].find("wibble") != std::string::npos) { | |
| 106 UMA_HISTOGRAM_TIMES("Net.ComodoDNSExperimentSuccessTime", total_time); | |
| 107 } else { | |
| 108 UMA_HISTOGRAM_TIMES("Net.ComodoDNSExperimentFailureTime", total_time); | |
| 109 } | |
| 110 } | |
| 111 | |
| 112 delete response; | |
| 113 } | |
| 114 | |
| 115 } // namespace | |
| 116 | |
| 51 class URLRequestHttpJob::HttpFilterContext : public FilterContext { | 117 class URLRequestHttpJob::HttpFilterContext : public FilterContext { |
| 52 public: | 118 public: |
| 53 explicit HttpFilterContext(URLRequestHttpJob* job); | 119 explicit HttpFilterContext(URLRequestHttpJob* job); |
| 54 virtual ~HttpFilterContext(); | 120 virtual ~HttpFilterContext(); |
| 55 | 121 |
| 56 // FilterContext implementation. | 122 // FilterContext implementation. |
| 57 virtual bool GetMimeType(std::string* mime_type) const; | 123 virtual bool GetMimeType(std::string* mime_type) const; |
| 58 virtual bool GetURL(GURL* gurl) const; | 124 virtual bool GetURL(GURL* gurl) const; |
| 59 virtual base::Time GetRequestTime() const; | 125 virtual base::Time GetRequestTime() const; |
| 60 virtual bool IsCachedContent() const; | 126 virtual bool IsCachedContent() const; |
| (...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 683 if (reporter != NULL) { | 749 if (reporter != NULL) { |
| 684 const SSLInfo& ssl_info = transaction_->GetResponseInfo()->ssl_info; | 750 const SSLInfo& ssl_info = transaction_->GetResponseInfo()->ssl_info; |
| 685 bool sni_available = SSLConfigService::IsSNIAvailable( | 751 bool sni_available = SSLConfigService::IsSNIAvailable( |
| 686 context_->ssl_config_service()); | 752 context_->ssl_config_service()); |
| 687 const std::string& host = request_->url().host(); | 753 const std::string& host = request_->url().host(); |
| 688 | 754 |
| 689 reporter->SendReport(host, ssl_info, sni_available); | 755 reporter->SendReport(host, ssl_info, sni_available); |
| 690 } | 756 } |
| 691 } | 757 } |
| 692 | 758 |
| 759 // This is a temporary experiment, in conjuction with Comodo, to measure the | |
| 760 // effectiveness of a possible DNS-based revocation mechanism. | |
| 761 // TODO(agl): remove once experiment is complete, by July 2012. | |
|
Ryan Sleevi
2012/03/19 18:58:15
Can this be implemented as a FieldTrial (base/metr
agl
2012/03/19 20:16:48
Yes, I like the idea of a date-based cutoff if all
| |
| 762 if (result == OK && transaction_->GetResponseInfo() != NULL) { | |
|
willchan no longer on Chromium
2012/03/19 19:11:01
Can we move all this code into ChromeNetworkDelega
agl
2012/03/19 20:16:48
Done.
| |
| 763 const HttpResponseInfo* response_info = transaction_->GetResponseInfo(); | |
| 764 const SSLInfo& ssl_info = response_info->ssl_info; | |
| 765 if (response_info->was_cached == false && | |
| 766 ssl_info.is_valid() && | |
| 767 ssl_info.is_issued_by_known_root && | |
| 768 IsComodoCertificate(ssl_info.public_key_hashes)) { | |
| 769 // The Comodo DNS record has a 20 minute TTL, so we won't actually | |
|
willchan no longer on Chromium
2012/03/19 19:11:01
What happens if Comodo screws up their TTL? Do we
agl
2012/03/19 20:16:48
Have added a rate limit of once every ten minutes.
| |
| 770 // request it more than three times an hour because it'll be in the | |
| 771 // DnsRRResolver's cache. | |
| 772 DnsRRResolver* dnsrr_resolver(context_->dnsrr_resolver()); | |
| 773 RRResponse* response(new(RRResponse)); | |
|
Ryan Sleevi
2012/03/19 18:58:15
drive by:
RRResponse* response = new RRResponse;
agl
2012/03/19 20:16:48
Yep, that's better. Thanks.
| |
| 774 base::TimeTicks start_time(base::TimeTicks::Now()); | |
| 775 dnsrr_resolver->Resolve("wibble.comodoca.com", kDNS_TXT, 0 /* flags */, | |
| 776 Bind(RecordComodoDNSResult, response, start_time), | |
| 777 response, 0 /* priority */, | |
|
willchan no longer on Chromium
2012/03/19 19:11:01
how about using base::Owned(response) so that on s
agl
2012/03/19 20:16:48
Done.
| |
| 778 request_->net_log()); | |
| 779 } | |
| 780 } | |
| 781 | |
| 693 if (result == OK) { | 782 if (result == OK) { |
| 694 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); | 783 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); |
| 695 if (request_->context() && request_->context()->network_delegate()) { | 784 if (request_->context() && request_->context()->network_delegate()) { |
| 696 // Note that |this| may not be deleted until | 785 // Note that |this| may not be deleted until |
| 697 // |on_headers_received_callback_| or | 786 // |on_headers_received_callback_| or |
| 698 // |NetworkDelegate::URLRequestDestroyed()| has been called. | 787 // |NetworkDelegate::URLRequestDestroyed()| has been called. |
| 699 int error = request_->context()->network_delegate()-> | 788 int error = request_->context()->network_delegate()-> |
| 700 NotifyHeadersReceived(request_, on_headers_received_callback_, | 789 NotifyHeadersReceived(request_, on_headers_received_callback_, |
| 701 headers, &override_response_headers_); | 790 headers, &override_response_headers_); |
| 702 if (error != net::OK) { | 791 if (error != net::OK) { |
| (...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1409 return override_response_headers_.get() ? | 1498 return override_response_headers_.get() ? |
| 1410 override_response_headers_ : | 1499 override_response_headers_ : |
| 1411 transaction_->GetResponseInfo()->headers; | 1500 transaction_->GetResponseInfo()->headers; |
| 1412 } | 1501 } |
| 1413 | 1502 |
| 1414 void URLRequestHttpJob::NotifyURLRequestDestroyed() { | 1503 void URLRequestHttpJob::NotifyURLRequestDestroyed() { |
| 1415 awaiting_callback_ = false; | 1504 awaiting_callback_ = false; |
| 1416 } | 1505 } |
| 1417 | 1506 |
| 1418 } // namespace net | 1507 } // namespace net |
| OLD | NEW |