blob: 1146b9af46e337baf7cd68bc5d3b3570420267e3 [file] [log] [blame]
Christopher Fauleta3d2a162018-10-22 08:59:39 +02001/*
2 * include/types/htx.h
3 * This file contains the internal HTTP definitions.
4 *
5 * Copyright (C) 2018 HAProxy Technologies, Christopher Faulet <cfaulet@haproxy.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation, version 2.1
10 * exclusively.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#ifndef _TYPES_HTX_H
23#define _TYPES_HTX_H
24
25#include <common/ist.h>
26#include <types/sample.h>
27
28/*
29 * The internal representation of an HTTP message is a contiguous array
30 * containing both the blocks (htx_blk) and their contents. Blocks are stored
31 * starting from the end of the array while their contents are stored at the
32 * beginning.
33 *
34 * As data are sent to the peer, blocks and contents are released at the
35 * edges. This free space is reused when no more space left. So blocks and
36 * contents may wrap, not necessarily the same time.
37 *
38 * An HTTP block is as well a header as a body part or a trailer part. For all
39 * these types of block, a content is attached to the block. It can also be a
40 * mark, like the end-of-headers or end-of-message. For these blocks, there is
41 * no content but it count for a byte. It is important to not skip it when data
42 * are forwarded. An HTTP block is composed of 2 fields:
43 *
44 * - .info : It a 32 bits field containing the block's type on 4 bits
45 * followed by content' length. See below for details.
46 *
47 * - .addr : The content's address, if any, relatively to the beginning the
48 * array used to store the HTTP message itself.
49 *
50 * htx_blk.info representation:
51 *
52 * 0b 0000 0000 0000 0000 0000 0000 0000 0000
53 * ---- ------------------------ ---------
54 * type value (1 MB max) name length (header)
55 * ----------------------------------
56 * data length (256 MB max)
57 * (body, method, path, version, status, reason, trailers)
58 *
59 * types:
60 * - 0000 = request start-line
61 * - 0001 = response start-line
62 * - 0010 = header
63 * - 0011 = pseudo-header ou "special" header
64 * - 0100 = end-of-headers
65 * - 0101 = data
66 * - 0110 = end-of-data
67 * - 0111 = trailer
68 * - 1000 = end-of-message
69 * ...
70 * - 1101 = out-of-band
71 * - 1110 = error
72 * - 1111 = unused
73 *
74 */
75
Christopher Faulet570d1612018-11-26 11:13:57 +010076/*HTX start-line flags */
77#define HTX_SL_F_NONE 0x00000000
78#define HTX_SL_F_IS_RESP 0x00000001 /* It is the response start-line (unset means the request one) */
79#define HTX_SL_F_XFER_LEN 0x00000002 /* The message xfer size can be dertermined */
80#define HTX_SL_F_XFER_ENC 0x00000004 /* The transfer-encoding header was found in message */
81#define HTX_SL_F_CLEN 0x00000008 /* The content-length header was found in message */
82#define HTX_SL_F_CHNK 0x00000010 /* The message payload is chunked */
83#define HTX_SL_F_VER_11 0x00000020 /* The message indicates version 1.1 or above */
Christopher Fauletb2db4fa2018-11-27 16:51:09 +010084#define HTX_SL_F_BODYLESS 0x00000040 /* The message has no body (content-length = 0) */
Christopher Faulet570d1612018-11-26 11:13:57 +010085
Christopher Fauleta3d2a162018-10-22 08:59:39 +020086/* HTX flags */
87#define HTX_FL_NONE 0x00000000
88#define HTX_FL_PARSING_ERROR 0x00000001
89
90
91/* Pseudo header types (max 255). */
92enum htx_phdr_type {
93 HTX_PHDR_UNKNOWN = 0,
94 HTX_PHDR_SIZE,
95};
96
97/* HTTP block's type (max 15). */
98enum htx_blk_type {
99 HTX_BLK_REQ_SL = 0, /* Request start-line */
100 HTX_BLK_RES_SL = 1, /* Response start-line */
101 HTX_BLK_HDR = 2, /* header name/value block */
102 HTX_BLK_PHDR = 3, /* pseudo header block */
103 HTX_BLK_EOH = 4, /* end-of-headers block */
104 HTX_BLK_DATA = 5, /* data block */
105 HTX_BLK_EOD = 6, /* end-of-data block */
106 HTX_BLK_TLR = 7, /* trailer name/value block */
107 HTX_BLK_EOM = 8, /* end-of-message block */
108 /* 9 .. 13 unused */
109 HTX_BLK_OOB = 14, /* Out of band block, don't alter the parser */
110 HTX_BLK_UNUSED = 15, /* unused/removed block */
111};
112
113/* One HTTP block descriptor */
114struct htx_blk {
115 uint32_t addr; /* relative storage address of a data block */
116 uint32_t info; /* information about data stored */
117};
118
119struct htx_ret {
120 int32_t ret;
121 struct htx_blk *blk;
122};
123
Christopher Faulet570d1612018-11-26 11:13:57 +0100124struct htx_sl {
125 unsigned int flags; /* HTX_SL_F_* */
126 union {
127 struct {
128 enum http_meth_t meth; /* method */
129 } req;
130 struct {
131 uint16_t status; /* status code */
132 } res;
133 } info;
134
135 /* XXX 2 bytes unused */
136
137 unsigned int len[3]; /* length of differnt parts of the start-line */
138 char l[0];
Christopher Fauleta3d2a162018-10-22 08:59:39 +0200139};
140
141/* Internal representation of an HTTP message */
142struct htx {
143 uint32_t size; /* the array size, in bytes, used to store the HTTP message itself */
144 uint32_t data; /* the data size, in bytes. To known to total size used by all allocated
145 * blocks (blocks and their contents), you need to add size used by blocks,
146 * i.e. [ used * sizeof(struct htx_blk *) ] */
147
148 uint32_t used; /* number of blocks in use */
149 uint32_t tail; /* last inserted block */
150 uint32_t front; /* block's position of the first content before the blocks table */
151 uint32_t wrap; /* the position were the blocks table wraps, if any */
152
153 uint64_t extra; /* known bytes amount remaining to receive */
154 uint32_t flags; /* HTX_FL_* */
155
Christopher Faulet54483df2018-11-26 15:05:52 +0100156 int32_t sl_off; /* Offset of the start-line of the HTTP message relatively to the beginning the
157 data block. -1 if unset */
158
Christopher Fauleta3d2a162018-10-22 08:59:39 +0200159 struct htx_blk blocks[0]; /* Blocks representing the HTTP message itself */
160};
161
162#endif /* _TYPES_HTX_H */
163
164/*
165 * Local variables:
166 * c-indent-level: 8
167 * c-basic-offset: 8
168 * End:
169 */