1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim: set sw=4 ts=8 et tw=80 : */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef nsHttpConnectionInfo_h__
8 #define nsHttpConnectionInfo_h__
9 
10 #include "nsHttp.h"
11 #include "nsProxyInfo.h"
12 #include "nsCOMPtr.h"
13 #include "nsStringFwd.h"
14 #include "mozilla/Logging.h"
15 #include "mozilla/BasePrincipal.h"
16 #include "ARefBase.h"
17 
18 //-----------------------------------------------------------------------------
19 // nsHttpConnectionInfo - holds the properties of a connection
20 //-----------------------------------------------------------------------------
21 
22 // http:// uris through a proxy will all share the same CI, because they can
23 // all use the same connection. (modulo pb and anonymous flags). They just use
24 // the proxy as the origin host name.
25 // however, https:// uris tunnel through the proxy so they will have different
26 // CIs - the CI reflects both the proxy and the origin.
27 // however, proxy conenctions made with http/2 (or spdy) can tunnel to the origin
28 // and multiplex non tunneled transactions at the same time, so they have a
29 // special wildcard CI that accepts all origins through that proxy.
30 
31 namespace mozilla { namespace net {
32 
33 extern LazyLogModule gHttpLog;
34 
35 class nsHttpConnectionInfo: public ARefBase
36 {
37 public:
38     nsHttpConnectionInfo(const nsACString &originHost,
39                          int32_t originPort,
40                          const nsACString &npnToken,
41                          const nsACString &username,
42                          nsProxyInfo *proxyInfo,
43                          const NeckoOriginAttributes &originAttributes,
44                          bool endToEndSSL = false);
45 
46     // this version must use TLS and you may supply separate
47     // connection (aka routing) information than the authenticated
48     // origin information
49     nsHttpConnectionInfo(const nsACString &originHost,
50                          int32_t originPort,
51                          const nsACString &npnToken,
52                          const nsACString &username,
53                          nsProxyInfo *proxyInfo,
54                          const NeckoOriginAttributes &originAttributes,
55                          const nsACString &routedHost,
56                          int32_t routedPort);
57 
58 private:
~nsHttpConnectionInfo()59     virtual ~nsHttpConnectionInfo()
60     {
61         MOZ_LOG(gHttpLog, LogLevel::Debug, ("Destroying nsHttpConnectionInfo @%x\n", this));
62     }
63 
64     void BuildHashKey();
65 
66 public:
HashKey()67     const nsAFlatCString &HashKey() const { return mHashKey; }
68 
GetOrigin()69     const nsCString &GetOrigin() const { return mOrigin; }
Origin()70     const char   *Origin()       const { return mOrigin.get(); }
OriginPort()71     int32_t       OriginPort()   const { return mOriginPort; }
72 
GetRoutedHost()73     const nsCString &GetRoutedHost() const { return mRoutedHost; }
RoutedHost()74     const char      *RoutedHost() const { return mRoutedHost.get(); }
RoutedPort()75     int32_t          RoutedPort() const { return mRoutedPort; }
76 
77     // With overhead rebuilding the hash key. The initial
78     // network interface is empty. So you can reduce one call
79     // if there's no explicit route after ctor.
80     void SetNetworkInterfaceId(const nsACString& aNetworkInterfaceId);
81 
82     // OK to treat these as an infalible allocation
83     nsHttpConnectionInfo* Clone() const;
84     void CloneAsDirectRoute(nsHttpConnectionInfo **outParam);
85     nsresult CreateWildCard(nsHttpConnectionInfo **outParam);
86 
ProxyHost()87     const char *ProxyHost() const { return mProxyInfo ? mProxyInfo->Host().get() : nullptr; }
ProxyPort()88     int32_t     ProxyPort() const { return mProxyInfo ? mProxyInfo->Port() : -1; }
ProxyType()89     const char *ProxyType() const { return mProxyInfo ? mProxyInfo->Type() : nullptr; }
ProxyUsername()90     const char *ProxyUsername() const { return mProxyInfo ? mProxyInfo->Username().get() : nullptr; }
ProxyPassword()91     const char *ProxyPassword() const { return mProxyInfo ? mProxyInfo->Password().get() : nullptr; }
92 
93     // Compare this connection info to another...
94     // Two connections are 'equal' if they end up talking the same
95     // protocol to the same server. This is needed to properly manage
96     // persistent connections to proxies
97     // Note that we don't care about transparent proxies -
98     // it doesn't matter if we're talking via socks or not, since
99     // a request will end up at the same host.
Equals(const nsHttpConnectionInfo * info)100     bool Equals(const nsHttpConnectionInfo *info)
101     {
102         return mHashKey.Equals(info->HashKey());
103     }
104 
Username()105     const char   *Username() const       { return mUsername.get(); }
ProxyInfo()106     nsProxyInfo  *ProxyInfo() const      { return mProxyInfo; }
DefaultPort()107     int32_t       DefaultPort() const    { return mEndToEndSSL ? NS_HTTPS_DEFAULT_PORT : NS_HTTP_DEFAULT_PORT; }
SetAnonymous(bool anon)108     void          SetAnonymous(bool anon)
109                                          { mHashKey.SetCharAt(anon ? 'A' : '.', 2); }
GetAnonymous()110     bool          GetAnonymous() const   { return mHashKey.CharAt(2) == 'A'; }
SetPrivate(bool priv)111     void          SetPrivate(bool priv)  { mHashKey.SetCharAt(priv ? 'P' : '.', 3); }
GetPrivate()112     bool          GetPrivate() const     { return mHashKey.CharAt(3) == 'P'; }
SetInsecureScheme(bool insecureScheme)113     void          SetInsecureScheme(bool insecureScheme)
114                                        { mHashKey.SetCharAt(insecureScheme ? 'I' : '.', 4); }
GetInsecureScheme()115     bool          GetInsecureScheme() const   { return mHashKey.CharAt(4) == 'I'; }
116 
SetNoSpdy(bool aNoSpdy)117     void          SetNoSpdy(bool aNoSpdy)
118                                        { mHashKey.SetCharAt(aNoSpdy ? 'X' : '.', 5); }
GetNoSpdy()119     bool          GetNoSpdy() const    { return mHashKey.CharAt(5) == 'X'; }
120 
SetBeConservative(bool aBeConservative)121     void          SetBeConservative(bool aBeConservative)
122                                             { mHashKey.SetCharAt(aBeConservative ? 'C' : '.', 6); }
GetBeConservative()123     bool          GetBeConservative() const { return mHashKey.CharAt(6) == 'C'; }
124 
GetNetworkInterfaceId()125     const nsCString &GetNetworkInterfaceId() const { return mNetworkInterfaceId; }
126 
GetNPNToken()127     const nsCString &GetNPNToken() { return mNPNToken; }
GetUsername()128     const nsCString &GetUsername() { return mUsername; }
129 
GetOriginAttributes()130     const NeckoOriginAttributes &GetOriginAttributes() { return mOriginAttributes; }
131 
132     // Returns true for any kind of proxy (http, socks, https, etc..)
133     bool UsingProxy();
134 
135     // Returns true when proxying over HTTP or HTTPS
UsingHttpProxy()136     bool UsingHttpProxy() const { return mUsingHttpProxy || mUsingHttpsProxy; }
137 
138     // Returns true when proxying over HTTPS
UsingHttpsProxy()139     bool UsingHttpsProxy() const { return mUsingHttpsProxy; }
140 
141     // Returns true when a resource is in SSL end to end (e.g. https:// uri)
EndToEndSSL()142     bool EndToEndSSL() const { return mEndToEndSSL; }
143 
144     // Returns true when at least first hop is SSL (e.g. proxy over https or https uri)
FirstHopSSL()145     bool FirstHopSSL() const { return mEndToEndSSL || mUsingHttpsProxy; }
146 
147     // Returns true when CONNECT is used to tunnel through the proxy (e.g. https:// or ws://)
UsingConnect()148     bool UsingConnect() const { return mUsingConnect; }
149 
150     // Returns true when origin/proxy is an RFC1918 literal.
151     bool HostIsLocalIPLiteral() const;
152 
153 private:
154     void Init(const nsACString &host,
155               int32_t port,
156               const nsACString &npnToken,
157               const nsACString &username,
158               nsProxyInfo* proxyInfo,
159               const NeckoOriginAttributes &originAttributes,
160               bool EndToEndSSL);
161     void SetOriginServer(const nsACString &host, int32_t port);
162 
163     nsCString              mOrigin;
164     int32_t                mOriginPort;
165     nsCString              mRoutedHost;
166     int32_t                mRoutedPort;
167 
168     nsCString              mHashKey;
169     nsCString              mNetworkInterfaceId;
170     nsCString              mUsername;
171     nsCOMPtr<nsProxyInfo>  mProxyInfo;
172     bool                   mUsingHttpProxy;
173     bool                   mUsingHttpsProxy;
174     bool                   mEndToEndSSL;
175     bool                   mUsingConnect;  // if will use CONNECT with http proxy
176     nsCString              mNPNToken;
177     NeckoOriginAttributes  mOriginAttributes;
178 
179 // for RefPtr
180     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsHttpConnectionInfo)
181 };
182 
183 } // namespace net
184 } // namespace mozilla
185 
186 #endif // nsHttpConnectionInfo_h__
187