Popular sites on the NTP: re-download popular suggestions once per Chrome run
[chromium-blink-merge.git] / chrome / browser / devtools / devtools_network_transaction.cc
blob12881cb097f930b812b32b2092ab53003db4adf4
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 "chrome/browser/devtools/devtools_network_transaction.h"
7 #include "chrome/browser/devtools/devtools_network_controller.h"
8 #include "chrome/browser/devtools/devtools_network_interceptor.h"
9 #include "net/base/net_errors.h"
10 #include "net/base/upload_progress.h"
11 #include "net/http/http_network_transaction.h"
12 #include "net/http/http_request_info.h"
13 #include "net/socket/connection_attempts.h"
15 // Keep in sync with kDevToolsRequestInitiator and
16 // kDevToolsEmulateNetworkConditionsClientId defined in
17 // InspectorResourceAgent.cpp.
18 const char DevToolsNetworkTransaction::kDevToolsRequestInitiator[] =
19 "X-DevTools-Request-Initiator";
20 const char
21 DevToolsNetworkTransaction::kDevToolsEmulateNetworkConditionsClientId[] =
22 "X-DevTools-Emulate-Network-Conditions-Client-Id";
24 DevToolsNetworkTransaction::DevToolsNetworkTransaction(
25 DevToolsNetworkController* controller,
26 scoped_ptr<net::HttpTransaction> network_transaction)
27 : controller_(controller),
28 network_transaction_(network_transaction.Pass()),
29 request_(NULL),
30 failed_(false),
31 throttled_byte_count_(0),
32 callback_type_(NONE),
33 proxy_callback_(base::Bind(&DevToolsNetworkTransaction::OnCallback,
34 base::Unretained(this))) {
35 DCHECK(controller);
38 DevToolsNetworkTransaction::~DevToolsNetworkTransaction() {
39 if (interceptor_)
40 interceptor_->RemoveTransaction(this);
43 void DevToolsNetworkTransaction::Throttle(int result) {
44 throttled_result_ = result;
46 if (callback_type_ == START)
47 throttled_byte_count_ += network_transaction_->GetTotalReceivedBytes();
48 if (result > 0)
49 throttled_byte_count_ += result;
51 if (interceptor_)
52 interceptor_->ThrottleTransaction(this, callback_type_ == START);
55 void DevToolsNetworkTransaction::OnCallback(int rv) {
56 if (failed_)
57 return;
58 DCHECK(!callback_.is_null());
59 if (callback_type_ == START || callback_type_ == READ) {
60 if (interceptor_ && interceptor_->ShouldThrottle(this)) {
61 Throttle(rv);
62 return;
65 net::CompletionCallback callback = callback_;
66 callback_.Reset();
67 callback_type_ = NONE;
68 callback.Run(rv);
71 int DevToolsNetworkTransaction::SetupCallback(
72 net::CompletionCallback callback,
73 int result,
74 CallbackType callback_type) {
75 DCHECK(callback_type_ == NONE);
77 if (result == net::ERR_IO_PENDING) {
78 callback_type_ = callback_type;
79 callback_ = callback;
80 return result;
83 if (!interceptor_ || !interceptor_->ShouldThrottle(this))
84 return result;
86 // Only START and READ operation throttling is supported.
87 if (callback_type != START && callback_type != READ)
88 return result;
90 // In case of error |throttled_byte_count_| is unknown.
91 if (result < 0)
92 return result;
94 // URLRequestJob relies on synchronous end-of-stream notification.
95 if (callback_type == READ && result == 0)
96 return result;
98 callback_type_ = callback_type;
99 callback_ = callback;
100 Throttle(result);
101 return net::ERR_IO_PENDING;
104 void DevToolsNetworkTransaction::Fail() {
105 DCHECK(request_);
106 DCHECK(!failed_);
107 failed_ = true;
108 network_transaction_->SetBeforeNetworkStartCallback(
109 BeforeNetworkStartCallback());
110 if (callback_.is_null())
111 return;
112 net::CompletionCallback callback = callback_;
113 callback_.Reset();
114 callback_type_ = NONE;
115 callback.Run(net::ERR_INTERNET_DISCONNECTED);
118 int DevToolsNetworkTransaction::Start(
119 const net::HttpRequestInfo* request,
120 const net::CompletionCallback& callback,
121 const net::BoundNetLog& net_log) {
122 DCHECK(request);
123 request_ = request;
124 interceptor_ = controller_->GetInterceptor(this);
125 interceptor_->AddTransaction(this);
127 if (interceptor_->ShouldFail(this)) {
128 failed_ = true;
129 network_transaction_->SetBeforeNetworkStartCallback(
130 BeforeNetworkStartCallback());
131 return net::ERR_INTERNET_DISCONNECTED;
133 int rv = network_transaction_->Start(request_, proxy_callback_, net_log);
134 return SetupCallback(callback, rv, START);
137 void DevToolsNetworkTransaction::ProcessRequest() {
138 DCHECK(request_);
139 bool has_devtools_client_id = request_->extra_headers.HasHeader(
140 kDevToolsEmulateNetworkConditionsClientId);
141 bool has_devtools_request_initiator = request_->extra_headers.HasHeader(
142 kDevToolsRequestInitiator);
143 if (!has_devtools_client_id && !has_devtools_request_initiator)
144 return;
146 custom_request_.reset(new net::HttpRequestInfo(*request_));
148 if (has_devtools_client_id) {
149 custom_request_->extra_headers.GetHeader(
150 kDevToolsEmulateNetworkConditionsClientId, &client_id_);
151 custom_request_->extra_headers.RemoveHeader(
152 kDevToolsEmulateNetworkConditionsClientId);
155 if (has_devtools_request_initiator) {
156 custom_request_->extra_headers.GetHeader(
157 kDevToolsRequestInitiator, &request_initiator_);
158 custom_request_->extra_headers.RemoveHeader(kDevToolsRequestInitiator);
161 request_ = custom_request_.get();
164 int DevToolsNetworkTransaction::RestartIgnoringLastError(
165 const net::CompletionCallback& callback) {
166 if (failed_)
167 return net::ERR_INTERNET_DISCONNECTED;
168 int rv = network_transaction_->RestartIgnoringLastError(proxy_callback_);
169 return SetupCallback(callback, rv, RESTART_IGNORING_LAST_ERROR);
172 int DevToolsNetworkTransaction::RestartWithCertificate(
173 net::X509Certificate* client_cert,
174 const net::CompletionCallback& callback) {
175 if (failed_)
176 return net::ERR_INTERNET_DISCONNECTED;
177 int rv = network_transaction_->RestartWithCertificate(
178 client_cert, proxy_callback_);
179 return SetupCallback(callback, rv, RESTART_WITH_CERTIFICATE);
182 int DevToolsNetworkTransaction::RestartWithAuth(
183 const net::AuthCredentials& credentials,
184 const net::CompletionCallback& callback) {
185 if (failed_)
186 return net::ERR_INTERNET_DISCONNECTED;
187 int rv = network_transaction_->RestartWithAuth(credentials, proxy_callback_);
188 return SetupCallback(callback, rv, RESTART_WITH_AUTH);
191 bool DevToolsNetworkTransaction::IsReadyToRestartForAuth() {
192 return network_transaction_->IsReadyToRestartForAuth();
195 int DevToolsNetworkTransaction::Read(
196 net::IOBuffer* buf,
197 int buf_len,
198 const net::CompletionCallback& callback) {
199 if (failed_)
200 return net::ERR_INTERNET_DISCONNECTED;
201 int rv = network_transaction_->Read(buf, buf_len, proxy_callback_);
202 return SetupCallback(callback, rv, READ);
205 void DevToolsNetworkTransaction::StopCaching() {
206 network_transaction_->StopCaching();
209 bool DevToolsNetworkTransaction::GetFullRequestHeaders(
210 net::HttpRequestHeaders* headers) const {
211 return network_transaction_->GetFullRequestHeaders(headers);
214 int64 DevToolsNetworkTransaction::GetTotalReceivedBytes() const {
215 return network_transaction_->GetTotalReceivedBytes();
218 int64_t DevToolsNetworkTransaction::GetTotalSentBytes() const {
219 return network_transaction_->GetTotalSentBytes();
222 void DevToolsNetworkTransaction::DoneReading() {
223 network_transaction_->DoneReading();
226 const net::HttpResponseInfo*
227 DevToolsNetworkTransaction::GetResponseInfo() const {
228 return network_transaction_->GetResponseInfo();
231 net::LoadState DevToolsNetworkTransaction::GetLoadState() const {
232 return network_transaction_->GetLoadState();
235 net::UploadProgress DevToolsNetworkTransaction::GetUploadProgress() const {
236 return network_transaction_->GetUploadProgress();
239 void DevToolsNetworkTransaction::SetQuicServerInfo(
240 net::QuicServerInfo* quic_server_info) {
241 network_transaction_->SetQuicServerInfo(quic_server_info);
244 bool DevToolsNetworkTransaction::GetLoadTimingInfo(
245 net::LoadTimingInfo* load_timing_info) const {
246 return network_transaction_->GetLoadTimingInfo(load_timing_info);
249 void DevToolsNetworkTransaction::SetPriority(net::RequestPriority priority) {
250 network_transaction_->SetPriority(priority);
253 void DevToolsNetworkTransaction::SetWebSocketHandshakeStreamCreateHelper(
254 net::WebSocketHandshakeStreamBase::CreateHelper* create_helper) {
255 network_transaction_->SetWebSocketHandshakeStreamCreateHelper(create_helper);
258 void DevToolsNetworkTransaction::SetBeforeNetworkStartCallback(
259 const BeforeNetworkStartCallback& callback) {
260 network_transaction_->SetBeforeNetworkStartCallback(callback);
263 void DevToolsNetworkTransaction::SetBeforeProxyHeadersSentCallback(
264 const BeforeProxyHeadersSentCallback& callback) {
265 network_transaction_->SetBeforeProxyHeadersSentCallback(callback);
268 int DevToolsNetworkTransaction::ResumeNetworkStart() {
269 if (failed_)
270 return net::ERR_INTERNET_DISCONNECTED;
271 return network_transaction_->ResumeNetworkStart();
274 void
275 DevToolsNetworkTransaction::GetConnectionAttempts(net::ConnectionAttempts* out)
276 const {
277 network_transaction_->GetConnectionAttempts(out);
280 void DevToolsNetworkTransaction::FireThrottledCallback() {
281 DCHECK(!callback_.is_null());
282 DCHECK(callback_type_ == READ || callback_type_ == START);
283 net::CompletionCallback callback = callback_;
284 callback_.Reset();
285 callback_type_ = NONE;
286 callback.Run(throttled_result_);