From: Willy Tarreau Date: Sun, 7 Jan 2007 14:46:13 +0000 (+0100) Subject: [MEDIUM] separate the http request from the session (step 1) X-Git-Tag: v1.3.6~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0f7562b8d3fa7345ff876c6372887b4c56862f27;p=thirdparty%2Fhaproxy.git [MEDIUM] separate the http request from the session (step 1) A struct http_req has been created to collect every information related to an HTTP request being processed. Right now, it is still in the struct session but the frontier is clear now. --- diff --git a/include/types/session.h b/include/types/session.h index 03a03bc48d..a9f1bbb3f1 100644 --- a/include/types/session.h +++ b/include/types/session.h @@ -112,7 +112,34 @@ typedef enum { HTTP_METH_OTHER, } http_meth_t; -/* WARNING: if new fields are added, they must be initialized in event_accept() */ +/* FIXME-20070107: this should move out to another file when HTTP will not be + * in the session anymore. + */ + +/* This is an HTTP message, as described in RFC2616. It can be either a request + * message or a response message. + */ +struct http_msg { + int hdr_state; /* where we are in the current header parsing */ + int sor, eoh; /* Start Of Request and End Of Headers, relative to buffer */ + char **cap; /* array of captured request headers (may be NULL) */ +}; + +/* This is an HTTP request, as described in RFC2616. It contains both a request + * message and a response message (which can be empty). + */ +struct http_req { + int req_state; /* what we are currently parsing */ + http_meth_t meth; /* HTTP method */ + struct hdr_idx hdr_idx; /* array of header indexes (max: MAX_HTTP_HDR) */ + struct chunk start; /* points to first line, called "start line" in RFC2616 */ + struct chunk auth_hdr; /* points to 'Authorization:' header */ + struct http_msg req, rsp; /* HTTP request and response messages */ +}; + +/* WARNING: if new fields are added, they must be initialized in event_accept() + * and freed in session_free() ! + */ struct session { struct task *task; /* the task associated with this session */ /* application specific below */ @@ -131,15 +158,7 @@ struct session { struct server *srv; /* the server being used */ struct pendconn *pend_pos; /* if not NULL, points to the position in the pending queue */ char **rsp_cap; /* array of captured response headers (may be NULL) */ - struct { - int hdr_state; /* where we are in the current header parsing */ - http_meth_t meth; /* HTTP method */ - int sor, eoh; /* Start Of Request and End Of Headers, relative to buffer */ - struct hdr_idx hdr_idx; /* array of header indexes (max: MAX_HTTP_HDR) */ - struct chunk start; /* points to first line, called "start line" in RFC2616 */ - struct chunk auth_hdr; /* points to 'Authorization:' header */ - char **cap; /* array of captured request headers (may be NULL) */ - } hreq; /* information associated to HTTP request */ + struct http_req hreq; /* current HTTP request being processed. Should become a list. */ struct { int logwait; /* log fields waiting to be collected : LW_* */ struct timeval tv_accept; /* date of the accept() (beginning of the session) */ diff --git a/src/client.c b/src/client.c index a8aad8e3ce..a28273238c 100644 --- a/src/client.c +++ b/src/client.c @@ -56,6 +56,7 @@ int event_accept(int fd) { struct proxy *p = (struct proxy *)fdtab[fd].owner; struct session *s; + struct http_req *hreq; struct task *t; int cfd; int max_accept; @@ -198,20 +199,21 @@ int event_accept(int fd) { p->cum_feconn++; /* cum_beconn will be increased once assigned */ s->rsp_cap = NULL; - s->hreq.cap = NULL; - s->hreq.hdr_idx.v = NULL; - s->hreq.hdr_idx.size = s->hreq.hdr_idx.used = 0; + hreq = &s->hreq; + hreq->req.cap = NULL; + hreq->hdr_idx.v = NULL; + hreq->hdr_idx.size = hreq->hdr_idx.used = 0; if (p->mode == PR_MODE_HTTP) { - s->hreq.hdr_state = HTTP_PA_EMPTY; /* at the very beginning of the request */ - s->hreq.start.len = -1; - s->hreq.auth_hdr.len = -1; - s->hreq.sor = s->hreq.eoh = 0; /* relative to the buffer */ + hreq->req.hdr_state = HTTP_PA_EMPTY; /* at the very beginning of the request */ + hreq->req.sor = hreq->req.eoh = 0; /* relative to the buffer */ + hreq->start.len = -1; + hreq->auth_hdr.len = -1; - s->hreq.hdr_idx.size = MAX_HTTP_HDR; + hreq->hdr_idx.size = MAX_HTTP_HDR; if (p->fiprm->nb_req_cap > 0) { - if ((s->hreq.cap = + if ((hreq->req.cap = pool_alloc_from(p->fiprm->req_cap_pool, p->fiprm->nb_req_cap*sizeof(char *))) == NULL) { /* no memory */ close(cfd); /* nothing can be done for this fd without memory */ @@ -219,7 +221,7 @@ int event_accept(int fd) { pool_free(session, s); return 0; } - memset(s->hreq.cap, 0, p->fiprm->nb_req_cap*sizeof(char *)); + memset(hreq->req.cap, 0, p->fiprm->nb_req_cap*sizeof(char *)); } @@ -227,8 +229,8 @@ int event_accept(int fd) { if ((s->rsp_cap = pool_alloc_from(p->fiprm->rsp_cap_pool, p->fiprm->nb_rsp_cap*sizeof(char *))) == NULL) { /* no memory */ - if (s->hreq.cap != NULL) - pool_free_to(p->fiprm->req_cap_pool, s->hreq.cap); + if (hreq->req.cap != NULL) + pool_free_to(p->fiprm->req_cap_pool, hreq->req.cap); close(cfd); /* nothing can be done for this fd without memory */ pool_free(task, t); pool_free(session, s); @@ -238,19 +240,19 @@ int event_accept(int fd) { } - if ((s->hreq.hdr_idx.v = - pool_alloc_from(p->hdr_idx_pool, s->hreq.hdr_idx.size*sizeof(*s->hreq.hdr_idx.v))) + if ((hreq->hdr_idx.v = + pool_alloc_from(p->hdr_idx_pool, hreq->hdr_idx.size*sizeof(*hreq->hdr_idx.v))) == NULL) { /* no memory */ if (s->rsp_cap != NULL) pool_free_to(p->fiprm->rsp_cap_pool, s->rsp_cap); - if (s->hreq.cap != NULL) - pool_free_to(p->fiprm->req_cap_pool, s->hreq.cap); + if (hreq->req.cap != NULL) + pool_free_to(p->fiprm->req_cap_pool, hreq->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->hreq.hdr_idx); + hdr_idx_init(&hreq->hdr_idx); } if ((p->mode == PR_MODE_TCP || p->mode == PR_MODE_HTTP) @@ -329,12 +331,12 @@ int event_accept(int fd) { } if ((s->req = pool_alloc(buffer)) == NULL) { /* no memory */ - if (s->hreq.hdr_idx.v != NULL) - pool_free_to(p->hdr_idx_pool, s->hreq.hdr_idx.v); + if (hreq->hdr_idx.v != NULL) + pool_free_to(p->hdr_idx_pool, hreq->hdr_idx.v); if (s->rsp_cap != NULL) pool_free_to(p->fiprm->rsp_cap_pool, s->rsp_cap); - if (s->hreq.cap != NULL) - pool_free_to(p->fiprm->req_cap_pool, s->hreq.cap); + if (hreq->req.cap != NULL) + pool_free_to(p->fiprm->req_cap_pool, hreq->req.cap); close(cfd); /* nothing can be done for this fd without memory */ pool_free(task, t); pool_free(session, s); @@ -352,12 +354,12 @@ int event_accept(int fd) { if ((s->rep = pool_alloc(buffer)) == NULL) { /* no memory */ pool_free(buffer, s->req); - if (s->hreq.hdr_idx.v != NULL) - pool_free_to(p->hdr_idx_pool, s->hreq.hdr_idx.v); + if (hreq->hdr_idx.v != NULL) + pool_free_to(p->hdr_idx_pool, hreq->hdr_idx.v); if (s->rsp_cap != NULL) pool_free_to(p->fiprm->rsp_cap_pool, s->rsp_cap); - if (s->hreq.cap != NULL) - pool_free_to(p->fiprm->req_cap_pool, s->hreq.cap); + if (hreq->req.cap != NULL) + pool_free_to(p->fiprm->req_cap_pool, hreq->req.cap); close(cfd); /* nothing can be done for this fd without memory */ pool_free(task, t); pool_free(session, s); diff --git a/src/log.c b/src/log.c index 5079185a52..c8b3194782 100644 --- a/src/log.c +++ b/src/log.c @@ -290,6 +290,7 @@ void sess_log(struct session *s) struct proxy *fe = s->fe; struct proxy *be = s->be; struct proxy *prx_log; + struct http_req *hreq = &s->hreq; int log, tolog; char *uri; char *pxid; @@ -350,9 +351,9 @@ void sess_log(struct session *s) for (hdr = 0; hdr < fe->nb_req_cap; hdr++) { if (hdr) *(h++) = '|'; - if (s->hreq.cap[hdr] != NULL) + if (hreq->req.cap[hdr] != NULL) h = encode_string(h, tmpline + sizeof(tmpline) - 7, - '#', hdr_encode_map, s->hreq.cap[hdr]); + '#', hdr_encode_map, hreq->req.cap[hdr]); } *(h++) = '}'; } diff --git a/src/proto_http.c b/src/proto_http.c index f66083121c..b051467d94 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -440,6 +440,7 @@ int process_session(struct task *t) */ int process_cli(struct session *t) { + struct http_req *hreq = &t->hreq; int s = t->srv_state; int c = t->cli_state; struct buffer *req = t->req; @@ -485,24 +486,24 @@ int process_cli(struct session *t) char *sol, *eol; /* Start Of Line, End Of Line */ struct proxy *cur_proxy; - eol = sol = req->data + t->hreq.eoh; + eol = sol = req->data + hreq->req.eoh; while (req->lr < req->r) { int parse; FSM_PRINTF(stderr, "WHL: hdr_st=0x%02x, hdr_used=%d hdr_tail=%d hdr_last=%d, h=%d, lr=%d, r=%d, eoh=%d\n", - t->hreq.hdr_state, t->hreq.hdr_idx.used, t->hreq.hdr_idx.tail, t->hreq.hdr_idx.last, - sol - req->data, req->lr - req->data, req->r - req->data, t->hreq.eoh); + hreq->req.hdr_state, hreq->hdr_idx.used, hreq->hdr_idx.tail, hreq->hdr_idx.last, + sol - req->data, req->lr - req->data, req->r - req->data, hreq->req.eoh); - if (t->hreq.hdr_state & HTTP_PA_LF_EXP) { + if (hreq->req.hdr_state & HTTP_PA_LF_EXP) { if (*req->lr != '\n') { - t->hreq.hdr_state = HTTP_PA_ERROR; + hreq->req.hdr_state = HTTP_PA_ERROR; break; } - t->hreq.hdr_state &= ~HTTP_PA_LF_EXP; + hreq->req.hdr_state &= ~HTTP_PA_LF_EXP; } - parse = t->hreq.hdr_state & ~HTTP_PA_CR_SKIP;; + parse = hreq->req.hdr_state & ~HTTP_PA_CR_SKIP;; if (parse == HTTP_PA_HDR_LF) { parse_hdr_lf: @@ -514,7 +515,7 @@ int process_cli(struct session *t) * which case it means the end of the request. */ eol = req->lr; - if (t->hreq.hdr_state & HTTP_PA_CR_SKIP) + if (hreq->req.hdr_state & HTTP_PA_CR_SKIP) eol--; /* Get back to the CR */ if (eol == sol) { @@ -524,7 +525,7 @@ int process_cli(struct session *t) * after the LF, so it is easy to append * anything there. */ - t->hreq.hdr_state = HTTP_PA_LFLF; + hreq->req.hdr_state = HTTP_PA_LFLF; QUICK_JUMP(parse_lflf, continue); } @@ -545,7 +546,7 @@ int process_cli(struct session *t) for (;eol < req->lr; eol++) *eol = ' '; - t->hreq.hdr_state = HTTP_PA_HDR_LWS; + hreq->req.hdr_state = HTTP_PA_HDR_LWS; QUICK_JUMP(parse_hdr_lws, continue); } @@ -580,11 +581,11 @@ int process_cli(struct session *t) if ((h->namelen + 2 <= eol - sol) && (sol[h->namelen] == ':') && (strncasecmp(sol, h->name, h->namelen) == 0)) { - if (t->hreq.cap[h->index] == NULL) - t->hreq.cap[h->index] = + if (hreq->req.cap[h->index] == NULL) + hreq->req.cap[h->index] = pool_alloc_from(h->pool, h->len + 1); - if (t->hreq.cap[h->index] == NULL) { + if (hreq->req.cap[h->index] == NULL) { Alert("HTTP capture : out of memory.\n"); continue; } @@ -593,8 +594,8 @@ int process_cli(struct session *t) if (len > h->len) len = h->len; - memcpy(t->hreq.cap[h->index], sol + h->namelen + 2, len); - t->hreq.cap[h->index][len]=0; + memcpy(hreq->req.cap[h->index], sol + h->namelen + 2, len); + hreq->req.cap[h->index][len]=0; } } } @@ -615,8 +616,8 @@ int process_cli(struct session *t) if (!delete_header) { /* we insert it into the index */ if (hdr_idx_add(eol - sol, req->lr - eol - 1, - &t->hreq.hdr_idx, t->hreq.hdr_idx.tail) < 0) { - t->hreq.hdr_state = HTTP_PA_ERROR; + &hreq->hdr_idx, hreq->hdr_idx.tail) < 0) { + hreq->req.hdr_state = HTTP_PA_ERROR; break; } } else { @@ -633,7 +634,7 @@ int process_cli(struct session *t) sol = req->lr; #ifdef DEBUG_PARSE_NO_SPEEDUP - t->hreq.hdr_state = HTTP_PA_HEADER; + hreq->req.hdr_state = HTTP_PA_HEADER; continue; #else /* @@ -645,19 +646,19 @@ int process_cli(struct session *t) if (IS_CTL(*req->lr)) { if (*eol == '\r') { req->lr++; - t->hreq.hdr_state = HTTP_PA_LFLF | HTTP_PA_LF_EXP; + hreq->req.hdr_state = HTTP_PA_LFLF | HTTP_PA_LF_EXP; continue; } else if (*eol == '\n') { - t->hreq.hdr_state = HTTP_PA_LFLF; + hreq->req.hdr_state = HTTP_PA_LFLF; goto parse_lflf; } else { - t->hreq.hdr_state = HTTP_PA_ERROR; + hreq->req.hdr_state = HTTP_PA_ERROR; break; } } - t->hreq.hdr_state = HTTP_PA_HEADER; + hreq->req.hdr_state = HTTP_PA_HEADER; goto parse_inside_hdr; #endif @@ -666,7 +667,7 @@ int process_cli(struct session *t) /* The LF validating the request line */ eol = req->lr; - if (t->hreq.hdr_state & HTTP_PA_CR_SKIP) + if (hreq->req.hdr_state & HTTP_PA_CR_SKIP) eol--; /* Get back to the CR */ /* We have the complete start line between @@ -702,8 +703,8 @@ int process_cli(struct session *t) /* 3: reference this line as the start line */ if (hdr_idx_add(eol - sol, req->lr - eol, - &t->hreq.hdr_idx, t->hreq.hdr_idx.tail) < 0) { - t->hreq.hdr_state = HTTP_PA_ERROR; + &hreq->hdr_idx, hreq->hdr_idx.tail) < 0) { + hreq->req.hdr_state = HTTP_PA_ERROR; break; } @@ -713,7 +714,7 @@ int process_cli(struct session *t) * be able to distinguish between an empty line * and a header. */ - t->hreq.hdr_state = HTTP_PA_HEADER; + hreq->req.hdr_state = HTTP_PA_HEADER; #ifdef DEBUG_PARSE_NO_SPEEDUP continue; #else @@ -764,15 +765,15 @@ int process_cli(struct session *t) /* we have a CTL char */ if (*ptr == '\r') { - t->hreq.hdr_state = HTTP_PA_HDR_LF | HTTP_PA_CR_SKIP | HTTP_PA_LF_EXP; + hreq->req.hdr_state = HTTP_PA_HDR_LF | HTTP_PA_CR_SKIP | HTTP_PA_LF_EXP; req->lr++; continue; } else if (*ptr == '\n') { - t->hreq.hdr_state = HTTP_PA_HDR_LF; + hreq->req.hdr_state = HTTP_PA_HDR_LF; QUICK_JUMP(parse_hdr_lf, continue); } - t->hreq.hdr_state = HTTP_PA_ERROR; + hreq->req.hdr_state = HTTP_PA_ERROR; break; } else if (parse == HTTP_PA_EMPTY) { @@ -780,12 +781,12 @@ int process_cli(struct session *t) if (*req->lr == '\n') { req->lr ++; - t->hreq.hdr_state = HTTP_PA_EMPTY; + hreq->req.hdr_state = HTTP_PA_EMPTY; continue; } else if (*req->lr == '\r') { req->lr ++; - t->hreq.hdr_state = HTTP_PA_EMPTY | HTTP_PA_CR_SKIP | HTTP_PA_LF_EXP; + hreq->req.hdr_state = HTTP_PA_EMPTY | HTTP_PA_CR_SKIP | HTTP_PA_LF_EXP; continue; } @@ -794,8 +795,8 @@ int process_cli(struct session *t) #if PARSE_PRESERVE_EMPTY_LINES /* only skip empty leading lines, don't remove them */ - t->hreq.hdr_idx.v[0].len = req->lr - sol; - t->hreq.sor = t->hreq.hdr_idx.v[0].len; + hreq->hdr_idx.v[0].len = req->lr - sol; + hreq->sor = hreq->hdr_idx.v[0].len; #else /* remove empty leading lines, as recommended by * RFC2616. This takes a lot of time because we @@ -810,7 +811,7 @@ int process_cli(struct session *t) FSM_PRINTF(stderr, "PA_EMPTY[1]: h=%d, lr=%d, r=%d\n", sol - req->data, req->lr - req->data, req->r - req->data); - t->hreq.hdr_state = HTTP_PA_START; + hreq->req.hdr_state = HTTP_PA_START; /* we know that we still have one char available */ QUICK_JUMP(parse_start, continue); @@ -854,15 +855,15 @@ int process_cli(struct session *t) /* we have a CTL char */ if (*ptr == '\r') { req->lr++; - t->hreq.hdr_state = HTTP_PA_STRT_LF | HTTP_PA_CR_SKIP | HTTP_PA_LF_EXP; + hreq->req.hdr_state = HTTP_PA_STRT_LF | HTTP_PA_CR_SKIP | HTTP_PA_LF_EXP; continue; } else if (*ptr == '\n') { - t->hreq.hdr_state = HTTP_PA_STRT_LF; + hreq->req.hdr_state = HTTP_PA_STRT_LF; /* we know that we still have one char available */ QUICK_JUMP(parse_strt_lf, continue); } - t->hreq.hdr_state = HTTP_PA_ERROR; + hreq->req.hdr_state = HTTP_PA_ERROR; break; @@ -889,7 +890,7 @@ int process_cli(struct session *t) if (*req->lr == '\t') *req->lr = ' '; else if (*req->lr != ' ') { - t->hreq.hdr_state = HTTP_PA_HEADER; + hreq->req.hdr_state = HTTP_PA_HEADER; QUICK_JUMP(parse_inside_hdr, break); } req->lr++; @@ -903,17 +904,17 @@ int process_cli(struct session *t) } /* end of the "while(req->lr < req->r)" loop */ /* update the end of headers */ - t->hreq.eoh = sol - req->data; + hreq->req.eoh = sol - req->data; FSM_PRINTF(stderr, "END: hdr_st=0x%02x, hdr_used=%d hdr_tail=%d hdr_last=%d, h=%d, lr=%d, r=%d, eoh=%d\n", - t->hreq.hdr_state, t->hreq.hdr_idx.used, t->hreq.hdr_idx.tail, t->hreq.hdr_idx.last, - sol - req->data, req->lr - req->data, req->r - req->data, t->hreq.eoh); + hreq->req.hdr_state, hreq->hdr_idx.used, hreq->hdr_idx.tail, hreq->hdr_idx.last, + sol - req->data, req->lr - req->data, req->r - req->data, hreq->req.eoh); /* * Now, let's catch bad requests. */ - if (t->hreq.hdr_state == HTTP_PA_ERROR) + if (hreq->req.hdr_state == HTTP_PA_ERROR) goto return_bad_req; /* @@ -924,7 +925,7 @@ int process_cli(struct session *t) * */ - if (t->hreq.hdr_state != HTTP_PA_LFLF) { /* Request not complete yet */ + if (hreq->req.hdr_state != HTTP_PA_LFLF) { /* Request not complete yet */ /* 1: Since we are in header mode, if there's no space * left for headers, we won't be able to free more @@ -932,7 +933,7 @@ int process_cli(struct session *t) * must terminate it now. */ if (req->l >= req->rlim - req->data) { - /* FIXME: check if hreq.hdr_state & mask < HTTP_PA_HEADER, + /* FIXME: check if hreq.req.hdr_state & mask < HTTP_PA_HEADER, * and return Status 414 Request URI too long instead. */ goto return_bad_req; @@ -998,21 +999,21 @@ int process_cli(struct session *t) * send pre-formatted requests too. */ - t->hreq.start.str = req->data + t->hreq.sor; /* start of the REQURI */ - t->hreq.start.len = t->hreq.hdr_idx.v[t->hreq.hdr_idx.v[0].next].len; /* end of the REQURI */ - t->hreq.meth = find_http_meth(t->hreq.start.str, t->hreq.start.len); + hreq->start.str = req->data + hreq->req.sor; /* start of the REQURI */ + hreq->start.len = hreq->hdr_idx.v[hreq->hdr_idx.v[0].next].len; /* end of the REQURI */ + hreq->meth = find_http_meth(hreq->start.str, hreq->start.len); if ((t->fe->monitor_uri_len != 0) && - (t->hreq.start.len >= t->fe->monitor_uri_len)) { - char *p = t->hreq.start.str; + (hreq->start.len >= t->fe->monitor_uri_len)) { + char *p = hreq->start.str; int idx = 0; /* skip the method so that we accept any method */ - while (idx < t->hreq.start.len && p[idx] != ' ') + while (idx < hreq->start.len && p[idx] != ' ') idx++; p += idx; - if (t->hreq.start.len - idx >= t->fe->monitor_uri_len && + if (hreq->start.len - idx >= t->fe->monitor_uri_len && !memcmp(p, t->fe->monitor_uri, t->fe->monitor_uri_len)) { /* * We have found the monitor URI @@ -1058,8 +1059,8 @@ int process_cli(struct session *t) apply_filters_to_session(t, req, rule_set->req_exp); /* the start line might have been modified */ - t->hreq.start.len = t->hreq.hdr_idx.v[t->hreq.hdr_idx.v[0].next].len; - t->hreq.meth = find_http_meth(t->hreq.start.str, t->hreq.start.len); + hreq->start.len = hreq->hdr_idx.v[hreq->hdr_idx.v[0].next].len; + hreq->meth = find_http_meth(hreq->start.str, hreq->start.len); } if (!(t->flags & SN_BE_ASSIGNED) && (t->be != cur_proxy)) { @@ -1089,16 +1090,16 @@ int process_cli(struct session *t) int len; len = sprintf(trash, "%s\r\n", rule_set->req_add[cur_hdr]); - len = buffer_replace2(req, req->data + t->hreq.eoh, - req->data + t->hreq.eoh, trash, len); - t->hreq.eoh += len; + len = buffer_replace2(req, req->data + hreq->req.eoh, + req->data + hreq->req.eoh, trash, len); + hreq->req.eoh += len; - if (hdr_idx_add(len - 2, 1, &t->hreq.hdr_idx, t->hreq.hdr_idx.tail) < 0) + if (hdr_idx_add(len - 2, 1, &hreq->hdr_idx, hreq->hdr_idx.tail) < 0) goto return_bad_req; } if (rule_set->uri_auth != NULL && - (t->hreq.meth == HTTP_METH_GET || t->hreq.meth == HTTP_METH_HEAD)) { + (hreq->meth == HTTP_METH_GET || hreq->meth == HTTP_METH_HEAD)) { /* we have to check the URI and auth for this request */ if (stats_check_uri_auth(t, rule_set)) return 1; @@ -1150,8 +1151,8 @@ int process_cli(struct session *t) /* It needs to look into the URI */ if (t->be->beprm->appsession_name) { get_srv_from_appsession(t, - t->hreq.start.str, - t->hreq.start.str + t->hreq.start.len); + hreq->start.str, + hreq->start.str + hreq->start.len); } @@ -1175,11 +1176,11 @@ int process_cli(struct session *t) pn = (unsigned char *)&((struct sockaddr_in *)&t->cli_addr)->sin_addr; len = sprintf(trash, "X-Forwarded-For: %d.%d.%d.%d\r\n", pn[0], pn[1], pn[2], pn[3]); - len = buffer_replace2(req, req->data + t->hreq.eoh, - req->data + t->hreq.eoh, trash, len); - t->hreq.eoh += len; + len = buffer_replace2(req, req->data + hreq->req.eoh, + req->data + hreq->req.eoh, trash, len); + hreq->req.eoh += len; - if (hdr_idx_add(len - 2, 1, &t->hreq.hdr_idx, t->hreq.hdr_idx.tail) < 0) + if (hdr_idx_add(len - 2, 1, &hreq->hdr_idx, hreq->hdr_idx.tail) < 0) goto return_bad_req; } else if (t->cli_addr.ss_family == AF_INET6) { @@ -1189,11 +1190,11 @@ int process_cli(struct session *t) (const void *)&((struct sockaddr_in6 *)(&t->cli_addr))->sin6_addr, pn, sizeof(pn)); len = sprintf(trash, "X-Forwarded-For: %s\r\n", pn); - len = buffer_replace2(req, req->data + t->hreq.eoh, - req->data + t->hreq.eoh, trash, len); - t->hreq.eoh += len; + len = buffer_replace2(req, req->data + hreq->req.eoh, + req->data + hreq->req.eoh, trash, len); + hreq->req.eoh += len; - if (hdr_idx_add(len - 2, 1, &t->hreq.hdr_idx, t->hreq.hdr_idx.tail) < 0) + if (hdr_idx_add(len - 2, 1, &hreq->hdr_idx, hreq->hdr_idx.tail) < 0) goto return_bad_req; } } @@ -1209,11 +1210,11 @@ int process_cli(struct session *t) */ if ((t->fe->options | t->be->beprm->options) & PR_O_HTTP_CLOSE) { int len; - len = buffer_replace2(req, req->data + t->hreq.eoh, - req->data + t->hreq.eoh, "Connection: close\r\n", 19); - t->hreq.eoh += len; + len = buffer_replace2(req, req->data + hreq->req.eoh, + req->data + hreq->req.eoh, "Connection: close\r\n", 19); + hreq->req.eoh += len; - if (hdr_idx_add(17, 1, &t->hreq.hdr_idx, t->hreq.hdr_idx.tail) < 0) + if (hdr_idx_add(17, 1, &hreq->hdr_idx, hreq->hdr_idx.tail) < 0) goto return_bad_req; } @@ -1268,25 +1269,25 @@ int process_cli(struct session *t) fprintf(stderr, "t->flags=0x%08x\n", t->flags & (SN_CLALLOW|SN_CLDENY|SN_CLTARPIT)); fprintf(stderr, "sol=%d\n", sol - req->data); - sol = req->data + t->hreq.sor; + sol = req->data + hreq->sor; cur_hdr = 0; - cur_idx = t->hreq.hdr_idx.v[0].next; + cur_idx = hreq->hdr_idx.v[0].next; cur_hdr = 1; - while (cur_hdr < t->hreq.hdr_idx.used) { - eol = sol + t->hreq.hdr_idx.v[cur_idx].len + t->hreq.hdr_idx.v[cur_idx].cr + 1; + while (cur_hdr < hreq->hdr_idx.used) { + eol = sol + hreq->hdr_idx.v[cur_idx].len + hreq->hdr_idx.v[cur_idx].cr + 1; fprintf(stderr, "lr=%d r=%d hdr=%d idx=%d adr=%d..%d len=%d cr=%d data:\n", req->lr - req->data, req->r - req->data, cur_hdr, cur_idx, sol - req->data, - sol - req->data + t->hreq.hdr_idx.v[cur_idx].len + t->hreq.hdr_idx.v[cur_idx].cr, - t->hreq.hdr_idx.v[cur_idx].len, - t->hreq.hdr_idx.v[cur_idx].cr); + sol - req->data + hreq->hdr_idx.v[cur_idx].len + hreq->hdr_idx.v[cur_idx].cr, + hreq->hdr_idx.v[cur_idx].len, + hreq->hdr_idx.v[cur_idx].cr); write(2, sol, eol - sol); sol = eol; - cur_idx = t->hreq.hdr_idx.v[cur_idx].next; + cur_idx = hreq->hdr_idx.v[cur_idx].next; cur_hdr++; } #endif @@ -1294,7 +1295,7 @@ int process_cli(struct session *t) goto process_data; return_bad_req: /* let's centralize all bad requests */ - t->hreq.hdr_state = HTTP_PA_ERROR; + hreq->req.hdr_state = HTTP_PA_ERROR; t->logs.status = 400; client_retnclose(t, error_message(t, HTTP_ERR_400)); t->fe->failed_req++; @@ -1598,6 +1599,7 @@ int process_cli(struct session *t) */ int process_srv(struct session *t) { + struct http_req *hreq = &t->hreq; int s = t->srv_state; int c = t->cli_state; struct buffer *req = t->req; @@ -1906,7 +1908,7 @@ int process_srv(struct session *t) /* we'll have something else to do here : add new headers ... */ if ((t->srv) && !(t->flags & SN_DIRECT) && (t->be->beprm->options & PR_O_COOK_INS) && - (!(t->be->beprm->options & PR_O_COOK_POST) || (t->hreq.meth == HTTP_METH_POST))) { + (!(t->be->beprm->options & PR_O_COOK_POST) || (hreq->meth == HTTP_METH_POST))) { /* the server is known, it's not the one the client requested, we have to * insert a set-cookie here, except if we want to insert only on POST * requests and this one isn't. Note that servers which don't have cookies @@ -2031,7 +2033,7 @@ int process_srv(struct session *t) * unless the response includes appropriate * Cache-Control or Expires header fields." */ - if (!(t->hreq.meth == HTTP_METH_POST) && (t->be->beprm->options & PR_O_CHK_CACHE)) + if (!(hreq->meth == HTTP_METH_POST) && (t->be->beprm->options & PR_O_CHK_CACHE)) t->flags |= SN_CACHEABLE | SN_CACHE_COOK; break; default: @@ -3271,6 +3273,8 @@ int produce_content_stats_proxy(struct session *s, struct proxy *px) void apply_filters_to_session(struct session *t, struct buffer *req, struct hdr_exp *exp) { + struct http_req *hreq = &t->hreq; + /* iterate through the filters in the outer loop */ while (exp && !(t->flags & (SN_CLDENY|SN_CLTARPIT))) { char term; @@ -3295,11 +3299,11 @@ void apply_filters_to_session(struct session *t, struct buffer *req, struct hdr_ * we start with the start line. */ old_idx = cur_idx = 0; - cur_next = req->data + t->hreq.sor; + cur_next = req->data + hreq->req.sor; abort_filt = 0; - while (!abort_filt && (cur_idx = t->hreq.hdr_idx.v[cur_idx].next)) { - struct hdr_idx_elem *cur_hdr = &t->hreq.hdr_idx.v[cur_idx]; + while (!abort_filt && (cur_idx = hreq->hdr_idx.v[cur_idx].next)) { + struct hdr_idx_elem *cur_hdr = &hreq->hdr_idx.v[cur_idx]; cur_ptr = cur_next; cur_end = cur_ptr + cur_hdr->len; cur_next = cur_end + cur_hdr->cr + 1; @@ -3371,7 +3375,7 @@ void apply_filters_to_session(struct session *t, struct buffer *req, struct hdr_ cur_end += delta; cur_next += delta; cur_hdr->len += delta; - t->hreq.eoh += delta; + hreq->req.eoh += delta; } break; case ACT_REMOVE: @@ -3380,9 +3384,9 @@ void apply_filters_to_session(struct session *t, struct buffer *req, struct hdr_ cur_next += delta; /* FIXME: this should be a separate function */ - t->hreq.eoh += delta; - t->hreq.hdr_idx.v[old_idx].next = cur_hdr->next; - t->hreq.hdr_idx.used--; + hreq->req.eoh += delta; + hreq->hdr_idx.v[old_idx].next = cur_hdr->next; + hreq->hdr_idx.used--; cur_hdr->len = 0; cur_end = NULL; /* null-term has been rewritten */ @@ -3423,6 +3427,7 @@ void apply_filters_to_session(struct session *t, struct buffer *req, struct hdr_ */ void manage_client_side_cookies(struct session *t, struct buffer *req) { + struct http_req *hreq = &t->hreq; char *p1, *p2, *p3, *p4; char *del_colon, *del_cookie, *colon; int app_cookies; @@ -3442,13 +3447,13 @@ void manage_client_side_cookies(struct session *t, struct buffer *req) * we start with the start line. */ old_idx = cur_idx = 0; - cur_next = req->data + t->hreq.sor; + cur_next = req->data + hreq->req.sor; abort_filt = 0; - while ((cur_idx = t->hreq.hdr_idx.v[cur_idx].next)) { + while ((cur_idx = hreq->hdr_idx.v[cur_idx].next)) { struct hdr_idx_elem *cur_hdr; - cur_hdr = &t->hreq.hdr_idx.v[cur_idx]; + cur_hdr = &hreq->hdr_idx.v[cur_idx]; cur_ptr = cur_next; cur_end = cur_ptr + cur_hdr->len; cur_next = cur_end + cur_hdr->cr + 1; @@ -3630,7 +3635,7 @@ void manage_client_side_cookies(struct session *t, struct buffer *req) cur_end += delta; cur_next += delta; cur_hdr->len += delta; - t->hreq.eoh += delta; + hreq->req.eoh += delta; del_cookie = del_colon = NULL; app_cookies++; /* protect the header from deletion */ @@ -3656,7 +3661,7 @@ void manage_client_side_cookies(struct session *t, struct buffer *req) cur_end += delta; cur_next += delta; cur_hdr->len += delta; - t->hreq.eoh += delta; + hreq->req.eoh += delta; del_cookie = del_colon = NULL; } } @@ -3744,12 +3749,12 @@ void manage_client_side_cookies(struct session *t, struct buffer *req) delta = buffer_replace2(req, cur_ptr, cur_next, NULL, 0); /* FIXME: this should be a separate function */ - t->hreq.hdr_idx.v[old_idx].next = cur_hdr->next; - t->hreq.hdr_idx.used--; + hreq->hdr_idx.v[old_idx].next = cur_hdr->next; + hreq->hdr_idx.used--; cur_hdr->len = 0; } cur_next += delta; - t->hreq.eoh += delta; + hreq->req.eoh += delta; } /* keep the link from this header to next one */ @@ -3860,6 +3865,7 @@ void get_srv_from_appsession(struct session *t, const char *begin, const char *e */ int stats_check_uri_auth(struct session *t, struct proxy *backend) { + struct http_req *hreq = &t->hreq; struct uri_auth *uri_auth = backend->uri_auth; struct user_auth *user; int authenticated, cur_idx; @@ -3867,8 +3873,8 @@ int stats_check_uri_auth(struct session *t, struct proxy *backend) /* FIXME: this will soon be easier */ /* skip the method */ - h = t->hreq.start.str; - e = h + t->hreq.start.len - uri_auth->uri_len; + h = hreq->start.str; + e = h + hreq->start.len - uri_auth->uri_len; while (h < e && *h != ' ' && *h != '\t') h++; @@ -3900,25 +3906,25 @@ int stats_check_uri_auth(struct session *t, struct proxy *backend) /* FIXME: this should move to an earlier place */ cur_idx = 0; - h = t->req->data + t->hreq.sor; - while ((cur_idx = t->hreq.hdr_idx.v[cur_idx].next)) { - int len = t->hreq.hdr_idx.v[cur_idx].len; + h = t->req->data + hreq->req.sor; + while ((cur_idx = hreq->hdr_idx.v[cur_idx].next)) { + int len = hreq->hdr_idx.v[cur_idx].len; if (len > 14 && !strncasecmp("Authorization:", h, 14)) { - t->hreq.auth_hdr.str = h; - t->hreq.auth_hdr.len = len; + hreq->auth_hdr.str = h; + hreq->auth_hdr.len = len; break; } - h += len + t->hreq.hdr_idx.v[cur_idx].cr + 1; + h += len + hreq->hdr_idx.v[cur_idx].cr + 1; } - if (t->hreq.auth_hdr.len < 21 || - memcmp(t->hreq.auth_hdr.str + 14, " Basic ", 7)) + if (hreq->auth_hdr.len < 21 || + memcmp(hreq->auth_hdr.str + 14, " Basic ", 7)) user = NULL; while (user) { - if ((t->hreq.auth_hdr.len == user->user_len + 14 + 7) - && !memcmp(t->hreq.auth_hdr.str + 14 + 7, + if ((hreq->auth_hdr.len == user->user_len + 14 + 7) + && !memcmp(hreq->auth_hdr.str + 14 + 7, user->user_pwd, user->user_len)) { authenticated = 1; break; diff --git a/src/session.c b/src/session.c index 45af997c13..5372b7dbc5 100644 --- a/src/session.c +++ b/src/session.c @@ -32,6 +32,8 @@ void **pool_session = NULL; */ void session_free(struct session *s) { + struct http_req *hreq = &s->hreq; + if (s->pend_pos) pendconn_free(s->pend_pos); if (s->req) @@ -39,8 +41,8 @@ void session_free(struct session *s) if (s->rep) pool_free(buffer, s->rep); - if (s->hreq.hdr_idx.v != NULL) - pool_free_to(s->fe->hdr_idx_pool, s->hreq.hdr_idx.v); + if (hreq->hdr_idx.v != NULL) + pool_free_to(s->fe->hdr_idx_pool, hreq->hdr_idx.v); if (s->rsp_cap != NULL) { struct cap_hdr *h; @@ -50,13 +52,13 @@ void session_free(struct session *s) } pool_free_to(s->fe->fiprm->rsp_cap_pool, s->rsp_cap); } - if (s->hreq.cap != NULL) { + if (hreq->req.cap != NULL) { struct cap_hdr *h; for (h = s->fe->fiprm->req_cap; h; h = h->next) { - if (s->hreq.cap[h->index] != NULL) - pool_free_to(h->pool, s->hreq.cap[h->index]); + if (hreq->req.cap[h->index] != NULL) + pool_free_to(h->pool, hreq->req.cap[h->index]); } - pool_free_to(s->fe->fiprm->req_cap_pool, s->hreq.cap); + pool_free_to(s->fe->fiprm->req_cap_pool, hreq->req.cap); } if (s->logs.uri)