mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-03-03 18:09:25 +00:00
[MEDIUM] move all HTTP Request-related session material to struct hreq
The req_cap, hdr_state, hdr_idx, auth_hdr and req_line have been moved to a dedicated hreq structure in the session. It makes is easier to add HTTP-specific fields such as SOR (start of request) and EOF (end of headers). It also made it possible to fix two bugs introduced by last commit : - end of headers not correctly detected - hdr_idx not freed upon one specific error during session creation When the backend side will be reworked, it should rely on a similar structure.
This commit is contained in:
parent
8a68c24b91
commit
45e73e3cd9
@ -119,12 +119,15 @@ struct session {
|
|||||||
struct sockaddr_in srv_addr; /* the address to connect to */
|
struct sockaddr_in srv_addr; /* the address to connect to */
|
||||||
struct server *srv; /* the server being used */
|
struct server *srv; /* the server being used */
|
||||||
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 **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 {
|
||||||
int hdr_state; /* where we are in the current header parsing */
|
int hdr_state; /* where we are in the current header parsing */
|
||||||
struct chunk req_line; /* points to first line */
|
int sor, eoh; /* Start Of Request and End Of Headers, relative to buffer */
|
||||||
struct chunk auth_hdr; /* points to 'Authorization:' header */
|
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 {
|
struct {
|
||||||
int logwait; /* log fields waiting to be collected : LW_* */
|
int logwait; /* log fields waiting to be collected : LW_* */
|
||||||
struct timeval tv_accept; /* date of the accept() (beginning of the session) */
|
struct timeval tv_accept; /* date of the accept() (beginning of the session) */
|
||||||
|
100
src/client.c
100
src/client.c
@ -161,13 +161,10 @@ int event_accept(int fd) {
|
|||||||
|
|
||||||
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 */
|
||||||
s->srv_state = SV_STIDLE;
|
s->srv_state = SV_STIDLE;
|
||||||
s->hdr_state = HTTP_PA_EMPTY; /* at the very beginning of the request */
|
|
||||||
s->req = s->rep = NULL; /* will be allocated later */
|
s->req = s->rep = NULL; /* will be allocated later */
|
||||||
|
|
||||||
s->cli_fd = cfd;
|
s->cli_fd = cfd;
|
||||||
s->srv_fd = -1;
|
s->srv_fd = -1;
|
||||||
s->req_line.len = -1;
|
|
||||||
s->auth_hdr.len = -1;
|
|
||||||
s->srv = NULL;
|
s->srv = NULL;
|
||||||
s->pend_pos = NULL;
|
s->pend_pos = NULL;
|
||||||
s->conn_retries = p->conn_retries;
|
s->conn_retries = p->conn_retries;
|
||||||
@ -196,55 +193,60 @@ int event_accept(int fd) {
|
|||||||
s->uniq_id = totalconn;
|
s->uniq_id = totalconn;
|
||||||
p->cum_conn++;
|
p->cum_conn++;
|
||||||
|
|
||||||
if (p->nb_req_cap > 0) {
|
s->rsp_cap = NULL;
|
||||||
if ((s->req_cap =
|
s->hreq.cap = NULL;
|
||||||
pool_alloc_from(p->req_cap_pool, p->nb_req_cap*sizeof(char *)))
|
s->hreq.hdr_idx.v = NULL;
|
||||||
== NULL) { /* no memory */
|
s->hreq.hdr_idx.size = s->hreq.hdr_idx.used = 0;
|
||||||
close(cfd); /* nothing can be done for this fd without memory */
|
|
||||||
pool_free(task, t);
|
|
||||||
pool_free(session, s);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memset(s->req_cap, 0, p->nb_req_cap*sizeof(char *));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
s->req_cap = NULL;
|
|
||||||
|
|
||||||
if (p->nb_rsp_cap > 0) {
|
|
||||||
if ((s->rsp_cap =
|
|
||||||
pool_alloc_from(p->rsp_cap_pool, p->nb_rsp_cap*sizeof(char *)))
|
|
||||||
== NULL) { /* no memory */
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
memset(s->rsp_cap, 0, p->nb_rsp_cap*sizeof(char *));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
s->rsp_cap = NULL;
|
|
||||||
|
|
||||||
if (p->mode == PR_MODE_HTTP) {
|
if (p->mode == PR_MODE_HTTP) {
|
||||||
s->hdr_idx.size = MAX_HTTP_HDR;
|
s->hreq.hdr_state = HTTP_PA_EMPTY; /* at the very beginning of the request */
|
||||||
if ((s->hdr_idx.v =
|
s->hreq.start.len = -1;
|
||||||
pool_alloc_from(p->hdr_idx_pool, s->hdr_idx.size*sizeof(*s->hdr_idx.v)))
|
s->hreq.auth_hdr.len = -1;
|
||||||
|
s->hreq.sor = s->hreq.eoh = 0; /* relative to the buffer */
|
||||||
|
|
||||||
|
s->hreq.hdr_idx.size = MAX_HTTP_HDR;
|
||||||
|
|
||||||
|
if (p->nb_req_cap > 0) {
|
||||||
|
if ((s->hreq.cap =
|
||||||
|
pool_alloc_from(p->req_cap_pool, p->nb_req_cap*sizeof(char *)))
|
||||||
|
== NULL) { /* no memory */
|
||||||
|
close(cfd); /* nothing can be done for this fd without memory */
|
||||||
|
pool_free(task, t);
|
||||||
|
pool_free(session, s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset(s->hreq.cap, 0, p->nb_req_cap*sizeof(char *));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (p->nb_rsp_cap > 0) {
|
||||||
|
if ((s->rsp_cap =
|
||||||
|
pool_alloc_from(p->rsp_cap_pool, p->nb_rsp_cap*sizeof(char *)))
|
||||||
|
== NULL) { /* no memory */
|
||||||
|
if (s->hreq.cap != NULL)
|
||||||
|
pool_free_to(p->req_cap_pool, s->hreq.cap);
|
||||||
|
close(cfd); /* nothing can be done for this fd without memory */
|
||||||
|
pool_free(task, t);
|
||||||
|
pool_free(session, s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset(s->rsp_cap, 0, p->nb_rsp_cap*sizeof(char *));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((s->hreq.hdr_idx.v =
|
||||||
|
pool_alloc_from(p->hdr_idx_pool, s->hreq.hdr_idx.size*sizeof(*s->hreq.hdr_idx.v)))
|
||||||
== NULL) { /* no memory */
|
== NULL) { /* no memory */
|
||||||
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->hreq.cap != NULL)
|
||||||
pool_free_to(p->req_cap_pool, s->req_cap);
|
pool_free_to(p->req_cap_pool, s->hreq.cap);
|
||||||
close(cfd); /* nothing can be done for this fd without memory */
|
close(cfd); /* nothing can be done for this fd without memory */
|
||||||
pool_free(task, t);
|
pool_free(task, t);
|
||||||
pool_free(session, s);
|
pool_free(session, s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
hdr_idx_init(&s->hdr_idx);
|
hdr_idx_init(&s->hreq.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)
|
||||||
@ -323,12 +325,12 @@ 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)
|
if (s->hreq.hdr_idx.v != NULL)
|
||||||
pool_free_to(p->hdr_idx_pool, s->hdr_idx.v);
|
pool_free_to(p->hdr_idx_pool, s->hreq.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->hreq.cap != NULL)
|
||||||
pool_free_to(p->req_cap_pool, s->req_cap);
|
pool_free_to(p->req_cap_pool, s->hreq.cap);
|
||||||
close(cfd); /* nothing can be done for this fd without memory */
|
close(cfd); /* nothing can be done for this fd without memory */
|
||||||
pool_free(task, t);
|
pool_free(task, t);
|
||||||
pool_free(session, s);
|
pool_free(session, s);
|
||||||
@ -346,10 +348,12 @@ int event_accept(int fd) {
|
|||||||
|
|
||||||
if ((s->rep = pool_alloc(buffer)) == NULL) { /* no memory */
|
if ((s->rep = pool_alloc(buffer)) == NULL) { /* no memory */
|
||||||
pool_free(buffer, s->req);
|
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 (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->hreq.cap != NULL)
|
||||||
pool_free_to(p->req_cap_pool, s->req_cap);
|
pool_free_to(p->req_cap_pool, s->hreq.cap);
|
||||||
close(cfd); /* nothing can be done for this fd without memory */
|
close(cfd); /* nothing can be done for this fd without memory */
|
||||||
pool_free(task, t);
|
pool_free(task, t);
|
||||||
pool_free(session, s);
|
pool_free(session, s);
|
||||||
|
@ -333,9 +333,9 @@ void sess_log(struct session *s)
|
|||||||
for (hdr = 0; hdr < p->nb_req_cap; hdr++) {
|
for (hdr = 0; hdr < p->nb_req_cap; hdr++) {
|
||||||
if (hdr)
|
if (hdr)
|
||||||
*(h++) = '|';
|
*(h++) = '|';
|
||||||
if (s->req_cap[hdr] != NULL)
|
if (s->hreq.cap[hdr] != NULL)
|
||||||
h = encode_string(h, tmpline + sizeof(tmpline) - 7,
|
h = encode_string(h, tmpline + sizeof(tmpline) - 7,
|
||||||
'#', hdr_encode_map, s->req_cap[hdr]);
|
'#', hdr_encode_map, s->hreq.cap[hdr]);
|
||||||
}
|
}
|
||||||
*(h++) = '}';
|
*(h++) = '}';
|
||||||
}
|
}
|
||||||
|
280
src/proto_http.c
280
src/proto_http.c
@ -186,7 +186,9 @@ int process_session(struct task *t)
|
|||||||
|
|
||||||
if ((global.mode & MODE_DEBUG) && (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
|
if ((global.mode & MODE_DEBUG) && (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
|
||||||
int len;
|
int len;
|
||||||
len = sprintf(trash, "%08x:%s.closed[%04x:%04x]\n", s->uniq_id, s->be->id, (unsigned short)s->cli_fd, (unsigned short)s->srv_fd);
|
len = sprintf(trash, "%08x:%s.closed[%04x:%04x]\n",
|
||||||
|
s->uniq_id, s->be->id,
|
||||||
|
(unsigned short)s->cli_fd, (unsigned short)s->srv_fd);
|
||||||
write(1, trash, len);
|
write(1, trash, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,17 +229,12 @@ int process_cli(struct session *t)
|
|||||||
|
|
||||||
int cur_hdr, cur_idx;
|
int cur_hdr, cur_idx;
|
||||||
|
|
||||||
#ifdef DEBUG_FULL
|
DPRINTF(stderr,"process_cli: c=%s s=%s set(r,w)=%d,%d exp(r,w)=%d.%d,%d.%d\n",
|
||||||
fprintf(stderr,"process_cli: c=%s s=%s set(r,w)=%d,%d exp(r,w)=%d.%d,%d.%d\n",
|
|
||||||
cli_stnames[c], srv_stnames[s],
|
cli_stnames[c], srv_stnames[s],
|
||||||
MY_FD_ISSET(t->cli_fd, StaticReadEvent), MY_FD_ISSET(t->cli_fd, StaticWriteEvent),
|
MY_FD_ISSET(t->cli_fd, StaticReadEvent), MY_FD_ISSET(t->cli_fd, StaticWriteEvent),
|
||||||
req->rex.tv_sec, req->rex.tv_usec,
|
req->rex.tv_sec, req->rex.tv_usec,
|
||||||
rep->wex.tv_sec, rep->wex.tv_usec);
|
rep->wex.tv_sec, rep->wex.tv_usec);
|
||||||
#endif
|
|
||||||
//fprintf(stderr,"process_cli: c=%d, s=%d, cr=%d, cw=%d, sr=%d, sw=%d\n", c, s,
|
|
||||||
//MY_FD_ISSET(t->cli_fd, StaticReadEvent), MY_FD_ISSET(t->cli_fd, StaticWriteEvent),
|
|
||||||
//MY_FD_ISSET(t->srv_fd, StaticReadEvent), MY_FD_ISSET(t->srv_fd, StaticWriteEvent)
|
|
||||||
//);
|
|
||||||
if (c == CL_STHEADERS) {
|
if (c == CL_STHEADERS) {
|
||||||
/*
|
/*
|
||||||
* Now parse the partial (or complete) lines.
|
* Now parse the partial (or complete) lines.
|
||||||
@ -260,49 +257,53 @@ int process_cli(struct session *t)
|
|||||||
* skipped.
|
* skipped.
|
||||||
*
|
*
|
||||||
* Here is the information we currently have :
|
* Here is the information we currently have :
|
||||||
* req->data = beginning of request
|
* req->data + req->sor = beginning of request
|
||||||
|
* req->data + req->eoh = end of (parsed) headers
|
||||||
* req->lr = first non-visited byte
|
* req->lr = first non-visited byte
|
||||||
* req->r = end of data
|
* req->r = end of data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char *sol, *eol; /* Start Of Line, End Of Line */
|
char *sol, *eol; /* Start Of Line, End Of Line */
|
||||||
|
|
||||||
eol = sol = req->data;
|
eol = sol = req->data + t->hreq.eoh;
|
||||||
|
|
||||||
while (req->lr < req->r) {
|
while (req->lr < req->r) {
|
||||||
int parse;
|
int parse;
|
||||||
|
|
||||||
DPRINTF(stderr, "WHL: hdr_st=0x%02x, hdr_used=%d hdr_tail=%d hdr_last=%d, h=%p, lr=%p, r=%p\n",
|
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->hdr_state, t->hdr_idx.used, t->hdr_idx.tail, t->hdr_idx.last, sol, req->lr, req->r);
|
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);
|
||||||
if (t->hdr_state & HTTP_PA_LF_EXP) {
|
|
||||||
|
if (t->hreq.hdr_state & HTTP_PA_LF_EXP) {
|
||||||
if (*req->lr != '\n') {
|
if (*req->lr != '\n') {
|
||||||
t->hdr_state = HTTP_PA_ERROR;
|
t->hreq.hdr_state = HTTP_PA_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
t->hdr_state &= ~HTTP_PA_LF_EXP;
|
t->hreq.hdr_state &= ~HTTP_PA_LF_EXP;
|
||||||
}
|
}
|
||||||
|
|
||||||
parse = t->hdr_state & ~HTTP_PA_CR_SKIP;;
|
parse = t->hreq.hdr_state & ~HTTP_PA_CR_SKIP;;
|
||||||
|
|
||||||
if (parse == HTTP_PA_EMPTY) {
|
if (parse == HTTP_PA_EMPTY) {
|
||||||
/* leading empty lines */
|
/* leading empty lines */
|
||||||
|
|
||||||
if (*req->lr == '\n') {
|
if (*req->lr == '\n') {
|
||||||
req->lr ++;
|
req->lr ++;
|
||||||
t->hdr_state = HTTP_PA_EMPTY;
|
t->hreq.hdr_state = HTTP_PA_EMPTY;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (*req->lr == '\r') {
|
else if (*req->lr == '\r') {
|
||||||
req->lr ++;
|
req->lr ++;
|
||||||
t->hdr_state = HTTP_PA_EMPTY | HTTP_PA_CR_SKIP | HTTP_PA_LF_EXP;
|
t->hreq.hdr_state = HTTP_PA_EMPTY | HTTP_PA_CR_SKIP | HTTP_PA_LF_EXP;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(stderr, "PA_EMPTY[0]: h=%d, lr=%d, r=%d\n", sol-req->data, req->lr-req->data, req->r-req->data);
|
FSM_PRINTF(stderr, "PA_EMPTY[0]: h=%d, lr=%d, r=%d\n",
|
||||||
|
sol - req->data, req->lr - req->data, req->r - req->data);
|
||||||
#if PARSE_PRESERVE_EMPTY_LINES
|
#if PARSE_PRESERVE_EMPTY_LINES
|
||||||
/* only skip empty leading lines, don't remove them */
|
/* only skip empty leading lines, don't remove them */
|
||||||
t->hdr_idx.v[0].len = req->lr - sol;
|
t->hreq.hdr_idx.v[0].len = req->lr - sol;
|
||||||
|
t->hreq.sor = t->hreq.hdr_idx.v[0].len;
|
||||||
#else
|
#else
|
||||||
/* remove empty leading lines, as recommended by
|
/* remove empty leading lines, as recommended by
|
||||||
* RFC2616. This takes a lot of time because we
|
* RFC2616. This takes a lot of time because we
|
||||||
@ -314,9 +315,10 @@ int process_cli(struct session *t)
|
|||||||
buffer_replace2(req, sol, req->lr, NULL, 0);
|
buffer_replace2(req, sol, req->lr, NULL, 0);
|
||||||
#endif
|
#endif
|
||||||
sol = req->lr;
|
sol = req->lr;
|
||||||
DPRINTF(stderr, "PA_EMPTY[1]: h=%d, lr=%d, r=%d\n", sol-req->data, req->lr-req->data, req->r-req->data);
|
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->hdr_state = HTTP_PA_START;
|
t->hreq.hdr_state = HTTP_PA_START;
|
||||||
#ifndef DEBUG_PARSE_NO_SPEEDUP
|
#ifndef DEBUG_PARSE_NO_SPEEDUP
|
||||||
/* we know that we still have one char available */
|
/* we know that we still have one char available */
|
||||||
goto parse_start;
|
goto parse_start;
|
||||||
@ -334,11 +336,11 @@ int process_cli(struct session *t)
|
|||||||
/* we have a CTL char */
|
/* we have a CTL char */
|
||||||
if (*req->lr == '\r') {
|
if (*req->lr == '\r') {
|
||||||
req->lr++;
|
req->lr++;
|
||||||
t->hdr_state = HTTP_PA_STRT_LF | HTTP_PA_CR_SKIP | HTTP_PA_LF_EXP;
|
t->hreq.hdr_state = HTTP_PA_STRT_LF | HTTP_PA_CR_SKIP | HTTP_PA_LF_EXP;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (*req->lr == '\n') {
|
else if (*req->lr == '\n') {
|
||||||
t->hdr_state = HTTP_PA_STRT_LF;
|
t->hreq.hdr_state = HTTP_PA_STRT_LF;
|
||||||
#ifndef DEBUG_PARSE_NO_SPEEDUP
|
#ifndef DEBUG_PARSE_NO_SPEEDUP
|
||||||
/* we know that we still have one char available */
|
/* we know that we still have one char available */
|
||||||
goto parse_strt_lf;
|
goto parse_strt_lf;
|
||||||
@ -346,7 +348,7 @@ int process_cli(struct session *t)
|
|||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
t->hdr_state = HTTP_PA_ERROR;
|
t->hreq.hdr_state = HTTP_PA_ERROR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} else if (parse == HTTP_PA_STRT_LF) {
|
} else if (parse == HTTP_PA_STRT_LF) {
|
||||||
@ -354,7 +356,7 @@ int process_cli(struct session *t)
|
|||||||
/* The LF validating the request line */
|
/* The LF validating the request line */
|
||||||
|
|
||||||
eol = req->lr;
|
eol = req->lr;
|
||||||
if (t->hdr_state & HTTP_PA_CR_SKIP)
|
if (t->hreq.hdr_state & HTTP_PA_CR_SKIP)
|
||||||
eol--; /* Get back to the CR */
|
eol--; /* Get back to the CR */
|
||||||
|
|
||||||
/* We have the complete start line between
|
/* We have the complete start line between
|
||||||
@ -390,8 +392,8 @@ int process_cli(struct session *t)
|
|||||||
|
|
||||||
/* 3: reference this line as the start line */
|
/* 3: reference this line as the start line */
|
||||||
if (hdr_idx_add(eol - sol, req->lr - eol,
|
if (hdr_idx_add(eol - sol, req->lr - eol,
|
||||||
&t->hdr_idx, t->hdr_idx.tail) < 0) {
|
&t->hreq.hdr_idx, t->hreq.hdr_idx.tail) < 0) {
|
||||||
t->hdr_state = HTTP_PA_ERROR;
|
t->hreq.hdr_state = HTTP_PA_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,7 +403,7 @@ int process_cli(struct session *t)
|
|||||||
* be able to distinguish between an empty line
|
* be able to distinguish between an empty line
|
||||||
* and a header.
|
* and a header.
|
||||||
*/
|
*/
|
||||||
t->hdr_state = HTTP_PA_HEADER;
|
t->hreq.hdr_state = HTTP_PA_HEADER;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
} else if (parse == HTTP_PA_HEADER) {
|
} else if (parse == HTTP_PA_HEADER) {
|
||||||
@ -416,19 +418,19 @@ int process_cli(struct session *t)
|
|||||||
|
|
||||||
/* we have a CTL char */
|
/* we have a CTL char */
|
||||||
if (*req->lr == '\r') {
|
if (*req->lr == '\r') {
|
||||||
t->hdr_state = HTTP_PA_HDR_LF | HTTP_PA_CR_SKIP | HTTP_PA_LF_EXP;
|
t->hreq.hdr_state = HTTP_PA_HDR_LF | HTTP_PA_CR_SKIP | HTTP_PA_LF_EXP;
|
||||||
req->lr++;
|
req->lr++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (*req->lr == '\n') {
|
else if (*req->lr == '\n') {
|
||||||
t->hdr_state = HTTP_PA_HDR_LF;
|
t->hreq.hdr_state = HTTP_PA_HDR_LF;
|
||||||
#ifndef DEBUG_PARSE_NO_SPEEDUP
|
#ifndef DEBUG_PARSE_NO_SPEEDUP
|
||||||
goto parse_hdr_lf;
|
goto parse_hdr_lf;
|
||||||
#else
|
#else
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
t->hdr_state = HTTP_PA_ERROR;
|
t->hreq.hdr_state = HTTP_PA_ERROR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} else if (parse == HTTP_PA_HDR_LF) {
|
} else if (parse == HTTP_PA_HDR_LF) {
|
||||||
@ -441,7 +443,7 @@ int process_cli(struct session *t)
|
|||||||
* which case it means the end of the request.
|
* which case it means the end of the request.
|
||||||
*/
|
*/
|
||||||
eol = req->lr;
|
eol = req->lr;
|
||||||
if (t->hdr_state & HTTP_PA_CR_SKIP)
|
if (t->hreq.hdr_state & HTTP_PA_CR_SKIP)
|
||||||
eol--; /* Get back to the CR */
|
eol--; /* Get back to the CR */
|
||||||
|
|
||||||
if (eol == sol) {
|
if (eol == sol) {
|
||||||
@ -451,7 +453,7 @@ int process_cli(struct session *t)
|
|||||||
* after the LF, so it is easy to append
|
* after the LF, so it is easy to append
|
||||||
* anything there.
|
* anything there.
|
||||||
*/
|
*/
|
||||||
t->hdr_state = HTTP_PA_LFLF;
|
t->hreq.hdr_state = HTTP_PA_LFLF;
|
||||||
#ifndef DEBUG_PARSE_NO_SPEEDUP
|
#ifndef DEBUG_PARSE_NO_SPEEDUP
|
||||||
goto parse_lflf;
|
goto parse_lflf;
|
||||||
#else
|
#else
|
||||||
@ -478,7 +480,7 @@ int process_cli(struct session *t)
|
|||||||
for (;eol < req->lr; eol++)
|
for (;eol < req->lr; eol++)
|
||||||
*eol = ' ';
|
*eol = ' ';
|
||||||
|
|
||||||
t->hdr_state = HTTP_PA_HDR_LWS;
|
t->hreq.hdr_state = HTTP_PA_HDR_LWS;
|
||||||
#ifndef DEBUG_PARSE_NO_SPEEDUP
|
#ifndef DEBUG_PARSE_NO_SPEEDUP
|
||||||
goto parse_hdr_lws;
|
goto parse_hdr_lws;
|
||||||
#else
|
#else
|
||||||
@ -517,10 +519,11 @@ int process_cli(struct session *t)
|
|||||||
if ((h->namelen + 2 <= eol - sol) &&
|
if ((h->namelen + 2 <= eol - sol) &&
|
||||||
(sol[h->namelen] == ':') &&
|
(sol[h->namelen] == ':') &&
|
||||||
(strncasecmp(sol, h->name, h->namelen) == 0)) {
|
(strncasecmp(sol, h->name, h->namelen) == 0)) {
|
||||||
if (t->req_cap[h->index] == NULL)
|
if (t->hreq.cap[h->index] == NULL)
|
||||||
t->req_cap[h->index] = pool_alloc_from(h->pool, h->len + 1);
|
t->hreq.cap[h->index] =
|
||||||
|
pool_alloc_from(h->pool, h->len + 1);
|
||||||
|
|
||||||
if (t->req_cap[h->index] == NULL) {
|
if (t->hreq.cap[h->index] == NULL) {
|
||||||
Alert("HTTP capture : out of memory.\n");
|
Alert("HTTP capture : out of memory.\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -529,8 +532,8 @@ int process_cli(struct session *t)
|
|||||||
if (len > h->len)
|
if (len > h->len)
|
||||||
len = h->len;
|
len = h->len;
|
||||||
|
|
||||||
memcpy(t->req_cap[h->index], sol + h->namelen + 2, len);
|
memcpy(t->hreq.cap[h->index], sol + h->namelen + 2, len);
|
||||||
t->req_cap[h->index][len]=0;
|
t->hreq.cap[h->index][len]=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -550,8 +553,8 @@ int process_cli(struct session *t)
|
|||||||
if (!delete_header) {
|
if (!delete_header) {
|
||||||
/* we insert it into the index */
|
/* we insert it into the index */
|
||||||
if (hdr_idx_add(eol - sol, req->lr - eol - 1,
|
if (hdr_idx_add(eol - sol, req->lr - eol - 1,
|
||||||
&t->hdr_idx, t->hdr_idx.tail) < 0) {
|
&t->hreq.hdr_idx, t->hreq.hdr_idx.tail) < 0) {
|
||||||
t->hdr_state = HTTP_PA_ERROR;
|
t->hreq.hdr_state = HTTP_PA_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -577,22 +580,22 @@ int process_cli(struct session *t)
|
|||||||
if (IS_CTL(*req->lr)) {
|
if (IS_CTL(*req->lr)) {
|
||||||
if (*eol == '\r') {
|
if (*eol == '\r') {
|
||||||
req->lr++;
|
req->lr++;
|
||||||
t->hdr_state = HTTP_PA_LFLF | HTTP_PA_LF_EXP;
|
t->hreq.hdr_state = HTTP_PA_LFLF | HTTP_PA_LF_EXP;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (*eol == '\n') {
|
else if (*eol == '\n') {
|
||||||
t->hdr_state = HTTP_PA_LFLF;
|
t->hreq.hdr_state = HTTP_PA_LFLF;
|
||||||
goto parse_lflf;
|
goto parse_lflf;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
t->hdr_state = HTTP_PA_ERROR;
|
t->hreq.hdr_state = HTTP_PA_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t->hdr_state = HTTP_PA_HEADER;
|
t->hreq.hdr_state = HTTP_PA_HEADER;
|
||||||
goto parse_inside_hdr;
|
goto parse_inside_hdr;
|
||||||
#else
|
#else
|
||||||
t->hdr_state = HTTP_PA_HEADER;
|
t->hreq.hdr_state = HTTP_PA_HEADER;
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -607,7 +610,7 @@ int process_cli(struct session *t)
|
|||||||
if (*req->lr == '\t')
|
if (*req->lr == '\t')
|
||||||
*req->lr = ' ';
|
*req->lr = ' ';
|
||||||
else if (*req->lr != ' ') {
|
else if (*req->lr != ' ') {
|
||||||
t->hdr_state = HTTP_PA_HEADER;
|
t->hreq.hdr_state = HTTP_PA_HEADER;
|
||||||
#ifndef DEBUG_PARSE_NO_SPEEDUP
|
#ifndef DEBUG_PARSE_NO_SPEEDUP
|
||||||
goto parse_inside_hdr;
|
goto parse_inside_hdr;
|
||||||
#else
|
#else
|
||||||
@ -635,14 +638,18 @@ int process_cli(struct session *t)
|
|||||||
|
|
||||||
} /* end of the "while(req->lr < req->r)" loop */
|
} /* end of the "while(req->lr < req->r)" loop */
|
||||||
|
|
||||||
DPRINTF(stderr, "END: hdr_st=0x%02x, hdr_used=%d hdr_tail=%d hdr_last=%d, h=%p, lr=%p, r=%p\n",
|
/* update the end of headers */
|
||||||
t->hdr_state, t->hdr_idx.used, t->hdr_idx.tail, t->hdr_idx.last, sol, req->lr, req->r);
|
t->hreq.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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now, let's catch bad requests.
|
* Now, let's catch bad requests.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (t->hdr_state == HTTP_PA_ERROR) {
|
if (t->hreq.hdr_state == HTTP_PA_ERROR) {
|
||||||
t->logs.status = 400;
|
t->logs.status = 400;
|
||||||
client_retnclose(t, t->fe->errmsg.len400, t->fe->errmsg.msg400);
|
client_retnclose(t, t->fe->errmsg.len400, t->fe->errmsg.msg400);
|
||||||
if (!(t->flags & SN_ERR_MASK))
|
if (!(t->flags & SN_ERR_MASK))
|
||||||
@ -662,7 +669,7 @@ int process_cli(struct session *t)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (t->hdr_state != HTTP_PA_LFLF) { /* Request not complete yet */
|
if (t->hreq.hdr_state != HTTP_PA_LFLF) { /* Request not complete yet */
|
||||||
|
|
||||||
/* 1: Since we are in header mode, if there's no space
|
/* 1: Since we are in header mode, if there's no space
|
||||||
* left for headers, we won't be able to free more
|
* left for headers, we won't be able to free more
|
||||||
@ -670,7 +677,7 @@ int process_cli(struct session *t)
|
|||||||
* must terminate it now.
|
* must terminate it now.
|
||||||
*/
|
*/
|
||||||
if (req->l >= req->rlim - req->data) {
|
if (req->l >= req->rlim - req->data) {
|
||||||
/* FIXME: check if hdr_state & mask < HTTP_PA_HEADER,
|
/* FIXME: check if hreq.hdr_state & mask < HTTP_PA_HEADER,
|
||||||
* and return Status 414 Request URI too long instead.
|
* and return Status 414 Request URI too long instead.
|
||||||
*/
|
*/
|
||||||
t->logs.status = 400;
|
t->logs.status = 400;
|
||||||
@ -737,8 +744,8 @@ int process_cli(struct session *t)
|
|||||||
|
|
||||||
/* It needs to look into the URI */
|
/* It needs to look into the URI */
|
||||||
if (t->be->appsession_name) {
|
if (t->be->appsession_name) {
|
||||||
sol = req->data + t->hdr_idx.v[0].len; /* start of the URI */
|
sol = req->data + t->hreq.sor; /* start of the URI */
|
||||||
eol = sol + t->hdr_idx.v[t->hdr_idx.v[0].next].len; /* end of the URI */
|
eol = sol + t->hreq.hdr_idx.v[t->hreq.hdr_idx.v[0].next].len; /* end of the URI */
|
||||||
get_srv_from_appsession(t, sol, eol);
|
get_srv_from_appsession(t, sol, eol);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -780,11 +787,11 @@ int process_cli(struct session *t)
|
|||||||
* check the method (needed for cookies).
|
* check the method (needed for cookies).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t->req_line.str = req->data + t->hdr_idx.v[0].len; /* start of the REQURI */
|
t->hreq.start.str = req->data + t->hreq.hdr_idx.v[0].len; /* start of the REQURI */
|
||||||
t->req_line.len = t->hdr_idx.v[t->hdr_idx.v[0].next].len; /* end of the REQURI */
|
t->hreq.start.len = t->hreq.hdr_idx.v[t->hreq.hdr_idx.v[0].next].len; /* end of the REQURI */
|
||||||
|
|
||||||
sol = t->req_line.str;
|
sol = t->hreq.start.str;
|
||||||
eol = sol + t->req_line.len;
|
eol = sol + t->hreq.start.len;
|
||||||
|
|
||||||
if (!memcmp(sol, "POST ", 5)) {
|
if (!memcmp(sol, "POST ", 5)) {
|
||||||
/* this is a POST request, which is not cacheable by default */
|
/* this is a POST request, which is not cacheable by default */
|
||||||
@ -814,16 +821,16 @@ int process_cli(struct session *t)
|
|||||||
* comparison.
|
* comparison.
|
||||||
*/
|
*/
|
||||||
if ((t->be->monitor_uri_len != 0) &&
|
if ((t->be->monitor_uri_len != 0) &&
|
||||||
(t->req_line.len >= t->be->monitor_uri_len)) {
|
(t->hreq.start.len >= t->be->monitor_uri_len)) {
|
||||||
char *p = t->req_line.str;
|
char *p = t->hreq.start.str;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
||||||
/* skip the method so that we accept any method */
|
/* skip the method so that we accept any method */
|
||||||
while (idx < t->req_line.len && p[idx] != ' ')
|
while (idx < t->hreq.start.len && p[idx] != ' ')
|
||||||
idx++;
|
idx++;
|
||||||
p += idx;
|
p += idx;
|
||||||
|
|
||||||
if (t->req_line.len - idx >= t->be->monitor_uri_len &&
|
if (t->hreq.start.len - idx >= t->be->monitor_uri_len &&
|
||||||
!memcmp(p, t->be->monitor_uri, t->be->monitor_uri_len)) {
|
!memcmp(p, t->be->monitor_uri, t->be->monitor_uri_len)) {
|
||||||
/*
|
/*
|
||||||
* We have found the monitor URI
|
* We have found the monitor URI
|
||||||
@ -844,10 +851,10 @@ int process_cli(struct session *t)
|
|||||||
* 6: check if the user tries to access a protected URI.
|
* 6: check if the user tries to access a protected URI.
|
||||||
*/
|
*/
|
||||||
if (t->fi->uri_auth != NULL
|
if (t->fi->uri_auth != NULL
|
||||||
&& t->req_line.len >= t->fi->uri_auth->uri_len + 4) { /* +4 for "GET /" */
|
&& t->hreq.start.len >= t->fi->uri_auth->uri_len + 4) { /* +4 for "GET /" */
|
||||||
if (!memcmp(t->req_line.str + 4,
|
if (!memcmp(t->hreq.start.str + 4,
|
||||||
t->fi->uri_auth->uri_prefix, t->fi->uri_auth->uri_len)
|
t->fi->uri_auth->uri_prefix, t->fi->uri_auth->uri_len)
|
||||||
&& !memcmp(t->req_line.str, "GET ", 4)) {
|
&& !memcmp(t->hreq.start.str, "GET ", 4)) {
|
||||||
struct user_auth *user;
|
struct user_auth *user;
|
||||||
int authenticated;
|
int authenticated;
|
||||||
char *h;
|
char *h;
|
||||||
@ -868,25 +875,27 @@ int process_cli(struct session *t)
|
|||||||
|
|
||||||
/* FIXME: this should move to an earlier place */
|
/* FIXME: this should move to an earlier place */
|
||||||
cur_idx = 0;
|
cur_idx = 0;
|
||||||
h = req->data + t->hdr_idx.v[0].len;
|
h = req->data + t->hreq.sor;
|
||||||
while ((cur_idx = t->hdr_idx.v[cur_idx].next)) {
|
while ((cur_idx = t->hreq.hdr_idx.v[cur_idx].next)) {
|
||||||
int len = t->hdr_idx.v[cur_idx].len;
|
int len = t->hreq.hdr_idx.v[cur_idx].len;
|
||||||
if (len > 14 &&
|
if (len > 14 &&
|
||||||
!strncasecmp("Authorization:", h, 14)) {
|
!strncasecmp("Authorization:", h, 14)) {
|
||||||
t->auth_hdr.str = h;
|
t->hreq.auth_hdr.str = h;
|
||||||
t->auth_hdr.len = len;
|
t->hreq.auth_hdr.len = len;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
h += len + t->hdr_idx.v[cur_idx].cr + 1;
|
h += len + t->hreq.hdr_idx.v[cur_idx].cr + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (t->auth_hdr.len < 21 || memcmp(t->auth_hdr.str + 14, " Basic ", 7))
|
if (t->hreq.auth_hdr.len < 21 ||
|
||||||
|
memcmp(t->hreq.auth_hdr.str + 14, " Basic ", 7))
|
||||||
user = NULL;
|
user = NULL;
|
||||||
|
|
||||||
while (user) {
|
while (user) {
|
||||||
if ((t->auth_hdr.len == user->user_len + 21)
|
if ((t->hreq.auth_hdr.len == user->user_len + 14 + 7)
|
||||||
&& !memcmp(t->auth_hdr.str+21, user->user_pwd, user->user_len)) {
|
&& !memcmp(t->hreq.auth_hdr.str + 14 + 7,
|
||||||
|
user->user_pwd, user->user_len)) {
|
||||||
authenticated = 1;
|
authenticated = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -920,26 +929,24 @@ int process_cli(struct session *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
// /*
|
||||||
* We will now have some data to append after the end of the
|
// * We will now have some data to append after the end of the
|
||||||
* request. Right now we do not have the end of request pointer
|
// * request. Right now we do not have the end of request pointer
|
||||||
* anymore, so we have to look for it.
|
// * anymore, so we have to look for it.
|
||||||
*/
|
// */
|
||||||
|
//
|
||||||
#if READABLE_PARSER_VERSION
|
//#if READABLE_PARSER_VERSION
|
||||||
for (sol = req->data + t->hdr_idx.v[cur_idx=0].len;
|
// for (sol = req->data + t->hreq.sor;
|
||||||
(cur_idx = t->hdr_idx.v[cur_idx].next);
|
// (cur_idx = t->hreq.hdr_idx.v[cur_idx].next);
|
||||||
sol += t->hdr_idx.v[cur_idx].len + t->hdr_idx.v[cur_idx]cr + 1);
|
// sol += t->hreq.hdr_idx.v[cur_idx].len + t->hreq.hdr_idx.v[cur_idx]cr + 1);
|
||||||
#else
|
//#else
|
||||||
sol = req->data;
|
// sol = req->data + t->hreq.sor;
|
||||||
cur_idx = 0;
|
// cur_idx = 0;
|
||||||
|
//
|
||||||
while ((sol += t->hdr_idx.v[cur_idx].len,
|
// while ((cur_idx = t->hreq.hdr_idx.v[cur_idx].next))
|
||||||
cur_idx = t->hdr_idx.v[cur_idx].next))
|
// sol += t->hreq.hdr_idx.v[cur_idx].len +
|
||||||
sol += t->hdr_idx.v[cur_idx].cr + 1;
|
// t->hreq.hdr_idx.v[cur_idx].cr + 1;
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
/* now sol points to the last LF/CRLF */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 7: add request headers
|
* 7: add request headers
|
||||||
@ -947,9 +954,12 @@ int process_cli(struct session *t)
|
|||||||
*/
|
*/
|
||||||
for (cur_hdr = 0; cur_hdr < t->fi->nb_reqadd; cur_hdr++) {
|
for (cur_hdr = 0; cur_hdr < t->fi->nb_reqadd; cur_hdr++) {
|
||||||
int len = sprintf(trash, "%s\r\n", t->fi->req_add[cur_hdr]);
|
int len = sprintf(trash, "%s\r\n", t->fi->req_add[cur_hdr]);
|
||||||
buffer_replace2(req, sol, sol, trash, len);
|
len = buffer_replace2(req, req->data + t->hreq.eoh,
|
||||||
if (hdr_idx_add(len - 2, 1, &t->hdr_idx, t->hdr_idx.tail) < 0) {
|
req->data + t->hreq.eoh, trash, len);
|
||||||
t->hdr_state = HTTP_PA_ERROR;
|
t->hreq.eoh += len;
|
||||||
|
|
||||||
|
if (hdr_idx_add(len - 2, 1, &t->hreq.hdr_idx, t->hreq.hdr_idx.tail) < 0) {
|
||||||
|
t->hreq.hdr_state = HTTP_PA_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -965,9 +975,12 @@ int process_cli(struct session *t)
|
|||||||
pn = (unsigned char *)&((struct sockaddr_in *)&t->cli_addr)->sin_addr;
|
pn = (unsigned char *)&((struct sockaddr_in *)&t->cli_addr)->sin_addr;
|
||||||
len = sprintf(trash, "X-Forwarded-For: %d.%d.%d.%d\r\n",
|
len = sprintf(trash, "X-Forwarded-For: %d.%d.%d.%d\r\n",
|
||||||
pn[0], pn[1], pn[2], pn[3]);
|
pn[0], pn[1], pn[2], pn[3]);
|
||||||
buffer_replace2(req, sol, sol, trash, len);
|
len = buffer_replace2(req, req->data + t->hreq.eoh,
|
||||||
if (hdr_idx_add(len - 2, 1, &t->hdr_idx, t->hdr_idx.tail) < 0) {
|
req->data + t->hreq.eoh, trash, len);
|
||||||
t->hdr_state = HTTP_PA_ERROR;
|
t->hreq.eoh += len;
|
||||||
|
|
||||||
|
if (hdr_idx_add(len - 2, 1, &t->hreq.hdr_idx, t->hreq.hdr_idx.tail) < 0) {
|
||||||
|
t->hreq.hdr_state = HTTP_PA_ERROR;
|
||||||
t->logs.status = 400;
|
t->logs.status = 400;
|
||||||
client_retnclose(t, t->fe->errmsg.len400, t->fe->errmsg.msg400);
|
client_retnclose(t, t->fe->errmsg.len400, t->fe->errmsg.msg400);
|
||||||
if (!(t->flags & SN_ERR_MASK))
|
if (!(t->flags & SN_ERR_MASK))
|
||||||
@ -984,9 +997,12 @@ int process_cli(struct session *t)
|
|||||||
(const void *)&((struct sockaddr_in6 *)(&t->cli_addr))->sin6_addr,
|
(const void *)&((struct sockaddr_in6 *)(&t->cli_addr))->sin6_addr,
|
||||||
pn, sizeof(pn));
|
pn, sizeof(pn));
|
||||||
len = sprintf(trash, "X-Forwarded-For: %s\r\n", pn);
|
len = sprintf(trash, "X-Forwarded-For: %s\r\n", pn);
|
||||||
buffer_replace2(req, sol, sol, trash, len);
|
len = buffer_replace2(req, req->data + t->hreq.eoh,
|
||||||
if (hdr_idx_add(len - 2, 1, &t->hdr_idx, t->hdr_idx.tail) < 0) {
|
req->data + t->hreq.eoh, trash, len);
|
||||||
t->hdr_state = HTTP_PA_ERROR;
|
t->hreq.eoh += len;
|
||||||
|
|
||||||
|
if (hdr_idx_add(len - 2, 1, &t->hreq.hdr_idx, t->hreq.hdr_idx.tail) < 0) {
|
||||||
|
t->hreq.hdr_state = HTTP_PA_ERROR;
|
||||||
t->logs.status = 400;
|
t->logs.status = 400;
|
||||||
client_retnclose(t, t->fe->errmsg.len400, t->fe->errmsg.msg400);
|
client_retnclose(t, t->fe->errmsg.len400, t->fe->errmsg.msg400);
|
||||||
if (!(t->flags & SN_ERR_MASK))
|
if (!(t->flags & SN_ERR_MASK))
|
||||||
@ -1005,9 +1021,13 @@ int process_cli(struct session *t)
|
|||||||
|
|
||||||
/* add a "connection: close" line if needed */
|
/* add a "connection: close" line if needed */
|
||||||
if (t->fe->options & PR_O_HTTP_CLOSE) {
|
if (t->fe->options & PR_O_HTTP_CLOSE) {
|
||||||
buffer_replace2(req, sol, sol, "Connection: close\r\n", 19);
|
int len;
|
||||||
if (hdr_idx_add(17, 1, &t->hdr_idx, t->hdr_idx.tail) < 0) {
|
len = buffer_replace2(req, req->data + t->hreq.eoh,
|
||||||
t->hdr_state = HTTP_PA_ERROR;
|
req->data + t->hreq.eoh, "Connection: close\r\n", 19);
|
||||||
|
t->hreq.eoh += len;
|
||||||
|
|
||||||
|
if (hdr_idx_add(17, 1, &t->hreq.hdr_idx, t->hreq.hdr_idx.tail) < 0) {
|
||||||
|
t->hreq.hdr_state = HTTP_PA_ERROR;
|
||||||
t->logs.status = 400;
|
t->logs.status = 400;
|
||||||
client_retnclose(t, t->fe->errmsg.len400, t->fe->errmsg.msg400);
|
client_retnclose(t, t->fe->errmsg.len400, t->fe->errmsg.msg400);
|
||||||
if (!(t->flags & SN_ERR_MASK))
|
if (!(t->flags & SN_ERR_MASK))
|
||||||
@ -1078,25 +1098,25 @@ int process_cli(struct session *t)
|
|||||||
fprintf(stderr, "t->flags=0x%08x\n", t->flags & (SN_CLALLOW|SN_CLDENY|SN_CLTARPIT));
|
fprintf(stderr, "t->flags=0x%08x\n", t->flags & (SN_CLALLOW|SN_CLDENY|SN_CLTARPIT));
|
||||||
|
|
||||||
fprintf(stderr, "sol=%d\n", sol - req->data);
|
fprintf(stderr, "sol=%d\n", sol - req->data);
|
||||||
sol = req->data + t->hdr_idx.v[0].len;
|
sol = req->data + t->hreq.sor;
|
||||||
cur_hdr = 0;
|
cur_hdr = 0;
|
||||||
|
|
||||||
cur_idx = t->hdr_idx.v[0].next;
|
cur_idx = t->hreq.hdr_idx.v[0].next;
|
||||||
cur_hdr = 1;
|
cur_hdr = 1;
|
||||||
|
|
||||||
while (cur_hdr < t->hdr_idx.used) {
|
while (cur_hdr < t->hreq.hdr_idx.used) {
|
||||||
eol = sol + t->hdr_idx.v[cur_idx].len + t->hdr_idx.v[cur_idx].cr + 1;
|
eol = sol + t->hreq.hdr_idx.v[cur_idx].len + t->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",
|
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,
|
req->lr - req->data, req->r - req->data,
|
||||||
cur_hdr, cur_idx,
|
cur_hdr, cur_idx,
|
||||||
sol - req->data,
|
sol - req->data,
|
||||||
sol - req->data + t->hdr_idx.v[cur_idx].len + t->hdr_idx.v[cur_idx].cr,
|
sol - req->data + t->hreq.hdr_idx.v[cur_idx].len + t->hreq.hdr_idx.v[cur_idx].cr,
|
||||||
t->hdr_idx.v[cur_idx].len,
|
t->hreq.hdr_idx.v[cur_idx].len,
|
||||||
t->hdr_idx.v[cur_idx].cr);
|
t->hreq.hdr_idx.v[cur_idx].cr);
|
||||||
write(2, sol, eol - sol);
|
write(2, sol, eol - sol);
|
||||||
|
|
||||||
sol = eol;
|
sol = eol;
|
||||||
cur_idx = t->hdr_idx.v[cur_idx].next;
|
cur_idx = t->hreq.hdr_idx.v[cur_idx].next;
|
||||||
cur_hdr++;
|
cur_hdr++;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -2966,11 +2986,11 @@ void apply_filters_to_session(struct session *t, struct buffer *req, struct hdr_
|
|||||||
* we start with the start line.
|
* we start with the start line.
|
||||||
*/
|
*/
|
||||||
old_idx = cur_idx = 0;
|
old_idx = cur_idx = 0;
|
||||||
cur_next = req->data + t->hdr_idx.v[0].len;
|
cur_next = req->data + t->hreq.sor;
|
||||||
abort_filt = 0;
|
abort_filt = 0;
|
||||||
|
|
||||||
while (!abort_filt && (cur_idx = t->hdr_idx.v[cur_idx].next)) {
|
while (!abort_filt && (cur_idx = t->hreq.hdr_idx.v[cur_idx].next)) {
|
||||||
struct hdr_idx_elem *cur_hdr = &t->hdr_idx.v[cur_idx];
|
struct hdr_idx_elem *cur_hdr = &t->hreq.hdr_idx.v[cur_idx];
|
||||||
cur_ptr = cur_next;
|
cur_ptr = cur_next;
|
||||||
cur_end = cur_ptr + cur_hdr->len;
|
cur_end = cur_ptr + cur_hdr->len;
|
||||||
cur_next = cur_end + cur_hdr->cr + 1;
|
cur_next = cur_end + cur_hdr->cr + 1;
|
||||||
@ -3007,6 +3027,7 @@ void apply_filters_to_session(struct session *t, struct buffer *req, struct hdr_
|
|||||||
cur_end += delta;
|
cur_end += delta;
|
||||||
cur_next += delta;
|
cur_next += delta;
|
||||||
cur_hdr->len += delta;
|
cur_hdr->len += delta;
|
||||||
|
t->hreq.eoh += delta;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACT_REMOVE:
|
case ACT_REMOVE:
|
||||||
@ -3015,8 +3036,9 @@ void apply_filters_to_session(struct session *t, struct buffer *req, struct hdr_
|
|||||||
cur_next += delta;
|
cur_next += delta;
|
||||||
|
|
||||||
/* FIXME: this should be a separate function */
|
/* FIXME: this should be a separate function */
|
||||||
t->hdr_idx.v[old_idx].next = cur_hdr->next;
|
t->hreq.eoh += delta;
|
||||||
t->hdr_idx.used--;
|
t->hreq.hdr_idx.v[old_idx].next = cur_hdr->next;
|
||||||
|
t->hreq.hdr_idx.used--;
|
||||||
cur_hdr->len = 0;
|
cur_hdr->len = 0;
|
||||||
|
|
||||||
cur_end = NULL; /* null-term has been rewritten */
|
cur_end = NULL; /* null-term has been rewritten */
|
||||||
@ -3076,13 +3098,13 @@ void manage_client_side_cookies(struct session *t, struct buffer *req)
|
|||||||
* we start with the start line.
|
* we start with the start line.
|
||||||
*/
|
*/
|
||||||
old_idx = cur_idx = 0;
|
old_idx = cur_idx = 0;
|
||||||
cur_next = req->data + t->hdr_idx.v[0].len;
|
cur_next = req->data + t->hreq.sor;
|
||||||
abort_filt = 0;
|
abort_filt = 0;
|
||||||
|
|
||||||
while ((cur_idx = t->hdr_idx.v[cur_idx].next)) {
|
while ((cur_idx = t->hreq.hdr_idx.v[cur_idx].next)) {
|
||||||
struct hdr_idx_elem *cur_hdr;
|
struct hdr_idx_elem *cur_hdr;
|
||||||
|
|
||||||
cur_hdr = &t->hdr_idx.v[cur_idx];
|
cur_hdr = &t->hreq.hdr_idx.v[cur_idx];
|
||||||
cur_ptr = cur_next;
|
cur_ptr = cur_next;
|
||||||
cur_end = cur_ptr + cur_hdr->len;
|
cur_end = cur_ptr + cur_hdr->len;
|
||||||
cur_next = cur_end + cur_hdr->cr + 1;
|
cur_next = cur_end + cur_hdr->cr + 1;
|
||||||
@ -3264,6 +3286,7 @@ void manage_client_side_cookies(struct session *t, struct buffer *req)
|
|||||||
cur_end += delta;
|
cur_end += delta;
|
||||||
cur_next += delta;
|
cur_next += delta;
|
||||||
cur_hdr->len += delta;
|
cur_hdr->len += delta;
|
||||||
|
t->hreq.eoh += delta;
|
||||||
|
|
||||||
del_cookie = del_colon = NULL;
|
del_cookie = del_colon = NULL;
|
||||||
app_cookies++; /* protect the header from deletion */
|
app_cookies++; /* protect the header from deletion */
|
||||||
@ -3289,6 +3312,7 @@ void manage_client_side_cookies(struct session *t, struct buffer *req)
|
|||||||
cur_end += delta;
|
cur_end += delta;
|
||||||
cur_next += delta;
|
cur_next += delta;
|
||||||
cur_hdr->len += delta;
|
cur_hdr->len += delta;
|
||||||
|
t->hreq.eoh += delta;
|
||||||
del_cookie = del_colon = NULL;
|
del_cookie = del_colon = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3371,17 +3395,17 @@ void manage_client_side_cookies(struct session *t, struct buffer *req)
|
|||||||
if (app_cookies) {
|
if (app_cookies) {
|
||||||
delta = buffer_replace2(req, del_colon, cur_end, NULL, 0);
|
delta = buffer_replace2(req, del_colon, cur_end, NULL, 0);
|
||||||
cur_end = del_colon;
|
cur_end = del_colon;
|
||||||
cur_next += delta;
|
|
||||||
cur_hdr->len += delta;
|
cur_hdr->len += delta;
|
||||||
} else {
|
} else {
|
||||||
delta = buffer_replace2(req, cur_ptr, cur_next, NULL, 0);
|
delta = buffer_replace2(req, cur_ptr, cur_next, NULL, 0);
|
||||||
cur_next += delta;
|
|
||||||
|
|
||||||
/* FIXME: this should be a separate function */
|
/* FIXME: this should be a separate function */
|
||||||
t->hdr_idx.v[old_idx].next = cur_hdr->next;
|
t->hreq.hdr_idx.v[old_idx].next = cur_hdr->next;
|
||||||
t->hdr_idx.used--;
|
t->hreq.hdr_idx.used--;
|
||||||
cur_hdr->len = 0;
|
cur_hdr->len = 0;
|
||||||
}
|
}
|
||||||
|
cur_next += delta;
|
||||||
|
t->hreq.eoh += delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* keep the link from this header to next one */
|
/* keep the link from this header to next one */
|
||||||
|
@ -47,13 +47,13 @@ void session_free(struct session *s)
|
|||||||
}
|
}
|
||||||
pool_free_to(s->fi->rsp_cap_pool, s->rsp_cap);
|
pool_free_to(s->fi->rsp_cap_pool, s->rsp_cap);
|
||||||
}
|
}
|
||||||
if (s->req_cap != NULL) {
|
if (s->hreq.cap != NULL) {
|
||||||
struct cap_hdr *h;
|
struct cap_hdr *h;
|
||||||
for (h = s->fi->req_cap; h; h = h->next) {
|
for (h = s->fi->req_cap; h; h = h->next) {
|
||||||
if (s->req_cap[h->index] != NULL)
|
if (s->hreq.cap[h->index] != NULL)
|
||||||
pool_free_to(h->pool, s->req_cap[h->index]);
|
pool_free_to(h->pool, s->hreq.cap[h->index]);
|
||||||
}
|
}
|
||||||
pool_free_to(s->fi->req_cap_pool, s->req_cap);
|
pool_free_to(s->fi->req_cap_pool, s->hreq.cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->logs.uri)
|
if (s->logs.uri)
|
||||||
|
Loading…
Reference in New Issue
Block a user