mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 23:27:04 +02:00
[CLEANUP] move http_txn out of session.h
The http_txn structure definitions moved to proto_http.h
This commit is contained in:
parent
5416b36b43
commit
3bac9ffe20
@ -24,6 +24,9 @@
|
||||
|
||||
#include <common/config.h>
|
||||
|
||||
#include <types/buffers.h>
|
||||
#include <types/hdr_idx.h>
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
|
@ -32,11 +32,11 @@
|
||||
#include <common/mini-clist.h>
|
||||
|
||||
#include <types/buffers.h>
|
||||
#include <types/proto_http.h>
|
||||
#include <types/proxy.h>
|
||||
#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) */
|
||||
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 : "<BADREQ>" : "";
|
||||
uri = (log & LW_REQ) ? txn->uri ? txn->uri : "<BADREQ>" : "";
|
||||
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] : '-',
|
||||
|
@ -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 <ptr>.
|
||||
*/
|
||||
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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user