summaryrefslogtreecommitdiffstats
path: root/chromium/net/base/proxy_server.h
blob: 178607a52e4855e6dfe3900e55cf1f4871c28498 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright (c) 2011 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 file.

#ifndef NET_BASE_PROXY_SERVER_H_
#define NET_BASE_PROXY_SERVER_H_

#include <stdint.h>

#include <ostream>
#include <string>
#include <tuple>

#include "base/strings/string_piece.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_export.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace net {

// ProxyServer encodes the {type, host, port} of a proxy server.
// ProxyServer is immutable.
class NET_EXPORT ProxyServer {
 public:
  // The type of proxy. These are defined as bit flags so they can be ORed
  // together to pass as the |scheme_bit_field| argument to
  // ProxyList::RemoveProxiesWithoutScheme().
  enum Scheme {
    SCHEME_INVALID = 1 << 0,
    SCHEME_DIRECT  = 1 << 1,
    SCHEME_HTTP    = 1 << 2,
    SCHEME_SOCKS4  = 1 << 3,
    SCHEME_SOCKS5  = 1 << 4,
    SCHEME_HTTPS   = 1 << 5,
    // A QUIC proxy is an HTTP proxy in which QUIC is used as the transport,
    // instead of TCP.
    SCHEME_QUIC    = 1 << 6,
  };

  // Default copy-constructor and assignment operator are OK!

  // Constructs an invalid ProxyServer.
  ProxyServer() {}

  ProxyServer(Scheme scheme, const HostPortPair& host_port_pair);

  // Creates a ProxyServer, validating and canonicalizing input. Port is
  // optional and, if not provided, will be replaced with the default port for
  // the given scheme. Accepts IPv6 literal `host`s with surrounding brackets
  // (URL format) or without (HostPortPair format). On invalid input, result
  // will be a `SCHEME_INVALID` ProxyServer.
  //
  // Must not be called with `SCHEME_INVALID` or `SCHEME_DIRECT`. Use
  // `ProxyServer()` or `Direct()` respectively to create an invalid or direct
  // ProxyServer.
  static ProxyServer FromSchemeHostAndPort(Scheme scheme,
                                           base::StringPiece host,
                                           base::StringPiece port_str);
  static ProxyServer FromSchemeHostAndPort(Scheme scheme,
                                           base::StringPiece host,
                                           absl::optional<uint16_t> port);

  // In URL format (with brackets around IPv6 literals). Must not call for
  // ProxyServers without a host (invalid or direct).
  std::string GetHost() const;

  // Must not call for ProxyServers without a host (invalid or direct).
  uint16_t GetPort() const;

  bool is_valid() const { return scheme_ != SCHEME_INVALID; }

  // Gets the proxy's scheme (i.e. SOCKS4, SOCKS5, HTTP)
  Scheme scheme() const { return scheme_; }

  // Returns true if this ProxyServer is actually just a DIRECT connection.
  bool is_direct() const { return scheme_ == SCHEME_DIRECT; }

  // Returns true if this ProxyServer is an HTTP proxy.
  bool is_http() const { return scheme_ == SCHEME_HTTP; }

  // Returns true if this ProxyServer is an HTTPS proxy. Note this
  // does not include proxies matched by |is_quic()|.
  //
  // Generally one should test the more general concept of
  // |is_secure_http_like()| to account for |is_quic()|.
  bool is_https() const { return scheme_ == SCHEME_HTTPS; }

  // Returns true if this ProxyServer is a SOCKS proxy.
  bool is_socks() const {
    return scheme_ == SCHEME_SOCKS4 || scheme_ == SCHEME_SOCKS5;
  }

  // Returns true if this ProxyServer is a QUIC proxy.
  bool is_quic() const { return scheme_ == SCHEME_QUIC; }

  // Returns true if the ProxyServer's scheme is HTTP compatible (uses HTTP
  // headers, has a CONNECT method for establishing tunnels).
  bool is_http_like() const { return is_http() || is_https() || is_quic(); }

  // Returns true if the proxy server has HTTP semantics, AND
  // the channel between the client and proxy server is secure.
  bool is_secure_http_like() const { return is_https() || is_quic(); }

  const HostPortPair& host_port_pair() const;

  // Returns a ProxyServer representing DIRECT connections.
  static ProxyServer Direct() {
    return ProxyServer(SCHEME_DIRECT, HostPortPair());
  }

  // Returns the default port number for a proxy server with the specified
  // scheme. Returns -1 if unknown.
  static int GetDefaultPortForScheme(Scheme scheme);

  bool operator==(const ProxyServer& other) const {
    return scheme_ == other.scheme_ &&
           host_port_pair_.Equals(other.host_port_pair_);
  }

  bool operator!=(const ProxyServer& other) const { return !(*this == other); }

  // Comparator function so this can be placed in a std::map.
  bool operator<(const ProxyServer& other) const {
    return std::tie(scheme_, host_port_pair_) <
           std::tie(other.scheme_, other.host_port_pair_);
  }

 private:
  Scheme scheme_ = SCHEME_INVALID;
  HostPortPair host_port_pair_;
};

NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
                                            const ProxyServer& proxy_server);

typedef std::pair<HostPortPair, ProxyServer> HostPortProxyPair;

}  // namespace net

#endif  // NET_BASE_PROXY_SERVER_H_