Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 #include "components/safe_browsing/password_protection/password_protection_reque st.h" | 4 #include "components/safe_browsing/password_protection/password_protection_reque st.h" |
| 5 | 5 |
| 6 #include "base/memory/ptr_util.h" | 6 #include "base/memory/ptr_util.h" |
| 7 #include "base/memory/weak_ptr.h" | 7 #include "base/memory/weak_ptr.h" |
| 8 #include "base/metrics/histogram_macros.h" | 8 #include "base/metrics/histogram_macros.h" |
| 9 #include "components/data_use_measurement/core/data_use_user_data.h" | 9 #include "components/data_use_measurement/core/data_use_user_data.h" |
| 10 #include "content/public/browser/browser_thread.h" | 10 #include "components/safe_browsing_db/database_manager.h" |
| 11 #include "net/base/escape.h" | 11 #include "net/base/escape.h" |
| 12 #include "net/base/load_flags.h" | 12 #include "net/base/load_flags.h" |
| 13 #include "net/base/url_util.h" | 13 #include "net/base/url_util.h" |
| 14 #include "net/http/http_status_code.h" | 14 #include "net/http/http_status_code.h" |
| 15 | 15 |
| 16 using content::BrowserThread; | 16 using content::BrowserThread; |
| 17 | 17 |
| 18 namespace safe_browsing { | 18 namespace safe_browsing { |
|
Nathan Parker
2017/04/18 23:07:26
Maybe it'd be good to have a state diagram on what
Jialiu Lin
2017/04/19 00:21:14
Added a flow diagram in the .h file.
| |
| 19 | 19 |
| 20 PasswordProtectionRequest::PasswordProtectionRequest( | 20 PasswordProtectionRequest::PasswordProtectionRequest( |
| 21 const GURL& main_frame_url, | 21 const GURL& main_frame_url, |
| 22 LoginReputationClientRequest::TriggerType type, | 22 LoginReputationClientRequest::TriggerType type, |
| 23 bool is_extended_reporting, | 23 std::unique_ptr<PasswordProtectionFrameList> pending_password_frames, |
| 24 bool is_incognito, | |
| 25 base::WeakPtr<PasswordProtectionService> pps, | 24 base::WeakPtr<PasswordProtectionService> pps, |
| 26 int request_timeout_in_ms) | 25 int request_timeout_in_ms) |
| 27 : main_frame_url_(main_frame_url), | 26 : main_frame_url_(main_frame_url), |
| 28 request_type_(type), | 27 request_type_(type), |
| 29 is_extended_reporting_(is_extended_reporting), | 28 pending_password_frames_(std::move(pending_password_frames)), |
| 30 is_incognito_(is_incognito), | |
| 31 password_protection_service_(pps), | 29 password_protection_service_(pps), |
| 30 database_manager_(password_protection_service_->database_manager()), | |
| 32 request_timeout_in_ms_(request_timeout_in_ms), | 31 request_timeout_in_ms_(request_timeout_in_ms), |
| 33 weakptr_factory_(this) { | 32 weakptr_factory_(this) { |
| 34 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 33 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 35 } | 34 } |
| 36 | 35 |
| 37 PasswordProtectionRequest::~PasswordProtectionRequest() { | 36 PasswordProtectionRequest::~PasswordProtectionRequest() { |
| 38 weakptr_factory_.InvalidateWeakPtrs(); | 37 weakptr_factory_.InvalidateWeakPtrs(); |
| 39 } | 38 } |
| 40 | 39 |
| 41 void PasswordProtectionRequest::Start() { | 40 void PasswordProtectionRequest::Start() { |
| 42 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 41 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 43 // Initially we only send ping for Safe Browsing Extended Reporting users when | 42 // Initially we only send ping for Safe Browsing Extended Reporting users when |
| 44 // they are not in incognito mode. We may loose these conditions later. | 43 // they are not in incognito mode. We may loose these conditions later. |
| 45 if (is_incognito_) { | 44 if (password_protection_service_->IsIncognito()) { |
| 46 Finish(RequestOutcome::INCOGNITO, nullptr); | 45 Finish(RequestOutcome::INCOGNITO, nullptr); |
| 47 return; | 46 return; |
| 48 } | 47 } |
| 49 if (!is_extended_reporting_) { | 48 if (!password_protection_service_->IsExtendedReporting()) { |
| 50 Finish(RequestOutcome::NO_EXTENDED_REPORTING, nullptr); | 49 Finish(RequestOutcome::NO_EXTENDED_REPORTING, nullptr); |
| 51 return; | 50 return; |
| 52 } | 51 } |
| 53 | 52 |
| 54 CheckWhitelistsOnUIThread(); | 53 CheckWhitelistOnUIThread(); |
| 55 } | 54 } |
| 56 | 55 |
| 57 void PasswordProtectionRequest::CheckWhitelistsOnUIThread() { | 56 void PasswordProtectionRequest::CheckWhitelistOnUIThread() { |
| 58 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 57 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 59 DCHECK(password_protection_service_); | 58 bool* match_whitelist = new bool(false); |
| 60 | 59 tracker_.PostTaskAndReply( |
| 61 BrowserThread::PostTask( | 60 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO).get(), FROM_HERE, |
| 62 BrowserThread::IO, FROM_HERE, | |
| 63 base::Bind(&PasswordProtectionService::CheckCsdWhitelistOnIOThread, | 61 base::Bind(&PasswordProtectionService::CheckCsdWhitelistOnIOThread, |
| 64 password_protection_service_, main_frame_url_, | 62 base::Unretained(password_protection_service_.get()), |
| 65 base::Bind(&PasswordProtectionRequest::OnWhitelistCheckDone, | 63 main_frame_url_, match_whitelist), |
| 66 GetWeakPtr()))); | 64 base::Bind(&PasswordProtectionRequest::OnWhitelistCheckDone, this, |
| 65 base::Owned(match_whitelist))); | |
| 67 } | 66 } |
| 68 | 67 |
| 69 void PasswordProtectionRequest::OnWhitelistCheckDone(bool match_whitelist) { | 68 void PasswordProtectionRequest::OnWhitelistCheckDone( |
| 69 const bool* match_whitelist) { | |
| 70 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 70 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 71 if (match_whitelist) | 71 if (*match_whitelist) |
| 72 Finish(RequestOutcome::MATCHED_WHITELIST, nullptr); | 72 Finish(RequestOutcome::MATCHED_WHITELIST, nullptr); |
| 73 else | 73 else |
| 74 CheckCachedVerdicts(); | 74 CheckCachedVerdicts(); |
| 75 } | 75 } |
| 76 | 76 |
| 77 void PasswordProtectionRequest::CheckCachedVerdicts() { | 77 void PasswordProtectionRequest::CheckCachedVerdicts() { |
| 78 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 78 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 79 if (!password_protection_service_) { | 79 if (!password_protection_service_) { |
| 80 Finish(RequestOutcome::SERVICE_DESTROYED, nullptr); | 80 Finish(RequestOutcome::SERVICE_DESTROYED, nullptr); |
| 81 return; | 81 return; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 93 | 93 |
| 94 void PasswordProtectionRequest::FillRequestProto() { | 94 void PasswordProtectionRequest::FillRequestProto() { |
| 95 request_proto_ = base::MakeUnique<LoginReputationClientRequest>(); | 95 request_proto_ = base::MakeUnique<LoginReputationClientRequest>(); |
| 96 request_proto_->set_page_url(main_frame_url_.spec()); | 96 request_proto_->set_page_url(main_frame_url_.spec()); |
| 97 request_proto_->set_trigger_type(request_type_); | 97 request_proto_->set_trigger_type(request_type_); |
| 98 request_proto_->set_stored_verdict_cnt( | 98 request_proto_->set_stored_verdict_cnt( |
| 99 password_protection_service_->GetStoredVerdictCount()); | 99 password_protection_service_->GetStoredVerdictCount()); |
| 100 LoginReputationClientRequest::Frame* main_frame = | 100 LoginReputationClientRequest::Frame* main_frame = |
| 101 request_proto_->add_frames(); | 101 request_proto_->add_frames(); |
| 102 main_frame->set_url(main_frame_url_.spec()); | 102 main_frame->set_url(main_frame_url_.spec()); |
| 103 main_frame->set_frame_index(0 /* main frame */); | |
| 104 main_frame->set_has_password_field(true); | |
| 103 password_protection_service_->FillReferrerChain( | 105 password_protection_service_->FillReferrerChain( |
| 104 main_frame_url_, -1 /* tab id not available */, main_frame); | 106 main_frame_url_, -1 /* tab id not available */, main_frame); |
| 105 // TODO(jialiul): Add sub-frame information and password form information. | 107 |
| 108 // TODO(jialiul): Fill more password form related info based on | |
| 109 // |password_frame_map_| when Safe Browsing backend is ready to handle these | |
| 110 // pieces of information. | |
| 106 } | 111 } |
| 107 | 112 |
| 108 void PasswordProtectionRequest::SendRequest() { | 113 void PasswordProtectionRequest::SendRequest() { |
| 109 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 114 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 110 FillRequestProto(); | 115 FillRequestProto(); |
| 111 | 116 |
| 112 std::string serialized_request; | 117 std::string serialized_request; |
| 113 if (!request_proto_->SerializeToString(&serialized_request)) { | 118 if (!request_proto_->SerializeToString(&serialized_request)) { |
| 114 Finish(RequestOutcome::REQUEST_MALFORMED, nullptr); | 119 Finish(RequestOutcome::REQUEST_MALFORMED, nullptr); |
| 115 return; | 120 return; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 132 fetcher_->Start(); | 137 fetcher_->Start(); |
| 133 } | 138 } |
| 134 | 139 |
| 135 void PasswordProtectionRequest::StartTimeout() { | 140 void PasswordProtectionRequest::StartTimeout() { |
| 136 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 141 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 137 | 142 |
| 138 // If request is not done withing 10 seconds, we cancel this request. | 143 // If request is not done withing 10 seconds, we cancel this request. |
| 139 // The weak pointer used for the timeout will be invalidated (and | 144 // The weak pointer used for the timeout will be invalidated (and |
| 140 // hence would prevent the timeout) if the check completes on time and | 145 // hence would prevent the timeout) if the check completes on time and |
| 141 // execution reaches Finish(). | 146 // execution reaches Finish(). |
| 142 BrowserThread::PostDelayedTask( | 147 BrowserThread::PostDelayedTask( |
|
Nathan Parker
2017/04/18 23:07:26
Should this use the tracker_ too, so it'll get can
Jialiu Lin
2017/04/19 00:21:14
Since this is posted to the same thread, WeakPtr w
| |
| 143 BrowserThread::UI, FROM_HERE, | 148 BrowserThread::UI, FROM_HERE, |
| 144 base::Bind(&PasswordProtectionRequest::Cancel, GetWeakPtr(), true), | 149 base::Bind(&PasswordProtectionRequest::Cancel, GetWeakPtr(), true), |
| 145 base::TimeDelta::FromMilliseconds(request_timeout_in_ms_)); | 150 base::TimeDelta::FromMilliseconds(request_timeout_in_ms_)); |
| 146 } | 151 } |
| 147 | 152 |
| 148 void PasswordProtectionRequest::OnURLFetchComplete( | 153 void PasswordProtectionRequest::OnURLFetchComplete( |
| 149 const net::URLFetcher* source) { | 154 const net::URLFetcher* source) { |
| 150 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 155 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 151 net::URLRequestStatus status = source->GetStatus(); | 156 net::URLRequestStatus status = source->GetStatus(); |
| 152 const bool is_success = status.is_success(); | 157 const bool is_success = status.is_success(); |
| 153 const int response_code = source->GetResponseCode(); | 158 const int response_code = source->GetResponseCode(); |
| 154 | 159 |
| 155 UMA_HISTOGRAM_SPARSE_SLOWLY( | 160 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 156 "PasswordProtection.PasswordProtectionResponseOrErrorCode", | 161 "PasswordProtection.PasswordProtectionResponseOrErrorCode", |
| 157 is_success ? response_code : status.error()); | 162 is_success ? response_code : status.error()); |
| 158 | 163 |
| 159 if (!is_success || net::HTTP_OK != response_code) { | 164 if (!is_success || net::HTTP_OK != response_code) { |
| 160 Finish(RequestOutcome::FETCH_FAILED, nullptr); | 165 Finish(RequestOutcome::FETCH_FAILED, nullptr); |
| 161 return; | 166 return; |
| 162 } | 167 } |
| 163 | 168 |
| 164 std::unique_ptr<LoginReputationClientResponse> response = | 169 std::unique_ptr<LoginReputationClientResponse> response = |
| 165 base::MakeUnique<LoginReputationClientResponse>(); | 170 base::MakeUnique<LoginReputationClientResponse>(); |
| 166 std::string response_body; | 171 std::string response_body; |
| 167 bool received_data = source->GetResponseAsString(&response_body); | 172 bool received_data = source->GetResponseAsString(&response_body); |
| 168 DCHECK(received_data); | 173 DCHECK(received_data); |
| 169 fetcher_.reset(); // We don't need it anymore. | 174 fetcher_.reset(); // We don't need it anymore. |
| 170 UMA_HISTOGRAM_TIMES("PasswordProtection.RequestNetworkDuration", | 175 UMA_HISTOGRAM_TIMES("PasswordProtection.RequestNetworkDuration", |
| 171 base::TimeTicks::Now() - request_start_time_); | 176 base::TimeTicks::Now() - request_start_time_); |
| 172 if (response->ParseFromString(response_body)) { | 177 if (response->ParseFromString(response_body)) |
| 173 Finish(RequestOutcome::SUCCEEDED, std::move(response)); | 178 Finish(RequestOutcome::SUCCEEDED, std::move(response)); |
| 174 } else { | 179 else |
| 175 Finish(RequestOutcome::RESPONSE_MALFORMED, nullptr); | 180 Finish(RequestOutcome::RESPONSE_MALFORMED, nullptr); |
| 176 } | |
| 177 } | 181 } |
| 178 | 182 |
| 179 void PasswordProtectionRequest::Finish( | 183 void PasswordProtectionRequest::Finish( |
| 180 RequestOutcome outcome, | 184 RequestOutcome outcome, |
| 181 std::unique_ptr<LoginReputationClientResponse> response) { | 185 std::unique_ptr<LoginReputationClientResponse> response) { |
| 182 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 186 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 187 tracker_.TryCancelAll(); | |
|
Nathan Parker
2017/04/18 23:07:26
Will this automatically get called in the destruct
Jialiu Lin
2017/04/19 00:21:14
Yes.
The destruction of PasswordProtectionRequest
| |
| 183 | 188 |
| 184 UMA_HISTOGRAM_ENUMERATION("PasswordProtection.RequestOutcome", outcome, | 189 UMA_HISTOGRAM_ENUMERATION("PasswordProtection.RequestOutcome", outcome, |
| 185 RequestOutcome::MAX_OUTCOME); | 190 RequestOutcome::MAX_OUTCOME); |
| 186 | 191 |
| 187 if (response) { | 192 if (response) { |
| 188 switch (request_type_) { | 193 switch (request_type_) { |
| 189 case LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE: | 194 case LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE: |
| 190 UMA_HISTOGRAM_ENUMERATION( | 195 UMA_HISTOGRAM_ENUMERATION( |
| 191 "PasswordProtection.UnfamiliarLoginPageVerdict", | 196 "PasswordProtection.UnfamiliarLoginPageVerdict", |
| 192 response->verdict_type(), | 197 response->verdict_type(), |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 208 } | 213 } |
| 209 | 214 |
| 210 void PasswordProtectionRequest::Cancel(bool timed_out) { | 215 void PasswordProtectionRequest::Cancel(bool timed_out) { |
| 211 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 216 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 212 fetcher_.reset(); | 217 fetcher_.reset(); |
| 213 | 218 |
| 214 Finish(timed_out ? TIMEDOUT : CANCELED, nullptr); | 219 Finish(timed_out ? TIMEDOUT : CANCELED, nullptr); |
| 215 } | 220 } |
| 216 | 221 |
| 217 } // namespace safe_browsing | 222 } // namespace safe_browsing |
| OLD | NEW |