nsHttpConnectionInfo.h (12713B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set sw=2 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 "mozilla/AlreadyAddRefed.h" 17 #include "ARefBase.h" 18 #include "nsIRequest.h" 19 20 //----------------------------------------------------------------------------- 21 // nsHttpConnectionInfo - holds the properties of a connection 22 //----------------------------------------------------------------------------- 23 24 // http:// uris through a proxy will all share the same CI, because they can 25 // all use the same connection. (modulo pb and anonymous flags). They just use 26 // the proxy as the origin host name. 27 // however, https:// uris tunnel through the proxy so they will have different 28 // CIs - the CI reflects both the proxy and the origin. 29 // however, proxy conenctions made with http/2 (or spdy) can tunnel to the 30 // origin and multiplex non tunneled transactions at the same time, so they have 31 // a special wildcard CI that accepts all origins through that proxy. 32 33 class nsISVCBRecord; 34 35 namespace mozilla { 36 namespace net { 37 38 extern LazyLogModule gHttpLog; 39 class HttpConnectionInfoCloneArgs; 40 class nsHttpTransaction; 41 42 class nsHttpConnectionInfo final : public ARefBase { 43 public: 44 nsHttpConnectionInfo(const nsACString& originHost, int32_t originPort, 45 const nsACString& npnToken, const nsACString& username, 46 nsProxyInfo* proxyInfo, 47 const OriginAttributes& originAttributes, 48 bool endToEndSSL = false, bool aIsHttp3 = false, 49 bool aWebTransport = false); 50 51 // this version must use TLS and you may supply separate 52 // connection (aka routing) information than the authenticated 53 // origin information 54 nsHttpConnectionInfo(const nsACString& originHost, int32_t originPort, 55 const nsACString& npnToken, const nsACString& username, 56 nsProxyInfo* proxyInfo, 57 const OriginAttributes& originAttributes, 58 const nsACString& routedHost, int32_t routedPort, 59 bool aIsHttp3, bool aWebTransport = false); 60 61 static void SerializeHttpConnectionInfo(nsHttpConnectionInfo* aInfo, 62 HttpConnectionInfoCloneArgs& aArgs); 63 static already_AddRefed<nsHttpConnectionInfo> 64 DeserializeHttpConnectionInfoCloneArgs( 65 const HttpConnectionInfoCloneArgs& aInfoArgs); 66 67 static void BuildOriginFrameHashKey(nsACString& newKey, 68 nsHttpConnectionInfo* ci, 69 const nsACString& host, int32_t port); 70 71 private: 72 virtual ~nsHttpConnectionInfo() { 73 MOZ_LOG(gHttpLog, LogLevel::Debug, 74 ("Destroying nsHttpConnectionInfo @%p\n", this)); 75 } 76 77 void BuildHashKey(); 78 void RebuildHashKey(); 79 80 // See comments in nsHttpConnectionInfo::BuildHashKey for the meaning of each 81 // field. 82 enum class HashKeyIndex : uint32_t { 83 Proxy = 0, 84 EndToEndSSL, 85 Anonymous, 86 Private, 87 InsecureScheme, 88 NoSpdy, 89 BeConservative, 90 AnonymousAllowClientCert, 91 FallbackConnection, 92 WebTransport, 93 End, 94 }; 95 constexpr inline auto UnderlyingIndex(HashKeyIndex aIndex) const { 96 return std::underlying_type_t<HashKeyIndex>(aIndex); 97 } 98 99 public: 100 const nsCString& HashKey() const { return mHashKey; } 101 102 const nsCString& GetOrigin() const { return mOrigin; } 103 const char* Origin() const { return mOrigin.get(); } 104 int32_t OriginPort() const { return mOriginPort; } 105 106 const nsCString& GetRoutedHost() const { return mRoutedHost; } 107 const char* RoutedHost() const { return mRoutedHost.get(); } 108 int32_t RoutedPort() const { return mRoutedPort; } 109 110 // OK to treat these as an infalible allocation 111 already_AddRefed<nsHttpConnectionInfo> Clone() const; 112 // This main prupose of this function is to clone this connection info, but 113 // replace mRoutedHost with SvcDomainName in the given SVCB record. Note that 114 // if SvcParamKeyPort and SvcParamKeyAlpn are presented in the SVCB record, 115 // mRoutedPort and mNPNToken will be replaced as well. 116 already_AddRefed<nsHttpConnectionInfo> CloneAndAdoptHTTPSSVCRecord( 117 nsISVCBRecord* aRecord) const; 118 void CloneAsDirectRoute(nsHttpConnectionInfo** outCI, 119 nsProxyInfo* aProxyInfo = nullptr); 120 121 already_AddRefed<nsHttpConnectionInfo> CreateConnectUDPFallbackConnInfo(); 122 123 [[nodiscard]] nsresult CreateWildCard(nsHttpConnectionInfo** outParam); 124 125 const char* ProxyHost() const { 126 return mProxyInfo ? mProxyInfo->Host().get() : nullptr; 127 } 128 int32_t ProxyPort() const { return mProxyInfo ? mProxyInfo->Port() : -1; } 129 const char* ProxyType() const { 130 return mProxyInfo ? mProxyInfo->Type() : nullptr; 131 } 132 const char* ProxyUsername() const { 133 return mProxyInfo ? mProxyInfo->Username().get() : nullptr; 134 } 135 const char* ProxyPassword() const { 136 return mProxyInfo ? mProxyInfo->Password().get() : nullptr; 137 } 138 uint32_t ProxyFlag() const { 139 uint32_t flags = 0; 140 if (mProxyInfo) { 141 mProxyInfo->GetFlags(&flags); 142 } 143 return flags; 144 } 145 146 const nsCString& ProxyAuthorizationHeader() const { 147 return mProxyInfo ? mProxyInfo->ProxyAuthorizationHeader() : EmptyCString(); 148 } 149 const nsCString& ConnectionIsolationKey() const { 150 return mProxyInfo ? mProxyInfo->ConnectionIsolationKey() : EmptyCString(); 151 } 152 153 // Compare this connection info to another... 154 // Two connections are 'equal' if they end up talking the same 155 // protocol to the same server. This is needed to properly manage 156 // persistent connections to proxies 157 // Note that we don't care about transparent proxies - 158 // it doesn't matter if we're talking via socks or not, since 159 // a request will end up at the same host. 160 bool Equals(const nsHttpConnectionInfo* info) { 161 return mHashKey.Equals(info->HashKey()); 162 } 163 164 const char* Username() const { return mUsername.get(); } 165 nsProxyInfo* ProxyInfo() const { return mProxyInfo; } 166 int32_t DefaultPort() const { 167 return mEndToEndSSL ? NS_HTTPS_DEFAULT_PORT : NS_HTTP_DEFAULT_PORT; 168 } 169 void SetAnonymous(bool anon) { 170 SetHashCharAt(anon ? 'A' : '.', HashKeyIndex::Anonymous); 171 } 172 bool GetAnonymous() const { 173 return GetHashCharAt(HashKeyIndex::Anonymous) == 'A'; 174 } 175 void SetPrivate(bool priv) { 176 SetHashCharAt(priv ? 'P' : '.', HashKeyIndex::Private); 177 } 178 bool GetPrivate() const { 179 return GetHashCharAt(HashKeyIndex::Private) == 'P'; 180 } 181 void SetInsecureScheme(bool insecureScheme) { 182 SetHashCharAt(insecureScheme ? 'I' : '.', HashKeyIndex::InsecureScheme); 183 } 184 bool GetInsecureScheme() const { 185 return GetHashCharAt(HashKeyIndex::InsecureScheme) == 'I'; 186 } 187 188 void SetNoSpdy(bool aNoSpdy) { 189 SetHashCharAt(aNoSpdy ? 'X' : '.', HashKeyIndex::NoSpdy); 190 if (aNoSpdy && mNPNToken == "h2"_ns) { 191 mNPNToken.Truncate(); 192 RebuildHashKey(); 193 } 194 } 195 bool GetNoSpdy() const { return GetHashCharAt(HashKeyIndex::NoSpdy) == 'X'; } 196 197 void SetBeConservative(bool aBeConservative) { 198 SetHashCharAt(aBeConservative ? 'C' : '.', HashKeyIndex::BeConservative); 199 } 200 bool GetBeConservative() const { 201 return GetHashCharAt(HashKeyIndex::BeConservative) == 'C'; 202 } 203 204 void SetAnonymousAllowClientCert(bool anon) { 205 SetHashCharAt(anon ? 'B' : '.', HashKeyIndex::AnonymousAllowClientCert); 206 } 207 bool GetAnonymousAllowClientCert() const { 208 return GetHashCharAt(HashKeyIndex::AnonymousAllowClientCert) == 'B'; 209 } 210 211 void SetFallbackConnection(bool aFallback) { 212 SetHashCharAt(aFallback ? 'F' : '.', HashKeyIndex::FallbackConnection); 213 } 214 bool GetFallbackConnection() const { 215 return GetHashCharAt(HashKeyIndex::FallbackConnection) == 'F'; 216 } 217 218 void SetTlsFlags(uint32_t aTlsFlags); 219 uint32_t GetTlsFlags() const { return mTlsFlags; } 220 221 // IsTrrServiceChannel means that this connection is used to send TRR requests 222 // over 223 void SetIsTrrServiceChannel(bool aIsTRRChannel) { 224 mIsTrrServiceChannel = aIsTRRChannel; 225 } 226 bool GetIsTrrServiceChannel() const { return mIsTrrServiceChannel; } 227 228 void SetTRRMode(nsIRequest::TRRMode aTRRMode); 229 nsIRequest::TRRMode GetTRRMode() const { return mTRRMode; } 230 231 void SetIPv4Disabled(bool aNoIPv4); 232 bool GetIPv4Disabled() const { return mIPv4Disabled; } 233 234 void SetIPv6Disabled(bool aNoIPv6); 235 bool GetIPv6Disabled() const { return mIPv6Disabled; } 236 237 void SetWebTransport(bool aWebTransport); 238 bool GetWebTransport() const { return mWebTransport; } 239 240 void SetWebTransportId(uint64_t id); 241 uint32_t GetWebTransportId() const { return mWebTransportId; }; 242 243 const nsCString& GetNPNToken() const { return mNPNToken; } 244 const nsCString& GetProxyNPNToken() const { return mProxyNPNToken; } 245 const nsCString& GetUsername() { return mUsername; } 246 247 const OriginAttributes& GetOriginAttributes() { return mOriginAttributes; } 248 249 // Returns true for any kind of proxy (http, socks, https, etc..) 250 bool UsingProxy(); 251 252 // Returns true when proxying over HTTP or HTTPS 253 bool UsingHttpProxy() const { return mUsingHttpProxy || mUsingHttpsProxy; } 254 255 // Returns true when only proxying over HTTP 256 bool UsingOnlyHttpProxy() const { return mUsingHttpProxy; } 257 258 // Returns true when proxying over HTTPS 259 bool UsingHttpsProxy() const { return mUsingHttpsProxy; } 260 261 // Returns true when a resource is in SSL end to end (e.g. https:// uri) 262 bool EndToEndSSL() const { return mEndToEndSSL; } 263 264 // Returns true when at least first hop is SSL (e.g. proxy over https or https 265 // uri) 266 bool FirstHopSSL() const { return mEndToEndSSL || mUsingHttpsProxy; } 267 268 // Returns true when CONNECT is used to tunnel through the proxy (e.g. 269 // https:// or ws://) 270 bool UsingConnect() const { return mUsingConnect; } 271 272 // Returns true when origin/proxy is an RFC1918 literal. 273 bool HostIsLocalIPLiteral() const; 274 275 bool GetLessThanTls13() const { return mLessThanTls13; } 276 void SetLessThanTls13(bool aLessThanTls13) { 277 mLessThanTls13 = aLessThanTls13; 278 } 279 280 bool IsHttp3() const { return mIsHttp3; } 281 bool IsHttp3ProxyConnection() const { return mIsHttp3ProxyConnection; } 282 283 void SetHasIPHintAddress(bool aHasIPHint) { mHasIPHintAddress = aHasIPHint; } 284 bool HasIPHintAddress() const { return mHasIPHintAddress; } 285 286 void SetEchConfig(const nsACString& aEchConfig) { mEchConfig = aEchConfig; } 287 const nsCString& GetEchConfig() const { return mEchConfig; } 288 289 static uint64_t GenerateNewWebTransportId(); 290 291 private: 292 void Init(const nsACString& host, int32_t port, const nsACString& npnToken, 293 const nsACString& username, nsProxyInfo* proxyInfo, 294 const OriginAttributes& originAttributes, bool e2eSSL, 295 bool aIsHttp3, bool aWebTransport); 296 void SetOriginServer(const nsACString& host, int32_t port); 297 nsCString::char_type GetHashCharAt(HashKeyIndex aIndex) const { 298 return mHashKey.CharAt(UnderlyingIndex(aIndex)); 299 } 300 void SetHashCharAt(nsCString::char_type aValue, HashKeyIndex aIndex) { 301 mHashKey.SetCharAt(aValue, UnderlyingIndex(aIndex)); 302 } 303 304 nsCString mOrigin; 305 int32_t mOriginPort = 0; 306 nsCString mRoutedHost; 307 int32_t mRoutedPort; 308 309 nsCString mHashKey; 310 nsCString mUsername; 311 nsCOMPtr<nsProxyInfo> mProxyInfo; 312 bool mUsingHttpProxy = false; 313 bool mUsingHttpsProxy = false; 314 bool mEndToEndSSL = false; 315 // if will use CONNECT with http proxy 316 bool mUsingConnect = false; 317 nsCString mNPNToken; 318 nsCString mProxyNPNToken; 319 OriginAttributes mOriginAttributes; 320 nsIRequest::TRRMode mTRRMode; 321 322 uint32_t mTlsFlags = 0; 323 uint16_t mIsTrrServiceChannel : 1; 324 uint16_t mIPv4Disabled : 1; 325 uint16_t mIPv6Disabled : 1; 326 327 bool mLessThanTls13; // This will be set to true if we negotiate less than 328 // tls1.3. If the tls version is till not know or it 329 // is 1.3 or greater the value will be false. 330 bool mIsHttp3 = false; 331 bool mIsHttp3ProxyConnection = false; 332 bool mWebTransport = false; 333 334 bool mHasIPHintAddress = false; 335 nsCString mEchConfig; 336 337 uint64_t mWebTransportId = 0; // current dedicated Id only used for 338 // Webtransport, zero means not dedicated 339 340 // for RefPtr 341 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsHttpConnectionInfo, override) 342 }; 343 344 } // namespace net 345 } // namespace mozilla 346 347 #endif // nsHttpConnectionInfo_h__