File: proto_http.h

package info (click to toggle)
haproxy 1.4.8-1%2Bsqueeze1
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 5,220 kB
  • ctags: 4,072
  • sloc: ansic: 34,590; perl: 543; sh: 415; makefile: 377; xml: 124
file content (349 lines) | stat: -rw-r--r-- 14,966 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
/*
 * include/types/proto_http.h
 * This file contains HTTP protocol definitions.
 *
 * Copyright (C) 2000-2010 Willy Tarreau - w@1wt.eu
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation, version 2.1
 * exclusively.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef _TYPES_PROTO_HTTP_H
#define _TYPES_PROTO_HTTP_H

#include <common/config.h>

#include <types/buffers.h>
#include <types/hdr_idx.h>

/* These are the flags that are found in txn->flags */

/* action flags */
#define TX_CLDENY	0x00000001	/* a client header matches a deny regex */
#define TX_CLALLOW	0x00000002	/* a client header matches an allow regex */
#define TX_SVDENY	0x00000004	/* a server header matches a deny regex */
#define TX_SVALLOW	0x00000008	/* a server header matches an allow regex */
#define TX_CLTARPIT	0x00000010	/* the session is tarpitted (anti-dos) */

/* used only for keep-alive purposes, to indicate we're on a second transaction */
#define TX_NOT_FIRST	0x00000020	/* the transaction is not the first one */

/* transaction flags dedicated to cookies : bits values 0x40, 0x80 (0-3 shift 6) */
#define TX_CK_NONE	0x00000000	/* this session had no cookie */
#define TX_CK_INVALID	0x00000040	/* this session had a cookie which matches no server */
#define TX_CK_DOWN	0x00000080	/* this session had cookie matching a down server */
#define TX_CK_VALID	0x000000C0	/* this session had cookie matching a valid server */
#define TX_CK_MASK	0x000000C0	/* mask to get this session's cookie flags */
#define TX_CK_SHIFT	6		/* bit shift */

/* cookie information, bits values 0x100 to 0x800 (0-8 shift 8) */
#define TX_SCK_NONE	0x00000000	/* no set-cookie seen for the server cookie */
#define TX_SCK_DELETED	0x00000100	/* existing set-cookie deleted or changed */
#define TX_SCK_INSERTED	0x00000200	/* new set-cookie inserted or changed existing one */
#define TX_SCK_SEEN	0x00000400	/* set-cookie seen for the server cookie */
#define TX_SCK_MASK	0x00000700	/* mask to get the set-cookie field */
#define TX_SCK_ANY	0x00000800	/* at least one set-cookie seen (not to be counted) */
#define TX_SCK_SHIFT	8		/* bit shift */

/* cacheability management, bits values 0x1000 to 0x3000 (0-3 shift 12) */
#define TX_CACHEABLE	0x00001000	/* at least part of the response is cacheable */
#define TX_CACHE_COOK	0x00002000	/* a cookie in the response is cacheable */
#define TX_CACHE_SHIFT	12		/* bit shift */

/* request and response HTTP version */
#define TX_REQ_VER_11	0x00004000	/* the request is HTTP/1.1 or above */
#define TX_RES_VER_11	0x00008000	/* the response is HTTP/1.1 or above */

/* report presence of transfer-encoding:chunked and content-length headers */
#define TX_REQ_CNT_LEN	0x00010000	/* content-length present in the request */
#define TX_REQ_TE_CHNK	0x00020000	/* transfer-encoding: chunked present in the request */
#define TX_RES_CNT_LEN	0x00040000	/* content-length present in the response */
#define TX_RES_TE_CHNK	0x00080000	/* transfer-encoding: chunked present in the response */

/* indicate how we *want* the connection to behave, regardless of what is in
 * the headers. We have 4 possible values right now :
 * - WANT_TUN : will be a tunnel (default when nothing configured or with CONNECT).
 * - WANT_KAL : try to maintain keep-alive
 * - WANT_SCL : enforce close on the server side
 * - WANT_CLO : enforce close on both sides
 */
#define TX_CON_WANT_TUN 0x00000000	/* note: it's important that it is 0 (init) */
#define TX_CON_WANT_KAL 0x00100000
#define TX_CON_WANT_SCL 0x00200000
#define TX_CON_WANT_CLO 0x00300000
#define TX_CON_WANT_MSK 0x00300000	/* this is the mask to get the bits */

#define TX_CON_CLO_SET  0x00400000	/* "connection: close" is now set */
#define TX_CON_KAL_SET  0x00800000	/* "connection: keep-alive" is now set */

/* if either of these flags is not set, we may be forced to complete an
 * connection as a half-way tunnel. For instance, if no content-length
 * appears in a 1.1 response, but the request is correctly sized.
 */
#define TX_REQ_XFER_LEN	0x01000000	/* request xfer size can be determined */
#define TX_RES_XFER_LEN	0x02000000	/* response xfer size can be determined */
#define TX_WAIT_NEXT_RQ	0x04000000	/* waiting for the second request to start, use keep-alive timeout */

#define TX_HDR_CONN_PRS	0x08000000	/* "connection" header already parsed (req or res), results below */
#define TX_HDR_CONN_CLO	0x10000000	/* "Connection: close" was present at least once */
#define TX_HDR_CONN_KAL	0x20000000	/* "Connection: keep-alive" was present at least once */
#define TX_USE_PX_CONN	0x40000000	/* Use "Proxy-Connection" instead of "Connection" */


/* The HTTP parser is more complex than it looks like, because we have to
 * support multi-line headers and any number of spaces between the colon and
 * the value.
 *
 * All those examples must work :

 Hdr1:val1\r\n
 Hdr1: val1\r\n
 Hdr1:\t val1\r\n
 Hdr1: \r\n
  val1\r\n
 Hdr1:\r\n
  val1\n
 \tval2\r\n
  val3\n

 *
 */

/* Possible states while parsing HTTP messages (request|response) */
#define HTTP_MSG_RQBEFORE      0 // request: leading LF, before start line
#define HTTP_MSG_RQBEFORE_CR   1 // request: leading CRLF, before start line

/* these ones define a request start line */
#define HTTP_MSG_RQMETH        2 // parsing the Method
#define HTTP_MSG_RQMETH_SP     3 // space(s) after the ethod
#define HTTP_MSG_RQURI         4 // parsing the Request URI
#define HTTP_MSG_RQURI_SP      5 // space(s) after the Request URI
#define HTTP_MSG_RQVER         6 // parsing the Request Version
#define HTTP_MSG_RQLINE_END    7 // end of request line (CR or LF)

#define HTTP_MSG_RPBEFORE      8 // response: leading LF, before start line
#define HTTP_MSG_RPBEFORE_CR   9 // response: leading CRLF, before start line

/* these ones define a response start line */
#define HTTP_MSG_RPVER        10 // parsing the Response Version
#define HTTP_MSG_RPVER_SP     11 // space(s) after the Response Version
#define HTTP_MSG_RPCODE       12 // response code
#define HTTP_MSG_RPCODE_SP    13 // space(s) after the response code
#define HTTP_MSG_RPREASON     14 // response reason
#define HTTP_MSG_RPLINE_END   15 // end of response line (CR or LF)

/* common header processing */

#define HTTP_MSG_HDR_FIRST    16 // waiting for first header or last CRLF (no LWS possible)
#define HTTP_MSG_HDR_NAME     17 // parsing header name
#define HTTP_MSG_HDR_COL      18 // parsing header colon
#define HTTP_MSG_HDR_L1_SP    19 // parsing header LWS (SP|HT) before value
#define HTTP_MSG_HDR_L1_LF    20 // parsing header LWS (LF) before value
#define HTTP_MSG_HDR_L1_LWS   21 // checking whether it's a new header or an LWS
#define HTTP_MSG_HDR_VAL      22 // parsing header value
#define HTTP_MSG_HDR_L2_LF    23 // parsing header LWS (LF) inside/after value
#define HTTP_MSG_HDR_L2_LWS   24 // checking whether it's a new header or an LWS

#define HTTP_MSG_LAST_LF      25 // parsing last LF

/* error state : must be before HTTP_MSG_BODY so that (>=BODY) always indicates
 * that data are being processed.
 */

#define HTTP_MSG_ERROR        26 // an error occurred

/* Body processing.
 * The state HTTP_MSG_BODY is a delimiter to know if we're waiting for headers
 * or body. All the sub-states below also indicate we're processing the body,
 * with some additional information.
 */
#define HTTP_MSG_BODY         27 // parsing body at end of headers
#define HTTP_MSG_100_SENT     28 // parsing body after a 100-Continue was sent
#define HTTP_MSG_CHUNK_SIZE   29 // parsing the chunk size (RFC2616 #3.6.1)
#define HTTP_MSG_DATA         30 // skipping data chunk / content-length data
#define HTTP_MSG_DATA_CRLF    31 // skipping CRLF after data chunk
#define HTTP_MSG_TRAILERS     32 // trailers (post-data entity headers)

/* we enter this state when we've received the end of the current message */
#define HTTP_MSG_DONE         33 // message end received, waiting for resync or close
#define HTTP_MSG_CLOSING      34 // shutdown_w done, not all bytes sent yet
#define HTTP_MSG_CLOSED       35 // shutdown_w done, all bytes sent
#define HTTP_MSG_TUNNEL       36 // tunneled data after DONE

/* various data sources for the responses */
#define DATA_SRC_NONE	0
#define DATA_SRC_STATS	1

/* data transmission states for the stats responses */
enum {
	DATA_ST_INIT = 0,
	DATA_ST_HEAD,
	DATA_ST_INFO,
	DATA_ST_LIST,
	DATA_ST_END,
	DATA_ST_FIN,
};

/* data transmission states for the stats responses inside a proxy */
enum {
	DATA_ST_PX_INIT = 0,
	DATA_ST_PX_TH,
	DATA_ST_PX_FE,
	DATA_ST_PX_LI,
	DATA_ST_PX_SV,
	DATA_ST_PX_BE,
	DATA_ST_PX_END,
	DATA_ST_PX_FIN,
};

/* Redirect flags */
enum {
	REDIRECT_FLAG_NONE = 0,
	REDIRECT_FLAG_DROP_QS = 1,	/* drop query string */
	REDIRECT_FLAG_APPEND_SLASH = 2,	/* append a slash if missing at the end */
};

/* Redirect types (location, prefix, extended ) */
enum {
	REDIRECT_TYPE_NONE = 0,         /* no redirection */
	REDIRECT_TYPE_LOCATION,         /* location redirect */
	REDIRECT_TYPE_PREFIX,           /* prefix redirect */
};

/* Perist types (force-persist, ignore-persist) */
enum {
	PERSIST_TYPE_NONE = 0,          /* no persistence */
	PERSIST_TYPE_FORCE,             /* force-persist */
	PERSIST_TYPE_IGNORE,            /* ignore-persist */
};

/* Known HTTP methods */
typedef enum {
	HTTP_METH_NONE = 0,
	HTTP_METH_OPTIONS,
	HTTP_METH_GET,
	HTTP_METH_HEAD,
	HTTP_METH_POST,
	HTTP_METH_PUT,
	HTTP_METH_DELETE,
	HTTP_METH_TRACE,
	HTTP_METH_CONNECT,
	HTTP_METH_OTHER,
} http_meth_t;

enum {
	HTTP_AUTH_WRONG		= -1,		/* missing or unknown */
	HTTP_AUTH_UNKNOWN	= 0,
	HTTP_AUTH_BASIC,
	HTTP_AUTH_DIGEST,
};

/* This is an HTTP message, as described in RFC2616. It can be either a request
 * message or a response message.
 *
 * The values there are a little bit obscure, because their meaning can change
 * during the parsing :
 *
 *  - som (Start of Message) : relative offset in the buffer of first byte of
 *                             the request being processed or parsed. Reset to
 *                             zero during accept(), and changes while parsing
 *                             chunks.
 *  - eoh (End of Headers)   : relative offset in the buffer of first byte that
 *                             is not part of a completely processed header.
 *                             During parsing, it points to last header seen
 *                             for states after START. When in HTTP_MSG_BODY,
 *                             eoh points to the first byte of the last CRLF
 *                             preceeding data.
 *  - col and sov            : When in HTTP_MSG_BODY, will point to the first
 *                             byte of data (relative to buffer).
 *  - sol (start of line)    : start of line, also start of message when fully parsed.
 *  - eol (End of Line)      : relative offset in the buffer of the first byte
 *                             which marks the end of the line (LF or CRLF).
 * Note that all offsets are relative to the beginning of the buffer. To get
 * them relative to the current request, subtract ->som or ->sol.
 */
struct http_msg {
	unsigned int msg_state;                /* where we are in the current message parsing */
	unsigned int col, sov;                 /* current header: colon, start of value */
	unsigned int eoh;                      /* End Of Headers, relative to buffer */
	char *sol;                             /* start of line, also start of message when fully parsed */
	char *eol;                             /* end of line */
	unsigned int som;                      /* Start Of Message, relative to buffer */
	int err_pos;                           /* err handling: -2=block, -1=pass, 0+=detected */
	union {                                /* useful start line pointers, relative to ->sol */
		struct {
			int l;                 /* request line length (not including CR) */
			int m_l;               /* METHOD length (method starts at ->som) */
			int u, u_l;            /* URI, length */
			int v, v_l;            /* VERSION, length */
		} rq;                          /* request line : field, length */
		struct {
			int l;                 /* status line length (not including CR) */
			int v_l;               /* VERSION length (version starts at ->som) */
			int c, c_l;            /* CODE, length */
			int r, r_l;            /* REASON, length */
		} st;                          /* status line : field, length */
	} sl;                                  /* start line */
	unsigned long long hdr_content_len;    /* cache for parsed header value or for chunk-size if present */
	char **cap;                            /* array of captured headers (may be NULL) */
};

struct http_auth_data {
	int method;			/* one of HTTP_AUTH_* */
	struct chunk method_data;	/* points to the creditial part from 'Authorization:' header */
	char *user, *pass;		/* extracted username & password */
};

/* This is an HTTP transaction. It contains both a request message and a
 * response message (which can be empty).
 */
struct http_txn {
	struct http_msg req;            /* HTTP request message */
	struct hdr_idx hdr_idx;         /* array of header indexes (max: MAX_HTTP_HDR) */
	unsigned int flags;             /* transaction flags */
	http_meth_t meth;               /* HTTP method */

	int status;                     /* HTTP status from the server, negative if from proxy */
	struct http_msg rsp;            /* HTTP response message */

	char *uri;                      /* first line if log needed, NULL otherwise */
	char *cli_cookie;               /* cookie presented by the client, in capture mode */
	char *srv_cookie;               /* cookie presented by the server, in capture mode */
	char *sessid;                   /* the appsession id, if found in the request or in the response */

	struct http_auth_data auth;	/* HTTP auth data */
};

/* This structure is used by http_find_header() to return values of headers.
 * The header starts at <line>, the value at <line>+<val> for <vlen> bytes, and
 * sets <line>+<del> to point to the last delimitor (colon or comma) before
 * this value. <prev> points to the index of the header whose next is this one.
 */
struct hdr_ctx {
	char *line;
	int  idx;
	int  val;  /* relative to line */
	int  vlen; /* relative to line+val */
	int  del;  /* relative to line */
	int  prev; /* index of previous header */
};

#endif /* _TYPES_PROTO_HTTP_H */

/*
 * Local variables:
 *  c-indent-level: 8
 *  c-basic-offset: 8
 * End:
 */