mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 14:21:25 +02:00
MEDIUM: proto_htx: Adapt htx_process_res_common to handle HTX messages
This commit is contained in:
parent
f76ebe8bc7
commit
fec7bd16de
@ -1726,16 +1726,13 @@ int htx_process_res_common(struct stream *s, struct channel *rep, int an_bit, st
|
|||||||
struct session *sess = s->sess;
|
struct session *sess = s->sess;
|
||||||
struct http_txn *txn = s->txn;
|
struct http_txn *txn = s->txn;
|
||||||
struct http_msg *msg = &txn->rsp;
|
struct http_msg *msg = &txn->rsp;
|
||||||
|
struct htx *htx;
|
||||||
struct proxy *cur_proxy;
|
struct proxy *cur_proxy;
|
||||||
struct cond_wordlist *wl;
|
struct cond_wordlist *wl;
|
||||||
enum rule_result ret = HTTP_RULE_RES_CONT;
|
enum rule_result ret = HTTP_RULE_RES_CONT;
|
||||||
|
|
||||||
// TODO: Disabled for now
|
if (unlikely(msg->msg_state < HTTP_MSG_BODY)) /* we need more data */
|
||||||
rep->analysers &= ~AN_RES_FLT_XFER_DATA;
|
return 0;
|
||||||
rep->analysers |= AN_RES_HTTP_XFER_BODY;
|
|
||||||
rep->analyse_exp = TICK_ETERNITY;
|
|
||||||
rep->analysers &= ~an_bit;
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
DPRINTF(stderr,"[%u] %s: stream=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%lu analysers=%02x\n",
|
DPRINTF(stderr,"[%u] %s: stream=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%lu analysers=%02x\n",
|
||||||
now_ms, __FUNCTION__,
|
now_ms, __FUNCTION__,
|
||||||
@ -1746,8 +1743,7 @@ int htx_process_res_common(struct stream *s, struct channel *rep, int an_bit, st
|
|||||||
ci_data(rep),
|
ci_data(rep),
|
||||||
rep->analysers);
|
rep->analysers);
|
||||||
|
|
||||||
if (unlikely(msg->msg_state < HTTP_MSG_BODY)) /* we need more data */
|
htx = htx_from_buf(&rep->buf);
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* The stats applet needs to adjust the Connection header but we don't
|
/* The stats applet needs to adjust the Connection header but we don't
|
||||||
* apply any filter there.
|
* apply any filter there.
|
||||||
@ -1785,7 +1781,7 @@ int htx_process_res_common(struct stream *s, struct channel *rep, int an_bit, st
|
|||||||
|
|
||||||
/* evaluate http-response rules */
|
/* evaluate http-response rules */
|
||||||
if (ret == HTTP_RULE_RES_CONT) {
|
if (ret == HTTP_RULE_RES_CONT) {
|
||||||
ret = http_res_get_intercept_rule(cur_proxy, &cur_proxy->http_res_rules, s);
|
ret = htx_res_get_intercept_rule(cur_proxy, &cur_proxy->http_res_rules, s);
|
||||||
|
|
||||||
if (ret == HTTP_RULE_RES_BADREQ)
|
if (ret == HTTP_RULE_RES_BADREQ)
|
||||||
goto return_srv_prx_502;
|
goto return_srv_prx_502;
|
||||||
@ -1805,26 +1801,8 @@ int htx_process_res_common(struct stream *s, struct channel *rep, int an_bit, st
|
|||||||
|
|
||||||
/* try headers filters */
|
/* try headers filters */
|
||||||
if (rule_set->rsp_exp != NULL) {
|
if (rule_set->rsp_exp != NULL) {
|
||||||
if (apply_filters_to_response(s, rep, rule_set) < 0) {
|
if (htx_apply_filters_to_response(s, rep, rule_set) < 0)
|
||||||
return_bad_resp:
|
goto return_bad_resp;
|
||||||
if (objt_server(s->target)) {
|
|
||||||
HA_ATOMIC_ADD(&objt_server(s->target)->counters.failed_resp, 1);
|
|
||||||
health_adjust(objt_server(s->target), HANA_STATUS_HTTP_RSP);
|
|
||||||
}
|
|
||||||
HA_ATOMIC_ADD(&s->be->be_counters.failed_resp, 1);
|
|
||||||
return_srv_prx_502:
|
|
||||||
rep->analysers &= AN_RES_FLT_END;
|
|
||||||
txn->status = 502;
|
|
||||||
s->logs.t_data = -1; /* was not a valid response */
|
|
||||||
s->si[1].flags |= SI_FL_NOLINGER;
|
|
||||||
channel_truncate(rep);
|
|
||||||
http_reply_and_close(s, txn->status, http_error_message(s));
|
|
||||||
if (!(s->flags & SF_ERR_MASK))
|
|
||||||
s->flags |= SF_ERR_PRXCOND;
|
|
||||||
if (!(s->flags & SF_FINST_MASK))
|
|
||||||
s->flags |= SF_FINST_H;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* has the response been denied ? */
|
/* has the response been denied ? */
|
||||||
@ -1836,12 +1814,12 @@ int htx_process_res_common(struct stream *s, struct channel *rep, int an_bit, st
|
|||||||
HA_ATOMIC_ADD(&sess->fe->fe_counters.denied_resp, 1);
|
HA_ATOMIC_ADD(&sess->fe->fe_counters.denied_resp, 1);
|
||||||
if (sess->listener->counters)
|
if (sess->listener->counters)
|
||||||
HA_ATOMIC_ADD(&sess->listener->counters->denied_resp, 1);
|
HA_ATOMIC_ADD(&sess->listener->counters->denied_resp, 1);
|
||||||
|
|
||||||
goto return_srv_prx_502;
|
goto return_srv_prx_502;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add response headers from the rule sets in the same order */
|
/* add response headers from the rule sets in the same order */
|
||||||
list_for_each_entry(wl, &rule_set->rsp_add, list) {
|
list_for_each_entry(wl, &rule_set->rsp_add, list) {
|
||||||
|
struct ist n, v;
|
||||||
if (txn->status < 200 && txn->status != 101)
|
if (txn->status < 200 && txn->status != 101)
|
||||||
break;
|
break;
|
||||||
if (wl->cond) {
|
if (wl->cond) {
|
||||||
@ -1852,7 +1830,9 @@ int htx_process_res_common(struct stream *s, struct channel *rep, int an_bit, st
|
|||||||
if (!ret)
|
if (!ret)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (unlikely(http_header_add_tail2(&txn->rsp, &txn->hdr_idx, wl->s, strlen(wl->s)) < 0))
|
|
||||||
|
http_parse_header(ist2(wl->s, strlen(wl->s)), &n, &v);
|
||||||
|
if (unlikely(!http_add_header(htx, n, v)))
|
||||||
goto return_bad_resp;
|
goto return_bad_resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1879,7 +1859,7 @@ int htx_process_res_common(struct stream *s, struct channel *rep, int an_bit, st
|
|||||||
* Now check for a server cookie.
|
* Now check for a server cookie.
|
||||||
*/
|
*/
|
||||||
if (s->be->cookie_name || sess->fe->capture_name || (s->be->options & PR_O_CHK_CACHE))
|
if (s->be->cookie_name || sess->fe->capture_name || (s->be->options & PR_O_CHK_CACHE))
|
||||||
manage_server_side_cookies(s, rep);
|
htx_manage_server_side_cookies(s, rep);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for cache-control or pragma headers if required.
|
* Check for cache-control or pragma headers if required.
|
||||||
@ -1907,11 +1887,11 @@ int htx_process_res_common(struct stream *s, struct channel *rep, int an_bit, st
|
|||||||
*/
|
*/
|
||||||
if (!objt_server(s->target)->cookie) {
|
if (!objt_server(s->target)->cookie) {
|
||||||
chunk_printf(&trash,
|
chunk_printf(&trash,
|
||||||
"Set-Cookie: %s=; Expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/",
|
"%s=; Expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/",
|
||||||
s->be->cookie_name);
|
s->be->cookie_name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
chunk_printf(&trash, "Set-Cookie: %s=%s", s->be->cookie_name, objt_server(s->target)->cookie);
|
chunk_printf(&trash, "%s=%s", s->be->cookie_name, objt_server(s->target)->cookie);
|
||||||
|
|
||||||
if (s->be->cookie_maxidle || s->be->cookie_maxlife) {
|
if (s->be->cookie_maxidle || s->be->cookie_maxlife) {
|
||||||
/* emit last_date, which is mandatory */
|
/* emit last_date, which is mandatory */
|
||||||
@ -1944,7 +1924,7 @@ int htx_process_res_common(struct stream *s, struct channel *rep, int an_bit, st
|
|||||||
if (s->be->ck_opts & PR_CK_SECURE)
|
if (s->be->ck_opts & PR_CK_SECURE)
|
||||||
chunk_appendf(&trash, "; Secure");
|
chunk_appendf(&trash, "; Secure");
|
||||||
|
|
||||||
if (unlikely(http_header_add_tail2(&txn->rsp, &txn->hdr_idx, trash.area, trash.data) < 0))
|
if (unlikely(!http_add_header(htx, ist("Set-Cookie"), ist2(trash.area, trash.data))))
|
||||||
goto return_bad_resp;
|
goto return_bad_resp;
|
||||||
|
|
||||||
txn->flags &= ~TX_SCK_MASK;
|
txn->flags &= ~TX_SCK_MASK;
|
||||||
@ -1963,8 +1943,7 @@ int htx_process_res_common(struct stream *s, struct channel *rep, int an_bit, st
|
|||||||
|
|
||||||
txn->flags &= ~TX_CACHEABLE & ~TX_CACHE_COOK;
|
txn->flags &= ~TX_CACHEABLE & ~TX_CACHE_COOK;
|
||||||
|
|
||||||
if (unlikely(http_header_add_tail2(&txn->rsp, &txn->hdr_idx,
|
if (unlikely(!http_add_header(htx, ist("Cache-control"), ist("private"))))
|
||||||
"Cache-control: private", 22) < 0))
|
|
||||||
goto return_bad_resp;
|
goto return_bad_resp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1997,7 +1976,7 @@ int htx_process_res_common(struct stream *s, struct channel *rep, int an_bit, st
|
|||||||
goto return_srv_prx_502;
|
goto return_srv_prx_502;
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
/* Always enter in the body analyzer */
|
/* Always enter in the body analyzer */
|
||||||
rep->analysers &= ~AN_RES_FLT_XFER_DATA;
|
rep->analysers &= ~AN_RES_FLT_XFER_DATA;
|
||||||
rep->analysers |= AN_RES_HTTP_XFER_BODY;
|
rep->analysers |= AN_RES_HTTP_XFER_BODY;
|
||||||
@ -2008,11 +1987,30 @@ int htx_process_res_common(struct stream *s, struct channel *rep, int an_bit, st
|
|||||||
*/
|
*/
|
||||||
if (!LIST_ISEMPTY(&sess->fe->logformat) && !(s->logs.logwait & LW_BYTES)) {
|
if (!LIST_ISEMPTY(&sess->fe->logformat) && !(s->logs.logwait & LW_BYTES)) {
|
||||||
s->logs.t_close = s->logs.t_data; /* to get a valid end date */
|
s->logs.t_close = s->logs.t_data; /* to get a valid end date */
|
||||||
s->logs.bytes_out = txn->rsp.eoh;
|
s->logs.bytes_out = htx->data;
|
||||||
s->do_log(s);
|
s->do_log(s);
|
||||||
s->logs.bytes_out = 0;
|
s->logs.bytes_out = 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
return_bad_resp:
|
||||||
|
if (objt_server(s->target)) {
|
||||||
|
HA_ATOMIC_ADD(&objt_server(s->target)->counters.failed_resp, 1);
|
||||||
|
health_adjust(objt_server(s->target), HANA_STATUS_HTTP_RSP);
|
||||||
|
}
|
||||||
|
HA_ATOMIC_ADD(&s->be->be_counters.failed_resp, 1);
|
||||||
|
|
||||||
|
return_srv_prx_502:
|
||||||
|
rep->analysers &= AN_RES_FLT_END;
|
||||||
|
txn->status = 502;
|
||||||
|
s->logs.t_data = -1; /* was not a valid response */
|
||||||
|
s->si[1].flags |= SI_FL_NOLINGER;
|
||||||
|
htx_reply_and_close(s, txn->status, http_error_message(s));
|
||||||
|
if (!(s->flags & SF_ERR_MASK))
|
||||||
|
s->flags |= SF_ERR_PRXCOND;
|
||||||
|
if (!(s->flags & SF_FINST_MASK))
|
||||||
|
s->flags |= SF_FINST_H;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is an analyser which forwards response body (including chunk
|
/* This function is an analyser which forwards response body (including chunk
|
||||||
|
Loading…
x
Reference in New Issue
Block a user