mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-28 17:21:32 +02:00
CLEANUP: http: remove the useless "if (1)" inherited from version 1.4
This block has been enclosed inside an "if (1)" statement when migrating 1.3 to 1.4 to avoid a massive reindent. Let's get rid of it now.
This commit is contained in:
parent
f1fd9dc8fb
commit
5897567273
458
src/proto_http.c
458
src/proto_http.c
@ -5856,196 +5856,50 @@ int http_process_res_common(struct session *s, struct channel *rep, int an_bit,
|
|||||||
/* we want to have the response time before we start processing it */
|
/* we want to have the response time before we start processing it */
|
||||||
s->logs.t_data = tv_ms_elapsed(&s->logs.tv_accept, &now);
|
s->logs.t_data = tv_ms_elapsed(&s->logs.tv_accept, &now);
|
||||||
|
|
||||||
if (1) {
|
/*
|
||||||
/*
|
* We will have to evaluate the filters.
|
||||||
* 3: we will have to evaluate the filters.
|
* As opposed to version 1.2, now they will be evaluated in the
|
||||||
* As opposed to version 1.2, now they will be evaluated in the
|
* filters order and not in the header order. This means that
|
||||||
* filters order and not in the header order. This means that
|
* each filter has to be validated among all headers.
|
||||||
* each filter has to be validated among all headers.
|
*
|
||||||
*
|
* Filters are tried with ->be first, then with ->fe if it is
|
||||||
* Filters are tried with ->be first, then with ->fe if it is
|
* different from ->be.
|
||||||
* different from ->be.
|
*/
|
||||||
*/
|
|
||||||
|
|
||||||
cur_proxy = s->be;
|
cur_proxy = s->be;
|
||||||
while (1) {
|
while (1) {
|
||||||
struct proxy *rule_set = cur_proxy;
|
struct proxy *rule_set = cur_proxy;
|
||||||
|
|
||||||
/* evaluate http-response rules */
|
/* evaluate http-response rules */
|
||||||
if (!http_res_last_rule)
|
if (!http_res_last_rule)
|
||||||
http_res_last_rule = http_res_get_intercept_rule(cur_proxy, &cur_proxy->http_res_rules, s, txn);
|
http_res_last_rule = http_res_get_intercept_rule(cur_proxy, &cur_proxy->http_res_rules, s, txn);
|
||||||
|
|
||||||
/* 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 (apply_filters_to_response(s, rep, rule_set) < 0) {
|
||||||
return_bad_resp:
|
return_bad_resp:
|
||||||
if (objt_server(s->target)) {
|
if (objt_server(s->target)) {
|
||||||
objt_server(s->target)->counters.failed_resp++;
|
objt_server(s->target)->counters.failed_resp++;
|
||||||
health_adjust(objt_server(s->target), HANA_STATUS_HTTP_RSP);
|
health_adjust(objt_server(s->target), HANA_STATUS_HTTP_RSP);
|
||||||
}
|
|
||||||
s->be->be_counters.failed_resp++;
|
|
||||||
return_srv_prx_502:
|
|
||||||
rep->analysers = 0;
|
|
||||||
txn->status = 502;
|
|
||||||
s->logs.t_data = -1; /* was not a valid response */
|
|
||||||
rep->prod->flags |= SI_FL_NOLINGER;
|
|
||||||
bi_erase(rep);
|
|
||||||
stream_int_retnclose(rep->cons, http_error_message(s, HTTP_ERR_502));
|
|
||||||
if (!(s->flags & SN_ERR_MASK))
|
|
||||||
s->flags |= SN_ERR_PRXCOND;
|
|
||||||
if (!(s->flags & SN_FINST_MASK))
|
|
||||||
s->flags |= SN_FINST_H;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
s->be->be_counters.failed_resp++;
|
||||||
|
return_srv_prx_502:
|
||||||
/* has the response been denied ? */
|
rep->analysers = 0;
|
||||||
if (txn->flags & TX_SVDENY) {
|
txn->status = 502;
|
||||||
if (objt_server(s->target))
|
s->logs.t_data = -1; /* was not a valid response */
|
||||||
objt_server(s->target)->counters.failed_secu++;
|
rep->prod->flags |= SI_FL_NOLINGER;
|
||||||
|
bi_erase(rep);
|
||||||
s->be->be_counters.denied_resp++;
|
stream_int_retnclose(rep->cons, http_error_message(s, HTTP_ERR_502));
|
||||||
s->fe->fe_counters.denied_resp++;
|
if (!(s->flags & SN_ERR_MASK))
|
||||||
if (s->listener->counters)
|
s->flags |= SN_ERR_PRXCOND;
|
||||||
s->listener->counters->denied_resp++;
|
if (!(s->flags & SN_FINST_MASK))
|
||||||
|
s->flags |= SN_FINST_H;
|
||||||
goto return_srv_prx_502;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
/* add response headers from the rule sets in the same order */
|
|
||||||
list_for_each_entry(wl, &rule_set->rsp_add, list) {
|
|
||||||
if (txn->status < 200)
|
|
||||||
break;
|
|
||||||
if (wl->cond) {
|
|
||||||
int ret = acl_exec_cond(wl->cond, px, s, txn, SMP_OPT_DIR_RES|SMP_OPT_FINAL);
|
|
||||||
ret = acl_pass(ret);
|
|
||||||
if (((struct acl_cond *)wl->cond)->pol == ACL_COND_UNLESS)
|
|
||||||
ret = !ret;
|
|
||||||
if (!ret)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (unlikely(http_header_add_tail(&txn->rsp, &txn->hdr_idx, wl->s) < 0))
|
|
||||||
goto return_bad_resp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check whether we're already working on the frontend */
|
|
||||||
if (cur_proxy == s->fe)
|
|
||||||
break;
|
|
||||||
cur_proxy = s->fe;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(txn->status < 200))
|
|
||||||
goto skip_header_mangling;
|
|
||||||
|
|
||||||
/* we don't have any 1xx status code now */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 4: check for server cookie.
|
|
||||||
*/
|
|
||||||
if (s->be->cookie_name || s->be->appsession_name || s->fe->capture_name ||
|
|
||||||
(s->be->options & PR_O_CHK_CACHE))
|
|
||||||
manage_server_side_cookies(s, rep);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 5: check for cache-control or pragma headers if required.
|
|
||||||
*/
|
|
||||||
if ((s->be->options & PR_O_CHK_CACHE) || (s->be->ck_opts & PR_CK_NOC))
|
|
||||||
check_response_for_cacheability(s, rep);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 6: add server cookie in the response if needed
|
|
||||||
*/
|
|
||||||
if (objt_server(s->target) && (s->be->ck_opts & PR_CK_INS) &&
|
|
||||||
!((txn->flags & TX_SCK_FOUND) && (s->be->ck_opts & PR_CK_PSV)) &&
|
|
||||||
(!(s->flags & SN_DIRECT) ||
|
|
||||||
((s->be->cookie_maxidle || txn->cookie_last_date) &&
|
|
||||||
(!txn->cookie_last_date || (txn->cookie_last_date - date.tv_sec) < 0)) ||
|
|
||||||
(s->be->cookie_maxlife && !txn->cookie_first_date) || // set the first_date
|
|
||||||
(!s->be->cookie_maxlife && txn->cookie_first_date)) && // remove the first_date
|
|
||||||
(!(s->be->ck_opts & PR_CK_POST) || (txn->meth == HTTP_METH_POST)) &&
|
|
||||||
!(s->flags & SN_IGNORE_PRST)) {
|
|
||||||
/* the server is known, it's not the one the client requested, or the
|
|
||||||
* cookie's last seen date needs to be refreshed. We have to
|
|
||||||
* insert a set-cookie here, except if we want to insert only on POST
|
|
||||||
* requests and this one isn't. Note that servers which don't have cookies
|
|
||||||
* (eg: some backup servers) will return a full cookie removal request.
|
|
||||||
*/
|
|
||||||
if (!objt_server(s->target)->cookie) {
|
|
||||||
chunk_printf(&trash,
|
|
||||||
"Set-Cookie: %s=; Expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/",
|
|
||||||
s->be->cookie_name);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
chunk_printf(&trash, "Set-Cookie: %s=%s", s->be->cookie_name, objt_server(s->target)->cookie);
|
|
||||||
|
|
||||||
if (s->be->cookie_maxidle || s->be->cookie_maxlife) {
|
|
||||||
/* emit last_date, which is mandatory */
|
|
||||||
trash.str[trash.len++] = COOKIE_DELIM_DATE;
|
|
||||||
s30tob64((date.tv_sec+3) >> 2, trash.str + trash.len);
|
|
||||||
trash.len += 5;
|
|
||||||
|
|
||||||
if (s->be->cookie_maxlife) {
|
|
||||||
/* emit first_date, which is either the original one or
|
|
||||||
* the current date.
|
|
||||||
*/
|
|
||||||
trash.str[trash.len++] = COOKIE_DELIM_DATE;
|
|
||||||
s30tob64(txn->cookie_first_date ?
|
|
||||||
txn->cookie_first_date >> 2 :
|
|
||||||
(date.tv_sec+3) >> 2, trash.str + trash.len);
|
|
||||||
trash.len += 5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chunk_appendf(&trash, "; path=/");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->be->cookie_domain)
|
|
||||||
chunk_appendf(&trash, "; domain=%s", s->be->cookie_domain);
|
|
||||||
|
|
||||||
if (s->be->ck_opts & PR_CK_HTTPONLY)
|
|
||||||
chunk_appendf(&trash, "; HttpOnly");
|
|
||||||
|
|
||||||
if (s->be->ck_opts & PR_CK_SECURE)
|
|
||||||
chunk_appendf(&trash, "; Secure");
|
|
||||||
|
|
||||||
if (unlikely(http_header_add_tail2(&txn->rsp, &txn->hdr_idx, trash.str, trash.len) < 0))
|
|
||||||
goto return_bad_resp;
|
|
||||||
|
|
||||||
txn->flags &= ~TX_SCK_MASK;
|
|
||||||
if (objt_server(s->target)->cookie && (s->flags & SN_DIRECT))
|
|
||||||
/* the server did not change, only the date was updated */
|
|
||||||
txn->flags |= TX_SCK_UPDATED;
|
|
||||||
else
|
|
||||||
txn->flags |= TX_SCK_INSERTED;
|
|
||||||
|
|
||||||
/* Here, we will tell an eventual cache on the client side that we don't
|
|
||||||
* want it to cache this reply because HTTP/1.0 caches also cache cookies !
|
|
||||||
* Some caches understand the correct form: 'no-cache="set-cookie"', but
|
|
||||||
* others don't (eg: apache <= 1.3.26). So we use 'private' instead.
|
|
||||||
*/
|
|
||||||
if ((s->be->ck_opts & PR_CK_NOC) && (txn->flags & TX_CACHEABLE)) {
|
|
||||||
|
|
||||||
txn->flags &= ~TX_CACHEABLE & ~TX_CACHE_COOK;
|
|
||||||
|
|
||||||
if (unlikely(http_header_add_tail2(&txn->rsp, &txn->hdr_idx,
|
|
||||||
"Cache-control: private", 22) < 0))
|
|
||||||
goto return_bad_resp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* has the response been denied ? */
|
||||||
* 7: check if result will be cacheable with a cookie.
|
if (txn->flags & TX_SVDENY) {
|
||||||
* We'll block the response if security checks have caught
|
|
||||||
* nasty things such as a cacheable cookie.
|
|
||||||
*/
|
|
||||||
if (((txn->flags & (TX_CACHEABLE | TX_CACHE_COOK | TX_SCK_PRESENT)) ==
|
|
||||||
(TX_CACHEABLE | TX_CACHE_COOK | TX_SCK_PRESENT)) &&
|
|
||||||
(s->be->options & PR_O_CHK_CACHE)) {
|
|
||||||
|
|
||||||
/* we're in presence of a cacheable response containing
|
|
||||||
* a set-cookie header. We'll block it as requested by
|
|
||||||
* the 'checkcache' option, and send an alert.
|
|
||||||
*/
|
|
||||||
if (objt_server(s->target))
|
if (objt_server(s->target))
|
||||||
objt_server(s->target)->counters.failed_secu++;
|
objt_server(s->target)->counters.failed_secu++;
|
||||||
|
|
||||||
@ -6054,72 +5908,202 @@ int http_process_res_common(struct session *s, struct channel *rep, int an_bit,
|
|||||||
if (s->listener->counters)
|
if (s->listener->counters)
|
||||||
s->listener->counters->denied_resp++;
|
s->listener->counters->denied_resp++;
|
||||||
|
|
||||||
Alert("Blocking cacheable cookie in response from instance %s, server %s.\n",
|
|
||||||
s->be->id, objt_server(s->target) ? objt_server(s->target)->id : "<dispatch>");
|
|
||||||
send_log(s->be, LOG_ALERT,
|
|
||||||
"Blocking cacheable cookie in response from instance %s, server %s.\n",
|
|
||||||
s->be->id, objt_server(s->target) ? objt_server(s->target)->id : "<dispatch>");
|
|
||||||
goto return_srv_prx_502;
|
goto return_srv_prx_502;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* add response headers from the rule sets in the same order */
|
||||||
* 8: adjust "Connection: close" or "Connection: keep-alive" if needed.
|
list_for_each_entry(wl, &rule_set->rsp_add, list) {
|
||||||
* If an "Upgrade" token is found, the header is left untouched in order
|
if (txn->status < 200)
|
||||||
* not to have to deal with some client bugs : some of them fail an upgrade
|
break;
|
||||||
* if anything but "Upgrade" is present in the Connection header.
|
if (wl->cond) {
|
||||||
*/
|
int ret = acl_exec_cond(wl->cond, px, s, txn, SMP_OPT_DIR_RES|SMP_OPT_FINAL);
|
||||||
if (!(txn->flags & TX_HDR_CONN_UPG) &&
|
ret = acl_pass(ret);
|
||||||
(((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN) ||
|
if (((struct acl_cond *)wl->cond)->pol == ACL_COND_UNLESS)
|
||||||
((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL ||
|
ret = !ret;
|
||||||
(s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL))) {
|
if (!ret)
|
||||||
unsigned int want_flags = 0;
|
continue;
|
||||||
|
|
||||||
if ((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL ||
|
|
||||||
(txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL) {
|
|
||||||
/* we want a keep-alive response here. Keep-alive header
|
|
||||||
* required if either side is not 1.1.
|
|
||||||
*/
|
|
||||||
if (!(txn->req.flags & msg->flags & HTTP_MSGF_VER_11))
|
|
||||||
want_flags |= TX_CON_KAL_SET;
|
|
||||||
}
|
}
|
||||||
else {
|
if (unlikely(http_header_add_tail(&txn->rsp, &txn->hdr_idx, wl->s) < 0))
|
||||||
/* we want a close response here. Close header required if
|
goto return_bad_resp;
|
||||||
* the server is 1.1, regardless of the client.
|
|
||||||
*/
|
|
||||||
if (msg->flags & HTTP_MSGF_VER_11)
|
|
||||||
want_flags |= TX_CON_CLO_SET;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (want_flags != (txn->flags & (TX_CON_CLO_SET|TX_CON_KAL_SET)))
|
|
||||||
http_change_connection_header(txn, msg, want_flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_header_mangling:
|
/* check whether we're already working on the frontend */
|
||||||
if ((msg->flags & HTTP_MSGF_XFER_LEN) ||
|
if (cur_proxy == s->fe)
|
||||||
(txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_TUN)
|
break;
|
||||||
rep->analysers |= AN_RES_HTTP_XFER_BODY;
|
cur_proxy = s->fe;
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************
|
/* OK that's all we can do for 1xx responses */
|
||||||
* OK, that's finished for the headers. We have done what we *
|
if (unlikely(txn->status < 200))
|
||||||
* could. Let's switch to the DATA state. *
|
goto skip_header_mangling;
|
||||||
************************************************************/
|
|
||||||
|
|
||||||
/* if the user wants to log as soon as possible, without counting
|
/*
|
||||||
* bytes from the server, then this is the right moment. We have
|
* Now check for a server cookie.
|
||||||
* to temporarily assign bytes_out to log what we currently have.
|
*/
|
||||||
|
if (s->be->cookie_name || s->be->appsession_name || s->fe->capture_name ||
|
||||||
|
(s->be->options & PR_O_CHK_CACHE))
|
||||||
|
manage_server_side_cookies(s, rep);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for cache-control or pragma headers if required.
|
||||||
|
*/
|
||||||
|
if ((s->be->options & PR_O_CHK_CACHE) || (s->be->ck_opts & PR_CK_NOC))
|
||||||
|
check_response_for_cacheability(s, rep);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add server cookie in the response if needed
|
||||||
|
*/
|
||||||
|
if (objt_server(s->target) && (s->be->ck_opts & PR_CK_INS) &&
|
||||||
|
!((txn->flags & TX_SCK_FOUND) && (s->be->ck_opts & PR_CK_PSV)) &&
|
||||||
|
(!(s->flags & SN_DIRECT) ||
|
||||||
|
((s->be->cookie_maxidle || txn->cookie_last_date) &&
|
||||||
|
(!txn->cookie_last_date || (txn->cookie_last_date - date.tv_sec) < 0)) ||
|
||||||
|
(s->be->cookie_maxlife && !txn->cookie_first_date) || // set the first_date
|
||||||
|
(!s->be->cookie_maxlife && txn->cookie_first_date)) && // remove the first_date
|
||||||
|
(!(s->be->ck_opts & PR_CK_POST) || (txn->meth == HTTP_METH_POST)) &&
|
||||||
|
!(s->flags & SN_IGNORE_PRST)) {
|
||||||
|
/* the server is known, it's not the one the client requested, or the
|
||||||
|
* cookie's last seen date needs to be refreshed. We have to
|
||||||
|
* insert a set-cookie here, except if we want to insert only on POST
|
||||||
|
* requests and this one isn't. Note that servers which don't have cookies
|
||||||
|
* (eg: some backup servers) will return a full cookie removal request.
|
||||||
*/
|
*/
|
||||||
if (!LIST_ISEMPTY(&s->fe->logformat) && !(s->logs.logwait & LW_BYTES)) {
|
if (!objt_server(s->target)->cookie) {
|
||||||
s->logs.t_close = s->logs.t_data; /* to get a valid end date */
|
chunk_printf(&trash,
|
||||||
s->logs.bytes_out = txn->rsp.eoh;
|
"Set-Cookie: %s=; Expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/",
|
||||||
s->do_log(s);
|
s->be->cookie_name);
|
||||||
s->logs.bytes_out = 0;
|
}
|
||||||
|
else {
|
||||||
|
chunk_printf(&trash, "Set-Cookie: %s=%s", s->be->cookie_name, objt_server(s->target)->cookie);
|
||||||
|
|
||||||
|
if (s->be->cookie_maxidle || s->be->cookie_maxlife) {
|
||||||
|
/* emit last_date, which is mandatory */
|
||||||
|
trash.str[trash.len++] = COOKIE_DELIM_DATE;
|
||||||
|
s30tob64((date.tv_sec+3) >> 2, trash.str + trash.len);
|
||||||
|
trash.len += 5;
|
||||||
|
|
||||||
|
if (s->be->cookie_maxlife) {
|
||||||
|
/* emit first_date, which is either the original one or
|
||||||
|
* the current date.
|
||||||
|
*/
|
||||||
|
trash.str[trash.len++] = COOKIE_DELIM_DATE;
|
||||||
|
s30tob64(txn->cookie_first_date ?
|
||||||
|
txn->cookie_first_date >> 2 :
|
||||||
|
(date.tv_sec+3) >> 2, trash.str + trash.len);
|
||||||
|
trash.len += 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chunk_appendf(&trash, "; path=/");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: we must not try to cheat by jumping directly to DATA,
|
if (s->be->cookie_domain)
|
||||||
* otherwise we would not let the client side wake up.
|
chunk_appendf(&trash, "; domain=%s", s->be->cookie_domain);
|
||||||
*/
|
|
||||||
|
|
||||||
return 1;
|
if (s->be->ck_opts & PR_CK_HTTPONLY)
|
||||||
|
chunk_appendf(&trash, "; HttpOnly");
|
||||||
|
|
||||||
|
if (s->be->ck_opts & PR_CK_SECURE)
|
||||||
|
chunk_appendf(&trash, "; Secure");
|
||||||
|
|
||||||
|
if (unlikely(http_header_add_tail2(&txn->rsp, &txn->hdr_idx, trash.str, trash.len) < 0))
|
||||||
|
goto return_bad_resp;
|
||||||
|
|
||||||
|
txn->flags &= ~TX_SCK_MASK;
|
||||||
|
if (objt_server(s->target)->cookie && (s->flags & SN_DIRECT))
|
||||||
|
/* the server did not change, only the date was updated */
|
||||||
|
txn->flags |= TX_SCK_UPDATED;
|
||||||
|
else
|
||||||
|
txn->flags |= TX_SCK_INSERTED;
|
||||||
|
|
||||||
|
/* Here, we will tell an eventual cache on the client side that we don't
|
||||||
|
* want it to cache this reply because HTTP/1.0 caches also cache cookies !
|
||||||
|
* Some caches understand the correct form: 'no-cache="set-cookie"', but
|
||||||
|
* others don't (eg: apache <= 1.3.26). So we use 'private' instead.
|
||||||
|
*/
|
||||||
|
if ((s->be->ck_opts & PR_CK_NOC) && (txn->flags & TX_CACHEABLE)) {
|
||||||
|
|
||||||
|
txn->flags &= ~TX_CACHEABLE & ~TX_CACHE_COOK;
|
||||||
|
|
||||||
|
if (unlikely(http_header_add_tail2(&txn->rsp, &txn->hdr_idx,
|
||||||
|
"Cache-control: private", 22) < 0))
|
||||||
|
goto return_bad_resp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if result will be cacheable with a cookie.
|
||||||
|
* We'll block the response if security checks have caught
|
||||||
|
* nasty things such as a cacheable cookie.
|
||||||
|
*/
|
||||||
|
if (((txn->flags & (TX_CACHEABLE | TX_CACHE_COOK | TX_SCK_PRESENT)) ==
|
||||||
|
(TX_CACHEABLE | TX_CACHE_COOK | TX_SCK_PRESENT)) &&
|
||||||
|
(s->be->options & PR_O_CHK_CACHE)) {
|
||||||
|
/* we're in presence of a cacheable response containing
|
||||||
|
* a set-cookie header. We'll block it as requested by
|
||||||
|
* the 'checkcache' option, and send an alert.
|
||||||
|
*/
|
||||||
|
if (objt_server(s->target))
|
||||||
|
objt_server(s->target)->counters.failed_secu++;
|
||||||
|
|
||||||
|
s->be->be_counters.denied_resp++;
|
||||||
|
s->fe->fe_counters.denied_resp++;
|
||||||
|
if (s->listener->counters)
|
||||||
|
s->listener->counters->denied_resp++;
|
||||||
|
|
||||||
|
Alert("Blocking cacheable cookie in response from instance %s, server %s.\n",
|
||||||
|
s->be->id, objt_server(s->target) ? objt_server(s->target)->id : "<dispatch>");
|
||||||
|
send_log(s->be, LOG_ALERT,
|
||||||
|
"Blocking cacheable cookie in response from instance %s, server %s.\n",
|
||||||
|
s->be->id, objt_server(s->target) ? objt_server(s->target)->id : "<dispatch>");
|
||||||
|
goto return_srv_prx_502;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adjust "Connection: close" or "Connection: keep-alive" if needed.
|
||||||
|
* If an "Upgrade" token is found, the header is left untouched in order
|
||||||
|
* not to have to deal with some client bugs : some of them fail an upgrade
|
||||||
|
* if anything but "Upgrade" is present in the Connection header.
|
||||||
|
*/
|
||||||
|
if (!(txn->flags & TX_HDR_CONN_UPG) &&
|
||||||
|
(((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN) ||
|
||||||
|
((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL ||
|
||||||
|
(s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL))) {
|
||||||
|
unsigned int want_flags = 0;
|
||||||
|
|
||||||
|
if ((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL ||
|
||||||
|
(txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL) {
|
||||||
|
/* we want a keep-alive response here. Keep-alive header
|
||||||
|
* required if either side is not 1.1.
|
||||||
|
*/
|
||||||
|
if (!(txn->req.flags & msg->flags & HTTP_MSGF_VER_11))
|
||||||
|
want_flags |= TX_CON_KAL_SET;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* we want a close response here. Close header required if
|
||||||
|
* the server is 1.1, regardless of the client.
|
||||||
|
*/
|
||||||
|
if (msg->flags & HTTP_MSGF_VER_11)
|
||||||
|
want_flags |= TX_CON_CLO_SET;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (want_flags != (txn->flags & (TX_CON_CLO_SET|TX_CON_KAL_SET)))
|
||||||
|
http_change_connection_header(txn, msg, want_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_header_mangling:
|
||||||
|
if ((msg->flags & HTTP_MSGF_XFER_LEN) ||
|
||||||
|
(txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_TUN)
|
||||||
|
rep->analysers |= AN_RES_HTTP_XFER_BODY;
|
||||||
|
|
||||||
|
/* if the user wants to log as soon as possible, without counting
|
||||||
|
* bytes from the server, then this is the right moment. We have
|
||||||
|
* to temporarily assign bytes_out to log what we currently have.
|
||||||
|
*/
|
||||||
|
if (!LIST_ISEMPTY(&s->fe->logformat) && !(s->logs.logwait & LW_BYTES)) {
|
||||||
|
s->logs.t_close = s->logs.t_data; /* to get a valid end date */
|
||||||
|
s->logs.bytes_out = txn->rsp.eoh;
|
||||||
|
s->do_log(s);
|
||||||
|
s->logs.bytes_out = 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user