Line data Source code
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 0 : 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 : const OriginAttributes &originAttributes);
60 : public:
61 : AltSvcMapping(DataStorage *storage, int32_t storageEpoch, const nsCString &serialized);
62 :
63 : static void ProcessHeader(const nsCString &buf, const nsCString &originScheme,
64 : const nsCString &originHost, int32_t originPort,
65 : const nsACString &username, bool privateBrowsing,
66 : nsIInterfaceRequestor *callbacks, nsProxyInfo *proxyInfo,
67 : uint32_t caps, const OriginAttributes &originAttributes);
68 :
69 0 : const nsCString &AlternateHost() const { return mAlternateHost; }
70 0 : const nsCString &OriginHost() const { return mOriginHost; }
71 0 : uint32_t OriginPort() const { return mOriginPort; }
72 0 : const nsCString &HashKey() const { return mHashKey; }
73 0 : uint32_t AlternatePort() const { return mAlternatePort; }
74 0 : bool Validated() { return mValidated; }
75 0 : int32_t GetExpiresAt() { return mExpiresAt; }
76 : bool RouteEquals(AltSvcMapping *map);
77 0 : bool HTTPS() { return mHttps; }
78 :
79 : void GetConnectionInfo(nsHttpConnectionInfo **outCI, nsProxyInfo *pi,
80 : const OriginAttributes &originAttributes);
81 :
82 : int32_t TTL();
83 0 : int32_t StorageEpoch() { return mStorageEpoch; }
84 0 : bool Private() { return mPrivate; }
85 :
86 : void SetValidated(bool val);
87 : void SetMixedScheme(bool val);
88 : void SetExpiresAt(int32_t val);
89 : void SetExpired();
90 : void Sync();
91 :
92 : static void MakeHashKey(nsCString &outKey,
93 : const nsACString &originScheme,
94 : const nsACString &originHost,
95 : int32_t originPort,
96 : bool privateBrowsing,
97 : const OriginAttributes &originAttributes);
98 :
99 : private:
100 0 : virtual ~AltSvcMapping() {};
101 : void SyncString(const nsCString& val);
102 : RefPtr<DataStorage> mStorage;
103 : int32_t mStorageEpoch;
104 : void Serialize (nsCString &out);
105 :
106 : nsCString mHashKey;
107 :
108 : // If you change any of these members, update Serialize()
109 : nsCString mAlternateHost;
110 : MOZ_INIT_OUTSIDE_CTOR int32_t mAlternatePort;
111 :
112 : nsCString mOriginHost;
113 : MOZ_INIT_OUTSIDE_CTOR int32_t mOriginPort;
114 :
115 : nsCString mUsername;
116 : MOZ_INIT_OUTSIDE_CTOR bool mPrivate;
117 :
118 : MOZ_INIT_OUTSIDE_CTOR uint32_t mExpiresAt; // alt-svc mappping
119 :
120 : MOZ_INIT_OUTSIDE_CTOR bool mValidated;
121 : MOZ_INIT_OUTSIDE_CTOR bool mHttps; // origin is https://
122 : MOZ_INIT_OUTSIDE_CTOR bool mMixedScheme; // .wk allows http and https on same con
123 :
124 : nsCString mNPNToken;
125 :
126 : OriginAttributes mOriginAttributes;
127 : };
128 :
129 : class AltSvcOverride : public nsIInterfaceRequestor
130 : , public nsISpeculativeConnectionOverrider
131 : {
132 : public:
133 : NS_DECL_THREADSAFE_ISUPPORTS
134 : NS_DECL_NSISPECULATIVECONNECTIONOVERRIDER
135 : NS_DECL_NSIINTERFACEREQUESTOR
136 :
137 0 : explicit AltSvcOverride(nsIInterfaceRequestor *aRequestor)
138 0 : : mCallbacks(aRequestor) {}
139 :
140 : private:
141 0 : virtual ~AltSvcOverride() {}
142 : nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
143 : };
144 :
145 : class TransactionObserver : public nsIStreamListener
146 : {
147 : public:
148 : NS_DECL_THREADSAFE_ISUPPORTS
149 : NS_DECL_NSISTREAMLISTENER
150 : NS_DECL_NSIREQUESTOBSERVER
151 :
152 : TransactionObserver(nsHttpChannel *channel, WellKnownChecker *checker);
153 : void Complete(nsHttpTransaction *, nsresult);
154 : private:
155 : friend class WellKnownChecker;
156 0 : virtual ~TransactionObserver() {}
157 :
158 : nsCOMPtr<nsISupports> mChannelRef;
159 : nsHttpChannel *mChannel;
160 : WellKnownChecker *mChecker;
161 : nsCString mWKResponse;
162 :
163 : bool mRanOnce;
164 : bool mAuthOK; // confirmed no TLS failure
165 : bool mVersionOK; // connection h2
166 : bool mStatusOK; // HTTP Status 200
167 : };
168 :
169 : class AltSvcCache
170 : {
171 : public:
172 1 : AltSvcCache() : mStorageEpoch(0) {}
173 0 : virtual ~AltSvcCache () {};
174 : void UpdateAltServiceMapping(AltSvcMapping *map, nsProxyInfo *pi,
175 : nsIInterfaceRequestor *, uint32_t caps,
176 : const OriginAttributes &originAttributes); // main thread
177 : already_AddRefed<AltSvcMapping> GetAltServiceMapping(const nsACString &scheme,
178 : const nsACString &host,
179 : int32_t port, bool pb,
180 : const OriginAttributes &originAttributes);
181 : void ClearAltServiceMappings();
182 : void ClearHostMapping(const nsACString &host, int32_t port, const OriginAttributes &originAttributes);
183 : void ClearHostMapping(nsHttpConnectionInfo *ci);
184 0 : DataStorage *GetStoragePtr() { return mStorage.get(); }
185 0 : int32_t StorageEpoch() { return mStorageEpoch; }
186 :
187 : private:
188 : already_AddRefed<AltSvcMapping> LookupMapping(const nsCString &key, bool privateBrowsing);
189 : RefPtr<DataStorage> mStorage;
190 : int32_t mStorageEpoch;
191 : };
192 :
193 : } // namespace net
194 : } // namespace mozilla
195 :
196 : #endif // include guard
|