| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #import "ios/web/net/request_tracker_impl.h" | 5 #import "ios/web/net/request_tracker_impl.h" |
| 6 | 6 |
| 7 #include <pthread.h> | 7 #include <pthread.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 | 10 |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 // Designated initializer. | 215 // Designated initializer. |
| 216 - (id)initWithTracker:(web::RequestTrackerImpl*)tracker | 216 - (id)initWithTracker:(web::RequestTrackerImpl*)tracker |
| 217 counts:(const TrackerCounts*)counts; | 217 counts:(const TrackerCounts*)counts; |
| 218 // URL of the request. | 218 // URL of the request. |
| 219 - (const GURL&)url; | 219 - (const GURL&)url; |
| 220 // Returns a SSLStatus representing the state of the page. This assumes the | 220 // Returns a SSLStatus representing the state of the page. This assumes the |
| 221 // target carrier is the main page request. | 221 // target carrier is the main page request. |
| 222 - (const web::SSLStatus&)sslStatus; | 222 - (const web::SSLStatus&)sslStatus; |
| 223 // Returns a SSLInfo with a reference to the certificate and SSL information. | 223 // Returns a SSLInfo with a reference to the certificate and SSL information. |
| 224 - (const net::SSLInfo&)sslInfo; | 224 - (const net::SSLInfo&)sslInfo; |
| 225 // Callback method to allow or deny the request from going through. | |
| 226 - (void)errorCallback:(BOOL)flag; | |
| 227 // Internal method used to build the SSLStatus object. Called from the | 225 // Internal method used to build the SSLStatus object. Called from the |
| 228 // initializer to make sure it is invoked on the network thread. | 226 // initializer to make sure it is invoked on the network thread. |
| 229 - (void)buildSSLStatus; | 227 - (void)buildSSLStatus; |
| 230 @end | 228 @end |
| 231 | 229 |
| 232 @implementation CRWSSLCarrier | 230 @implementation CRWSSLCarrier |
| 233 | 231 |
| 234 - (id)initWithTracker:(web::RequestTrackerImpl*)tracker | 232 - (id)initWithTracker:(web::RequestTrackerImpl*)tracker |
| 235 counts:(const TrackerCounts*)counts { | 233 counts:(const TrackerCounts*)counts { |
| 236 self = [super init]; | 234 self = [super init]; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 248 } | 246 } |
| 249 | 247 |
| 250 - (const net::SSLInfo&)sslInfo { | 248 - (const net::SSLInfo&)sslInfo { |
| 251 return sslInfo_; | 249 return sslInfo_; |
| 252 } | 250 } |
| 253 | 251 |
| 254 - (const web::SSLStatus&)sslStatus { | 252 - (const web::SSLStatus&)sslStatus { |
| 255 return status_; | 253 return status_; |
| 256 } | 254 } |
| 257 | 255 |
| 258 - (void)errorCallback:(BOOL)flag { | |
| 259 base::scoped_nsobject<CRWSSLCarrier> scoped(self); | |
| 260 web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, | |
| 261 base::Bind(&web::RequestTrackerImpl::ErrorCallback, | |
| 262 tracker_, scoped, flag)); | |
| 263 } | |
| 264 | |
| 265 - (void)buildSSLStatus { | 256 - (void)buildSSLStatus { |
| 266 DCHECK_CURRENTLY_ON(web::WebThread::IO); | 257 DCHECK_CURRENTLY_ON(web::WebThread::IO); |
| 267 if (!sslInfo_.is_valid()) | 258 if (!sslInfo_.is_valid()) |
| 268 return; | 259 return; |
| 269 | 260 |
| 270 status_.certificate = sslInfo_.cert; | 261 status_.certificate = sslInfo_.cert; |
| 271 | 262 |
| 272 status_.cert_status = sslInfo_.cert_status; | 263 status_.cert_status = sslInfo_.cert_status; |
| 273 if (status_.cert_status & net::CERT_STATUS_COMMON_NAME_INVALID) { | 264 if (status_.cert_status & net::CERT_STATUS_COMMON_NAME_INVALID) { |
| 274 // CAs issue certificates for intranet hosts to everyone. Therefore, we | 265 // CAs issue certificates for intranet hosts to everyone. Therefore, we |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 } | 459 } |
| 469 | 460 |
| 470 net::URLRequestContext* RequestTrackerImpl::GetRequestContext() { | 461 net::URLRequestContext* RequestTrackerImpl::GetRequestContext() { |
| 471 DCHECK_CURRENTLY_ON(web::WebThread::IO); | 462 DCHECK_CURRENTLY_ON(web::WebThread::IO); |
| 472 return request_context_getter_->GetURLRequestContext(); | 463 return request_context_getter_->GetURLRequestContext(); |
| 473 } | 464 } |
| 474 | 465 |
| 475 void RequestTrackerImpl::StartRequest(net::URLRequest* request) { | 466 void RequestTrackerImpl::StartRequest(net::URLRequest* request) { |
| 476 DCHECK_CURRENTLY_ON(web::WebThread::IO); | 467 DCHECK_CURRENTLY_ON(web::WebThread::IO); |
| 477 DCHECK(!counts_by_request_.count(request)); | 468 DCHECK(!counts_by_request_.count(request)); |
| 478 DCHECK_EQ(is_for_static_file_requests_, request->url().SchemeIsFile()); | 469 DCHECK(!request->url().SchemeIsFile()); |
| 479 | 470 |
| 480 if (new_estimate_round_) { | 471 if (new_estimate_round_) { |
| 481 // Starting a new estimate round. Ignore the previous requests for the | 472 // Starting a new estimate round. Ignore the previous requests for the |
| 482 // calculation. | 473 // calculation. |
| 483 counts_by_request_.clear(); | 474 counts_by_request_.clear(); |
| 484 estimate_start_index_ = counts_.size(); | 475 estimate_start_index_ = counts_.size(); |
| 485 new_estimate_round_ = false; | 476 new_estimate_round_ = false; |
| 486 } | 477 } |
| 487 const GURL& url = request->original_url(); | 478 const GURL& url = request->original_url(); |
| 488 auto counts = | 479 auto counts = |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 DCHECK(!counts->done); | 603 DCHECK(!counts->done); |
| 613 // Store the ssl error. | 604 // Store the ssl error. |
| 614 counts->ssl_info = ssl_info; | 605 counts->ssl_info = ssl_info; |
| 615 counts->ssl_callback = should_continue; | 606 counts->ssl_callback = should_continue; |
| 616 counts->ssl_judgment = | 607 counts->ssl_judgment = |
| 617 recoverable ? CertPolicy::UNKNOWN : CertPolicy::DENIED; | 608 recoverable ? CertPolicy::UNKNOWN : CertPolicy::DENIED; |
| 618 ReevaluateCallbacksForAllCounts(); | 609 ReevaluateCallbacksForAllCounts(); |
| 619 } | 610 } |
| 620 } | 611 } |
| 621 | 612 |
| 622 void RequestTrackerImpl::ErrorCallback(CRWSSLCarrier* carrier, bool allow) { | |
| 623 DCHECK_CURRENTLY_ON(web::WebThread::IO); | |
| 624 DCHECK(policy_cache_); | |
| 625 | |
| 626 if (allow) { | |
| 627 policy_cache_->AllowCertForHost([carrier sslInfo].cert.get(), | |
| 628 [carrier url].host(), | |
| 629 [carrier sslInfo].cert_status); | |
| 630 ReevaluateCallbacksForAllCounts(); | |
| 631 } | |
| 632 current_ssl_error_ = NULL; | |
| 633 } | |
| 634 | |
| 635 #pragma mark Client utility methods. | 613 #pragma mark Client utility methods. |
| 636 | 614 |
| 637 void RequestTrackerImpl::PostUITaskIfOpen(const base::Closure& task) { | 615 void RequestTrackerImpl::PostUITaskIfOpen(const base::Closure& task) { |
| 638 PostTask(task, web::WebThread::UI); | 616 PostTask(task, web::WebThread::UI); |
| 639 } | 617 } |
| 640 | 618 |
| 641 // static | 619 // static |
| 642 void RequestTrackerImpl::PostUITaskIfOpen( | 620 void RequestTrackerImpl::PostUITaskIfOpen( |
| 643 const base::WeakPtr<RequestTracker> tracker, | 621 const base::WeakPtr<RequestTracker> tracker, |
| 644 const base::Closure& task) { | 622 const base::Closure& task) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 661 #pragma mark Private Object Lifecycle API | 639 #pragma mark Private Object Lifecycle API |
| 662 | 640 |
| 663 RequestTrackerImpl::RequestTrackerImpl( | 641 RequestTrackerImpl::RequestTrackerImpl( |
| 664 NSString* request_group_id, | 642 NSString* request_group_id, |
| 665 net::URLRequestContextGetter* context_getter, | 643 net::URLRequestContextGetter* context_getter, |
| 666 id<CRWRequestTrackerDelegate> delegate) | 644 id<CRWRequestTrackerDelegate> delegate) |
| 667 : delegate_(delegate), | 645 : delegate_(delegate), |
| 668 previous_estimate_(0.0f), // Not active by default. | 646 previous_estimate_(0.0f), // Not active by default. |
| 669 estimate_start_index_(0), | 647 estimate_start_index_(0), |
| 670 notification_depth_(0), | 648 notification_depth_(0), |
| 671 current_ssl_error_(NULL), | |
| 672 has_mixed_content_(false), | 649 has_mixed_content_(false), |
| 673 is_loading_(false), | 650 is_loading_(false), |
| 674 new_estimate_round_(true), | 651 new_estimate_round_(true), |
| 675 is_for_static_file_requests_([delegate isForStaticFileRequests]), | |
| 676 request_context_getter_(context_getter), | 652 request_context_getter_(context_getter), |
| 677 identifier_(++g_next_request_tracker_id), | 653 identifier_(++g_next_request_tracker_id), |
| 678 request_group_id_([request_group_id copy]), | 654 request_group_id_([request_group_id copy]), |
| 679 is_closing_(false) { | 655 is_closing_(false) { |
| 680 DCHECK_CURRENTLY_ON(web::WebThread::UI); | 656 DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| 681 } | 657 } |
| 682 | 658 |
| 683 void RequestTrackerImpl::InitOnIOThread( | 659 void RequestTrackerImpl::InitOnIOThread( |
| 684 const scoped_refptr<CertificatePolicyCache>& policy_cache) { | 660 const scoped_refptr<CertificatePolicyCache>& policy_cache) { |
| 685 DCHECK_CURRENTLY_ON(web::WebThread::IO); | 661 DCHECK_CURRENTLY_ON(web::WebThread::IO); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 } | 797 } |
| 822 | 798 |
| 823 void RequestTrackerImpl::NotifyUpdatedSSLStatus( | 799 void RequestTrackerImpl::NotifyUpdatedSSLStatus( |
| 824 base::scoped_nsobject<CRWSSLCarrier> carrier) { | 800 base::scoped_nsobject<CRWSSLCarrier> carrier) { |
| 825 DCHECK_CURRENTLY_ON(web::WebThread::UI); | 801 DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| 826 [delegate_ updatedSSLStatus:[carrier sslStatus] | 802 [delegate_ updatedSSLStatus:[carrier sslStatus] |
| 827 forPageUrl:[carrier url] | 803 forPageUrl:[carrier url] |
| 828 userInfo:user_info_]; | 804 userInfo:user_info_]; |
| 829 } | 805 } |
| 830 | 806 |
| 831 void RequestTrackerImpl::NotifyPresentSSLError( | |
| 832 base::scoped_nsobject<CRWSSLCarrier> carrier, | |
| 833 bool recoverable) { | |
| 834 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
| 835 [delegate_ presentSSLError:[carrier sslInfo] | |
| 836 forSSLStatus:[carrier sslStatus] | |
| 837 onUrl:[carrier url] | |
| 838 recoverable:recoverable | |
| 839 callback:^(BOOL flag) { | |
| 840 [carrier errorCallback:flag && recoverable]; | |
| 841 }]; | |
| 842 } | |
| 843 | |
| 844 void RequestTrackerImpl::EvaluateSSLCallbackForCounts(TrackerCounts* counts) { | 807 void RequestTrackerImpl::EvaluateSSLCallbackForCounts(TrackerCounts* counts) { |
| 845 DCHECK_CURRENTLY_ON(web::WebThread::IO); | 808 DCHECK_CURRENTLY_ON(web::WebThread::IO); |
| 846 DCHECK(policy_cache_); | 809 DCHECK(policy_cache_); |
| 847 | 810 |
| 848 // Ignore non-SSL requests. | 811 // Ignore non-SSL requests. |
| 849 if (!counts->ssl_info.is_valid()) | 812 if (!counts->ssl_info.is_valid()) |
| 850 return; | 813 return; |
| 851 | 814 |
| 852 CertPolicy::Judgment judgment = | 815 CertPolicy::Judgment judgment = |
| 853 policy_cache_->QueryPolicy(counts->ssl_info.cert.get(), | 816 policy_cache_->QueryPolicy(counts->ssl_info.cert.get(), |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 | 877 |
| 915 void RequestTrackerImpl::ReevaluateCallbacksForAllCounts() { | 878 void RequestTrackerImpl::ReevaluateCallbacksForAllCounts() { |
| 916 DCHECK_CURRENTLY_ON(web::WebThread::IO); | 879 DCHECK_CURRENTLY_ON(web::WebThread::IO); |
| 917 if (is_closing_) | 880 if (is_closing_) |
| 918 return; | 881 return; |
| 919 | 882 |
| 920 for (const auto& tracker_count : counts_) { | 883 for (const auto& tracker_count : counts_) { |
| 921 // Check if the value hasn't changed via a user action. | 884 // Check if the value hasn't changed via a user action. |
| 922 if (tracker_count->ssl_judgment == CertPolicy::UNKNOWN) | 885 if (tracker_count->ssl_judgment == CertPolicy::UNKNOWN) |
| 923 EvaluateSSLCallbackForCounts(tracker_count.get()); | 886 EvaluateSSLCallbackForCounts(tracker_count.get()); |
| 924 | |
| 925 CertPolicy::Judgment judgment = tracker_count->ssl_judgment; | |
| 926 if (judgment == CertPolicy::ALLOWED) | |
| 927 continue; | |
| 928 | |
| 929 // SSL errors on subrequests are simply ignored. The call to | |
| 930 // EvaluateSSLCallbackForCounts() cancelled the request and nothing will | |
| 931 // restart it. | |
| 932 if (tracker_count->is_subrequest) | |
| 933 continue; | |
| 934 | |
| 935 if (!current_ssl_error_) { | |
| 936 // For the UNKNOWN and DENIED state the information should be pushed to | |
| 937 // the delegate. But only one at a time. | |
| 938 current_ssl_error_ = tracker_count.get(); | |
| 939 base::scoped_nsobject<CRWSSLCarrier> carrier([[CRWSSLCarrier alloc] | |
| 940 initWithTracker:this counts:current_ssl_error_]); | |
| 941 web::WebThread::PostTask( | |
| 942 web::WebThread::UI, FROM_HERE, | |
| 943 base::Bind(&RequestTrackerImpl::NotifyPresentSSLError, this, carrier, | |
| 944 judgment == CertPolicy::UNKNOWN)); | |
| 945 } | |
| 946 } | 887 } |
| 947 } | 888 } |
| 948 | 889 |
| 949 void RequestTrackerImpl::CancelRequestForCounts(TrackerCounts* counts) { | 890 void RequestTrackerImpl::CancelRequestForCounts(TrackerCounts* counts) { |
| 950 DCHECK_CURRENTLY_ON(web::WebThread::IO); | 891 DCHECK_CURRENTLY_ON(web::WebThread::IO); |
| 951 // Cancel the request. | 892 // Cancel the request. |
| 952 counts->done = true; | 893 counts->done = true; |
| 953 counts_by_request_.erase(counts->request); | 894 counts_by_request_.erase(counts->request); |
| 954 counts->ssl_callback.Run(NO); | 895 counts->ssl_callback.Run(NO); |
| 955 counts->ssl_callback = base::Bind(&DoNothing); | 896 counts->ssl_callback = base::Bind(&DoNothing); |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1228 net::NSURLWithGURL(page_url_), | 1169 net::NSURLWithGURL(page_url_), |
| 1229 [urls componentsJoinedByString:@"\n"]]; | 1170 [urls componentsJoinedByString:@"\n"]]; |
| 1230 } | 1171 } |
| 1231 | 1172 |
| 1232 void RequestTrackerImpl::SetCertificatePolicyCacheForTest( | 1173 void RequestTrackerImpl::SetCertificatePolicyCacheForTest( |
| 1233 web::CertificatePolicyCache* cache) { | 1174 web::CertificatePolicyCache* cache) { |
| 1234 policy_cache_ = cache; | 1175 policy_cache_ = cache; |
| 1235 } | 1176 } |
| 1236 | 1177 |
| 1237 } // namespace web | 1178 } // namespace web |
| OLD | NEW |