mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-11 03:31:36 +00:00
CLEANUP: proto_http: Move remaining code from proto_http.c to proto_htx.c
This commit is contained in:
parent
eb2754bef8
commit
a8a46e2041
162
src/proto_http.c
162
src/proto_http.c
@ -74,168 +74,6 @@
|
|||||||
#include <proto/pattern.h>
|
#include <proto/pattern.h>
|
||||||
#include <proto/vars.h>
|
#include <proto/vars.h>
|
||||||
|
|
||||||
DECLARE_POOL(pool_head_http_txn, "http_txn", sizeof(struct http_txn));
|
|
||||||
DECLARE_POOL(pool_head_uniqueid, "uniqueid", UNIQUEID_LEN);
|
|
||||||
|
|
||||||
struct pool_head *pool_head_requri = NULL;
|
|
||||||
struct pool_head *pool_head_capture = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
/* Allocate a new HTTP transaction for stream <s> unless there is one already.
|
|
||||||
* In case of allocation failure, everything allocated is freed and NULL is
|
|
||||||
* returned. Otherwise the new transaction is assigned to the stream and
|
|
||||||
* returned.
|
|
||||||
*/
|
|
||||||
struct http_txn *http_alloc_txn(struct stream *s)
|
|
||||||
{
|
|
||||||
struct http_txn *txn = s->txn;
|
|
||||||
|
|
||||||
if (txn)
|
|
||||||
return txn;
|
|
||||||
|
|
||||||
txn = pool_alloc(pool_head_http_txn);
|
|
||||||
if (!txn)
|
|
||||||
return txn;
|
|
||||||
|
|
||||||
s->txn = txn;
|
|
||||||
return txn;
|
|
||||||
}
|
|
||||||
|
|
||||||
void http_txn_reset_req(struct http_txn *txn)
|
|
||||||
{
|
|
||||||
txn->req.flags = 0;
|
|
||||||
txn->req.msg_state = HTTP_MSG_RQBEFORE; /* at the very beginning of the request */
|
|
||||||
}
|
|
||||||
|
|
||||||
void http_txn_reset_res(struct http_txn *txn)
|
|
||||||
{
|
|
||||||
txn->rsp.flags = 0;
|
|
||||||
txn->rsp.msg_state = HTTP_MSG_RPBEFORE; /* at the very beginning of the response */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize a new HTTP transaction for stream <s>. It is assumed that all
|
|
||||||
* the required fields are properly allocated and that we only need to (re)init
|
|
||||||
* them. This should be used before processing any new request.
|
|
||||||
*/
|
|
||||||
void http_init_txn(struct stream *s)
|
|
||||||
{
|
|
||||||
struct http_txn *txn = s->txn;
|
|
||||||
struct conn_stream *cs = objt_cs(s->si[0].end);
|
|
||||||
|
|
||||||
txn->flags = ((cs && cs->flags & CS_FL_NOT_FIRST)
|
|
||||||
? (TX_NOT_FIRST|TX_WAIT_NEXT_RQ)
|
|
||||||
: 0);
|
|
||||||
txn->status = -1;
|
|
||||||
*(unsigned int *)txn->cache_hash = 0;
|
|
||||||
|
|
||||||
txn->cookie_first_date = 0;
|
|
||||||
txn->cookie_last_date = 0;
|
|
||||||
|
|
||||||
txn->srv_cookie = NULL;
|
|
||||||
txn->cli_cookie = NULL;
|
|
||||||
txn->uri = NULL;
|
|
||||||
|
|
||||||
http_txn_reset_req(txn);
|
|
||||||
http_txn_reset_res(txn);
|
|
||||||
|
|
||||||
txn->req.chn = &s->req;
|
|
||||||
txn->rsp.chn = &s->res;
|
|
||||||
|
|
||||||
txn->auth.method = HTTP_AUTH_UNKNOWN;
|
|
||||||
|
|
||||||
vars_init(&s->vars_txn, SCOPE_TXN);
|
|
||||||
vars_init(&s->vars_reqres, SCOPE_REQ);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* to be used at the end of a transaction */
|
|
||||||
void http_end_txn(struct stream *s)
|
|
||||||
{
|
|
||||||
struct http_txn *txn = s->txn;
|
|
||||||
struct proxy *fe = strm_fe(s);
|
|
||||||
|
|
||||||
/* these ones will have been dynamically allocated */
|
|
||||||
pool_free(pool_head_requri, txn->uri);
|
|
||||||
pool_free(pool_head_capture, txn->cli_cookie);
|
|
||||||
pool_free(pool_head_capture, txn->srv_cookie);
|
|
||||||
pool_free(pool_head_uniqueid, s->unique_id);
|
|
||||||
|
|
||||||
s->unique_id = NULL;
|
|
||||||
txn->uri = NULL;
|
|
||||||
txn->srv_cookie = NULL;
|
|
||||||
txn->cli_cookie = NULL;
|
|
||||||
|
|
||||||
if (s->req_cap) {
|
|
||||||
struct cap_hdr *h;
|
|
||||||
for (h = fe->req_cap; h; h = h->next)
|
|
||||||
pool_free(h->pool, s->req_cap[h->index]);
|
|
||||||
memset(s->req_cap, 0, fe->nb_req_cap * sizeof(void *));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->res_cap) {
|
|
||||||
struct cap_hdr *h;
|
|
||||||
for (h = fe->rsp_cap; h; h = h->next)
|
|
||||||
pool_free(h->pool, s->res_cap[h->index]);
|
|
||||||
memset(s->res_cap, 0, fe->nb_rsp_cap * sizeof(void *));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!LIST_ISEMPTY(&s->vars_txn.head))
|
|
||||||
vars_prune(&s->vars_txn, s->sess, s);
|
|
||||||
if (!LIST_ISEMPTY(&s->vars_reqres.head))
|
|
||||||
vars_prune(&s->vars_reqres, s->sess, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* to be used at the end of a transaction to prepare a new one */
|
|
||||||
void http_reset_txn(struct stream *s)
|
|
||||||
{
|
|
||||||
http_end_txn(s);
|
|
||||||
http_init_txn(s);
|
|
||||||
|
|
||||||
/* reinitialise the current rule list pointer to NULL. We are sure that
|
|
||||||
* any rulelist match the NULL pointer.
|
|
||||||
*/
|
|
||||||
s->current_rule_list = NULL;
|
|
||||||
|
|
||||||
s->be = strm_fe(s);
|
|
||||||
s->logs.logwait = strm_fe(s)->to_log;
|
|
||||||
s->logs.level = 0;
|
|
||||||
stream_del_srv_conn(s);
|
|
||||||
s->target = NULL;
|
|
||||||
/* re-init store persistence */
|
|
||||||
s->store_count = 0;
|
|
||||||
s->uniq_id = _HA_ATOMIC_XADD(&global.req_count, 1);
|
|
||||||
|
|
||||||
s->req.flags |= CF_READ_DONTWAIT; /* one read is usually enough */
|
|
||||||
|
|
||||||
/* We must trim any excess data from the response buffer, because we
|
|
||||||
* may have blocked an invalid response from a server that we don't
|
|
||||||
* want to accidently forward once we disable the analysers, nor do
|
|
||||||
* we want those data to come along with next response. A typical
|
|
||||||
* example of such data would be from a buggy server responding to
|
|
||||||
* a HEAD with some data, or sending more than the advertised
|
|
||||||
* content-length.
|
|
||||||
*/
|
|
||||||
if (unlikely(ci_data(&s->res)))
|
|
||||||
b_set_data(&s->res.buf, co_data(&s->res));
|
|
||||||
|
|
||||||
/* Now we can realign the response buffer */
|
|
||||||
c_realign_if_empty(&s->res);
|
|
||||||
|
|
||||||
s->req.rto = strm_fe(s)->timeout.client;
|
|
||||||
s->req.wto = TICK_ETERNITY;
|
|
||||||
|
|
||||||
s->res.rto = TICK_ETERNITY;
|
|
||||||
s->res.wto = strm_fe(s)->timeout.client;
|
|
||||||
|
|
||||||
s->req.rex = TICK_ETERNITY;
|
|
||||||
s->req.wex = TICK_ETERNITY;
|
|
||||||
s->req.analyse_exp = TICK_ETERNITY;
|
|
||||||
s->res.rex = TICK_ETERNITY;
|
|
||||||
s->res.wex = TICK_ETERNITY;
|
|
||||||
s->res.analyse_exp = TICK_ETERNITY;
|
|
||||||
s->si[1].hcto = TICK_ETERNITY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Local variables:
|
* Local variables:
|
||||||
* c-indent-level: 8
|
* c-indent-level: 8
|
||||||
|
163
src/proto_htx.c
163
src/proto_htx.c
@ -33,9 +33,14 @@
|
|||||||
#include <proto/stream.h>
|
#include <proto/stream.h>
|
||||||
#include <proto/stream_interface.h>
|
#include <proto/stream_interface.h>
|
||||||
#include <proto/stats.h>
|
#include <proto/stats.h>
|
||||||
|
#include <proto/vars.h>
|
||||||
|
|
||||||
extern const char *stat_status_codes[];
|
extern const char *stat_status_codes[];
|
||||||
|
|
||||||
|
struct pool_head *pool_head_requri = NULL;
|
||||||
|
struct pool_head *pool_head_capture = NULL;
|
||||||
|
|
||||||
|
|
||||||
static void htx_end_request(struct stream *s);
|
static void htx_end_request(struct stream *s);
|
||||||
static void htx_end_response(struct stream *s);
|
static void htx_end_response(struct stream *s);
|
||||||
|
|
||||||
@ -5790,6 +5795,164 @@ static void htx_debug_hdr(const char *dir, struct stream *s, const struct ist n,
|
|||||||
shut_your_big_mouth_gcc(write(1, trash.area, trash.data));
|
shut_your_big_mouth_gcc(write(1, trash.area, trash.data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate a new HTTP transaction for stream <s> unless there is one already.
|
||||||
|
* In case of allocation failure, everything allocated is freed and NULL is
|
||||||
|
* returned. Otherwise the new transaction is assigned to the stream and
|
||||||
|
* returned.
|
||||||
|
*/
|
||||||
|
struct http_txn *http_alloc_txn(struct stream *s)
|
||||||
|
{
|
||||||
|
struct http_txn *txn = s->txn;
|
||||||
|
|
||||||
|
if (txn)
|
||||||
|
return txn;
|
||||||
|
|
||||||
|
txn = pool_alloc(pool_head_http_txn);
|
||||||
|
if (!txn)
|
||||||
|
return txn;
|
||||||
|
|
||||||
|
s->txn = txn;
|
||||||
|
return txn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void http_txn_reset_req(struct http_txn *txn)
|
||||||
|
{
|
||||||
|
txn->req.flags = 0;
|
||||||
|
txn->req.msg_state = HTTP_MSG_RQBEFORE; /* at the very beginning of the request */
|
||||||
|
}
|
||||||
|
|
||||||
|
void http_txn_reset_res(struct http_txn *txn)
|
||||||
|
{
|
||||||
|
txn->rsp.flags = 0;
|
||||||
|
txn->rsp.msg_state = HTTP_MSG_RPBEFORE; /* at the very beginning of the response */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize a new HTTP transaction for stream <s>. It is assumed that all
|
||||||
|
* the required fields are properly allocated and that we only need to (re)init
|
||||||
|
* them. This should be used before processing any new request.
|
||||||
|
*/
|
||||||
|
void http_init_txn(struct stream *s)
|
||||||
|
{
|
||||||
|
struct http_txn *txn = s->txn;
|
||||||
|
struct conn_stream *cs = objt_cs(s->si[0].end);
|
||||||
|
|
||||||
|
txn->flags = ((cs && cs->flags & CS_FL_NOT_FIRST)
|
||||||
|
? (TX_NOT_FIRST|TX_WAIT_NEXT_RQ)
|
||||||
|
: 0);
|
||||||
|
txn->status = -1;
|
||||||
|
*(unsigned int *)txn->cache_hash = 0;
|
||||||
|
|
||||||
|
txn->cookie_first_date = 0;
|
||||||
|
txn->cookie_last_date = 0;
|
||||||
|
|
||||||
|
txn->srv_cookie = NULL;
|
||||||
|
txn->cli_cookie = NULL;
|
||||||
|
txn->uri = NULL;
|
||||||
|
|
||||||
|
http_txn_reset_req(txn);
|
||||||
|
http_txn_reset_res(txn);
|
||||||
|
|
||||||
|
txn->req.chn = &s->req;
|
||||||
|
txn->rsp.chn = &s->res;
|
||||||
|
|
||||||
|
txn->auth.method = HTTP_AUTH_UNKNOWN;
|
||||||
|
|
||||||
|
vars_init(&s->vars_txn, SCOPE_TXN);
|
||||||
|
vars_init(&s->vars_reqres, SCOPE_REQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* to be used at the end of a transaction */
|
||||||
|
void http_end_txn(struct stream *s)
|
||||||
|
{
|
||||||
|
struct http_txn *txn = s->txn;
|
||||||
|
struct proxy *fe = strm_fe(s);
|
||||||
|
|
||||||
|
/* these ones will have been dynamically allocated */
|
||||||
|
pool_free(pool_head_requri, txn->uri);
|
||||||
|
pool_free(pool_head_capture, txn->cli_cookie);
|
||||||
|
pool_free(pool_head_capture, txn->srv_cookie);
|
||||||
|
pool_free(pool_head_uniqueid, s->unique_id);
|
||||||
|
|
||||||
|
s->unique_id = NULL;
|
||||||
|
txn->uri = NULL;
|
||||||
|
txn->srv_cookie = NULL;
|
||||||
|
txn->cli_cookie = NULL;
|
||||||
|
|
||||||
|
if (s->req_cap) {
|
||||||
|
struct cap_hdr *h;
|
||||||
|
for (h = fe->req_cap; h; h = h->next)
|
||||||
|
pool_free(h->pool, s->req_cap[h->index]);
|
||||||
|
memset(s->req_cap, 0, fe->nb_req_cap * sizeof(void *));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->res_cap) {
|
||||||
|
struct cap_hdr *h;
|
||||||
|
for (h = fe->rsp_cap; h; h = h->next)
|
||||||
|
pool_free(h->pool, s->res_cap[h->index]);
|
||||||
|
memset(s->res_cap, 0, fe->nb_rsp_cap * sizeof(void *));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!LIST_ISEMPTY(&s->vars_txn.head))
|
||||||
|
vars_prune(&s->vars_txn, s->sess, s);
|
||||||
|
if (!LIST_ISEMPTY(&s->vars_reqres.head))
|
||||||
|
vars_prune(&s->vars_reqres, s->sess, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* to be used at the end of a transaction to prepare a new one */
|
||||||
|
void http_reset_txn(struct stream *s)
|
||||||
|
{
|
||||||
|
http_end_txn(s);
|
||||||
|
http_init_txn(s);
|
||||||
|
|
||||||
|
/* reinitialise the current rule list pointer to NULL. We are sure that
|
||||||
|
* any rulelist match the NULL pointer.
|
||||||
|
*/
|
||||||
|
s->current_rule_list = NULL;
|
||||||
|
|
||||||
|
s->be = strm_fe(s);
|
||||||
|
s->logs.logwait = strm_fe(s)->to_log;
|
||||||
|
s->logs.level = 0;
|
||||||
|
stream_del_srv_conn(s);
|
||||||
|
s->target = NULL;
|
||||||
|
/* re-init store persistence */
|
||||||
|
s->store_count = 0;
|
||||||
|
s->uniq_id = _HA_ATOMIC_XADD(&global.req_count, 1);
|
||||||
|
|
||||||
|
s->req.flags |= CF_READ_DONTWAIT; /* one read is usually enough */
|
||||||
|
|
||||||
|
/* We must trim any excess data from the response buffer, because we
|
||||||
|
* may have blocked an invalid response from a server that we don't
|
||||||
|
* want to accidently forward once we disable the analysers, nor do
|
||||||
|
* we want those data to come along with next response. A typical
|
||||||
|
* example of such data would be from a buggy server responding to
|
||||||
|
* a HEAD with some data, or sending more than the advertised
|
||||||
|
* content-length.
|
||||||
|
*/
|
||||||
|
if (unlikely(ci_data(&s->res)))
|
||||||
|
b_set_data(&s->res.buf, co_data(&s->res));
|
||||||
|
|
||||||
|
/* Now we can realign the response buffer */
|
||||||
|
c_realign_if_empty(&s->res);
|
||||||
|
|
||||||
|
s->req.rto = strm_fe(s)->timeout.client;
|
||||||
|
s->req.wto = TICK_ETERNITY;
|
||||||
|
|
||||||
|
s->res.rto = TICK_ETERNITY;
|
||||||
|
s->res.wto = strm_fe(s)->timeout.client;
|
||||||
|
|
||||||
|
s->req.rex = TICK_ETERNITY;
|
||||||
|
s->req.wex = TICK_ETERNITY;
|
||||||
|
s->req.analyse_exp = TICK_ETERNITY;
|
||||||
|
s->res.rex = TICK_ETERNITY;
|
||||||
|
s->res.wex = TICK_ETERNITY;
|
||||||
|
s->res.analyse_exp = TICK_ETERNITY;
|
||||||
|
s->si[1].hcto = TICK_ETERNITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DECLARE_POOL(pool_head_http_txn, "http_txn", sizeof(struct http_txn));
|
||||||
|
DECLARE_POOL(pool_head_uniqueid, "uniqueid", UNIQUEID_LEN);
|
||||||
|
|
||||||
__attribute__((constructor))
|
__attribute__((constructor))
|
||||||
static void __htx_protocol_init(void)
|
static void __htx_protocol_init(void)
|
||||||
|
Loading…
Reference in New Issue
Block a user