/src/mozilla-central/netwerk/protocol/http/nsHttp.h
Line | Count | Source (jump to first uncovered line) |
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 | 0 | #define NS_HTTP_ALLOW_KEEPALIVE (1<<0) |
61 | 0 | #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 | 0 | #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 | 0 | #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 | 0 | #define NS_HTTP_LOAD_ANONYMOUS (1<<4) |
74 | | |
75 | | // a transaction with this caps flag keeps timing information |
76 | 0 | #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 | 0 | #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 | 0 | #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 | 0 | #define NS_HTTP_LOAD_UNBLOCKED (1<<8) |
90 | | |
91 | | // This flag indicates the transaction should accept associated pushes |
92 | 0 | #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 | 0 | #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 | 0 | #define NS_HTTP_BE_CONSERVATIVE (1<<11) |
102 | | |
103 | | // Transactions with this flag should be processed first. |
104 | 0 | #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 | 0 | #define NS_HTTP_CONNECTION_RESTARTABLE (1<<13) |
109 | | |
110 | | // Disallow name resolutions for this transaction to use TRR - primarily |
111 | | // for use with TRR implementations themselves |
112 | 0 | #define NS_HTTP_DISABLE_TRR (1<<14) |
113 | | |
114 | | //----------------------------------------------------------------------------- |
115 | | // some default values |
116 | | //----------------------------------------------------------------------------- |
117 | | |
118 | 1.06M | #define NS_HTTP_DEFAULT_PORT 80 |
119 | 247 | #define NS_HTTPS_DEFAULT_PORT 443 |
120 | | |
121 | 0 | #define NS_HTTP_HEADER_SEPS ", \t" |
122 | | |
123 | | //----------------------------------------------------------------------------- |
124 | | // http atoms... |
125 | | //----------------------------------------------------------------------------- |
126 | | |
127 | | struct nsHttpAtom |
128 | | { |
129 | 0 | operator const char *() const { return _val; } |
130 | 0 | const char *get() const { return _val; } |
131 | | |
132 | | void operator=(const char *v) { _val = v; } |
133 | 0 | void operator=(const nsHttpAtom &a) { _val = a._val; } |
134 | | |
135 | | // private |
136 | | const char *_val; |
137 | | }; |
138 | | |
139 | | namespace nsHttp |
140 | | { |
141 | | MOZ_MUST_USE nsresult CreateAtomTable(); |
142 | | void DestroyAtomTable(); |
143 | | |
144 | | // The mutex is valid any time the Atom Table is valid |
145 | | // This mutex is used in the unusual case that the network thread and |
146 | | // main thread might access the same data |
147 | | Mutex *GetLock(); |
148 | | |
149 | | // will dynamically add atoms to the table if they don't already exist |
150 | | nsHttpAtom ResolveAtom(const char *); |
151 | | inline nsHttpAtom ResolveAtom(const nsACString &s) |
152 | 0 | { |
153 | 0 | return ResolveAtom(PromiseFlatCString(s).get()); |
154 | 0 | } |
155 | | |
156 | | // returns true if the specified token [start,end) is valid per RFC 2616 |
157 | | // section 2.2 |
158 | | bool IsValidToken(const char *start, const char *end); |
159 | | |
160 | 0 | inline bool IsValidToken(const nsACString &s) { |
161 | 0 | return IsValidToken(s.BeginReading(), s.EndReading()); |
162 | 0 | } |
163 | | |
164 | | // Strip the leading or trailing HTTP whitespace per fetch spec section 2.2. |
165 | | void TrimHTTPWhitespace(const nsACString& aSource, |
166 | | nsACString& aDest); |
167 | | |
168 | | // Returns true if the specified value is reasonable given the defintion |
169 | | // in RFC 2616 section 4.2. Full strict validation is not performed |
170 | | // currently as it would require full parsing of the value. |
171 | | bool IsReasonableHeaderValue(const nsACString &s); |
172 | | |
173 | | // find the first instance (case-insensitive comparison) of the given |
174 | | // |token| in the |input| string. the |token| is bounded by elements of |
175 | | // |separators| and may appear at the beginning or end of the |input| |
176 | | // string. null is returned if the |token| is not found. |input| may be |
177 | | // null, in which case null is returned. |
178 | | const char *FindToken(const char *input, const char *token, |
179 | | const char *separators); |
180 | | |
181 | | // This function parses a string containing a decimal-valued, non-negative |
182 | | // 64-bit integer. If the value would exceed INT64_MAX, then false is |
183 | | // returned. Otherwise, this function returns true and stores the |
184 | | // parsed value in |result|. The next unparsed character in |input| is |
185 | | // optionally returned via |next| if |next| is non-null. |
186 | | // |
187 | | // TODO(darin): Replace this with something generic. |
188 | | // |
189 | | MOZ_MUST_USE bool ParseInt64(const char *input, const char **next, |
190 | | int64_t *result); |
191 | | |
192 | | // Variant on ParseInt64 that expects the input string to contain nothing |
193 | | // more than the value being parsed. |
194 | | inline MOZ_MUST_USE bool ParseInt64(const char *input, |
195 | 0 | int64_t *result) { |
196 | 0 | const char *next; |
197 | 0 | return ParseInt64(input, &next, result) && *next == '\0'; |
198 | 0 | } |
199 | | |
200 | | // Return whether the HTTP status code represents a permanent redirect |
201 | | bool IsPermanentRedirect(uint32_t httpStatus); |
202 | | |
203 | | // Returns the APLN token which represents the used protocol version. |
204 | | const char* GetProtocolVersion(HttpVersion pv); |
205 | | |
206 | | bool ValidationRequired(bool isForcedValid, nsHttpResponseHead *cachedResponseHead, |
207 | | uint32_t loadFlags, bool allowStaleCacheContent, |
208 | | bool isImmutable, bool customConditionalRequest, |
209 | | nsHttpRequestHead &requestHead, |
210 | | nsICacheEntry *entry, CacheControlParser &cacheControlRequest, |
211 | | bool fromPreviousSession); |
212 | | |
213 | | nsresult GetHttpResponseHeadFromCacheEntry(nsICacheEntry *entry, |
214 | | nsHttpResponseHead *cachedResponseHead); |
215 | | |
216 | | nsresult CheckPartial(nsICacheEntry* aEntry, int64_t *aSize, |
217 | | int64_t *aContentLength, |
218 | | nsHttpResponseHead *responseHead); |
219 | | |
220 | | void DetermineFramingAndImmutability(nsICacheEntry *entry, nsHttpResponseHead *cachedResponseHead, |
221 | | bool isHttps, bool *weaklyFramed, |
222 | | bool *isImmutable); |
223 | | |
224 | | // Called when an optimization feature affecting active vs background tab load |
225 | | // took place. Called only on the parent process and only updates |
226 | | // mLastActiveTabLoadOptimizationHit timestamp to now. |
227 | | void NotifyActiveTabLoadOptimization(); |
228 | | TimeStamp const GetLastActiveTabLoadOptimizationHit(); |
229 | | void SetLastActiveTabLoadOptimizationHit(TimeStamp const &when); |
230 | | bool IsBeforeLastActiveTabLoadOptimization(TimeStamp const &when); |
231 | | |
232 | | HttpVersion GetHttpVersionFromSpdy(SpdyVersion sv); |
233 | | |
234 | | // Declare all atoms |
235 | | // |
236 | | // The atom names and values are stored in nsHttpAtomList.h and are brought |
237 | | // to you by the magic of C preprocessing. Add new atoms to nsHttpAtomList |
238 | | // and all support logic will be auto-generated. |
239 | | // |
240 | | #define HTTP_ATOM(_name, _value) extern nsHttpAtom _name; |
241 | | #include "nsHttpAtomList.h" |
242 | | #undef HTTP_ATOM |
243 | | } |
244 | | |
245 | | //----------------------------------------------------------------------------- |
246 | | // utilities... |
247 | | //----------------------------------------------------------------------------- |
248 | | |
249 | | static inline uint32_t |
250 | | PRTimeToSeconds(PRTime t_usec) |
251 | 2 | { |
252 | 2 | return uint32_t( t_usec / PR_USEC_PER_SEC ); |
253 | 2 | } Unexecuted instantiation: Unified_cpp_netwerk_base0.cpp:mozilla::net::PRTimeToSeconds(long) Unexecuted instantiation: Unified_cpp_netwerk_base1.cpp:mozilla::net::PRTimeToSeconds(long) Unexecuted instantiation: Unified_cpp_netwerk_base2.cpp:mozilla::net::PRTimeToSeconds(long) Unexecuted instantiation: Unified_cpp_netwerk_base3.cpp:mozilla::net::PRTimeToSeconds(long) Unexecuted instantiation: Unified_cpp_netwerk_base4.cpp:mozilla::net::PRTimeToSeconds(long) Unexecuted instantiation: nsHttpChannelAuthProvider.cpp:mozilla::net::PRTimeToSeconds(long) nsHttpHandler.cpp:mozilla::net::PRTimeToSeconds(long) Line | Count | Source | 251 | 2 | { | 252 | 2 | return uint32_t( t_usec / PR_USEC_PER_SEC ); | 253 | 2 | } |
Unexecuted instantiation: Unified_cpp_protocol_http0.cpp:mozilla::net::PRTimeToSeconds(long) Unexecuted instantiation: Unified_cpp_protocol_http1.cpp:mozilla::net::PRTimeToSeconds(long) Unexecuted instantiation: Unified_cpp_protocol_http2.cpp:mozilla::net::PRTimeToSeconds(long) Unexecuted instantiation: Unified_cpp_netwerk_ipc0.cpp:mozilla::net::PRTimeToSeconds(long) Unexecuted instantiation: nsNetModule.cpp:mozilla::net::PRTimeToSeconds(long) Unexecuted instantiation: Unified_cpp_dom_fetch0.cpp:mozilla::net::PRTimeToSeconds(long) Unexecuted instantiation: Unified_cpp_webrequest0.cpp:mozilla::net::PRTimeToSeconds(long) |
254 | | |
255 | 1 | #define NowInSeconds() PRTimeToSeconds(PR_Now()) |
256 | | |
257 | | // Round q-value to 2 decimal places; return 2 most significant digits as uint. |
258 | | #define QVAL_TO_UINT(q) ((unsigned int) ((q + 0.005) * 100.0)) |
259 | | |
260 | 0 | #define HTTP_LWS " \t" |
261 | 0 | #define HTTP_HEADER_VALUE_SEPS HTTP_LWS "," |
262 | | |
263 | | void EnsureBuffer(UniquePtr<char[]> &buf, uint32_t newSize, |
264 | | uint32_t preserve, uint32_t &objSize); |
265 | | void EnsureBuffer(UniquePtr<uint8_t[]> &buf, uint32_t newSize, |
266 | | uint32_t preserve, uint32_t &objSize); |
267 | | |
268 | | // h2=":443"; ma=60; single |
269 | | // results in 3 mValues = {{h2, :443}, {ma, 60}, {single}} |
270 | | |
271 | | class ParsedHeaderPair |
272 | | { |
273 | | public: |
274 | | ParsedHeaderPair(const char *name, int32_t nameLen, |
275 | | const char *val, int32_t valLen, bool isQuotedValue); |
276 | | |
277 | | ParsedHeaderPair(ParsedHeaderPair const ©) |
278 | | : mName(copy.mName) |
279 | | , mValue(copy.mValue) |
280 | | , mUnquotedValue(copy.mUnquotedValue) |
281 | | , mIsQuotedValue(copy.mIsQuotedValue) |
282 | 0 | { |
283 | 0 | if (mIsQuotedValue) { |
284 | 0 | mValue.Rebind(mUnquotedValue.BeginReading(), mUnquotedValue.Length()); |
285 | 0 | } |
286 | 0 | } |
287 | | |
288 | | nsDependentCSubstring mName; |
289 | | nsDependentCSubstring mValue; |
290 | | |
291 | | private: |
292 | | nsCString mUnquotedValue; |
293 | | bool mIsQuotedValue; |
294 | | |
295 | | void RemoveQuotedStringEscapes(const char *val, int32_t valLen); |
296 | | }; |
297 | | |
298 | | class ParsedHeaderValueList |
299 | | { |
300 | | public: |
301 | | ParsedHeaderValueList(const char *t, uint32_t len, bool allowInvalidValue); |
302 | | nsTArray<ParsedHeaderPair> mValues; |
303 | | |
304 | | private: |
305 | | void ParseNameAndValue(const char *input, bool allowInvalidValue); |
306 | | }; |
307 | | |
308 | | class ParsedHeaderValueListList |
309 | | { |
310 | | public: |
311 | | // RFC 7231 section 3.2.6 defines the syntax of the header field values. |
312 | | // |allowInvalidValue| indicates whether the rule will be used to check |
313 | | // the input text. |
314 | | // Note that ParsedHeaderValueListList is currently used to parse |
315 | | // Alt-Svc and Server-Timing header. |allowInvalidValue| is set to true |
316 | | // when parsing Alt-Svc for historical reasons. |
317 | | explicit ParsedHeaderValueListList(const nsCString &txt, |
318 | | bool allowInvalidValue = true); |
319 | | nsTArray<ParsedHeaderValueList> mValues; |
320 | | |
321 | | private: |
322 | | nsCString mFull; |
323 | | }; |
324 | | |
325 | | } // namespace net |
326 | | } // namespace mozilla |
327 | | |
328 | | #endif // nsHttp_h__ |