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
3 // found in the LICENSE file.
5 #include "components/domain_reliability/monitor.h"
7 #include "base/command_line.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/single_thread_task_runner.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "net/url_request/url_request.h"
12 #include "net/url_request/url_request_context.h"
13 #include "net/url_request/url_request_context_getter.h"
18 return content::BrowserThread::CurrentlyOn(content::BrowserThread::IO
);
21 // Shamelessly stolen from net/tools/get_server_time/get_server_time.cc.
22 // TODO(ttuttle): Merge them, if possible.
23 class TrivialURLRequestContextGetter
: public net::URLRequestContextGetter
{
25 TrivialURLRequestContextGetter(
26 net::URLRequestContext
* context
,
27 const scoped_refptr
<base::SingleThreadTaskRunner
>& main_task_runner
)
29 main_task_runner_(main_task_runner
) {}
31 // net::URLRequestContextGEtter implementation:
32 virtual net::URLRequestContext
* GetURLRequestContext() OVERRIDE
{
36 virtual scoped_refptr
<base::SingleThreadTaskRunner
>
37 GetNetworkTaskRunner() const OVERRIDE
{
38 return main_task_runner_
;
42 virtual ~TrivialURLRequestContextGetter() {}
44 net::URLRequestContext
* context_
;
45 const scoped_refptr
<base::SingleThreadTaskRunner
> main_task_runner_
;
50 namespace domain_reliability
{
52 DomainReliabilityMonitor::DomainReliabilityMonitor(
53 net::URLRequestContext
* url_request_context
)
54 : time_(new ActualTime()),
55 url_request_context_getter_(scoped_refptr
<net::URLRequestContextGetter
>(
56 new TrivialURLRequestContextGetter(
58 content::BrowserThread::GetMessageLoopProxyForThread(
59 content::BrowserThread::IO
)))),
61 DomainReliabilityScheduler::Params::GetFromFieldTrialsOrDefaults()),
62 dispatcher_(time_
.get()),
64 DomainReliabilityUploader::Create(url_request_context_getter_
)) {
68 DomainReliabilityMonitor::DomainReliabilityMonitor(
69 net::URLRequestContext
* url_request_context
,
70 scoped_ptr
<MockableTime
> time
)
72 url_request_context_getter_(scoped_refptr
<net::URLRequestContextGetter
>(
73 new TrivialURLRequestContextGetter(
75 content::BrowserThread::GetMessageLoopProxyForThread(
76 content::BrowserThread::IO
)))),
78 DomainReliabilityScheduler::Params::GetFromFieldTrialsOrDefaults()),
79 dispatcher_(time_
.get()),
81 DomainReliabilityUploader::Create(url_request_context_getter_
)) {
85 DomainReliabilityMonitor::~DomainReliabilityMonitor() {
87 STLDeleteContainerPairSecondPointers(
88 contexts_
.begin(), contexts_
.end());
91 void DomainReliabilityMonitor::OnBeforeRedirect(net::URLRequest
* request
) {
93 RequestInfo
request_info(*request
);
94 // Record the redirect itself in addition to the final request.
95 OnRequestLegComplete(request_info
);
98 void DomainReliabilityMonitor::OnCompleted(net::URLRequest
* request
,
100 DCHECK(OnIOThread());
103 RequestInfo
request_info(*request
);
104 OnRequestLegComplete(request_info
);
107 DomainReliabilityContext
* DomainReliabilityMonitor::AddContextForTesting(
108 scoped_ptr
<const DomainReliabilityConfig
> config
) {
109 DomainReliabilityContext
*& context_ref
= contexts_
[config
->domain
];
110 DCHECK(!context_ref
);
111 context_ref
= new DomainReliabilityContext(
120 DomainReliabilityMonitor::RequestInfo::RequestInfo() {}
122 DomainReliabilityMonitor::RequestInfo::RequestInfo(
123 const net::URLRequest
& request
)
124 : url(request
.url()),
125 status(request
.status()),
127 socket_address(request
.GetSocketAddress()),
128 was_cached(request
.was_cached()) {
129 request
.GetLoadTimingInfo(&load_timing_info
);
130 // Can't get response code of a canceled request -- there's no transaction.
131 if (status
.status() != net::URLRequestStatus::CANCELED
)
132 response_code
= request
.GetResponseCode();
135 DomainReliabilityMonitor::RequestInfo::~RequestInfo() {}
137 void DomainReliabilityMonitor::OnRequestLegComplete(
138 const RequestInfo
& request
) {
139 if (request
.was_cached
||
140 request
.status
.status() == net::URLRequestStatus::CANCELED
) {
144 std::map
<std::string
, DomainReliabilityContext
*>::iterator it
=
145 contexts_
.find(request
.url
.host());
146 if (it
== contexts_
.end())
148 DomainReliabilityContext
* context
= it
->second
;
150 std::string beacon_status
;
151 bool got_status
= DomainReliabilityUtil::GetBeaconStatus(
152 request
.status
.error(),
153 request
.response_code
,
158 DomainReliabilityBeacon beacon
;
159 beacon
.status
= beacon_status
;
160 beacon
.chrome_error
= request
.status
.error();
161 beacon
.server_ip
= request
.socket_address
.host();
162 beacon
.http_response_code
= request
.response_code
;
163 beacon
.start_time
= request
.load_timing_info
.request_start
;
164 beacon
.elapsed
= time_
->Now() - beacon
.start_time
;
165 context
->AddBeacon(beacon
, request
.url
);
168 } // namespace domain_reliability