mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-24 14:26:09 +03:00
Add --extra-headers option
This commit is contained in:
parent
c22e409d37
commit
6df2e54b26
@ -16,6 +16,7 @@
|
|||||||
#include "base/json/json_writer.h"
|
#include "base/json/json_writer.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
|
#include "base/rand_util.h"
|
||||||
#include "base/run_loop.h"
|
#include "base/run_loop.h"
|
||||||
#include "base/strings/string16.h"
|
#include "base/strings/string16.h"
|
||||||
#include "base/strings/string_number_conversions.h"
|
#include "base/strings/string_number_conversions.h"
|
||||||
@ -37,6 +38,8 @@
|
|||||||
#include "net/http/http_auth.h"
|
#include "net/http/http_auth.h"
|
||||||
#include "net/http/http_auth_cache.h"
|
#include "net/http/http_auth_cache.h"
|
||||||
#include "net/http/http_network_session.h"
|
#include "net/http/http_network_session.h"
|
||||||
|
#include "net/http/http_request_headers.h"
|
||||||
|
#include "net/http/http_response_headers.h"
|
||||||
#include "net/http/http_transaction_factory.h"
|
#include "net/http/http_transaction_factory.h"
|
||||||
#include "net/log/file_net_log_observer.h"
|
#include "net/log/file_net_log_observer.h"
|
||||||
#include "net/log/net_log.h"
|
#include "net/log/net_log.h"
|
||||||
@ -80,6 +83,7 @@ struct CommandLine {
|
|||||||
std::string listen;
|
std::string listen;
|
||||||
std::string proxy;
|
std::string proxy;
|
||||||
bool padding;
|
bool padding;
|
||||||
|
std::string extra_headers;
|
||||||
std::string host_resolver_rules;
|
std::string host_resolver_rules;
|
||||||
std::string resolver_range;
|
std::string resolver_range;
|
||||||
bool no_log;
|
bool no_log;
|
||||||
@ -93,6 +97,7 @@ struct Params {
|
|||||||
std::string listen_addr;
|
std::string listen_addr;
|
||||||
int listen_port;
|
int listen_port;
|
||||||
bool use_padding;
|
bool use_padding;
|
||||||
|
net::HttpRequestHeaders extra_headers;
|
||||||
std::string proxy_url;
|
std::string proxy_url;
|
||||||
base::string16 proxy_user;
|
base::string16 proxy_user;
|
||||||
base::string16 proxy_pass;
|
base::string16 proxy_pass;
|
||||||
@ -118,79 +123,6 @@ std::unique_ptr<base::Value> GetConstants(
|
|||||||
return constants_dict;
|
return constants_dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<net::URLRequestContext> BuildCertURLRequestContext(
|
|
||||||
net::NetLog* net_log) {
|
|
||||||
net::URLRequestContextBuilder builder;
|
|
||||||
|
|
||||||
builder.DisableHttpCache();
|
|
||||||
builder.set_net_log(net_log);
|
|
||||||
|
|
||||||
net::ProxyConfig proxy_config;
|
|
||||||
auto proxy_service =
|
|
||||||
net::ConfiguredProxyResolutionService::CreateWithoutProxyResolver(
|
|
||||||
std::make_unique<net::ProxyConfigServiceFixed>(
|
|
||||||
net::ProxyConfigWithAnnotation(proxy_config, kTrafficAnnotation)),
|
|
||||||
net_log);
|
|
||||||
proxy_service->ForceReloadProxyConfig();
|
|
||||||
builder.set_proxy_resolution_service(std::move(proxy_service));
|
|
||||||
|
|
||||||
return builder.Build();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builds a URLRequestContext assuming there's only a single loop.
|
|
||||||
std::unique_ptr<net::URLRequestContext> BuildURLRequestContext(
|
|
||||||
const Params& params,
|
|
||||||
scoped_refptr<net::CertNetFetcherURLRequest> cert_net_fetcher,
|
|
||||||
net::NetLog* net_log) {
|
|
||||||
net::URLRequestContextBuilder builder;
|
|
||||||
|
|
||||||
builder.DisableHttpCache();
|
|
||||||
builder.set_net_log(net_log);
|
|
||||||
|
|
||||||
net::ProxyConfig proxy_config;
|
|
||||||
proxy_config.proxy_rules().ParseFromString(params.proxy_url);
|
|
||||||
LOG(INFO) << "Proxying via " << params.proxy_url;
|
|
||||||
auto proxy_service =
|
|
||||||
net::ConfiguredProxyResolutionService::CreateWithoutProxyResolver(
|
|
||||||
std::make_unique<net::ProxyConfigServiceFixed>(
|
|
||||||
net::ProxyConfigWithAnnotation(proxy_config, kTrafficAnnotation)),
|
|
||||||
net_log);
|
|
||||||
proxy_service->ForceReloadProxyConfig();
|
|
||||||
builder.set_proxy_resolution_service(std::move(proxy_service));
|
|
||||||
|
|
||||||
if (!params.host_resolver_rules.empty()) {
|
|
||||||
builder.set_host_mapping_rules(params.host_resolver_rules);
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.SetCertVerifier(
|
|
||||||
net::CertVerifier::CreateDefault(std::move(cert_net_fetcher)));
|
|
||||||
|
|
||||||
auto context = builder.Build();
|
|
||||||
|
|
||||||
if (!params.proxy_url.empty() && !params.proxy_user.empty() &&
|
|
||||||
!params.proxy_pass.empty()) {
|
|
||||||
auto* session = context->http_transaction_factory()->GetSession();
|
|
||||||
auto* auth_cache = session->http_auth_cache();
|
|
||||||
std::string proxy_url = params.proxy_url;
|
|
||||||
if (proxy_url.compare(0, 7, "quic://") == 0) {
|
|
||||||
proxy_url.replace(0, 4, "https");
|
|
||||||
auto* quic = context->quic_context()->params();
|
|
||||||
const auto& versions = quic::SupportedVersions();
|
|
||||||
quic->supported_versions.assign(versions.begin(), versions.end());
|
|
||||||
quic->origins_to_force_quic_on.insert(
|
|
||||||
net::HostPortPair::FromURL(GURL(proxy_url)));
|
|
||||||
}
|
|
||||||
GURL auth_origin(proxy_url);
|
|
||||||
net::AuthCredentials credentials(params.proxy_user, params.proxy_pass);
|
|
||||||
auth_cache->Add(auth_origin, net::HttpAuth::AUTH_PROXY,
|
|
||||||
/*realm=*/std::string(), net::HttpAuth::AUTH_SCHEME_BASIC,
|
|
||||||
net::NetworkIsolationKey(), /*challenge=*/"Basic",
|
|
||||||
credentials, /*path=*/"/");
|
|
||||||
}
|
|
||||||
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetCommandLine(const base::CommandLine& proc, CommandLine* cmdline) {
|
void GetCommandLine(const base::CommandLine& proc, CommandLine* cmdline) {
|
||||||
if (proc.HasSwitch("h") || proc.HasSwitch("help")) {
|
if (proc.HasSwitch("h") || proc.HasSwitch("help")) {
|
||||||
std::cout << "Usage: naive { OPTIONS | config.json }\n"
|
std::cout << "Usage: naive { OPTIONS | config.json }\n"
|
||||||
@ -204,6 +136,7 @@ void GetCommandLine(const base::CommandLine& proc, CommandLine* cmdline) {
|
|||||||
"--proxy=<proto>://[<user>:<pass>@]<hostname>[:<port>]\n"
|
"--proxy=<proto>://[<user>:<pass>@]<hostname>[:<port>]\n"
|
||||||
" proto: https, quic\n"
|
" proto: https, quic\n"
|
||||||
"--padding Use padding\n"
|
"--padding Use padding\n"
|
||||||
|
"--extra-headers=... Extra headers split by CRLF\n"
|
||||||
"--host-resolver-rules=... Resolver rules\n"
|
"--host-resolver-rules=... Resolver rules\n"
|
||||||
"--resolver-range=... Redirect resolver range\n"
|
"--resolver-range=... Redirect resolver range\n"
|
||||||
"--log[=<path>] Log to stderr, or file\n"
|
"--log[=<path>] Log to stderr, or file\n"
|
||||||
@ -221,6 +154,7 @@ void GetCommandLine(const base::CommandLine& proc, CommandLine* cmdline) {
|
|||||||
cmdline->listen = proc.GetSwitchValueASCII("listen");
|
cmdline->listen = proc.GetSwitchValueASCII("listen");
|
||||||
cmdline->proxy = proc.GetSwitchValueASCII("proxy");
|
cmdline->proxy = proc.GetSwitchValueASCII("proxy");
|
||||||
cmdline->padding = proc.HasSwitch("padding");
|
cmdline->padding = proc.HasSwitch("padding");
|
||||||
|
cmdline->extra_headers = proc.GetSwitchValueASCII("extra-headers");
|
||||||
cmdline->host_resolver_rules =
|
cmdline->host_resolver_rules =
|
||||||
proc.GetSwitchValueASCII("host-resolver-rules");
|
proc.GetSwitchValueASCII("host-resolver-rules");
|
||||||
cmdline->resolver_range = proc.GetSwitchValueASCII("resolver-range");
|
cmdline->resolver_range = proc.GetSwitchValueASCII("resolver-range");
|
||||||
@ -245,36 +179,41 @@ void GetCommandLineFromConfig(const base::FilePath& config_path,
|
|||||||
std::cerr << "Invalid config format" << std::endl;
|
std::cerr << "Invalid config format" << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (value->FindKeyOfType("listen", base::Value::Type::STRING)) {
|
const auto* listen = value->FindStringKey("listen");
|
||||||
cmdline->listen = value->FindKey("listen")->GetString();
|
if (listen) {
|
||||||
|
cmdline->listen = *listen;
|
||||||
}
|
}
|
||||||
if (value->FindKeyOfType("proxy", base::Value::Type::STRING)) {
|
const auto* proxy = value->FindStringKey("proxy");
|
||||||
cmdline->proxy = value->FindKey("proxy")->GetString();
|
if (proxy) {
|
||||||
|
cmdline->proxy = *proxy;
|
||||||
}
|
}
|
||||||
cmdline->padding = false;
|
cmdline->padding = value->FindBoolKey("padding").value_or(false);
|
||||||
if (value->FindKeyOfType("padding", base::Value::Type::BOOLEAN)) {
|
const auto* extra_headers = value->FindStringKey("extra-headers");
|
||||||
cmdline->padding = value->FindKey("padding")->GetBool();
|
if (extra_headers) {
|
||||||
|
cmdline->extra_headers = *extra_headers;
|
||||||
}
|
}
|
||||||
if (value->FindKeyOfType("host-resolver-rules", base::Value::Type::STRING)) {
|
const auto* host_resolver_rules = value->FindStringKey("host-resolver-rules");
|
||||||
cmdline->host_resolver_rules =
|
if (host_resolver_rules) {
|
||||||
value->FindKey("host-resolver-rules")->GetString();
|
cmdline->host_resolver_rules = *host_resolver_rules;
|
||||||
}
|
}
|
||||||
if (value->FindKeyOfType("resolver-range", base::Value::Type::STRING)) {
|
const auto* resolver_range = value->FindStringKey("resolver-range");
|
||||||
cmdline->resolver_range = value->FindKey("resolver-range")->GetString();
|
if (resolver_range) {
|
||||||
|
cmdline->resolver_range = *resolver_range;
|
||||||
}
|
}
|
||||||
cmdline->no_log = true;
|
cmdline->no_log = true;
|
||||||
if (value->FindKeyOfType("log", base::Value::Type::STRING)) {
|
const auto* log = value->FindStringKey("log");
|
||||||
|
if (log) {
|
||||||
cmdline->no_log = false;
|
cmdline->no_log = false;
|
||||||
cmdline->log =
|
cmdline->log = base::FilePath::FromUTF8Unsafe(*log);
|
||||||
base::FilePath::FromUTF8Unsafe(value->FindKey("log")->GetString());
|
|
||||||
}
|
}
|
||||||
if (value->FindKeyOfType("log-net-log", base::Value::Type::STRING)) {
|
const auto* log_net_log = value->FindStringKey("log-net-log");
|
||||||
cmdline->log_net_log = base::FilePath::FromUTF8Unsafe(
|
if (log_net_log) {
|
||||||
value->FindKey("log-net-log")->GetString());
|
cmdline->log_net_log = base::FilePath::FromUTF8Unsafe(*log_net_log);
|
||||||
}
|
}
|
||||||
if (value->FindKeyOfType("ssl-key-log-file", base::Value::Type::STRING)) {
|
const auto* ssl_key_log_file = value->FindStringKey("ssl-key-log-file");
|
||||||
cmdline->ssl_key_log_file = base::FilePath::FromUTF8Unsafe(
|
if (ssl_key_log_file) {
|
||||||
value->FindKey("ssl-key-log-file")->GetString());
|
cmdline->ssl_key_log_file =
|
||||||
|
base::FilePath::FromUTF8Unsafe(*ssl_key_log_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,6 +286,8 @@ bool ParseCommandLine(const CommandLine& cmdline, Params* params) {
|
|||||||
|
|
||||||
params->use_padding = cmdline.padding;
|
params->use_padding = cmdline.padding;
|
||||||
|
|
||||||
|
params->extra_headers.AddHeadersFromString(cmdline.extra_headers);
|
||||||
|
|
||||||
params->host_resolver_rules = cmdline.host_resolver_rules;
|
params->host_resolver_rules = cmdline.host_resolver_rules;
|
||||||
|
|
||||||
if (params->protocol == net::NaiveConnection::kRedir) {
|
if (params->protocol == net::NaiveConnection::kRedir) {
|
||||||
@ -424,7 +365,110 @@ class PrintingLogObserver : public NetLog::ThreadSafeObserver {
|
|||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(PrintingLogObserver);
|
DISALLOW_COPY_AND_ASSIGN(PrintingLogObserver);
|
||||||
};
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
class ProxyInfo;
|
||||||
|
class ProxyServer;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class NaiveProxyDelegate : public ProxyDelegate {
|
||||||
|
public:
|
||||||
|
NaiveProxyDelegate(const Params& params) : params_(params) {}
|
||||||
|
void OnResolveProxy(const GURL& url,
|
||||||
|
const std::string& method,
|
||||||
|
const ProxyRetryInfoMap& proxy_retry_info,
|
||||||
|
ProxyInfo* result) override {}
|
||||||
|
void OnFallback(const ProxyServer& bad_proxy, int net_error) override {}
|
||||||
|
|
||||||
|
void OnBeforeTunnelRequest(const ProxyServer& proxy_server,
|
||||||
|
HttpRequestHeaders* extra_headers) override {
|
||||||
|
extra_headers->SetHeader("Padding",
|
||||||
|
std::string(base::RandInt(16, 32), '.'));
|
||||||
|
extra_headers->MergeFrom(params_.extra_headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error OnTunnelHeadersReceived(
|
||||||
|
const ProxyServer& proxy_server,
|
||||||
|
const HttpResponseHeaders& response_headers) override {
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Params& params_;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<URLRequestContext> BuildCertURLRequestContext(NetLog* net_log) {
|
||||||
|
URLRequestContextBuilder builder;
|
||||||
|
|
||||||
|
builder.DisableHttpCache();
|
||||||
|
builder.set_net_log(net_log);
|
||||||
|
|
||||||
|
ProxyConfig proxy_config;
|
||||||
|
auto proxy_service =
|
||||||
|
ConfiguredProxyResolutionService::CreateWithoutProxyResolver(
|
||||||
|
std::make_unique<ProxyConfigServiceFixed>(
|
||||||
|
ProxyConfigWithAnnotation(proxy_config, kTrafficAnnotation)),
|
||||||
|
net_log);
|
||||||
|
proxy_service->ForceReloadProxyConfig();
|
||||||
|
builder.set_proxy_resolution_service(std::move(proxy_service));
|
||||||
|
|
||||||
|
return builder.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Builds a URLRequestContext assuming there's only a single loop.
|
||||||
|
std::unique_ptr<URLRequestContext> BuildURLRequestContext(
|
||||||
|
const Params& params,
|
||||||
|
scoped_refptr<CertNetFetcherURLRequest> cert_net_fetcher,
|
||||||
|
NetLog* net_log) {
|
||||||
|
URLRequestContextBuilder builder;
|
||||||
|
|
||||||
|
builder.DisableHttpCache();
|
||||||
|
builder.set_net_log(net_log);
|
||||||
|
|
||||||
|
ProxyConfig proxy_config;
|
||||||
|
proxy_config.proxy_rules().ParseFromString(params.proxy_url);
|
||||||
|
LOG(INFO) << "Proxying via " << params.proxy_url;
|
||||||
|
auto proxy_service =
|
||||||
|
ConfiguredProxyResolutionService::CreateWithoutProxyResolver(
|
||||||
|
std::make_unique<ProxyConfigServiceFixed>(
|
||||||
|
ProxyConfigWithAnnotation(proxy_config, kTrafficAnnotation)),
|
||||||
|
net_log);
|
||||||
|
proxy_service->ForceReloadProxyConfig();
|
||||||
|
builder.set_proxy_resolution_service(std::move(proxy_service));
|
||||||
|
|
||||||
|
if (!params.host_resolver_rules.empty()) {
|
||||||
|
builder.set_host_mapping_rules(params.host_resolver_rules);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.SetCertVerifier(
|
||||||
|
CertVerifier::CreateDefault(std::move(cert_net_fetcher)));
|
||||||
|
|
||||||
|
builder.set_proxy_delegate(std::make_unique<NaiveProxyDelegate>(params));
|
||||||
|
|
||||||
|
auto context = builder.Build();
|
||||||
|
|
||||||
|
if (!params.proxy_url.empty() && !params.proxy_user.empty() &&
|
||||||
|
!params.proxy_pass.empty()) {
|
||||||
|
auto* session = context->http_transaction_factory()->GetSession();
|
||||||
|
auto* auth_cache = session->http_auth_cache();
|
||||||
|
std::string proxy_url = params.proxy_url;
|
||||||
|
if (proxy_url.compare(0, 7, "quic://") == 0) {
|
||||||
|
proxy_url.replace(0, 4, "https");
|
||||||
|
auto* quic = context->quic_context()->params();
|
||||||
|
const auto& versions = quic::SupportedVersions();
|
||||||
|
quic->supported_versions.assign(versions.begin(), versions.end());
|
||||||
|
quic->origins_to_force_quic_on.insert(
|
||||||
|
net::HostPortPair::FromURL(GURL(proxy_url)));
|
||||||
|
}
|
||||||
|
GURL auth_origin(proxy_url);
|
||||||
|
AuthCredentials credentials(params.proxy_user, params.proxy_pass);
|
||||||
|
auth_cache->Add(auth_origin, HttpAuth::AUTH_PROXY,
|
||||||
|
/*realm=*/{}, HttpAuth::AUTH_SCHEME_BASIC, {},
|
||||||
|
/*challenge=*/"Basic", credentials, /*path=*/"/");
|
||||||
|
}
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace net
|
} // namespace net
|
||||||
|
|
||||||
@ -498,14 +542,14 @@ int main(int argc, char* argv[]) {
|
|||||||
net::NetLogCaptureMode::kDefault);
|
net::NetLogCaptureMode::kDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cert_context = BuildCertURLRequestContext(net_log);
|
auto cert_context = net::BuildCertURLRequestContext(net_log);
|
||||||
scoped_refptr<net::CertNetFetcherURLRequest> cert_net_fetcher;
|
scoped_refptr<net::CertNetFetcherURLRequest> cert_net_fetcher;
|
||||||
#if defined(OS_LINUX) || defined(OS_MAC) || defined(OS_ANDROID)
|
#if defined(OS_LINUX) || defined(OS_MAC) || defined(OS_ANDROID)
|
||||||
cert_net_fetcher = base::MakeRefCounted<net::CertNetFetcherURLRequest>();
|
cert_net_fetcher = base::MakeRefCounted<net::CertNetFetcherURLRequest>();
|
||||||
cert_net_fetcher->SetURLRequestContext(cert_context.get());
|
cert_net_fetcher->SetURLRequestContext(cert_context.get());
|
||||||
#endif
|
#endif
|
||||||
auto context =
|
auto context =
|
||||||
BuildURLRequestContext(params, std::move(cert_net_fetcher), net_log);
|
net::BuildURLRequestContext(params, std::move(cert_net_fetcher), net_log);
|
||||||
auto* session = context->http_transaction_factory()->GetSession();
|
auto* session = context->http_transaction_factory()->GetSession();
|
||||||
|
|
||||||
auto listen_socket =
|
auto listen_socket =
|
||||||
|
Loading…
Reference in New Issue
Block a user