[MEDIUM] added the hdr_idx structure for future HTTP header indexing
This structure will consume 4 bytes per header to keep track of headers within a request or a response without having to parse the whole request for each regex. As it's not possible to allocate only 4 bytes, we define a max number of HTTP headers. We set it to (BUFSIZE+79)/80 so that 8kB buffers can contain 100 headers (like Apache), resulting in 400 bytes dedicated to indexation, or about 400/(2*8kB) ~= 2.4% of the memory usage.
This commit is contained in:
parent
09536952b3
commit
e5f20dcea8
2
Makefile
2
Makefile
@ -158,7 +158,7 @@ OBJS = src/haproxy.o src/list.o src/chtbl.o src/hashpjw.o src/base64.o \
|
|||||||
src/time.o src/fd.o src/regex.o src/cfgparse.o src/server.o \
|
src/time.o src/fd.o src/regex.o src/cfgparse.o src/server.o \
|
||||||
src/checks.o src/queue.o src/capture.o src/client.o src/proxy.o \
|
src/checks.o src/queue.o src/capture.o src/client.o src/proxy.o \
|
||||||
src/proto_http.o src/stream_sock.o src/appsession.o src/backend.o \
|
src/proto_http.o src/stream_sock.o src/appsession.o src/backend.o \
|
||||||
src/session.o
|
src/session.o src/hdr_idx.o
|
||||||
|
|
||||||
haproxy: $(OBJS)
|
haproxy: $(OBJS)
|
||||||
$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
|
$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
@ -87,7 +87,7 @@ OBJS = src/haproxy.o src/list.o src/chtbl.o src/hashpjw.o src/base64.o \
|
|||||||
src/time.o src/fd.o src/regex.o src/cfgparse.o src/server.o \
|
src/time.o src/fd.o src/regex.o src/cfgparse.o src/server.o \
|
||||||
src/checks.o src/queue.o src/capture.o src/client.o src/proxy.o \
|
src/checks.o src/queue.o src/capture.o src/client.o src/proxy.o \
|
||||||
src/proto_http.o src/stream_sock.o src/appsession.o src/backend.o \
|
src/proto_http.o src/stream_sock.o src/appsession.o src/backend.o \
|
||||||
src/session.o
|
src/session.o src/hdr_idx.o
|
||||||
|
|
||||||
all: haproxy
|
all: haproxy
|
||||||
|
|
||||||
|
@ -52,6 +52,12 @@
|
|||||||
// max # of matches per regexp
|
// max # of matches per regexp
|
||||||
#define MAX_MATCH 10
|
#define MAX_MATCH 10
|
||||||
|
|
||||||
|
// max # of headers in one HTTP request or response
|
||||||
|
// By default, about 100 headers per 8 kB.
|
||||||
|
#ifndef MAX_HTTP_HDR
|
||||||
|
#define MAX_HTTP_HDR ((BUFSIZE+79)/80)
|
||||||
|
#endif
|
||||||
|
|
||||||
// cookie delimitor in "prefix" mode. This character is inserted between the
|
// cookie delimitor in "prefix" mode. This character is inserted between the
|
||||||
// persistence cookie and the original value. The '~' is allowed by RFC2965,
|
// persistence cookie and the original value. The '~' is allowed by RFC2965,
|
||||||
// and should not be too common in server names.
|
// and should not be too common in server names.
|
||||||
|
@ -118,6 +118,7 @@ struct proxy {
|
|||||||
struct cap_hdr *req_cap; /* chained list of request headers to be captured */
|
struct cap_hdr *req_cap; /* chained list of request headers to be captured */
|
||||||
struct cap_hdr *rsp_cap; /* chained list of response headers to be captured */
|
struct cap_hdr *rsp_cap; /* chained list of response headers to be captured */
|
||||||
void *req_cap_pool, *rsp_cap_pool; /* pools of pre-allocated char ** used to build the sessions */
|
void *req_cap_pool, *rsp_cap_pool; /* pools of pre-allocated char ** used to build the sessions */
|
||||||
|
void *hdr_idx_pool; /* pools of pre-allocated int* used for headers indexing */
|
||||||
char *req_add[MAX_NEWHDR], *rsp_add[MAX_NEWHDR]; /* headers to be added */
|
char *req_add[MAX_NEWHDR], *rsp_add[MAX_NEWHDR]; /* headers to be added */
|
||||||
int grace; /* grace time after stop request */
|
int grace; /* grace time after stop request */
|
||||||
char *check_req; /* HTTP or SSL request to use for PR_O_HTTP_CHK|PR_O_SSL3_CHK */
|
char *check_req; /* HTTP or SSL request to use for PR_O_HTTP_CHK|PR_O_SSL3_CHK */
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include <types/queue.h>
|
#include <types/queue.h>
|
||||||
#include <types/server.h>
|
#include <types/server.h>
|
||||||
#include <types/task.h>
|
#include <types/task.h>
|
||||||
|
#include <types/hdr_idx.h>
|
||||||
|
|
||||||
|
|
||||||
/* various session flags, bits values 0x01 to 0x20 (shift 0) */
|
/* various session flags, bits values 0x01 to 0x20 (shift 0) */
|
||||||
@ -120,6 +121,7 @@ struct session {
|
|||||||
struct pendconn *pend_pos; /* if not NULL, points to the position in the pending queue */
|
struct pendconn *pend_pos; /* if not NULL, points to the position in the pending queue */
|
||||||
char **req_cap; /* array of captured request headers (may be NULL) */
|
char **req_cap; /* array of captured request headers (may be NULL) */
|
||||||
char **rsp_cap; /* array of captured response headers (may be NULL) */
|
char **rsp_cap; /* array of captured response headers (may be NULL) */
|
||||||
|
struct hdr_idx hdr_idx; /* array of header indexes (max: MAX_HTTP_HDR) */
|
||||||
struct chunk req_line; /* points to first line */
|
struct chunk req_line; /* points to first line */
|
||||||
struct chunk auth_hdr; /* points to 'Authorization:' header */
|
struct chunk auth_hdr; /* points to 'Authorization:' header */
|
||||||
struct {
|
struct {
|
||||||
|
27
src/client.c
27
src/client.c
@ -37,6 +37,7 @@
|
|||||||
#include <proto/client.h>
|
#include <proto/client.h>
|
||||||
#include <proto/fd.h>
|
#include <proto/fd.h>
|
||||||
#include <proto/log.h>
|
#include <proto/log.h>
|
||||||
|
#include <proto/hdr_idx.h>
|
||||||
#include <proto/proto_http.h>
|
#include <proto/proto_http.h>
|
||||||
#include <proto/stream_sock.h>
|
#include <proto/stream_sock.h>
|
||||||
#include <proto/task.h>
|
#include <proto/task.h>
|
||||||
@ -156,9 +157,6 @@ int event_accept(int fd) {
|
|||||||
t->context = s;
|
t->context = s;
|
||||||
|
|
||||||
s->task = t;
|
s->task = t;
|
||||||
#ifdef BUILD_WITH_PROXY
|
|
||||||
s->proxy = p;
|
|
||||||
#endif
|
|
||||||
s->be = s->fe = s->fi = p;
|
s->be = s->fe = s->fi = p;
|
||||||
|
|
||||||
s->cli_state = (p->mode == PR_MODE_HTTP) ? CL_STHEADERS : CL_STDATA; /* no HTTP headers for non-HTTP proxies */
|
s->cli_state = (p->mode == PR_MODE_HTTP) ? CL_STHEADERS : CL_STDATA; /* no HTTP headers for non-HTTP proxies */
|
||||||
@ -227,6 +225,27 @@ int event_accept(int fd) {
|
|||||||
else
|
else
|
||||||
s->rsp_cap = NULL;
|
s->rsp_cap = NULL;
|
||||||
|
|
||||||
|
if (p->mode == PR_MODE_HTTP) {
|
||||||
|
s->hdr_idx.size = MAX_HTTP_HDR;
|
||||||
|
if ((s->hdr_idx.v =
|
||||||
|
pool_alloc_from(p->hdr_idx_pool, s->hdr_idx.size*sizeof(*s->hdr_idx.v)))
|
||||||
|
== NULL) { /* no memory */
|
||||||
|
if (s->rsp_cap != NULL)
|
||||||
|
pool_free_to(p->rsp_cap_pool, s->rsp_cap);
|
||||||
|
if (s->req_cap != NULL)
|
||||||
|
pool_free_to(p->req_cap_pool, s->req_cap);
|
||||||
|
close(cfd); /* nothing can be done for this fd without memory */
|
||||||
|
pool_free(task, t);
|
||||||
|
pool_free(session, s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
hdr_idx_init(&s->hdr_idx);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
s->hdr_idx.size = s->hdr_idx.used = 0;
|
||||||
|
s->hdr_idx.v = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if ((p->mode == PR_MODE_TCP || p->mode == PR_MODE_HTTP)
|
if ((p->mode == PR_MODE_TCP || p->mode == PR_MODE_HTTP)
|
||||||
&& (p->logfac1 >= 0 || p->logfac2 >= 0)) {
|
&& (p->logfac1 >= 0 || p->logfac2 >= 0)) {
|
||||||
struct sockaddr_storage sockname;
|
struct sockaddr_storage sockname;
|
||||||
@ -303,6 +322,8 @@ int event_accept(int fd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((s->req = pool_alloc(buffer)) == NULL) { /* no memory */
|
if ((s->req = pool_alloc(buffer)) == NULL) { /* no memory */
|
||||||
|
if (s->hdr_idx.v != NULL)
|
||||||
|
pool_free_to(p->hdr_idx_pool, s->hdr_idx.v);
|
||||||
if (s->rsp_cap != NULL)
|
if (s->rsp_cap != NULL)
|
||||||
pool_free_to(p->rsp_cap_pool, s->rsp_cap);
|
pool_free_to(p->rsp_cap_pool, s->rsp_cap);
|
||||||
if (s->req_cap != NULL)
|
if (s->req_cap != NULL)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user