summaryrefslogtreecommitdiff
path: root/chromium/net/base/proxy_server.h
blob: 21206d059b5964679d1176029305e761e5ba841b (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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// 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 "build/build_config.h"

#if defined(OS_APPLE)
#include <CoreFoundation/CoreFoundation.h>
#endif

#include <string>
#include <tuple>

#include "base/strings/string_piece.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_export.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);

  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;

  // Parses from an input with format:
  //   [<scheme>"://"]<server>[":"<port>]
  //
  // Both <scheme> and <port> are optional. If <scheme> is omitted, it will be
  // assumed as |default_scheme|. If <port> is omitted, it will be assumed as
  // the default port for the chosen scheme (80 for "http", 1080 for "socks").
  //
  // If parsing fails the instance will be set to invalid.
  //
  // Examples (for |default_scheme| = SCHEME_HTTP ):
  //   "foopy"            {scheme=HTTP, host="foopy", port=80}
  //   "socks://foopy"    {scheme=SOCKS5, host="foopy", port=1080}
  //   "socks4://foopy"   {scheme=SOCKS4, host="foopy", port=1080}
  //   "socks5://foopy"   {scheme=SOCKS5, host="foopy", port=1080}
  //   "http://foopy:17"  {scheme=HTTP, host="foopy", port=17}
  //   "https://foopy:17" {scheme=HTTPS, host="foopy", port=17}
  //   "quic://foopy:17"  {scheme=QUIC, host="foopy", port=17}
  //   "direct://"        {scheme=DIRECT}
  //   "foopy:X"          INVALID -- bad port.
  static ProxyServer FromURI(base::StringPiece uri, Scheme default_scheme);

  // Formats as a URI string. This does the reverse of FromURI.
  std::string ToURI() const;

  // Parses from a PAC string result.
  //
  // If <port> is omitted, it will be assumed as the default port for the
  // chosen scheme (80 for "http", 1080 for "socks").
  //
  // If parsing fails the instance will be set to invalid.
  //
  // Examples:
  //   "PROXY foopy:19"   {scheme=HTTP, host="foopy", port=19}
  //   "DIRECT"           {scheme=DIRECT}
  //   "SOCKS5 foopy"     {scheme=SOCKS5, host="foopy", port=1080}
  //   "HTTPS foopy:123"  {scheme=HTTPS, host="foopy", port=123}
  //   "QUIC foopy:123"   {scheme=QUIC, host="foopy", port=123}
  //   "BLAH xxx:xx"      INVALID
  static ProxyServer FromPacString(base::StringPiece pac_string);

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

#if defined(OS_APPLE)
  // Utility function to pull out a host/port pair from a dictionary and return
  // it as a ProxyServer object. Pass in a dictionary that has a  value for the
  // host key and optionally a value for the port key. In the error condition
  // where the host value is especially malformed, returns an invalid
  // ProxyServer.
  static ProxyServer FromDictionary(Scheme scheme,
                                    CFDictionaryRef dict,
                                    CFStringRef host_key,
                                    CFStringRef port_key);
#endif

  // Formats as a PAC result entry. This does the reverse of FromPacString().
  std::string ToPacString() const;

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

  // Parses the proxy scheme from a URL-like representation, to a
  // ProxyServer::Scheme. This corresponds with the values used in
  // ProxyServer::ToURI(). If no type could be matched, returns SCHEME_INVALID.
  // |scheme| can be one of http, https, socks, socks4, socks5, direct.
  static Scheme GetSchemeFromURI(const std::string& 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_);
  }

  // Returns the estimate of dynamically allocated memory in bytes.
  size_t EstimateMemoryUsage() const;

 private:
  // Creates a ProxyServer given a scheme, and host/port string. If parsing the
  // host/port string fails, the returned instance will be invalid.
  static ProxyServer FromSchemeHostAndPort(Scheme scheme,
                                           base::StringPiece host_and_port);

  Scheme scheme_ = SCHEME_INVALID;
  HostPortPair host_port_pair_;
};

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

}  // namespace net

#endif  // NET_BASE_PROXY_SERVER_H_