- spread-checks
- tune.bufsize
- tune.chksize
+ - tune.http.maxhdr
- tune.maxaccept
- tune.maxpollevents
- tune.maxrewrite
build time. It is not recommended to change this value, but to use better
checks whenever possible.
+tune.http.maxhdr <number>
+ Sets the maximum number of headers in a request. When a request comes with a
+ number of headers greater than this value (including the first line), it is
+ rejected with a "400 Bad Request" status code. Similarly, too large responses
+ are blocked with "502 Bad Gateway". The default value is 101, which is enough
+ for all usages, considering that the widely deployed Apache server uses the
+ same limit. It can be useful to push this limit further to temporarily allow
+ a buggy application to work by the time it gets fixed. Keep in mind that each
+ new header consumes 32bits of memory for each session, so don't push this
+ limit too high.
+
tune.maxaccept <number>
Sets the maximum number of consecutive accepts that a process may perform on
a single wake up. High values give higher priority to high connection rates,
#define MAX_MATCH 10
// max # of headers in one HTTP request or response
-// By default, about 100 headers per 8 kB.
+// By default, about 100 headers (+1 for the first line)
#ifndef MAX_HTTP_HDR
-#define MAX_HTTP_HDR ((BUFSIZE+79)/80)
+#define MAX_HTTP_HDR 101
#endif
// max # of headers in history when looking for header #-X
int server_rcvbuf; /* set server rcvbuf to this value if not null */
int chksize; /* check buffer size in bytes, defaults to BUFSIZE */
int pipesize; /* pipe size in bytes, system defaults if zero */
+ int max_http_hdr; /* max number of HTTP headers, use MAX_HTTP_HDR if zero */
} tune;
struct {
char *prefix; /* path prefix of unix bind socket */
*/
struct http_txn {
struct http_msg req; /* HTTP request message */
- struct hdr_idx hdr_idx; /* array of header indexes (max: MAX_HTTP_HDR) */
+ struct hdr_idx hdr_idx; /* array of header indexes (max: global.tune.max_http_hdr) */
unsigned int flags; /* transaction flags */
http_meth_t meth; /* HTTP method */
}
global.tune.pipesize = atol(args[1]);
}
+ else if (!strcmp(args[0], "tune.http.maxhdr")) {
+ if (*(args[1]) == 0) {
+ Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ global.tune.max_http_hdr = atol(args[1]);
+ }
else if (!strcmp(args[0], "uid")) {
if (global.uid != 0) {
Alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
}
}
+ if (!global.tune.max_http_hdr)
+ global.tune.max_http_hdr = MAX_HTTP_HDR;
+
pool2_hdr_idx = create_pool("hdr_idx",
- MAX_HTTP_HDR * sizeof(struct hdr_idx_elem),
+ global.tune.max_http_hdr * sizeof(struct hdr_idx_elem),
MEM_F_SHARED);
if (cfgerr > 0)
* that we may make use of them. This of course includes
* (mode == PR_MODE_HTTP).
*/
- s->txn.hdr_idx.size = MAX_HTTP_HDR;
+ s->txn.hdr_idx.size = global.tune.max_http_hdr;
if (unlikely((s->txn.hdr_idx.v = pool_alloc2(pool2_hdr_idx)) == NULL))
goto out_free_rspcap; /* no memory */
/* and now initialize the HTTP transaction state */
http_init_txn(s);
- s->txn.hdr_idx.size = MAX_HTTP_HDR;
+ s->txn.hdr_idx.size = global.tune.max_http_hdr;
hdr_idx_init(&s->txn.hdr_idx);
}