From: Willy Tarreau Date: Sun, 18 Mar 2007 16:31:28 +0000 (+0100) Subject: [CLEANUP] move http_txn out of session.h X-Git-Tag: v1.3.8~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3bac9ffe209389947acfea05c6dfee30c9cbb80c;p=thirdparty%2Fhaproxy.git [CLEANUP] move http_txn out of session.h The http_txn structure definitions moved to proto_http.h --- diff --git a/include/types/proto_http.h b/include/types/proto_http.h index a00c88035d..58a89ffceb 100644 --- a/include/types/proto_http.h +++ b/include/types/proto_http.h @@ -24,6 +24,9 @@ #include +#include +#include + /* * FIXME: break this into HTTP state and TCP socket state. * See server.h for the other end. @@ -135,6 +138,74 @@ enum { DATA_ST_PX_FIN, }; +/* Known HTTP methods */ +typedef enum { + HTTP_METH_NONE = 0, + HTTP_METH_OPTIONS, + HTTP_METH_GET, + HTTP_METH_HEAD, + HTTP_METH_POST, + HTTP_METH_PUT, + HTTP_METH_DELETE, + HTTP_METH_TRACE, + HTTP_METH_CONNECT, + HTTP_METH_OTHER, +} http_meth_t; + +/* This is an HTTP message, as described in RFC2616. It can be either a request + * message or a response message. + * + * The values there are a little bit obscure, because their meaning can change + * during the parsing : + * + * - som (Start of Message) : relative offset in the buffer of first byte of + * the request being processed or parsed. Reset to + * zero during accept(). + * - eoh (End of Headers) : relative offset in the buffer of first byte that + * is not part of a completely processed header. + * During parsing, it points to last header seen + * for states after START. + * - eol (End of Line) : relative offset in the buffer of the first byte + * which marks the end of the line (LF or CRLF). + */ +struct http_msg { + int msg_state; /* where we are in the current message parsing */ + char *sol, *eol; /* start of line, end of line */ + int som; /* Start Of Message, relative to buffer */ + int col, sov; /* current header: colon, start of value */ + int eoh; /* End Of Headers, relative to buffer */ + char **cap; /* array of captured headers (may be NULL) */ + union { /* useful start line pointers, relative to buffer */ + struct { + int l; /* request line length (not including CR) */ + int m_l; /* METHOD length (method starts at ->som) */ + int u, u_l; /* URI, length */ + int v, v_l; /* VERSION, length */ + } rq; /* request line : field, length */ + struct { + int l; /* status line length (not including CR) */ + int v_l; /* VERSION length (version starts at ->som) */ + int c, c_l; /* CODE, length */ + int r, r_l; /* REASON, length */ + } st; /* status line : field, length */ + } sl; /* start line */ +}; + +/* This is an HTTP transaction. It contains both a request message and a + * response message (which can be empty). + */ +struct http_txn { + http_meth_t meth; /* HTTP method */ + struct hdr_idx hdr_idx; /* array of header indexes (max: MAX_HTTP_HDR) */ + struct chunk auth_hdr; /* points to 'Authorization:' header */ + struct http_msg req, rsp; /* HTTP request and response messages */ + + char *uri; /* first line if log needed, NULL otherwise */ + char *cli_cookie; /* cookie presented by the client, in capture mode */ + char *srv_cookie; /* cookie presented by the server, in capture mode */ + int status; /* HTTP status from the server, negative if from proxy */ +}; + #endif /* _TYPES_PROTO_HTTP_H */ diff --git a/include/types/session.h b/include/types/session.h index 885c3ffb5f..99f8819b83 100644 --- a/include/types/session.h +++ b/include/types/session.h @@ -32,11 +32,11 @@ #include #include +#include #include #include #include #include -#include /* various session flags, bits values 0x01 to 0x20 (shift 0) */ @@ -100,71 +100,6 @@ #define SN_SELF_GEN 0x02000000 /* the proxy generates data for the client (eg: stats) */ #define SN_CLTARPIT 0x04000000 /* the session is tarpitted (anti-dos) */ -typedef enum { - HTTP_METH_NONE = 0, - HTTP_METH_OPTIONS, - HTTP_METH_GET, - HTTP_METH_HEAD, - HTTP_METH_POST, - HTTP_METH_PUT, - HTTP_METH_DELETE, - HTTP_METH_TRACE, - HTTP_METH_CONNECT, - HTTP_METH_OTHER, -} http_meth_t; - -/* 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. - * - * The values there are a little bit obscure, because their meaning can change - * during the parsing : - * - * - som (Start of Message) : relative offset in the buffer of first byte of - * the request being processed or parsed. Reset to - * zero during accept(). - * - eoh (End of Headers) : relative offset in the buffer of first byte that - * is not part of a completely processed header. - * During parsing, it points to last header seen - * for states after START. - * - eol (End of Line) : relative offset in the buffer of the first byte - * which marks the end of the line (LF or CRLF). - */ -struct http_msg { - int msg_state; /* where we are in the current message parsing */ - char *sol, *eol; /* start of line, end of line */ - int som; /* Start Of Message, relative to buffer */ - int col, sov; /* current header: colon, start of value */ - int eoh; /* End Of Headers, relative to buffer */ - char **cap; /* array of captured headers (may be NULL) */ - union { /* useful start line pointers, relative to buffer */ - struct { - int l; /* request line length (not including CR) */ - int m_l; /* METHOD length (method starts at ->som) */ - int u, u_l; /* URI, length */ - int v, v_l; /* VERSION, length */ - } rq; /* request line : field, length */ - struct { - int l; /* status line length (not including CR) */ - int v_l; /* VERSION length (version starts at ->som) */ - int c, c_l; /* CODE, length */ - int r, r_l; /* REASON, length */ - } st; /* status line : field, length */ - } sl; /* start line */ -}; - -/* This is an HTTP transaction. It contains both a request message and a - * response message (which can be empty). - */ -struct http_txn { - http_meth_t meth; /* HTTP method */ - struct hdr_idx hdr_idx; /* array of header indexes (max: MAX_HTTP_HDR) */ - 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() ! @@ -194,13 +129,9 @@ struct session { long t_queue; /* delay before the session gets out of the connect queue, -1 if never occurs */ long t_connect; /* delay before the connect() to the server succeeds, -1 if never occurs */ long t_data; /* delay before the first data byte from the server ... */ - unsigned long t_close; /* total session duration */ + unsigned long t_close; /* total session duration */ unsigned long srv_queue_size; /* number of sessions waiting for a connect slot on this server at accept() time (in direct assignment) */ unsigned long prx_queue_size; /* overall number of sessions waiting for a connect slot on this instance at accept() time */ - char *uri; /* first line if log needed, NULL otherwise */ - char *cli_cookie; /* cookie presented by the client, in capture mode */ - char *srv_cookie; /* cookie presented by the server, in capture mode */ - int status; /* HTTP status from the server, negative if from proxy */ long long bytes_in; /* number of bytes transferred from the client to the server */ long long bytes_out; /* number of bytes transferred from the server to the client */ } logs; diff --git a/src/client.c b/src/client.c index 1f0fdc6b54..1a1ccca18a 100644 --- a/src/client.c +++ b/src/client.c @@ -185,10 +185,6 @@ int event_accept(int fd) { s->logs.t_connect = -1; s->logs.t_data = -1; s->logs.t_close = 0; - s->logs.uri = NULL; - s->logs.cli_cookie = NULL; - s->logs.srv_cookie = NULL; - s->logs.status = -1; s->logs.bytes_in = s->logs.bytes_out = 0; s->logs.prx_queue_size = 0; /* we get the number of pending conns before us */ s->logs.srv_queue_size = 0; /* we will get this number soon */ @@ -205,6 +201,11 @@ int event_accept(int fd) { txn->hdr_idx.size = txn->hdr_idx.used = 0; if (p->mode == PR_MODE_HTTP) { + txn->uri = NULL; + txn->cli_cookie = NULL; + txn->srv_cookie = NULL; + txn->status = -1; + txn->req.msg_state = HTTP_MSG_RQBEFORE; /* at the very beginning of the request */ txn->req.sol = txn->req.eol = NULL; txn->req.som = txn->req.eoh = 0; /* relative to the buffer */ diff --git a/src/log.c b/src/log.c index 9317acd0b6..a67a46d58f 100644 --- a/src/log.c +++ b/src/log.c @@ -321,7 +321,7 @@ void sess_log(struct session *s) (const void *)&((struct sockaddr_in6 *)(&s->cli_addr))->sin6_addr, pn, sizeof(pn)); - uri = (log & LW_REQ) ? s->logs.uri ? s->logs.uri : "" : ""; + uri = (log & LW_REQ) ? txn->uri ? txn->uri : "" : ""; pxid = be->beprm->id; srv = (tolog & LW_SVID) ? (s->data_source != DATA_SRC_STATS) ? @@ -404,10 +404,10 @@ void sess_log(struct session *s) (s->logs.t_connect >= 0) ? s->logs.t_connect - s->logs.t_queue : -1, (s->logs.t_data >= 0) ? s->logs.t_data - s->logs.t_connect : -1, (tolog & LW_BYTES) ? "" : "+", s->logs.t_close, - s->logs.status, + txn->status, (tolog & LW_BYTES) ? "" : "+", s->logs.bytes_in, - s->logs.cli_cookie ? s->logs.cli_cookie : "-", - s->logs.srv_cookie ? s->logs.srv_cookie : "-", + txn->cli_cookie ? txn->cli_cookie : "-", + txn->srv_cookie ? txn->srv_cookie : "-", sess_term_cond[(s->flags & SN_ERR_MASK) >> SN_ERR_SHIFT], sess_fin_state[(s->flags & SN_FINST_MASK) >> SN_FINST_SHIFT], (be->beprm->options & PR_O_COOK_ANY) ? sess_cookie[(s->flags & SN_CK_MASK) >> SN_CK_SHIFT] : '-', diff --git a/src/proto_http.c b/src/proto_http.c index ea9ebc8513..7ed6929819 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -362,7 +362,7 @@ void srv_close_with_err(struct session *t, int err, int finst, { t->srv_state = SV_STCLOSE; if (status > 0 && msg) { - t->logs.status = status; + t->txn.status = status; if (t->fe->mode == PR_MODE_HTTP) client_return(t, msg); } @@ -1287,7 +1287,7 @@ int process_cli(struct session *t) /* 3: has the read timeout expired ? */ else if (unlikely(tv_cmp2_ms(&req->rex, &now) <= 0)) { /* read timeout : give up with an error message. */ - t->logs.status = 408; + txn->status = 408; client_retnclose(t, error_message(t, HTTP_ERR_408)); t->fe->failed_req++; if (!(t->flags & SN_ERR_MASK)) @@ -1338,7 +1338,7 @@ int process_cli(struct session *t) * We have found the monitor URI */ t->flags |= SN_MONITOR; - t->logs.status = 200; + txn->status = 200; client_retnclose(t, &http_200_chunk); goto return_prx_cond; } @@ -1350,13 +1350,13 @@ int process_cli(struct session *t) */ if (unlikely(t->logs.logwait & LW_REQ)) { /* we have a complete HTTP request that we must log */ - if ((t->logs.uri = pool_alloc(requri)) != NULL) { + if ((txn->uri = pool_alloc(requri)) != NULL) { int urilen = msg->sl.rq.l; if (urilen >= REQURI_LEN) urilen = REQURI_LEN - 1; - memcpy(t->logs.uri, &req->data[msg->som], urilen); - t->logs.uri[urilen] = 0; + memcpy(txn->uri, &req->data[msg->som], urilen); + txn->uri[urilen] = 0; if (!(t->logs.logwait &= ~LW_REQ)) sess_log(t); @@ -1452,7 +1452,7 @@ int process_cli(struct session *t) /* has the request been denied ? */ if (t->flags & SN_CLDENY) { /* no need to go further */ - t->logs.status = 403; + txn->status = 403; /* let's log the request time */ t->logs.t_request = tv_diff(&t->logs.tv_accept, &now); client_retnclose(t, error_message(t, HTTP_ERR_403)); @@ -1681,7 +1681,7 @@ int process_cli(struct session *t) return_bad_req: /* let's centralize all bad requests */ txn->req.msg_state = HTTP_MSG_ERROR; - t->logs.status = 400; + txn->status = 400; client_retnclose(t, error_message(t, HTTP_ERR_400)); t->fe->failed_req++; return_prx_cond: @@ -2297,7 +2297,7 @@ int process_srv(struct session *t) } t->be->failed_resp++; t->srv_state = SV_STCLOSE; - t->logs.status = 502; + txn->status = 502; client_return(t, error_message(t, HTTP_ERR_502)); if (!(t->flags & SN_ERR_MASK)) t->flags |= SN_ERR_SRVCL; @@ -2340,7 +2340,7 @@ int process_srv(struct session *t) } t->be->failed_resp++; t->srv_state = SV_STCLOSE; - t->logs.status = 504; + txn->status = 504; client_return(t, error_message(t, HTTP_ERR_504)); if (!(t->flags & SN_ERR_MASK)) t->flags |= SN_ERR_SRVTO; @@ -2447,9 +2447,9 @@ int process_srv(struct session *t) */ t->logs.logwait &= ~LW_RESP; - t->logs.status = strl2ui(rep->data + msg->sl.st.c, msg->sl.st.c_l); + txn->status = strl2ui(rep->data + msg->sl.st.c, msg->sl.st.c_l); - switch (t->logs.status) { + switch (txn->status) { case 200: case 203: case 206: @@ -2512,7 +2512,7 @@ int process_srv(struct session *t) tv_eternity(&req->wex); fd_delete(t->srv_fd); t->srv_state = SV_STCLOSE; - t->logs.status = 502; + txn->status = 502; client_return(t, error_message(t, HTTP_ERR_502)); if (!(t->flags & SN_ERR_MASK)) t->flags |= SN_ERR_PRXCOND; @@ -3058,7 +3058,7 @@ int produce_content(struct session *s) } else { /* unknown data source */ - s->logs.status = 500; + s->txn.status = 500; client_retnclose(s, error_message(s, HTTP_ERR_500)); if (!(s->flags & SN_ERR_MASK)) s->flags |= SN_ERR_PRXCOND; @@ -3099,7 +3099,7 @@ int produce_content_stats(struct session *s) "Content-Type: text/html\r\n" "\r\n"); - s->logs.status = 200; + s->txn.status = 200; client_retnclose(s, &msg); // send the start of the response. msg.len = 0; @@ -3291,7 +3291,7 @@ int produce_content_stats(struct session *s) default: /* unknown state ! */ - s->logs.status = 500; + s->txn.status = 500; client_retnclose(s, error_message(s, HTTP_ERR_500)); if (!(s->flags & SN_ERR_MASK)) s->flags |= SN_ERR_PRXCOND; @@ -3954,18 +3954,18 @@ void manage_client_side_cookies(struct session *t, struct buffer *req) else { /* first, let's see if we want to capture it */ if (t->fe->fiprm->capture_name != NULL && - t->logs.cli_cookie == NULL && + txn->cli_cookie == NULL && (p4 - p1 >= t->fe->fiprm->capture_namelen) && memcmp(p1, t->fe->fiprm->capture_name, t->fe->fiprm->capture_namelen) == 0) { int log_len = p4 - p1; - if ((t->logs.cli_cookie = pool_alloc(capture)) == NULL) { + if ((txn->cli_cookie = pool_alloc(capture)) == NULL) { Alert("HTTP logging : out of memory.\n"); } else { if (log_len > t->fe->fiprm->capture_len) log_len = t->fe->fiprm->capture_len; - memcpy(t->logs.cli_cookie, p1, log_len); - t->logs.cli_cookie[log_len] = 0; + memcpy(txn->cli_cookie, p1, log_len); + txn->cli_cookie[log_len] = 0; } } @@ -4345,7 +4345,7 @@ int apply_filter_to_sts_line(struct session *t, struct buffer *rtr, struct hdr_e /* we have a full respnse and we know that we have either a CR * or an LF at . */ - t->logs.status = strl2ui(rtr->data + txn->rsp.sl.st.c, txn->rsp.sl.st.c_l); + txn->status = strl2ui(rtr->data + txn->rsp.sl.st.c, txn->rsp.sl.st.c_l); hdr_idx_set_start(&txn->hdr_idx, txn->rsp.sl.rq.l, *cur_end == '\r'); /* there is no point trying this regex on headers */ return 1; @@ -4487,19 +4487,19 @@ void manage_server_side_cookies(struct session *t, struct buffer *rtr) /* first, let's see if we want to capture it */ if (t->be->fiprm->capture_name != NULL && - t->logs.srv_cookie == NULL && + txn->srv_cookie == NULL && (p4 - p1 >= t->be->fiprm->capture_namelen) && memcmp(p1, t->be->fiprm->capture_name, t->be->fiprm->capture_namelen) == 0) { int log_len = p4 - p1; - if ((t->logs.srv_cookie = pool_alloc(capture)) == NULL) { + if ((txn->srv_cookie = pool_alloc(capture)) == NULL) { Alert("HTTP logging : out of memory.\n"); } if (log_len > t->be->fiprm->capture_len) log_len = t->be->fiprm->capture_len; - memcpy(t->logs.srv_cookie, p1, log_len); - t->logs.srv_cookie[log_len] = 0; + memcpy(txn->srv_cookie, p1, log_len); + txn->srv_cookie[log_len] = 0; } /* now check if we need to process it for persistence */ @@ -4862,7 +4862,7 @@ int stats_check_uri_auth(struct session *t, struct proxy *backend) /* no need to go further */ msg.str = trash; msg.len = sprintf(trash, HTTP_401_fmt, uri_auth->auth_realm); - t->logs.status = 401; + txn->status = 401; client_retnclose(t, &msg); if (!(t->flags & SN_ERR_MASK)) t->flags |= SN_ERR_PRXCOND; diff --git a/src/session.c b/src/session.c index 523a96a4f7..3ea4b9221f 100644 --- a/src/session.c +++ b/src/session.c @@ -62,12 +62,12 @@ void session_free(struct session *s) pool_free_to(s->fe->fiprm->req_cap_pool, txn->req.cap); } - if (s->logs.uri) - pool_free(requri, s->logs.uri); - if (s->logs.cli_cookie) - pool_free(capture, s->logs.cli_cookie); - if (s->logs.srv_cookie) - pool_free(capture, s->logs.srv_cookie); + if (txn->uri) + pool_free(requri, txn->uri); + if (txn->cli_cookie) + pool_free(capture, txn->cli_cookie); + if (txn->srv_cookie) + pool_free(capture, txn->srv_cookie); pool_free(session, s); }