blob: ffced83fbcfce7ef3d0268749c75dee1f571f70a [file] [log] [blame]
rchfdfdc8ed2015-03-18 00:35:201// Copyright (c) 2012 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// A binary wrapper for QuicClient.
6// Connects to a host using QUIC, sends a request to the provided URL, and
7// displays the response.
8//
9// Some usage examples:
10//
rchfdfdc8ed2015-03-18 00:35:2011// Standard request/response:
David Schinazic00136a2019-04-16 02:54:5212// quic_client http://www.google.com
13// quic_client http://www.google.com --quiet
14// quic_client https://www.google.com --port=443
rchfdfdc8ed2015-03-18 00:35:2015//
16// Use a specific version:
David Schinazic00136a2019-04-16 02:54:5217// quic_client http://www.google.com --quic_version=23
rchfdfdc8ed2015-03-18 00:35:2018//
19// Send a POST instead of a GET:
David Schinazic00136a2019-04-16 02:54:5220// quic_client http://www.google.com --body="this is a POST body"
rchfdfdc8ed2015-03-18 00:35:2021//
22// Append additional headers to the request:
23// quic_client http://www.google.com --host=${IP}
24// --headers="Header-A: 1234; Header-B: 5678"
25//
26// Connect to a host different to the URL being requested:
David Schinazic00136a2019-04-16 02:54:5227// quic_client mail.google.com --host=www.google.com
28//
29// Connect to a specific IP:
rchfdfdc8ed2015-03-18 00:35:2030// IP=`dig www.google.com +short | head -1`
David Schinazic00136a2019-04-16 02:54:5231// quic_client www.google.com --host=${IP}
rchfdfdc8ed2015-03-18 00:35:2032//
33// Try to connect to a host which does not speak QUIC:
David Schinazic00136a2019-04-16 02:54:5234// quic_client http://www.example.com
rchfdfdc8ed2015-03-18 00:35:2035
36#include <iostream>
37
38#include "base/at_exit.h"
39#include "base/command_line.h"
40#include "base/logging.h"
Alexander Timin4f9c35c2018-11-01 20:15:2041#include "base/message_loop/message_loop.h"
Gabriel Charette52fa3ae2019-04-15 21:44:3742#include "base/task/thread_pool/thread_pool.h"
rchda78df5a2015-03-22 05:16:3743#include "net/base/net_errors.h"
rchfdfdc8ed2015-03-18 00:35:2044#include "net/base/privacy_mode.h"
45#include "net/cert/cert_verifier.h"
rch71bd2332017-02-04 00:06:4746#include "net/cert/ct_log_verifier.h"
Ryan Sleevi8a9c9c12018-05-09 02:36:2347#include "net/cert/ct_policy_enforcer.h"
rtenneti052774e2015-11-24 21:00:1248#include "net/cert/multi_log_ct_verifier.h"
rchfdfdc8ed2015-03-18 00:35:2049#include "net/http/transport_security_state.h"
Victor Vasiliev4f6fb892019-05-31 16:58:3150#include "net/quic/address_utils.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0851#include "net/quic/crypto/proof_verifier_chromium.h"
Bence Béky94658bf2018-05-11 19:22:5852#include "net/spdy/spdy_http_utils.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5153#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
54#include "net/third_party/quiche/src/quic/core/quic_packets.h"
55#include "net/third_party/quiche/src/quic/core/quic_server_id.h"
David Schinazic00136a2019-04-16 02:54:5256#include "net/third_party/quiche/src/quic/core/quic_versions.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5157#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
58#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
59#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
Ryan Hamilton4aeec562019-05-17 21:22:5260#include "net/third_party/quiche/src/quic/platform/api/quic_system_event_loop.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5161#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
Ryan Hamilton4aeec562019-05-17 21:22:5262#include "net/third_party/quiche/src/quic/tools/quic_toy_client.h"
Victor Vasiliev27cc7712019-01-24 11:50:1463#include "net/third_party/quiche/src/spdy/core/spdy_header_block.h"
rcha9d12ce12015-03-19 23:06:4964#include "net/tools/quic/quic_simple_client.h"
rchda78df5a2015-03-22 05:16:3765#include "net/tools/quic/synchronous_host_resolver.h"
rchfdfdc8ed2015-03-18 00:35:2066#include "url/gurl.h"
67
rchfdfdc8ed2015-03-18 00:35:2068using net::CertVerifier;
rtenneti052774e2015-11-24 21:00:1269using net::CTVerifier;
70using net::MultiLogCTVerifier;
Ryan Hamilton8d9ee76e2018-05-29 23:52:5271using quic::ProofVerifier;
rchfdfdc8ed2015-03-18 00:35:2072using net::ProofVerifierChromium;
Ryan Hamilton8d9ee76e2018-05-29 23:52:5273using quic::QuicStringPiece;
74using quic::QuicTextUtils;
rchfdfdc8ed2015-03-18 00:35:2075using net::TransportSecurityState;
Ryan Hamilton0239aac2018-05-19 00:03:1376using spdy::SpdyHeaderBlock;
rchfdfdc8ed2015-03-18 00:35:2077using std::cout;
78using std::cerr;
rchfdfdc8ed2015-03-18 00:35:2079using std::endl;
rchfdfdc8ed2015-03-18 00:35:2080
Ryan Hamilton4aeec562019-05-17 21:22:5281namespace {
rchfdfdc8ed2015-03-18 00:35:2082
Ryan Hamilton8d54e392019-05-19 17:24:4083class QuicSimpleClientFactory : public quic::QuicToyClient::ClientFactory {
rche22c2fb2015-11-17 00:22:3284 public:
Ryan Hamilton4aeec562019-05-17 21:22:5285 std::unique_ptr<quic::QuicSpdyClientBase> CreateClient(
86 std::string host,
87 uint16_t port,
88 quic::ParsedQuicVersionVector versions,
89 std::unique_ptr<quic::ProofVerifier> verifier) override {
rchda78df5a2015-03-22 05:16:3790 net::AddressList addresses;
rch750447f92016-01-31 02:54:5391 int rv = net::SynchronousHostResolver::Resolve(host, &addresses);
rchda78df5a2015-03-22 05:16:3792 if (rv != net::OK) {
rjshaded5ced072015-12-18 19:26:0293 LOG(ERROR) << "Unable to resolve '" << host
94 << "' : " << net::ErrorToShortString(rv);
Ryan Hamilton4aeec562019-05-17 21:22:5295 return nullptr;
rchda78df5a2015-03-22 05:16:3796 }
Ryan Hamilton4aeec562019-05-17 21:22:5297 // Determine IP address to connect to from supplied hostname.
98 quic::QuicIpAddress ip_addr;
99 if (!ip_addr.FromString(host)) {
100 net::AddressList addresses;
101 int rv = net::SynchronousHostResolver::Resolve(host, &addresses);
102 if (rv != net::OK) {
103 LOG(ERROR) << "Unable to resolve '" << host
104 << "' : " << net::ErrorToShortString(rv);
105 return nullptr;
106 }
Victor Vasiliev4f6fb892019-05-31 16:58:31107 ip_addr = net::ToQuicIpAddress(addresses[0].address());
Takashi Sakamoto9014ca56d2019-05-17 09:02:52108 }
Ryan Hamilton4aeec562019-05-17 21:22:52109
110 quic::QuicServerId server_id(host, port, false);
111 return quic::QuicMakeUnique<net::QuicSimpleClient>(
112 quic::QuicSocketAddress(ip_addr, port), server_id, versions,
113 std::move(verifier));
Takashi Sakamoto9014ca56d2019-05-17 09:02:52114 }
Ryan Hamilton4aeec562019-05-17 21:22:52115};
116
117} // namespace
118
119int main(int argc, char* argv[]) {
120 QuicSystemEventLoop event_loop("quic_client");
121 const char* usage = "Usage: quic_client [options] <url>";
122
123 // All non-flag arguments should be interpreted as URLs to fetch.
124 std::vector<std::string> urls =
125 quic::QuicParseCommandLineFlags(usage, argc, argv);
126 if (urls.size() != 1) {
127 quic::QuicPrintCommandLineFlagHelp(usage);
128 exit(0);
Takashi Sakamoto9014ca56d2019-05-17 09:02:52129 }
130
Ryan Hamilton4aeec562019-05-17 21:22:52131 QuicSimpleClientFactory factory;
Ryan Hamilton8d54e392019-05-19 17:24:40132 quic::QuicToyClient client(&factory);
Ryan Hamilton4aeec562019-05-17 21:22:52133 return client.SendRequestsAndPrintResponses(urls);
rchfdfdc8ed2015-03-18 00:35:20134}