Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim:set ts=4 sw=4 sts=4 et cin: */
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 nsHttp_h__
8 : #define nsHttp_h__
9 :
10 : #include <stdint.h>
11 : #include "prtime.h"
12 : #include "nsAutoPtr.h"
13 : #include "nsString.h"
14 : #include "nsError.h"
15 : #include "nsTArray.h"
16 : #include "mozilla/TimeStamp.h"
17 : #include "mozilla/UniquePtr.h"
18 :
19 : class nsICacheEntry;
20 :
21 : namespace mozilla {
22 :
23 : class Mutex;
24 :
25 : namespace net {
26 : class nsHttpResponseHead;
27 : class nsHttpRequestHead;
28 : class CacheControlParser;
29 :
30 : enum class HttpVersion {
31 : UNKNOWN = 0,
32 : v0_9 = 9,
33 : v1_0 = 10,
34 : v1_1 = 11,
35 : v2_0 = 20
36 : };
37 :
38 : enum class SpdyVersion {
39 : NONE = 0,
40 : // SPDY_VERSION_2 = 2, REMOVED
41 : // SPDY_VERSION_3 = 3, REMOVED
42 : // SPDY_VERSION_31 = 4, REMOVED
43 : HTTP_2 = 5
44 :
45 : // leave room for official versions. telem goes to 48
46 : // 24 was a internal spdy/3.1
47 : // 25 was spdy/4a2
48 : // 26 was http/2-draft08 and http/2-draft07 (they were the same)
49 : // 27 was http/2-draft09, h2-10, and h2-11
50 : // 28 was http/2-draft12
51 : // 29 was http/2-draft13
52 : // 30 was h2-14 and h2-15
53 : // 31 was h2-16
54 : };
55 :
56 : //-----------------------------------------------------------------------------
57 : // http connection capabilities
58 : //-----------------------------------------------------------------------------
59 :
60 : #define NS_HTTP_ALLOW_KEEPALIVE (1<<0)
61 : #define NS_HTTP_LARGE_KEEPALIVE (1<<1)
62 :
63 : // a transaction with this caps flag will continue to own the connection,
64 : // preventing it from being reclaimed, even after the transaction completes.
65 : #define NS_HTTP_STICKY_CONNECTION (1<<2)
66 :
67 : // a transaction with this caps flag will, upon opening a new connection,
68 : // bypass the local DNS cache
69 : #define NS_HTTP_REFRESH_DNS (1<<3)
70 :
71 : // a transaction with this caps flag will not pass SSL client-certificates
72 : // to the server (see bug #466080), but is may also be used for other things
73 : #define NS_HTTP_LOAD_ANONYMOUS (1<<4)
74 :
75 : // a transaction with this caps flag keeps timing information
76 : #define NS_HTTP_TIMING_ENABLED (1<<5)
77 :
78 : // a transaction with this flag blocks the initiation of other transactons
79 : // in the same load group until it is complete
80 : #define NS_HTTP_LOAD_AS_BLOCKING (1<<6)
81 :
82 : // Disallow the use of the SPDY protocol. This is meant for the contexts
83 : // such as HTTP upgrade which are nonsensical for SPDY, it is not the
84 : // SPDY configuration variable.
85 : #define NS_HTTP_DISALLOW_SPDY (1<<7)
86 :
87 : // a transaction with this flag loads without respect to whether the load
88 : // group is currently blocking on some resources
89 : #define NS_HTTP_LOAD_UNBLOCKED (1<<8)
90 :
91 : // This flag indicates the transaction should accept associated pushes
92 : #define NS_HTTP_ONPUSH_LISTENER (1<<9)
93 :
94 : // Transactions with this flag should react to errors without side effects
95 : // First user is to prevent clearing of alt-svc cache on failed probe
96 : #define NS_HTTP_ERROR_SOFTLY (1<<10)
97 :
98 : // This corresponds to nsIHttpChannelInternal.beConservative
99 : // it disables any cutting edge features that we are worried might result in
100 : // interop problems with critical infrastructure
101 : #define NS_HTTP_BE_CONSERVATIVE (1<<11)
102 :
103 : // Transactions with this flag should be processed first.
104 : #define NS_HTTP_URGENT_START (1<<12)
105 :
106 : // A sticky connection of the transaction is explicitly allowed to be restarted
107 : // on ERROR_NET_RESET.
108 : #define NS_HTTP_CONNECTION_RESTARTABLE (1<<13)
109 :
110 : //-----------------------------------------------------------------------------
111 : // some default values
112 : //-----------------------------------------------------------------------------
113 :
114 : #define NS_HTTP_DEFAULT_PORT 80
115 : #define NS_HTTPS_DEFAULT_PORT 443
116 :
117 : #define NS_HTTP_HEADER_SEPS ", \t"
118 :
119 : //-----------------------------------------------------------------------------
120 : // http atoms...
121 : //-----------------------------------------------------------------------------
122 :
123 : struct nsHttpAtom
124 : {
125 0 : operator const char *() const { return _val; }
126 0 : const char *get() const { return _val; }
127 :
128 : void operator=(const char *v) { _val = v; }
129 0 : void operator=(const nsHttpAtom &a) { _val = a._val; }
130 :
131 : // private
132 : const char *_val;
133 : };
134 :
135 : namespace nsHttp
136 : {
137 : MOZ_MUST_USE nsresult CreateAtomTable();
138 : void DestroyAtomTable();
139 :
140 : // The mutex is valid any time the Atom Table is valid
141 : // This mutex is used in the unusual case that the network thread and
142 : // main thread might access the same data
143 : Mutex *GetLock();
144 :
145 : // will dynamically add atoms to the table if they don't already exist
146 : nsHttpAtom ResolveAtom(const char *);
147 0 : inline nsHttpAtom ResolveAtom(const nsACString &s)
148 : {
149 0 : return ResolveAtom(PromiseFlatCString(s).get());
150 : }
151 :
152 : // returns true if the specified token [start,end) is valid per RFC 2616
153 : // section 2.2
154 : bool IsValidToken(const char *start, const char *end);
155 :
156 0 : inline bool IsValidToken(const nsACString &s) {
157 0 : return IsValidToken(s.BeginReading(), s.EndReading());
158 : }
159 :
160 : // Strip the leading or trailing HTTP whitespace per fetch spec section 2.2.
161 : void TrimHTTPWhitespace(const nsACString& aSource,
162 : nsACString& aDest);
163 :
164 : // Returns true if the specified value is reasonable given the defintion
165 : // in RFC 2616 section 4.2. Full strict validation is not performed
166 : // currently as it would require full parsing of the value.
167 : bool IsReasonableHeaderValue(const nsACString &s);
168 :
169 : // find the first instance (case-insensitive comparison) of the given
170 : // |token| in the |input| string. the |token| is bounded by elements of
171 : // |separators| and may appear at the beginning or end of the |input|
172 : // string. null is returned if the |token| is not found. |input| may be
173 : // null, in which case null is returned.
174 : const char *FindToken(const char *input, const char *token,
175 : const char *separators);
176 :
177 : // This function parses a string containing a decimal-valued, non-negative
178 : // 64-bit integer. If the value would exceed INT64_MAX, then false is
179 : // returned. Otherwise, this function returns true and stores the
180 : // parsed value in |result|. The next unparsed character in |input| is
181 : // optionally returned via |next| if |next| is non-null.
182 : //
183 : // TODO(darin): Replace this with something generic.
184 : //
185 : MOZ_MUST_USE bool ParseInt64(const char *input, const char **next,
186 : int64_t *result);
187 :
188 : // Variant on ParseInt64 that expects the input string to contain nothing
189 : // more than the value being parsed.
190 0 : inline MOZ_MUST_USE bool ParseInt64(const char *input,
191 : int64_t *result) {
192 : const char *next;
193 0 : return ParseInt64(input, &next, result) && *next == '\0';
194 : }
195 :
196 : // Return whether the HTTP status code represents a permanent redirect
197 : bool IsPermanentRedirect(uint32_t httpStatus);
198 :
199 : // Returns the APLN token which represents the used protocol version.
200 : const char* GetProtocolVersion(HttpVersion pv);
201 :
202 : bool ValidationRequired(bool isForcedValid, nsHttpResponseHead *cachedResponseHead,
203 : uint32_t loadFlags, bool allowStaleCacheContent,
204 : bool isImmutable, bool customConditionalRequest,
205 : nsHttpRequestHead &requestHead,
206 : nsICacheEntry *entry, CacheControlParser &cacheControlRequest,
207 : bool fromPreviousSession);
208 :
209 : nsresult GetHttpResponseHeadFromCacheEntry(nsICacheEntry *entry,
210 : nsHttpResponseHead *cachedResponseHead);
211 :
212 : nsresult CheckPartial(nsICacheEntry* aEntry, int64_t *aSize,
213 : int64_t *aContentLength,
214 : nsHttpResponseHead *responseHead);
215 :
216 : void DetermineFramingAndImmutability(nsICacheEntry *entry, nsHttpResponseHead *cachedResponseHead,
217 : bool isHttps, bool *weaklyFramed,
218 : bool *isImmutable);
219 :
220 : // Called when an optimization feature affecting active vs background tab load
221 : // took place. Called only on the parent process and only updates
222 : // mLastActiveTabLoadOptimizationHit timestamp to now.
223 : void NotifyActiveTabLoadOptimization();
224 : TimeStamp const GetLastActiveTabLoadOptimizationHit();
225 : void SetLastActiveTabLoadOptimizationHit(TimeStamp const &when);
226 : bool IsBeforeLastActiveTabLoadOptimization(TimeStamp const &when);
227 :
228 : HttpVersion GetHttpVersionFromSpdy(SpdyVersion sv);
229 :
230 : // Declare all atoms
231 : //
232 : // The atom names and values are stored in nsHttpAtomList.h and are brought
233 : // to you by the magic of C preprocessing. Add new atoms to nsHttpAtomList
234 : // and all support logic will be auto-generated.
235 : //
236 : #define HTTP_ATOM(_name, _value) extern nsHttpAtom _name;
237 : #include "nsHttpAtomList.h"
238 : #undef HTTP_ATOM
239 : }
240 :
241 : //-----------------------------------------------------------------------------
242 : // utilities...
243 : //-----------------------------------------------------------------------------
244 :
245 : static inline uint32_t
246 : PRTimeToSeconds(PRTime t_usec)
247 : {
248 8 : return uint32_t( t_usec / PR_USEC_PER_SEC );
249 : }
250 :
251 : #define NowInSeconds() PRTimeToSeconds(PR_Now())
252 :
253 : // Round q-value to 2 decimal places; return 2 most significant digits as uint.
254 : #define QVAL_TO_UINT(q) ((unsigned int) ((q + 0.005) * 100.0))
255 :
256 : #define HTTP_LWS " \t"
257 : #define HTTP_HEADER_VALUE_SEPS HTTP_LWS ","
258 :
259 : void EnsureBuffer(UniquePtr<char[]> &buf, uint32_t newSize,
260 : uint32_t preserve, uint32_t &objSize);
261 : void EnsureBuffer(UniquePtr<uint8_t[]> &buf, uint32_t newSize,
262 : uint32_t preserve, uint32_t &objSize);
263 :
264 : // h2=":443"; ma=60; single
265 : // results in 3 mValues = {{h2, :443}, {ma, 60}, {single}}
266 :
267 0 : class ParsedHeaderPair
268 : {
269 : public:
270 : ParsedHeaderPair(const char *name, int32_t nameLen,
271 : const char *val, int32_t valLen, bool isQuotedValue);
272 :
273 0 : ParsedHeaderPair(ParsedHeaderPair const ©)
274 0 : : mName(copy.mName)
275 : , mValue(copy.mValue)
276 : , mUnquotedValue(copy.mUnquotedValue)
277 0 : , mIsQuotedValue(copy.mIsQuotedValue)
278 : {
279 0 : if (mIsQuotedValue) {
280 0 : mValue.Rebind(mUnquotedValue.BeginReading(), mUnquotedValue.Length());
281 : }
282 0 : }
283 :
284 : nsDependentCSubstring mName;
285 : nsDependentCSubstring mValue;
286 :
287 : private:
288 : nsCString mUnquotedValue;
289 : bool mIsQuotedValue;
290 :
291 : void RemoveQuotedStringEscapes(const char *val, int32_t valLen);
292 : };
293 :
294 0 : class ParsedHeaderValueList
295 : {
296 : public:
297 : ParsedHeaderValueList(const char *t, uint32_t len, bool allowInvalidValue);
298 : nsTArray<ParsedHeaderPair> mValues;
299 :
300 : private:
301 : void ParseNameAndValue(const char *input, bool allowInvalidValue);
302 : };
303 :
304 : class ParsedHeaderValueListList
305 : {
306 : public:
307 : // RFC 7231 section 3.2.6 defines the syntax of the header field values.
308 : // |allowInvalidValue| indicates whether the rule will be used to check
309 : // the input text.
310 : // Note that ParsedHeaderValueListList is currently used to parse
311 : // Alt-Svc and Server-Timing header. |allowInvalidValue| is set to true
312 : // when parsing Alt-Svc for historical reasons.
313 : explicit ParsedHeaderValueListList(const nsCString &txt,
314 : bool allowInvalidValue = true);
315 : nsTArray<ParsedHeaderValueList> mValues;
316 :
317 : private:
318 : nsCString mFull;
319 : };
320 :
321 : } // namespace net
322 : } // namespace mozilla
323 :
324 : #endif // nsHttp_h__
|