| 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 #include "components/domain_reliability/monitor.h" | 5 #include "components/domain_reliability/monitor.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
| 11 #include "base/time/time.h" | 11 #include "base/time/time.h" |
| 12 #include "components/domain_reliability/baked_in_configs.h" | 12 #include "components/domain_reliability/baked_in_configs.h" |
| 13 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
| 14 #include "net/base/load_flags.h" | 14 #include "net/base/load_flags.h" |
| 15 #include "net/http/http_response_headers.h" |
| 15 #include "net/url_request/url_request.h" | 16 #include "net/url_request/url_request.h" |
| 16 #include "net/url_request/url_request_context.h" | 17 #include "net/url_request/url_request_context.h" |
| 17 #include "net/url_request/url_request_context_getter.h" | 18 #include "net/url_request/url_request_context_getter.h" |
| 18 | 19 |
| 19 namespace { | 20 namespace { |
| 20 | 21 |
| 21 bool OnIOThread() { | 22 bool OnIOThread() { |
| 22 return content::BrowserThread::CurrentlyOn(content::BrowserThread::IO); | 23 return content::BrowserThread::CurrentlyOn(content::BrowserThread::IO); |
| 23 } | 24 } |
| 24 | 25 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 // Record the redirect itself in addition to the final request. | 116 // Record the redirect itself in addition to the final request. |
| 116 OnRequestLegComplete(RequestInfo(*request)); | 117 OnRequestLegComplete(RequestInfo(*request)); |
| 117 } | 118 } |
| 118 | 119 |
| 119 void DomainReliabilityMonitor::OnCompleted(net::URLRequest* request, | 120 void DomainReliabilityMonitor::OnCompleted(net::URLRequest* request, |
| 120 bool started) { | 121 bool started) { |
| 121 DCHECK(OnIOThread()); | 122 DCHECK(OnIOThread()); |
| 122 if (!started) | 123 if (!started) |
| 123 return; | 124 return; |
| 124 RequestInfo request_info(*request); | 125 RequestInfo request_info(*request); |
| 125 if (request_info.DefinitelyReachedNetwork()) { | 126 if (request_info.AccessedNetwork()) { |
| 126 OnRequestLegComplete(request_info); | 127 OnRequestLegComplete(request_info); |
| 127 // A request was just using the network, so now is a good time to run any | 128 // A request was just using the network, so now is a good time to run any |
| 128 // pending and eligible uploads. | 129 // pending and eligible uploads. |
| 129 dispatcher_.RunEligibleTasks(); | 130 dispatcher_.RunEligibleTasks(); |
| 130 } | 131 } |
| 131 } | 132 } |
| 132 | 133 |
| 133 DomainReliabilityContext* DomainReliabilityMonitor::AddContextForTesting( | 134 DomainReliabilityContext* DomainReliabilityMonitor::AddContextForTesting( |
| 134 scoped_ptr<const DomainReliabilityConfig> config) { | 135 scoped_ptr<const DomainReliabilityConfig> config) { |
| 135 return AddContext(config.Pass()); | 136 return AddContext(config.Pass()); |
| 136 } | 137 } |
| 137 | 138 |
| 138 DomainReliabilityMonitor::RequestInfo::RequestInfo() {} | 139 DomainReliabilityMonitor::RequestInfo::RequestInfo() {} |
| 139 | 140 |
| 140 DomainReliabilityMonitor::RequestInfo::RequestInfo( | 141 DomainReliabilityMonitor::RequestInfo::RequestInfo( |
| 141 const net::URLRequest& request) | 142 const net::URLRequest& request) |
| 142 : url(request.url()), | 143 : url(request.url()), |
| 143 status(request.status()), | 144 status(request.status()), |
| 144 response_code(-1), | 145 response_info(request.response_info()), |
| 145 socket_address(request.GetSocketAddress()), | |
| 146 was_cached(request.was_cached()), | |
| 147 load_flags(request.load_flags()), | 146 load_flags(request.load_flags()), |
| 148 is_upload(DomainReliabilityUploader::URLRequestIsUpload(request)) { | 147 is_upload(DomainReliabilityUploader::URLRequestIsUpload(request)) { |
| 149 request.GetLoadTimingInfo(&load_timing_info); | 148 request.GetLoadTimingInfo(&load_timing_info); |
| 150 // Can't get response code of a canceled request -- there's no transaction. | |
| 151 if (status.status() != net::URLRequestStatus::CANCELED) | |
| 152 response_code = request.GetResponseCode(); | |
| 153 } | 149 } |
| 154 | 150 |
| 155 DomainReliabilityMonitor::RequestInfo::~RequestInfo() {} | 151 DomainReliabilityMonitor::RequestInfo::~RequestInfo() {} |
| 156 | 152 |
| 157 bool DomainReliabilityMonitor::RequestInfo::DefinitelyReachedNetwork() const { | 153 bool DomainReliabilityMonitor::RequestInfo::AccessedNetwork() const { |
| 158 return status.status() != net::URLRequestStatus::CANCELED && !was_cached; | 154 return status.status() != net::URLRequestStatus::CANCELED && |
| 155 response_info.network_accessed; |
| 159 } | 156 } |
| 160 | 157 |
| 161 DomainReliabilityContext* DomainReliabilityMonitor::AddContext( | 158 DomainReliabilityContext* DomainReliabilityMonitor::AddContext( |
| 162 scoped_ptr<const DomainReliabilityConfig> config) { | 159 scoped_ptr<const DomainReliabilityConfig> config) { |
| 163 DCHECK(config); | 160 DCHECK(config); |
| 164 DCHECK(config->IsValid()); | 161 DCHECK(config->IsValid()); |
| 165 | 162 |
| 166 // Grab a copy of the domain before transferring ownership of |config|. | 163 // Grab a copy of the domain before transferring ownership of |config|. |
| 167 std::string domain = config->domain; | 164 std::string domain = config->domain; |
| 168 | 165 |
| 169 DomainReliabilityContext* context = | 166 DomainReliabilityContext* context = |
| 170 new DomainReliabilityContext(time_.get(), | 167 new DomainReliabilityContext(time_.get(), |
| 171 scheduler_params_, | 168 scheduler_params_, |
| 172 upload_reporter_string_, | 169 upload_reporter_string_, |
| 173 &dispatcher_, | 170 &dispatcher_, |
| 174 uploader_.get(), | 171 uploader_.get(), |
| 175 config.Pass()); | 172 config.Pass()); |
| 176 | 173 |
| 177 std::pair<ContextMap::iterator, bool> map_it = | 174 std::pair<ContextMap::iterator, bool> map_it = |
| 178 contexts_.insert(make_pair(domain, context)); | 175 contexts_.insert(make_pair(domain, context)); |
| 179 // Make sure the domain wasn't already in the map. | 176 // Make sure the domain wasn't already in the map. |
| 180 DCHECK(map_it.second); | 177 DCHECK(map_it.second); |
| 181 | 178 |
| 182 return map_it.first->second; | 179 return map_it.first->second; |
| 183 } | 180 } |
| 184 | 181 |
| 185 void DomainReliabilityMonitor::OnRequestLegComplete( | 182 void DomainReliabilityMonitor::OnRequestLegComplete( |
| 186 const RequestInfo& request) { | 183 const RequestInfo& request) { |
| 187 if (!request.DefinitelyReachedNetwork()) | 184 int response_code; |
| 185 if (request.response_info.headers) |
| 186 response_code = request.response_info.headers->response_code(); |
| 187 else |
| 188 response_code = -1; |
| 189 ContextMap::iterator context_it; |
| 190 std::string beacon_status; |
| 191 |
| 192 // Ignore requests where: |
| 193 // 1. There is no context for the request host. |
| 194 // 2. The request did not access the network. |
| 195 // 3. The request is not supposed to send cookies (to avoid associating the |
| 196 // request with any potentially unique data in the config). |
| 197 // 4. The request was itself a Domain Reliability upload (to avoid loops). |
| 198 // 5. There is no defined beacon status for the error or HTTP response code |
| 199 // (to avoid leaking network-local errors). |
| 200 if ((context_it = contexts_.find(request.url.host())) == contexts_.end() || |
| 201 !request.AccessedNetwork() || |
| 202 (request.load_flags & net::LOAD_DO_NOT_SEND_COOKIES) || |
| 203 request.is_upload || |
| 204 !GetDomainReliabilityBeaconStatus( |
| 205 request.status.error(), response_code, &beacon_status)) { |
| 188 return; | 206 return; |
| 189 | 207 } |
| 190 // Don't monitor requests that are not sending cookies, since sending a beacon | |
| 191 // for such requests may allow the server to correlate that request with the | |
| 192 // user (by correlating a particular config). | |
| 193 if (request.load_flags & net::LOAD_DO_NOT_SEND_COOKIES) | |
| 194 return; | |
| 195 | |
| 196 // Don't monitor requests that were, themselves, Domain Reliability uploads, | |
| 197 // to avoid infinite chains of uploads. | |
| 198 if (request.is_upload) | |
| 199 return; | |
| 200 | |
| 201 ContextMap::iterator it = contexts_.find(request.url.host()); | |
| 202 if (it == contexts_.end()) | |
| 203 return; | |
| 204 DomainReliabilityContext* context = it->second; | |
| 205 | |
| 206 std::string beacon_status; | |
| 207 bool got_status = GetDomainReliabilityBeaconStatus( | |
| 208 request.status.error(), | |
| 209 request.response_code, | |
| 210 &beacon_status); | |
| 211 if (!got_status) | |
| 212 return; | |
| 213 | 208 |
| 214 DomainReliabilityBeacon beacon; | 209 DomainReliabilityBeacon beacon; |
| 215 beacon.status = beacon_status; | 210 beacon.status = beacon_status; |
| 216 beacon.chrome_error = request.status.error(); | 211 beacon.chrome_error = request.status.error(); |
| 217 beacon.server_ip = request.socket_address.host(); | 212 if (!request.response_info.was_fetched_via_proxy) |
| 218 beacon.http_response_code = request.response_code; | 213 beacon.server_ip = request.response_info.socket_address.host(); |
| 214 else |
| 215 beacon.server_ip.clear(); |
| 216 beacon.http_response_code = response_code; |
| 219 beacon.start_time = request.load_timing_info.request_start; | 217 beacon.start_time = request.load_timing_info.request_start; |
| 220 beacon.elapsed = time_->NowTicks() - beacon.start_time; | 218 beacon.elapsed = time_->NowTicks() - beacon.start_time; |
| 221 context->OnBeacon(request.url, beacon); | 219 context_it->second->OnBeacon(request.url, beacon); |
| 222 } | 220 } |
| 223 | 221 |
| 224 } // namespace domain_reliability | 222 } // namespace domain_reliability |
| OLD | NEW |