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