blob: 54a9c0c42cc46712b56b0f1ded1e06cd29a2e919 [file] [log] [blame]
[email protected]45de676a2014-03-18 23:52:021// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "components/domain_reliability/monitor.h"
6
dcheng51606352015-12-26 21:16:237#include <utility>
8
[email protected]45de676a2014-03-18 23:52:029#include "base/command_line.h"
[email protected]5f404b32014-04-22 17:16:1410#include "base/logging.h"
dcheng04a35cd2016-04-22 15:07:2411#include "base/memory/ptr_util.h"
vadimtc8397232014-12-19 17:34:1412#include "base/profiler/scoped_tracker.h"
[email protected]45de676a2014-03-18 23:52:0213#include "base/single_thread_task_runner.h"
[email protected]b5c2b742014-06-14 22:21:4214#include "base/task_runner.h"
[email protected]5f404b32014-04-22 17:16:1415#include "components/domain_reliability/baked_in_configs.h"
ttuttleccdd6cc52015-11-22 06:09:4016#include "components/domain_reliability/google_configs.h"
ttuttle2935096c2016-02-09 22:31:4417#include "components/domain_reliability/header.h"
ttuttleb1607372016-02-09 16:27:1618#include "components/domain_reliability/quic_error_mapping.h"
ttuttleccdd6cc52015-11-22 06:09:4019#include "net/base/ip_endpoint.h"
[email protected]48b99c92014-04-21 22:23:2020#include "net/base/load_flags.h"
ttuttle8feb0182015-05-15 23:40:3221#include "net/base/net_errors.h"
[email protected]563dc4762014-05-11 00:43:4922#include "net/http/http_response_headers.h"
[email protected]45de676a2014-03-18 23:52:0223#include "net/url_request/url_request.h"
24#include "net/url_request/url_request_context.h"
25#include "net/url_request/url_request_context_getter.h"
26
[email protected]45de676a2014-03-18 23:52:0227namespace domain_reliability {
28
ttuttle8feb0182015-05-15 23:40:3229namespace {
30
31int URLRequestStatusToNetError(const net::URLRequestStatus& status) {
32 switch (status.status()) {
33 case net::URLRequestStatus::SUCCESS:
34 return net::OK;
35 case net::URLRequestStatus::IO_PENDING:
36 return net::ERR_IO_PENDING;
37 case net::URLRequestStatus::CANCELED:
38 return net::ERR_ABORTED;
39 case net::URLRequestStatus::FAILED:
40 return status.error();
41 default:
42 NOTREACHED();
43 return net::ERR_UNEXPECTED;
44 }
45}
46
ttuttleccdd6cc52015-11-22 06:09:4047// Creates a new beacon based on |beacon_template| but fills in the status,
48// chrome_error, and server_ip fields based on the endpoint and result of
49// |attempt|.
50//
51// If there is no matching status for the result, returns false (which
52// means the attempt should not result in a beacon being reported).
dcheng04a35cd2016-04-22 15:07:2453std::unique_ptr<DomainReliabilityBeacon> CreateBeaconFromAttempt(
ttuttleccdd6cc52015-11-22 06:09:4054 const DomainReliabilityBeacon& beacon_template,
55 const net::ConnectionAttempt& attempt) {
56 std::string status;
ttuttle8feb0182015-05-15 23:40:3257 if (!GetDomainReliabilityBeaconStatus(
ttuttleccdd6cc52015-11-22 06:09:4058 attempt.result, beacon_template.http_response_code, &status)) {
dcheng04a35cd2016-04-22 15:07:2459 return std::unique_ptr<DomainReliabilityBeacon>();
ttuttle8feb0182015-05-15 23:40:3260 }
ttuttleccdd6cc52015-11-22 06:09:4061
dcheng04a35cd2016-04-22 15:07:2462 std::unique_ptr<DomainReliabilityBeacon> beacon(
ttuttleccdd6cc52015-11-22 06:09:4063 new DomainReliabilityBeacon(beacon_template));
64 beacon->status = status;
ttuttle8feb0182015-05-15 23:40:3265 beacon->chrome_error = attempt.result;
66 if (!attempt.endpoint.address().empty())
67 beacon->server_ip = attempt.endpoint.ToString();
68 else
69 beacon->server_ip = "";
dcheng51606352015-12-26 21:16:2370 return beacon;
ttuttle8feb0182015-05-15 23:40:3271}
72
ttuttle2935096c2016-02-09 22:31:4473const char* kDomainReliabilityHeaderName = "NEL";
74
ttuttle8feb0182015-05-15 23:40:3275} // namespace
76
[email protected]bda8e362014-03-24 18:21:0377DomainReliabilityMonitor::DomainReliabilityMonitor(
ttuttlefa8427f92014-08-25 19:38:0378 const std::string& upload_reporter_string,
grt2792ed72015-02-20 19:40:2179 const scoped_refptr<base::SingleThreadTaskRunner>& pref_thread,
80 const scoped_refptr<base::SingleThreadTaskRunner>& network_thread)
[email protected]bda8e362014-03-24 18:21:0381 : time_(new ActualTime()),
[email protected]84d2a492014-05-09 22:18:5082 upload_reporter_string_(upload_reporter_string),
[email protected]bda8e362014-03-24 18:21:0383 scheduler_params_(
84 DomainReliabilityScheduler::Params::GetFromFieldTrialsOrDefaults()),
85 dispatcher_(time_.get()),
ttuttleca1ac312015-03-12 17:07:0086 context_manager_(this),
ttuttlefa8427f92014-08-25 19:38:0387 pref_task_runner_(pref_thread),
88 network_task_runner_(network_thread),
89 moved_to_network_thread_(false),
ttuttle91f1bbd2014-10-07 05:57:5490 discard_uploads_set_(false),
ttuttlefa8427f92014-08-25 19:38:0391 weak_factory_(this) {
92 DCHECK(OnPrefThread());
ttuttle743f4ae2014-11-04 20:22:3293 net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
ttuttlefa8427f92014-08-25 19:38:0394}
[email protected]45de676a2014-03-18 23:52:0295
96DomainReliabilityMonitor::DomainReliabilityMonitor(
[email protected]84d2a492014-05-09 22:18:5097 const std::string& upload_reporter_string,
grt2792ed72015-02-20 19:40:2198 const scoped_refptr<base::SingleThreadTaskRunner>& pref_thread,
99 const scoped_refptr<base::SingleThreadTaskRunner>& network_thread,
dcheng04a35cd2016-04-22 15:07:24100 std::unique_ptr<MockableTime> time)
dcheng51606352015-12-26 21:16:23101 : time_(std::move(time)),
[email protected]84d2a492014-05-09 22:18:50102 upload_reporter_string_(upload_reporter_string),
[email protected]bda8e362014-03-24 18:21:03103 scheduler_params_(
104 DomainReliabilityScheduler::Params::GetFromFieldTrialsOrDefaults()),
105 dispatcher_(time_.get()),
ttuttleca1ac312015-03-12 17:07:00106 context_manager_(this),
ttuttlefa8427f92014-08-25 19:38:03107 pref_task_runner_(pref_thread),
108 network_task_runner_(network_thread),
109 moved_to_network_thread_(false),
ttuttle91f1bbd2014-10-07 05:57:54110 discard_uploads_set_(false),
ttuttlefa8427f92014-08-25 19:38:03111 weak_factory_(this) {
112 DCHECK(OnPrefThread());
ttuttle743f4ae2014-11-04 20:22:32113 net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
ttuttlefa8427f92014-08-25 19:38:03114}
[email protected]45de676a2014-03-18 23:52:02115
116DomainReliabilityMonitor::~DomainReliabilityMonitor() {
ttuttlefa8427f92014-08-25 19:38:03117 if (moved_to_network_thread_)
118 DCHECK(OnNetworkThread());
119 else
120 DCHECK(OnPrefThread());
121
ttuttle743f4ae2014-11-04 20:22:32122 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
[email protected]45de676a2014-03-18 23:52:02123}
124
ttuttlefa8427f92014-08-25 19:38:03125void DomainReliabilityMonitor::MoveToNetworkThread() {
126 DCHECK(OnPrefThread());
127 DCHECK(!moved_to_network_thread_);
128
ttuttlefa8427f92014-08-25 19:38:03129 moved_to_network_thread_ = true;
130}
131
ttuttlefa8427f92014-08-25 19:38:03132void DomainReliabilityMonitor::InitURLRequestContext(
133 net::URLRequestContext* url_request_context) {
134 DCHECK(OnNetworkThread());
135 DCHECK(moved_to_network_thread_);
[email protected]b5c2b742014-06-14 22:21:42136
137 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
138 new net::TrivialURLRequestContextGetter(url_request_context,
ttuttlefa8427f92014-08-25 19:38:03139 network_task_runner_);
140 InitURLRequestContext(url_request_context_getter);
[email protected]b5c2b742014-06-14 22:21:42141}
142
ttuttlefa8427f92014-08-25 19:38:03143void DomainReliabilityMonitor::InitURLRequestContext(
grt2792ed72015-02-20 19:40:21144 const scoped_refptr<net::URLRequestContextGetter>&
145 url_request_context_getter) {
ttuttlefa8427f92014-08-25 19:38:03146 DCHECK(OnNetworkThread());
147 DCHECK(moved_to_network_thread_);
[email protected]b5c2b742014-06-14 22:21:42148
ttuttlefa8427f92014-08-25 19:38:03149 // Make sure the URLRequestContext actually lives on what was declared to be
150 // the network thread.
[email protected]b5c2b742014-06-14 22:21:42151 DCHECK(url_request_context_getter->GetNetworkTaskRunner()->
152 RunsTasksOnCurrentThread());
153
ttuttle280a73d2014-11-13 21:38:04154 uploader_ = DomainReliabilityUploader::Create(time_.get(),
155 url_request_context_getter);
[email protected]b5c2b742014-06-14 22:21:42156}
157
[email protected]5f404b32014-04-22 17:16:14158void DomainReliabilityMonitor::AddBakedInConfigs() {
ttuttlefa8427f92014-08-25 19:38:03159 DCHECK(OnNetworkThread());
ttuttle91f1bbd2014-10-07 05:57:54160 DCHECK(moved_to_network_thread_);
ttuttlefa8427f92014-08-25 19:38:03161
[email protected]5f404b32014-04-22 17:16:14162 for (size_t i = 0; kBakedInJsonConfigs[i]; ++i) {
grt2792ed72015-02-20 19:40:21163 base::StringPiece json(kBakedInJsonConfigs[i]);
dcheng04a35cd2016-04-22 15:07:24164 std::unique_ptr<const DomainReliabilityConfig> config =
[email protected]5f404b32014-04-22 17:16:14165 DomainReliabilityConfig::FromJSON(json);
ttuttleccdd6cc52015-11-22 06:09:40166 if (!config) {
167 DLOG(WARNING) << "Baked-in Domain Reliability config failed to parse: "
168 << json;
grt2792ed72015-02-20 19:40:21169 continue;
ttuttleccdd6cc52015-11-22 06:09:40170 }
dcheng51606352015-12-26 21:16:23171 context_manager_.AddContextForConfig(std::move(config));
[email protected]5f404b32014-04-22 17:16:14172 }
ttuttleccdd6cc52015-11-22 06:09:40173
174 std::vector<DomainReliabilityConfig*> google_configs;
175 GetAllGoogleConfigs(&google_configs);
176 for (auto google_config : google_configs)
dcheng04a35cd2016-04-22 15:07:24177 context_manager_.AddContextForConfig(base::WrapUnique(google_config));
[email protected]5f404b32014-04-22 17:16:14178}
179
ttuttle91f1bbd2014-10-07 05:57:54180void DomainReliabilityMonitor::SetDiscardUploads(bool discard_uploads) {
181 DCHECK(OnNetworkThread());
182 DCHECK(moved_to_network_thread_);
183 DCHECK(uploader_);
184
185 uploader_->set_discard_uploads(discard_uploads);
186 discard_uploads_set_ = true;
187}
188
[email protected]45de676a2014-03-18 23:52:02189void DomainReliabilityMonitor::OnBeforeRedirect(net::URLRequest* request) {
ttuttlefa8427f92014-08-25 19:38:03190 DCHECK(OnNetworkThread());
ttuttle91f1bbd2014-10-07 05:57:54191 DCHECK(discard_uploads_set_);
ttuttlefa8427f92014-08-25 19:38:03192
[email protected]45de676a2014-03-18 23:52:02193 // Record the redirect itself in addition to the final request.
[email protected]84d2a492014-05-09 22:18:50194 OnRequestLegComplete(RequestInfo(*request));
[email protected]45de676a2014-03-18 23:52:02195}
196
197void DomainReliabilityMonitor::OnCompleted(net::URLRequest* request,
198 bool started) {
ttuttlefa8427f92014-08-25 19:38:03199 DCHECK(OnNetworkThread());
ttuttle91f1bbd2014-10-07 05:57:54200 DCHECK(discard_uploads_set_);
ttuttlefa8427f92014-08-25 19:38:03201
[email protected]45de676a2014-03-18 23:52:02202 if (!started)
203 return;
204 RequestInfo request_info(*request);
ttuttle8feb0182015-05-15 23:40:32205 OnRequestLegComplete(request_info);
206
207 if (request_info.response_info.network_accessed) {
[email protected]a5553ace2014-04-15 03:42:28208 // A request was just using the network, so now is a good time to run any
209 // pending and eligible uploads.
210 dispatcher_.RunEligibleTasks();
211 }
[email protected]45de676a2014-03-18 23:52:02212}
213
ttuttle743f4ae2014-11-04 20:22:32214void DomainReliabilityMonitor::OnNetworkChanged(
215 net::NetworkChangeNotifier::ConnectionType type) {
216 last_network_change_time_ = time_->NowTicks();
217}
218
[email protected]9b2034032014-05-11 18:10:31219void DomainReliabilityMonitor::ClearBrowsingData(
220 DomainReliabilityClearMode mode) {
ttuttlefa8427f92014-08-25 19:38:03221 DCHECK(OnNetworkThread());
[email protected]9b2034032014-05-11 18:10:31222
[email protected]9b2034032014-05-11 18:10:31223 switch (mode) {
ttuttleca1ac312015-03-12 17:07:00224 case CLEAR_BEACONS:
225 context_manager_.ClearBeaconsInAllContexts();
[email protected]9b2034032014-05-11 18:10:31226 break;
[email protected]9b2034032014-05-11 18:10:31227 case CLEAR_CONTEXTS:
ttuttleca1ac312015-03-12 17:07:00228 context_manager_.RemoveAllContexts();
[email protected]9b2034032014-05-11 18:10:31229 break;
230 case MAX_CLEAR_MODE:
231 NOTREACHED();
232 }
233}
234
dcheng04a35cd2016-04-22 15:07:24235std::unique_ptr<base::Value> DomainReliabilityMonitor::GetWebUIData() const {
ttuttlefa8427f92014-08-25 19:38:03236 DCHECK(OnNetworkThread());
237
dcheng04a35cd2016-04-22 15:07:24238 std::unique_ptr<base::DictionaryValue> data_value(
239 new base::DictionaryValue());
ttuttleca1ac312015-03-12 17:07:00240 data_value->Set("contexts", context_manager_.GetWebUIData());
dcheng51606352015-12-26 21:16:23241 return std::move(data_value);
[email protected]a6093f412014-07-10 00:57:09242}
243
[email protected]45de676a2014-03-18 23:52:02244DomainReliabilityContext* DomainReliabilityMonitor::AddContextForTesting(
dcheng04a35cd2016-04-22 15:07:24245 std::unique_ptr<const DomainReliabilityConfig> config) {
ttuttlefa8427f92014-08-25 19:38:03246 DCHECK(OnNetworkThread());
247
dcheng51606352015-12-26 21:16:23248 return context_manager_.AddContextForConfig(std::move(config));
ttuttleca1ac312015-03-12 17:07:00249}
250
dcheng04a35cd2016-04-22 15:07:24251std::unique_ptr<DomainReliabilityContext>
ttuttleca1ac312015-03-12 17:07:00252DomainReliabilityMonitor::CreateContextForConfig(
dcheng04a35cd2016-04-22 15:07:24253 std::unique_ptr<const DomainReliabilityConfig> config) {
ttuttleca1ac312015-03-12 17:07:00254 DCHECK(OnNetworkThread());
255 DCHECK(config);
256 DCHECK(config->IsValid());
257
dcheng04a35cd2016-04-22 15:07:24258 return base::WrapUnique(new DomainReliabilityContext(
dcheng51606352015-12-26 21:16:23259 time_.get(), scheduler_params_, upload_reporter_string_,
260 &last_network_change_time_, &dispatcher_, uploader_.get(),
261 std::move(config)));
[email protected]45de676a2014-03-18 23:52:02262}
263
264DomainReliabilityMonitor::RequestInfo::RequestInfo() {}
265
266DomainReliabilityMonitor::RequestInfo::RequestInfo(
267 const net::URLRequest& request)
268 : url(request.url()),
269 status(request.status()),
[email protected]563dc4762014-05-11 00:43:49270 response_info(request.response_info()),
[email protected]d1acfe02014-04-24 17:15:29271 load_flags(request.load_flags()),
ttuttle42144d8a2015-12-01 23:57:37272 upload_depth(
273 DomainReliabilityUploader::GetURLRequestUploadDepth(request)) {
[email protected]45de676a2014-03-18 23:52:02274 request.GetLoadTimingInfo(&load_timing_info);
ttuttle8feb0182015-05-15 23:40:32275 request.GetConnectionAttempts(&connection_attempts);
zhongyic51f4ed2015-12-08 00:41:13276 request.PopulateNetErrorDetails(&details);
ttuttle661a7b92015-09-29 22:36:33277 if (!request.GetRemoteEndpoint(&remote_endpoint))
278 remote_endpoint = net::IPEndPoint();
[email protected]45de676a2014-03-18 23:52:02279}
280
vmpstrb6449d512016-02-25 23:55:40281DomainReliabilityMonitor::RequestInfo::RequestInfo(const RequestInfo& other) =
282 default;
283
[email protected]45de676a2014-03-18 23:52:02284DomainReliabilityMonitor::RequestInfo::~RequestInfo() {}
285
ttuttle8feb0182015-05-15 23:40:32286// static
287bool DomainReliabilityMonitor::RequestInfo::ShouldReportRequest(
288 const DomainReliabilityMonitor::RequestInfo& request) {
ttuttle42144d8a2015-12-01 23:57:37289 // Don't report requests that weren't supposed to send cookies.
ttuttle8feb0182015-05-15 23:40:32290 if (request.load_flags & net::LOAD_DO_NOT_SEND_COOKIES)
291 return false;
ttuttle42144d8a2015-12-01 23:57:37292
ttuttle8feb0182015-05-15 23:40:32293 // Report requests that accessed the network or failed with an error code
294 // that Domain Reliability is interested in.
295 if (request.response_info.network_accessed)
296 return true;
297 if (URLRequestStatusToNetError(request.status) != net::OK)
298 return true;
zhongyi93fa5a92016-03-14 18:10:57299 if (request.details.quic_port_migration_detected)
300 return true;
ttuttle42144d8a2015-12-01 23:57:37301
ttuttle8feb0182015-05-15 23:40:32302 return false;
[email protected]a5553ace2014-04-15 03:42:28303}
304
[email protected]45de676a2014-03-18 23:52:02305void DomainReliabilityMonitor::OnRequestLegComplete(
306 const RequestInfo& request) {
ttuttle91f1bbd2014-10-07 05:57:54307 // Check these again because unit tests call this directly.
308 DCHECK(OnNetworkThread());
309 DCHECK(discard_uploads_set_);
310
ttuttle2935096c2016-02-09 22:31:44311 MaybeHandleHeader(request);
312
ttuttle8feb0182015-05-15 23:40:32313 if (!RequestInfo::ShouldReportRequest(request))
314 return;
315
[email protected]563dc4762014-05-11 00:43:49316 int response_code;
dcheng45252e8e2014-08-26 17:59:54317 if (request.response_info.headers.get())
[email protected]563dc4762014-05-11 00:43:49318 response_code = request.response_info.headers->response_code();
319 else
320 response_code = -1;
[email protected]563dc4762014-05-11 00:43:49321
ttuttle8feb0182015-05-15 23:40:32322 net::ConnectionAttempt url_request_attempt(
ttuttle661a7b92015-09-29 22:36:33323 request.remote_endpoint, URLRequestStatusToNetError(request.status));
ttuttle8feb0182015-05-15 23:40:32324
ttuttleccdd6cc52015-11-22 06:09:40325 DomainReliabilityBeacon beacon_template;
zhongyi2ed4a6a2016-02-26 19:45:42326 if (request.response_info.connection_info !=
327 net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN) {
328 beacon_template.protocol =
329 GetDomainReliabilityProtocol(request.response_info.connection_info,
330 request.response_info.ssl_info.is_valid());
331 } else {
332 // Use the connection info from the network error details if the response
333 // is unavailable.
334 beacon_template.protocol =
335 GetDomainReliabilityProtocol(request.details.connection_info,
336 request.response_info.ssl_info.is_valid());
337 }
zhongyi291d0302015-12-14 07:06:25338 GetDomainReliabilityBeaconQuicError(request.details.quic_connection_error,
339 &beacon_template.quic_error);
ttuttleccdd6cc52015-11-22 06:09:40340 beacon_template.http_response_code = response_code;
341 beacon_template.start_time = request.load_timing_info.request_start;
342 beacon_template.elapsed = time_->NowTicks() - beacon_template.start_time;
343 beacon_template.was_proxied = request.response_info.was_fetched_via_proxy;
344 beacon_template.url = request.url;
ttuttle42144d8a2015-12-01 23:57:37345 beacon_template.upload_depth = request.upload_depth;
zhongyic51f4ed2015-12-08 00:41:13346 beacon_template.details = request.details;
ttuttle8feb0182015-05-15 23:40:32347
348 // This is not foolproof -- it's possible that we'll see the same error twice
349 // (e.g. an SSL error during connection on one attempt, and then an error
350 // that maps to the same code during a read).
ttuttle960fcbf2016-04-19 13:26:32351 // TODO(juliatuttle): Find a way for this code to reliably tell whether we
ttuttle8feb0182015-05-15 23:40:32352 // eventually established a connection or not.
353 bool url_request_attempt_is_duplicate = false;
354 for (const auto& attempt : request.connection_attempts) {
355 if (attempt.result == url_request_attempt.result)
356 url_request_attempt_is_duplicate = true;
ttuttleccdd6cc52015-11-22 06:09:40357
dcheng04a35cd2016-04-22 15:07:24358 std::unique_ptr<DomainReliabilityBeacon> beacon =
ttuttleccdd6cc52015-11-22 06:09:40359 CreateBeaconFromAttempt(beacon_template, attempt);
360 if (beacon)
dcheng51606352015-12-26 21:16:23361 context_manager_.RouteBeacon(std::move(beacon));
ttuttle8feb0182015-05-15 23:40:32362 }
363
364 if (url_request_attempt_is_duplicate)
365 return;
ttuttleccdd6cc52015-11-22 06:09:40366
dcheng04a35cd2016-04-22 15:07:24367 std::unique_ptr<DomainReliabilityBeacon> beacon =
ttuttleccdd6cc52015-11-22 06:09:40368 CreateBeaconFromAttempt(beacon_template, url_request_attempt);
369 if (beacon)
dcheng51606352015-12-26 21:16:23370 context_manager_.RouteBeacon(std::move(beacon));
[email protected]45de676a2014-03-18 23:52:02371}
372
ttuttle2935096c2016-02-09 22:31:44373void DomainReliabilityMonitor::MaybeHandleHeader(
374 const RequestInfo& request) {
375 if (!request.response_info.headers.get())
376 return;
377
378 size_t iter = 0;
379 std::string kHeaderNameString(kDomainReliabilityHeaderName);
380
381 std::string header_value;
382 if (!request.response_info.headers->EnumerateHeader(
383 &iter, kHeaderNameString, &header_value)) {
384 // No header found.
385 return;
386 }
387
388 std::string ignored_header_value;
389 if (request.response_info.headers->EnumerateHeader(
390 &iter, kHeaderNameString, &ignored_header_value)) {
391 LOG(WARNING) << "Request to " << request.url << " had (at least) two "
392 << kHeaderNameString << " headers: \"" << header_value
393 << "\" and \"" << ignored_header_value << "\".";
394 return;
395 }
396
dcheng04a35cd2016-04-22 15:07:24397 std::unique_ptr<DomainReliabilityHeader> parsed =
ttuttle2935096c2016-02-09 22:31:44398 DomainReliabilityHeader::Parse(header_value);
399 GURL origin = request.url.GetOrigin();
400 switch (parsed->status()) {
401 case DomainReliabilityHeader::PARSE_SET_CONFIG:
402 {
403 base::TimeDelta max_age = parsed->max_age();
404 context_manager_.SetConfig(origin, parsed->ReleaseConfig(), max_age);
405 }
406 break;
407 case DomainReliabilityHeader::PARSE_CLEAR_CONFIG:
408 context_manager_.ClearConfig(origin);
409 break;
410 case DomainReliabilityHeader::PARSE_ERROR:
411 LOG(WARNING) << "Request to " << request.url << " had invalid "
412 << kHeaderNameString << " header \"" << header_value
413 << "\".";
414 break;
415 }
416}
417
[email protected]b5c2b742014-06-14 22:21:42418base::WeakPtr<DomainReliabilityMonitor>
419DomainReliabilityMonitor::MakeWeakPtr() {
420 return weak_factory_.GetWeakPtr();
421}
422
[email protected]45de676a2014-03-18 23:52:02423} // namespace domain_reliability