1 /* -*- Mode: C++; tab-width: 2; 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 /* 8 Alt-Svc allows separation of transport routing from the origin host without 9 using a proxy. See https://httpwg.github.io/http-extensions/alt-svc.html and 10 https://tools.ietf.org/html/draft-ietf-httpbis-alt-svc-06 11 12 Nice To Have Future Enhancements:: 13 * flush on network change event when we have an indicator 14 * use established https channel for http instead separate of conninfo hash 15 * pin via http-tls header 16 * clear based on origin when a random fail happens not just 421 17 * upon establishment of channel, cancel and retry trans that have not yet written anything 18 * persistent storage (including private browsing filter) 19 * memory reporter for cache, but this is rather tiny 20 */ 21 22 #ifndef mozilla_net_AlternateServices_h 23 #define mozilla_net_AlternateServices_h 24 25 #include "mozilla/DataStorage.h" 26 #include "nsRefPtrHashtable.h" 27 #include "nsString.h" 28 #include "nsIInterfaceRequestor.h" 29 #include "nsIStreamListener.h" 30 #include "nsISpeculativeConnect.h" 31 #include "mozilla/BasePrincipal.h" 32 33 class nsILoadInfo; 34 35 namespace mozilla { namespace net { 36 37 class nsProxyInfo; 38 class nsHttpConnectionInfo; 39 class nsHttpTransaction; 40 class nsHttpChannel; 41 class WellKnownChecker; 42 43 class AltSvcMapping 44 { 45 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AltSvcMapping) 46 47 private: // ctor from ProcessHeader 48 AltSvcMapping(DataStorage *storage, 49 int32_t storageEpoch, 50 const nsACString &originScheme, 51 const nsACString &originHost, 52 int32_t originPort, 53 const nsACString &username, 54 bool privateBrowsing, 55 uint32_t expiresAt, 56 const nsACString &alternateHost, 57 int32_t alternatePort, 58 const nsACString &npnToken); 59 public: 60 AltSvcMapping(DataStorage *storage, int32_t storageEpoch, const nsCString &serialized); 61 62 static void ProcessHeader(const nsCString &buf, const nsCString &originScheme, 63 const nsCString &originHost, int32_t originPort, 64 const nsACString &username, bool privateBrowsing, 65 nsIInterfaceRequestor *callbacks, nsProxyInfo *proxyInfo, 66 uint32_t caps, const NeckoOriginAttributes &originAttributes); 67 AlternateHost()68 const nsCString &AlternateHost() const { return mAlternateHost; } OriginHost()69 const nsCString &OriginHost() const { return mOriginHost; } OriginPort()70 uint32_t OriginPort() const { return mOriginPort; } HashKey()71 const nsCString &HashKey() const { return mHashKey; } AlternatePort()72 uint32_t AlternatePort() const { return mAlternatePort; } Validated()73 bool Validated() { return mValidated; } GetExpiresAt()74 int32_t GetExpiresAt() { return mExpiresAt; } 75 bool RouteEquals(AltSvcMapping *map); HTTPS()76 bool HTTPS() { return mHttps; } 77 78 void GetConnectionInfo(nsHttpConnectionInfo **outCI, nsProxyInfo *pi, 79 const NeckoOriginAttributes &originAttributes); 80 81 int32_t TTL(); StorageEpoch()82 int32_t StorageEpoch() { return mStorageEpoch; } Private()83 bool Private() { return mPrivate; } 84 85 void SetValidated(bool val); 86 void SetMixedScheme(bool val); 87 void SetExpiresAt(int32_t val); 88 void SetExpired(); 89 void Sync(); 90 91 static void MakeHashKey(nsCString &outKey, 92 const nsACString &originScheme, 93 const nsACString &originHost, 94 int32_t originPort, 95 bool privateBrowsing); 96 97 private: ~AltSvcMapping()98 virtual ~AltSvcMapping() {}; 99 void SyncString(nsCString val); 100 RefPtr<DataStorage> mStorage; 101 int32_t mStorageEpoch; 102 void Serialize (nsCString &out); 103 104 nsCString mHashKey; 105 106 // If you change any of these members, update Serialize() 107 nsCString mAlternateHost; 108 MOZ_INIT_OUTSIDE_CTOR int32_t mAlternatePort; 109 110 nsCString mOriginHost; 111 MOZ_INIT_OUTSIDE_CTOR int32_t mOriginPort; 112 113 nsCString mUsername; 114 MOZ_INIT_OUTSIDE_CTOR bool mPrivate; 115 116 MOZ_INIT_OUTSIDE_CTOR uint32_t mExpiresAt; // alt-svc mappping 117 118 MOZ_INIT_OUTSIDE_CTOR bool mValidated; 119 MOZ_INIT_OUTSIDE_CTOR bool mHttps; // origin is https:// 120 MOZ_INIT_OUTSIDE_CTOR bool mMixedScheme; // .wk allows http and https on same con 121 122 nsCString mNPNToken; 123 }; 124 125 class AltSvcOverride : public nsIInterfaceRequestor 126 , public nsISpeculativeConnectionOverrider 127 { 128 public: 129 NS_DECL_THREADSAFE_ISUPPORTS 130 NS_DECL_NSISPECULATIVECONNECTIONOVERRIDER 131 NS_DECL_NSIINTERFACEREQUESTOR 132 AltSvcOverride(nsIInterfaceRequestor * aRequestor)133 explicit AltSvcOverride(nsIInterfaceRequestor *aRequestor) 134 : mCallbacks(aRequestor) {} 135 136 private: ~AltSvcOverride()137 virtual ~AltSvcOverride() {} 138 nsCOMPtr<nsIInterfaceRequestor> mCallbacks; 139 }; 140 141 class TransactionObserver : public nsIStreamListener 142 { 143 public: 144 NS_DECL_THREADSAFE_ISUPPORTS 145 NS_DECL_NSISTREAMLISTENER 146 NS_DECL_NSIREQUESTOBSERVER 147 148 TransactionObserver(nsHttpChannel *channel, WellKnownChecker *checker); 149 void Complete(nsHttpTransaction *, nsresult); 150 private: 151 friend class WellKnownChecker; ~TransactionObserver()152 virtual ~TransactionObserver() {} 153 154 nsCOMPtr<nsISupports> mChannelRef; 155 nsHttpChannel *mChannel; 156 WellKnownChecker *mChecker; 157 nsCString mWKResponse; 158 159 bool mRanOnce; 160 bool mAuthOK; // confirmed no TLS failure 161 bool mVersionOK; // connection h2 162 bool mStatusOK; // HTTP Status 200 163 }; 164 165 class AltSvcCache 166 { 167 public: AltSvcCache()168 AltSvcCache() : mStorageEpoch(0) {} ~AltSvcCache()169 virtual ~AltSvcCache () {}; 170 void UpdateAltServiceMapping(AltSvcMapping *map, nsProxyInfo *pi, 171 nsIInterfaceRequestor *, uint32_t caps, 172 const NeckoOriginAttributes &originAttributes); // main thread 173 already_AddRefed<AltSvcMapping> GetAltServiceMapping(const nsACString &scheme, 174 const nsACString &host, 175 int32_t port, bool pb); 176 void ClearAltServiceMappings(); 177 void ClearHostMapping(const nsACString &host, int32_t port); 178 void ClearHostMapping(nsHttpConnectionInfo *ci); GetStoragePtr()179 DataStorage *GetStoragePtr() { return mStorage.get(); } StorageEpoch()180 int32_t StorageEpoch() { return mStorageEpoch; } 181 182 private: 183 already_AddRefed<AltSvcMapping> LookupMapping(const nsCString &key, bool privateBrowsing); 184 RefPtr<DataStorage> mStorage; 185 int32_t mStorageEpoch; 186 }; 187 188 } // namespace net 189 } // namespace mozilla 190 191 #endif // include guard 192