Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(448)

Side by Side Diff: components/domain_reliability/monitor.cc

Issue 1095553004: Domain Reliability: Create beacons from ConnectionAttempts. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@domrel_serverip2
Patch Set: Clarify logic in ShouldReportRequets Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/domain_reliability/monitor.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/profiler/scoped_tracker.h" 9 #include "base/profiler/scoped_tracker.h"
10 #include "base/single_thread_task_runner.h" 10 #include "base/single_thread_task_runner.h"
11 #include "base/task_runner.h" 11 #include "base/task_runner.h"
12 #include "base/time/time.h" 12 #include "base/time/time.h"
13 #include "components/domain_reliability/baked_in_configs.h" 13 #include "components/domain_reliability/baked_in_configs.h"
14 #include "net/base/ip_endpoint.h"
14 #include "net/base/load_flags.h" 15 #include "net/base/load_flags.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/net_util.h"
15 #include "net/http/http_response_headers.h" 18 #include "net/http/http_response_headers.h"
16 #include "net/url_request/url_request.h" 19 #include "net/url_request/url_request.h"
17 #include "net/url_request/url_request_context.h" 20 #include "net/url_request/url_request_context.h"
18 #include "net/url_request/url_request_context_getter.h" 21 #include "net/url_request/url_request_context_getter.h"
19 22
20 namespace domain_reliability { 23 namespace domain_reliability {
21 24
25 namespace {
26
27 int URLRequestStatusToNetError(const net::URLRequestStatus& status) {
28 switch (status.status()) {
29 case net::URLRequestStatus::SUCCESS:
30 return net::OK;
31 case net::URLRequestStatus::IO_PENDING:
32 return net::ERR_IO_PENDING;
33 case net::URLRequestStatus::CANCELED:
34 return net::ERR_ABORTED;
35 case net::URLRequestStatus::FAILED:
36 return status.error();
37 default:
38 NOTREACHED();
39 return net::ERR_UNEXPECTED;
40 }
41 }
42
43 // Updates the status, chrome_error, and server_ip fields of |beacon| from
44 // the endpoint and result of |attempt|. If there is no matching status for
45 // the result, returns false (which means the attempt should not result in a
46 // beacon being reported).
47 bool UpdateBeaconFromAttempt(DomainReliabilityBeacon* beacon,
48 const net::ConnectionAttempt& attempt) {
49 if (!GetDomainReliabilityBeaconStatus(
50 attempt.result, beacon->http_response_code, &beacon->status)) {
51 return false;
52 }
53 beacon->chrome_error = attempt.result;
54 if (!attempt.endpoint.address().empty())
55 beacon->server_ip = attempt.endpoint.ToString();
56 else
57 beacon->server_ip = "";
58 return true;
59 }
60
61 // TODO(ttuttle): This function is absurd. See if |socket_address| in
62 // HttpResponseInfo can become an IPEndPoint.
63 bool ConvertHostPortPairToIPEndPoint(const net::HostPortPair& host_port_pair,
64 net::IPEndPoint* ip_endpoint_out) {
65 net::IPAddressNumber ip_address_number;
66 if (!net::ParseIPLiteralToNumber(host_port_pair.host(), &ip_address_number))
67 return false;
68 *ip_endpoint_out = net::IPEndPoint(ip_address_number, host_port_pair.port());
69 return true;
70 }
71
72 } // namespace
73
22 DomainReliabilityMonitor::DomainReliabilityMonitor( 74 DomainReliabilityMonitor::DomainReliabilityMonitor(
23 const std::string& upload_reporter_string, 75 const std::string& upload_reporter_string,
24 const scoped_refptr<base::SingleThreadTaskRunner>& pref_thread, 76 const scoped_refptr<base::SingleThreadTaskRunner>& pref_thread,
25 const scoped_refptr<base::SingleThreadTaskRunner>& network_thread) 77 const scoped_refptr<base::SingleThreadTaskRunner>& network_thread)
26 : time_(new ActualTime()), 78 : time_(new ActualTime()),
27 upload_reporter_string_(upload_reporter_string), 79 upload_reporter_string_(upload_reporter_string),
28 scheduler_params_( 80 scheduler_params_(
29 DomainReliabilityScheduler::Params::GetFromFieldTrialsOrDefaults()), 81 DomainReliabilityScheduler::Params::GetFromFieldTrialsOrDefaults()),
30 dispatcher_(time_.get()), 82 dispatcher_(time_.get()),
31 context_manager_(this), 83 context_manager_(this),
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 } 195 }
144 196
145 void DomainReliabilityMonitor::OnCompleted(net::URLRequest* request, 197 void DomainReliabilityMonitor::OnCompleted(net::URLRequest* request,
146 bool started) { 198 bool started) {
147 DCHECK(OnNetworkThread()); 199 DCHECK(OnNetworkThread());
148 DCHECK(discard_uploads_set_); 200 DCHECK(discard_uploads_set_);
149 201
150 if (!started) 202 if (!started)
151 return; 203 return;
152 RequestInfo request_info(*request); 204 RequestInfo request_info(*request);
153 if (request_info.AccessedNetwork()) { 205 OnRequestLegComplete(request_info);
154 OnRequestLegComplete(request_info); 206
207 if (request_info.response_info.network_accessed) {
155 // A request was just using the network, so now is a good time to run any 208 // A request was just using the network, so now is a good time to run any
156 // pending and eligible uploads. 209 // pending and eligible uploads.
157 dispatcher_.RunEligibleTasks(); 210 dispatcher_.RunEligibleTasks();
158 } 211 }
159 } 212 }
160 213
161 void DomainReliabilityMonitor::OnNetworkChanged( 214 void DomainReliabilityMonitor::OnNetworkChanged(
162 net::NetworkChangeNotifier::ConnectionType type) { 215 net::NetworkChangeNotifier::ConnectionType type) {
163 last_network_change_time_ = time_->NowTicks(); 216 last_network_change_time_ = time_->NowTicks();
164 } 217 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 DomainReliabilityMonitor::RequestInfo::RequestInfo() {} 267 DomainReliabilityMonitor::RequestInfo::RequestInfo() {}
215 268
216 DomainReliabilityMonitor::RequestInfo::RequestInfo( 269 DomainReliabilityMonitor::RequestInfo::RequestInfo(
217 const net::URLRequest& request) 270 const net::URLRequest& request)
218 : url(request.url()), 271 : url(request.url()),
219 status(request.status()), 272 status(request.status()),
220 response_info(request.response_info()), 273 response_info(request.response_info()),
221 load_flags(request.load_flags()), 274 load_flags(request.load_flags()),
222 is_upload(DomainReliabilityUploader::URLRequestIsUpload(request)) { 275 is_upload(DomainReliabilityUploader::URLRequestIsUpload(request)) {
223 request.GetLoadTimingInfo(&load_timing_info); 276 request.GetLoadTimingInfo(&load_timing_info);
277 request.GetConnectionAttempts(&connection_attempts);
224 } 278 }
225 279
226 DomainReliabilityMonitor::RequestInfo::~RequestInfo() {} 280 DomainReliabilityMonitor::RequestInfo::~RequestInfo() {}
227 281
228 bool DomainReliabilityMonitor::RequestInfo::AccessedNetwork() const { 282 // static
229 return status.status() != net::URLRequestStatus::CANCELED && 283 bool DomainReliabilityMonitor::RequestInfo::ShouldReportRequest(
230 response_info.network_accessed; 284 const DomainReliabilityMonitor::RequestInfo& request) {
285 // Don't report requests for Domain Reliability uploads or that weren't
286 // supposed to send cookies.
287 if (request.is_upload)
288 return false;
289 if (request.load_flags & net::LOAD_DO_NOT_SEND_COOKIES)
290 return false;
291 // Report requests that accessed the network or failed with an error code
292 // that Domain Reliability is interested in.
293 if (request.response_info.network_accessed)
294 return true;
295 if (URLRequestStatusToNetError(request.status) != net::OK)
296 return true;
297 return false;
231 } 298 }
232 299
233 void DomainReliabilityMonitor::OnRequestLegComplete( 300 void DomainReliabilityMonitor::OnRequestLegComplete(
234 const RequestInfo& request) { 301 const RequestInfo& request) {
235 // Check these again because unit tests call this directly. 302 // Check these again because unit tests call this directly.
236 DCHECK(OnNetworkThread()); 303 DCHECK(OnNetworkThread());
237 DCHECK(discard_uploads_set_); 304 DCHECK(discard_uploads_set_);
238 305
306 if (!RequestInfo::ShouldReportRequest(request))
307 return;
308
239 int response_code; 309 int response_code;
240 if (request.response_info.headers.get()) 310 if (request.response_info.headers.get())
241 response_code = request.response_info.headers->response_code(); 311 response_code = request.response_info.headers->response_code();
242 else 312 else
243 response_code = -1; 313 response_code = -1;
244 std::string beacon_status;
245 314
246 int error_code = net::OK; 315 net::IPEndPoint url_request_endpoint;
247 if (request.status.status() == net::URLRequestStatus::FAILED) 316 // If response was cached, socket address will be from the serialized
248 error_code = request.status.error(); 317 // response info in the cache, so don't report it.
249 318 // TODO(ttuttle): Plumb out the "current" socket address so we can always
250 // Ignore requests where: 319 // report it.
251 // 1. The request did not access the network. 320 if (!request.response_info.was_cached &&
252 // 2. The request is not supposed to send cookies (to avoid associating the 321 !request.response_info.was_fetched_via_proxy) {
253 // request with any potentially unique data in the config). 322 ConvertHostPortPairToIPEndPoint(request.response_info.socket_address,
254 // 3. The request was itself a Domain Reliability upload (to avoid loops). 323 &url_request_endpoint);
255 // 4. There is no matching beacon status for the error or HTTP response code
256 // (to avoid leaking network-local errors).
257 if (!request.AccessedNetwork() ||
258 (request.load_flags & net::LOAD_DO_NOT_SEND_COOKIES) ||
259 request.is_upload ||
260 !GetDomainReliabilityBeaconStatus(
261 error_code, response_code, &beacon_status)) {
262 return;
263 } 324 }
264 325
326 net::ConnectionAttempt url_request_attempt(
327 url_request_endpoint, URLRequestStatusToNetError(request.status));
328
265 DomainReliabilityBeacon beacon; 329 DomainReliabilityBeacon beacon;
266 beacon.status = beacon_status;
267 beacon.chrome_error = error_code;
268 // If the response was cached, the socket address was the address that the
269 // response was originally received from, so it shouldn't be copied into the
270 // beacon.
271 //
272 // TODO(ttuttle): Wire up a way to get the real socket address in that case.
273 if (!request.response_info.was_cached &&
274 !request.response_info.was_fetched_via_proxy) {
275 beacon.server_ip = request.response_info.socket_address.host();
276 }
277 beacon.protocol = GetDomainReliabilityProtocol( 330 beacon.protocol = GetDomainReliabilityProtocol(
278 request.response_info.connection_info, 331 request.response_info.connection_info,
279 request.response_info.ssl_info.is_valid()); 332 request.response_info.ssl_info.is_valid());
280 beacon.http_response_code = response_code; 333 beacon.http_response_code = response_code;
281 beacon.start_time = request.load_timing_info.request_start; 334 beacon.start_time = request.load_timing_info.request_start;
282 beacon.elapsed = time_->NowTicks() - beacon.start_time; 335 beacon.elapsed = time_->NowTicks() - beacon.start_time;
283 beacon.was_proxied = request.response_info.was_fetched_via_proxy; 336 beacon.was_proxied = request.response_info.was_fetched_via_proxy;
284 beacon.domain = request.url.host(); 337 beacon.domain = request.url.host();
338
339 // This is not foolproof -- it's possible that we'll see the same error twice
340 // (e.g. an SSL error during connection on one attempt, and then an error
341 // that maps to the same code during a read).
342 // TODO(ttuttle): Find a way for this code to reliably tell whether we
343 // eventually established a connection or not.
344 bool url_request_attempt_is_duplicate = false;
345 for (const auto& attempt : request.connection_attempts) {
346 if (attempt.result == url_request_attempt.result)
347 url_request_attempt_is_duplicate = true;
348 if (!UpdateBeaconFromAttempt(&beacon, attempt))
349 continue;
350 context_manager_.RouteBeacon(request.url, beacon);
351 }
352
353 if (url_request_attempt_is_duplicate)
354 return;
355 if (!UpdateBeaconFromAttempt(&beacon, url_request_attempt))
356 return;
285 context_manager_.RouteBeacon(request.url, beacon); 357 context_manager_.RouteBeacon(request.url, beacon);
286 } 358 }
287 359
288 base::WeakPtr<DomainReliabilityMonitor> 360 base::WeakPtr<DomainReliabilityMonitor>
289 DomainReliabilityMonitor::MakeWeakPtr() { 361 DomainReliabilityMonitor::MakeWeakPtr() {
290 return weak_factory_.GetWeakPtr(); 362 return weak_factory_.GetWeakPtr();
291 } 363 }
292 364
293 } // namespace domain_reliability 365 } // namespace domain_reliability
OLDNEW
« no previous file with comments | « components/domain_reliability/monitor.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698