electron/brightray/browser/net/devtools_network_transaction.cc

300 lines
9.4 KiB
C++
Raw Normal View History

2015-09-26 18:19:27 +00:00
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-CHROMIUM file.
#include "browser/net/devtools_network_transaction.h"
#include "browser/net/devtools_network_controller.h"
#include "browser/net/devtools_network_upload_data_stream.h"
#include "net/base/load_timing_info.h"
2015-09-26 18:19:27 +00:00
#include "net/base/net_errors.h"
#include "net/base/upload_progress.h"
#include "net/http/http_network_transaction.h"
#include "net/http/http_request_info.h"
#include "net/socket/connection_attempts.h"
namespace brightray {
// static
const char
DevToolsNetworkTransaction::kDevToolsEmulateNetworkConditionsClientId[] =
"X-DevTools-Emulate-Network-Conditions-Client-Id";
2015-09-26 18:19:27 +00:00
DevToolsNetworkTransaction::DevToolsNetworkTransaction(
DevToolsNetworkController* controller,
std::unique_ptr<net::HttpTransaction> transaction)
: throttled_byte_count_(0),
controller_(controller),
2016-03-08 11:59:29 +00:00
transaction_(std::move(transaction)),
2015-09-26 18:19:27 +00:00
request_(nullptr),
failed_(false) {
DCHECK(controller);
2015-09-26 18:19:27 +00:00
}
DevToolsNetworkTransaction::~DevToolsNetworkTransaction() {
if (interceptor_ && !throttle_callback_.is_null())
interceptor_->StopThrottle(throttle_callback_);
2015-09-26 18:19:27 +00:00
}
void DevToolsNetworkTransaction::IOCallback(
const net::CompletionCallback& callback, bool start, int result) {
result = Throttle(callback, start, result);
if (result != net::ERR_IO_PENDING)
callback.Run(result);
}
2015-09-26 18:19:27 +00:00
int DevToolsNetworkTransaction::Throttle(
const net::CompletionCallback& callback, bool start, int result) {
if (failed_)
return net::ERR_INTERNET_DISCONNECTED;
if (!interceptor_ || result < 0)
return result;
2015-09-26 18:19:27 +00:00
base::TimeTicks send_end;
if (start) {
throttled_byte_count_ += transaction_->GetTotalReceivedBytes();
net::LoadTimingInfo load_timing_info;
if (GetLoadTimingInfo(&load_timing_info))
send_end = load_timing_info.send_end;
if (send_end.is_null())
send_end = base::TimeTicks::Now();
}
if (result > 0)
throttled_byte_count_ += result;
throttle_callback_ = base::Bind(&DevToolsNetworkTransaction::ThrottleCallback,
base::Unretained(this),
callback);
int rv = interceptor_->StartThrottle(result, throttled_byte_count_, send_end,
start, false, throttle_callback_);
if (rv != net::ERR_IO_PENDING)
throttle_callback_.Reset();
if (rv == net::ERR_INTERNET_DISCONNECTED)
Fail();
return rv;
}
2015-09-26 18:19:27 +00:00
void DevToolsNetworkTransaction::ThrottleCallback(
const net::CompletionCallback& callback, int result, int64_t bytes) {
DCHECK(!throttle_callback_.is_null());
throttle_callback_.Reset();
if (result == net::ERR_INTERNET_DISCONNECTED)
Fail();
throttled_byte_count_ = bytes;
callback.Run(result);
2015-09-26 18:19:27 +00:00
}
void DevToolsNetworkTransaction::Fail() {
DCHECK(request_);
DCHECK(!failed_);
failed_ = true;
transaction_->SetBeforeNetworkStartCallback(BeforeNetworkStartCallback());
if (interceptor_)
interceptor_.reset();
2015-09-26 18:19:27 +00:00
}
bool DevToolsNetworkTransaction::CheckFailed() {
if (failed_)
return true;
if (interceptor_ && interceptor_->IsOffline()) {
Fail();
return true;
}
return false;
2015-09-26 18:19:27 +00:00
}
2017-01-23 06:18:52 +00:00
int DevToolsNetworkTransaction::Start(const net::HttpRequestInfo* request,
const net::CompletionCallback& callback,
const net::NetLogWithSource& net_log) {
2015-09-26 18:19:27 +00:00
DCHECK(request);
request_ = request;
std::string client_id;
bool has_devtools_client_id = request_->extra_headers.HasHeader(
kDevToolsEmulateNetworkConditionsClientId);
if (has_devtools_client_id) {
custom_request_.reset(new net::HttpRequestInfo(*request_));
custom_request_->extra_headers.GetHeader(
kDevToolsEmulateNetworkConditionsClientId, &client_id);
custom_request_->extra_headers.RemoveHeader(
kDevToolsEmulateNetworkConditionsClientId);
if (request_->upload_data_stream) {
custom_upload_data_stream_.reset(
new DevToolsNetworkUploadDataStream(request_->upload_data_stream));
custom_request_->upload_data_stream = custom_upload_data_stream_.get();
}
request_ = custom_request_.get();
}
2017-01-23 06:10:34 +00:00
DevToolsNetworkInterceptor* interceptor =
controller_->GetInterceptor(client_id);
if (interceptor) {
interceptor_ = interceptor->GetWeakPtr();
if (custom_upload_data_stream_)
custom_upload_data_stream_->SetInterceptor(interceptor);
2015-09-26 18:19:27 +00:00
}
if (CheckFailed())
return net::ERR_INTERNET_DISCONNECTED;
if (!interceptor_)
2017-01-23 06:18:52 +00:00
return transaction_->Start(request_, callback, net_log);
2017-01-23 06:18:52 +00:00
int result = transaction_->Start(request_,
base::Bind(&DevToolsNetworkTransaction::IOCallback,
base::Unretained(this), callback, true),
net_log);
return Throttle(callback, true, result);
2015-09-26 18:19:27 +00:00
}
int DevToolsNetworkTransaction::RestartIgnoringLastError(
const net::CompletionCallback& callback) {
if (CheckFailed())
2015-09-26 18:19:27 +00:00
return net::ERR_INTERNET_DISCONNECTED;
if (!interceptor_)
return transaction_->RestartIgnoringLastError(callback);
int result = transaction_->RestartIgnoringLastError(
base::Bind(&DevToolsNetworkTransaction::IOCallback,
base::Unretained(this), callback, true));
return Throttle(callback, true, result);
2015-09-26 18:19:27 +00:00
}
int DevToolsNetworkTransaction::RestartWithCertificate(
net::X509Certificate* client_cert,
2016-03-08 06:29:23 +00:00
net::SSLPrivateKey* client_private_key,
2015-09-26 18:19:27 +00:00
const net::CompletionCallback& callback) {
if (CheckFailed())
2015-09-26 18:19:27 +00:00
return net::ERR_INTERNET_DISCONNECTED;
if (!interceptor_) {
return transaction_->RestartWithCertificate(
client_cert, client_private_key, callback);
}
int result = transaction_->RestartWithCertificate(
client_cert, client_private_key,
base::Bind(&DevToolsNetworkTransaction::IOCallback,
base::Unretained(this), callback, true));
return Throttle(callback, true, result);
2015-09-26 18:19:27 +00:00
}
int DevToolsNetworkTransaction::RestartWithAuth(
const net::AuthCredentials& credentials,
const net::CompletionCallback& callback) {
if (CheckFailed())
2015-09-26 18:19:27 +00:00
return net::ERR_INTERNET_DISCONNECTED;
if (!interceptor_)
return transaction_->RestartWithAuth(credentials, callback);
int result = transaction_->RestartWithAuth(credentials,
base::Bind(&DevToolsNetworkTransaction::IOCallback,
base::Unretained(this), callback, true));
return Throttle(callback, true, result);
2015-09-26 18:19:27 +00:00
}
bool DevToolsNetworkTransaction::IsReadyToRestartForAuth() {
return transaction_->IsReadyToRestartForAuth();
}
int DevToolsNetworkTransaction::Read(
net::IOBuffer* buf,
int buf_len,
2015-09-26 18:19:27 +00:00
const net::CompletionCallback& callback) {
if (CheckFailed())
2015-09-26 18:19:27 +00:00
return net::ERR_INTERNET_DISCONNECTED;
if (!interceptor_)
return transaction_->Read(buf, buf_len, callback);
int result = transaction_->Read(buf, buf_len,
base::Bind(&DevToolsNetworkTransaction::IOCallback,
base::Unretained(this), callback, false));
// URLRequestJob relies on synchronous end-of-stream notification.
if (result == 0)
return result;
return Throttle(callback, false, result);
2015-09-26 18:19:27 +00:00
}
void DevToolsNetworkTransaction::StopCaching() {
transaction_->StopCaching();
}
bool DevToolsNetworkTransaction::GetFullRequestHeaders(
net::HttpRequestHeaders* headers) const {
return transaction_->GetFullRequestHeaders(headers);
}
int64_t DevToolsNetworkTransaction::GetTotalReceivedBytes() const {
return transaction_->GetTotalReceivedBytes();
}
2015-12-07 11:55:01 +00:00
int64_t DevToolsNetworkTransaction::GetTotalSentBytes() const {
return transaction_->GetTotalSentBytes();
}
2015-09-26 18:19:27 +00:00
void DevToolsNetworkTransaction::DoneReading() {
transaction_->DoneReading();
}
const net::HttpResponseInfo*
DevToolsNetworkTransaction::GetResponseInfo() const {
return transaction_->GetResponseInfo();
}
net::LoadState DevToolsNetworkTransaction::GetLoadState() const {
return transaction_->GetLoadState();
}
void DevToolsNetworkTransaction::SetQuicServerInfo(
net::QuicServerInfo* info) {
transaction_->SetQuicServerInfo(info);
}
bool DevToolsNetworkTransaction::GetLoadTimingInfo(
net::LoadTimingInfo* info) const {
return transaction_->GetLoadTimingInfo(info);
}
2015-12-07 11:55:01 +00:00
bool DevToolsNetworkTransaction::GetRemoteEndpoint(
net::IPEndPoint* endpoint) const {
return transaction_->GetRemoteEndpoint(endpoint);
}
2016-03-08 06:29:23 +00:00
void DevToolsNetworkTransaction::PopulateNetErrorDetails(
net::NetErrorDetails* details) const {
return transaction_->PopulateNetErrorDetails(details);
}
2015-09-26 18:19:27 +00:00
void DevToolsNetworkTransaction::SetPriority(net::RequestPriority priority) {
transaction_->SetPriority(priority);
}
void DevToolsNetworkTransaction::SetWebSocketHandshakeStreamCreateHelper(
net::WebSocketHandshakeStreamBase::CreateHelper* helper) {
transaction_->SetWebSocketHandshakeStreamCreateHelper(helper);
}
void DevToolsNetworkTransaction::SetBeforeNetworkStartCallback(
const BeforeNetworkStartCallback& callback) {
transaction_->SetBeforeNetworkStartCallback(callback);
}
2016-09-06 08:22:52 +00:00
void DevToolsNetworkTransaction::SetBeforeHeadersSentCallback(
const BeforeHeadersSentCallback& callback) {
transaction_->SetBeforeHeadersSentCallback(callback);
2015-09-26 18:19:27 +00:00
}
int DevToolsNetworkTransaction::ResumeNetworkStart() {
if (CheckFailed())
2015-09-26 18:19:27 +00:00
return net::ERR_INTERNET_DISCONNECTED;
return transaction_->ResumeNetworkStart();
}
void DevToolsNetworkTransaction::GetConnectionAttempts(
net::ConnectionAttempts* out) const {
transaction_->GetConnectionAttempts(out);
}
} // namespace brightray