]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] added the hdr_idx structure for future HTTP header indexing
authorWilly Tarreau <w@1wt.eu>
Sun, 3 Dec 2006 14:21:35 +0000 (15:21 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 3 Dec 2006 14:21:35 +0000 (15:21 +0100)
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.

Makefile
Makefile.bsd
include/common/defaults.h
include/types/proxy.h
include/types/session.h
src/client.c

index 1eef960aef93f98ef0b668950cf4431a4c00c3ad..f690a14af3fff150d48f504292e792ee5cc3fa79 100644 (file)
--- a/Makefile
+++ b/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/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/session.o
+       src/session.o src/hdr_idx.o
 
 haproxy: $(OBJS)
        $(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
index 4e274b029de534fac7dd3ac55547c1b4c2b9afd4..b288820b3bfab394f0485e45ab6de807c1b61103 100644 (file)
@@ -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/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/session.o
+       src/session.o src/hdr_idx.o
 
 all: haproxy
 
index e44a64c2ece3add97b88900e5ef635426b35e106..84032ae5627259706d64c26a861269ec271b67ba 100644 (file)
 // max # of matches per regexp
 #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
 // persistence cookie and the original value. The '~' is allowed by RFC2965,
 // and should not be too common in server names.
index 8523a694a4c9fd705aae674e4b449e77c80d83bf..28b05a05b6811b697bb88c3c876c4ba7e1e8b67e 100644 (file)
@@ -118,6 +118,7 @@ struct proxy {
        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 */
        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 */
        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 */
index dd12d4f9ebece51f2212e5fc16050cdd242e558a..f5e94905439d1cdd060a61c72d2d48785f8f2e07 100644 (file)
@@ -36,6 +36,7 @@
 #include <types/queue.h>
 #include <types/server.h>
 #include <types/task.h>
+#include <types/hdr_idx.h>
 
 
 /* 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 */
        char **req_cap;                         /* array of captured request 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 auth_hdr;                  /* points to 'Authorization:' header */
        struct {
index 26ef18698d3969f6c8ed281b85e3bbb7d026c55e..b867830674ce13ea3aa2c0881cb7c59456e28cc0 100644 (file)
@@ -37,6 +37,7 @@
 #include <proto/client.h>
 #include <proto/fd.h>
 #include <proto/log.h>
+#include <proto/hdr_idx.h>
 #include <proto/proto_http.h>
 #include <proto/stream_sock.h>
 #include <proto/task.h>
@@ -156,9 +157,6 @@ int event_accept(int fd) {
                t->context = s;
 
                s->task = t;
-#ifdef BUILD_WITH_PROXY
-               s->proxy = p;
-#endif
                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 */
@@ -227,6 +225,27 @@ int event_accept(int fd) {
                else
                        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)
                    && (p->logfac1 >= 0 || p->logfac2 >= 0)) {
                        struct sockaddr_storage sockname;
@@ -303,6 +322,8 @@ int event_accept(int fd) {
                }
 
                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)
                                pool_free_to(p->rsp_cap_pool, s->rsp_cap);
                        if (s->req_cap != NULL)