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.
diff --git a/src/proto_http.c b/src/proto_http.c
index 7b478fd..746caed 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -5856,270 +5856,254 @@
/* we want to have the response time before we start processing it */
s->logs.t_data = tv_ms_elapsed(&s->logs.tv_accept, &now);
- if (1) {
- /*
- * 3: we will have to evaluate the filters.
- * As opposed to version 1.2, now they will be evaluated in the
- * filters order and not in the header order. This means that
- * each filter has to be validated among all headers.
- *
- * Filters are tried with ->be first, then with ->fe if it is
- * different from ->be.
- */
+ /*
+ * We will have to evaluate the filters.
+ * As opposed to version 1.2, now they will be evaluated in the
+ * filters order and not in the header order. This means that
+ * each filter has to be validated among all headers.
+ *
+ * Filters are tried with ->be first, then with ->fe if it is
+ * different from ->be.
+ */
- cur_proxy = s->be;
- while (1) {
- struct proxy *rule_set = cur_proxy;
+ cur_proxy = s->be;
+ while (1) {
+ struct proxy *rule_set = cur_proxy;
- /* evaluate http-response rules */
- if (!http_res_last_rule)
- http_res_last_rule = http_res_get_intercept_rule(cur_proxy, &cur_proxy->http_res_rules, s, txn);
+ /* evaluate http-response rules */
+ if (!http_res_last_rule)
+ http_res_last_rule = http_res_get_intercept_rule(cur_proxy, &cur_proxy->http_res_rules, s, txn);
- /* try headers filters */
- if (rule_set->rsp_exp != NULL) {
- if (apply_filters_to_response(s, rep, rule_set) < 0) {
- return_bad_resp:
- if (objt_server(s->target)) {
- objt_server(s->target)->counters.failed_resp++;
- 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;
+ /* try headers filters */
+ if (rule_set->rsp_exp != NULL) {
+ if (apply_filters_to_response(s, rep, rule_set) < 0) {
+ return_bad_resp:
+ if (objt_server(s->target)) {
+ objt_server(s->target)->counters.failed_resp++;
+ 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;
}
-
- /* has the response been denied ? */
- if (txn->flags & TX_SVDENY) {
- 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++;
+ /* has the response been denied ? */
+ if (txn->flags & TX_SVDENY) {
+ if (objt_server(s->target))
+ objt_server(s->target)->counters.failed_secu++;
- goto return_srv_prx_502;
- }
+ s->be->be_counters.denied_resp++;
+ s->fe->fe_counters.denied_resp++;
+ if (s->listener->counters)
+ s->listener->counters->denied_resp++;
- /* 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;
- }
+ goto return_srv_prx_502;
+ }
- /* check whether we're already working on the frontend */
- if (cur_proxy == s->fe)
+ /* 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;
- cur_proxy = s->fe;
+ 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;
}
- if (unlikely(txn->status < 200))
- goto skip_header_mangling;
+ /* check whether we're already working on the frontend */
+ if (cur_proxy == s->fe)
+ break;
+ cur_proxy = s->fe;
+ }
- /* we don't have any 1xx status code now */
+ /* OK that's all we can do for 1xx responses */
+ if (unlikely(txn->status < 200))
+ goto skip_header_mangling;
- /*
- * 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);
+ /*
+ * Now check for a 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);
+ /*
+ * 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);
- /*
- * 5: check for cache-control or pragma headers if required.
+ /*
+ * 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 ((s->be->options & PR_O_CHK_CACHE) || (s->be->ck_opts & PR_CK_NOC))
- check_response_for_cacheability(s, rep);
+ 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);
- /*
- * 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_maxidle || s->be->cookie_maxlife) {
- /* emit last_date, which is mandatory */
+ 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((date.tv_sec+3) >> 2, trash.str + trash.len);
+ s30tob64(txn->cookie_first_date ?
+ txn->cookie_first_date >> 2 :
+ (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");
+ chunk_appendf(&trash, "; path=/");
+ }
- if (unlikely(http_header_add_tail2(&txn->rsp, &txn->hdr_idx, trash.str, trash.len) < 0))
- goto return_bad_resp;
+ if (s->be->cookie_domain)
+ chunk_appendf(&trash, "; domain=%s", s->be->cookie_domain);
- 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;
+ if (s->be->ck_opts & PR_CK_HTTPONLY)
+ chunk_appendf(&trash, "; HttpOnly");
- /* 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)) {
+ if (s->be->ck_opts & PR_CK_SECURE)
+ chunk_appendf(&trash, "; Secure");
- txn->flags &= ~TX_CACHEABLE & ~TX_CACHE_COOK;
+ if (unlikely(http_header_add_tail2(&txn->rsp, &txn->hdr_idx, trash.str, trash.len) < 0))
+ goto return_bad_resp;
- if (unlikely(http_header_add_tail2(&txn->rsp, &txn->hdr_idx,
- "Cache-control: private", 22) < 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;
- /*
- * 7: 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.
+ /* 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 (((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)) {
+ if ((s->be->ck_opts & PR_CK_NOC) && (txn->flags & TX_CACHEABLE)) {
- /* 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++;
+ txn->flags &= ~TX_CACHEABLE & ~TX_CACHE_COOK;
- 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;
+ if (unlikely(http_header_add_tail2(&txn->rsp, &txn->hdr_idx,
+ "Cache-control: private", 22) < 0))
+ goto return_bad_resp;
}
+ }
- /*
- * 8: 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.
+ /*
+ * 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 (!(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 (objt_server(s->target))
+ objt_server(s->target)->counters.failed_secu++;
- if (want_flags != (txn->flags & (TX_CON_CLO_SET|TX_CON_KAL_SET)))
- http_change_connection_header(txn, msg, want_flags);
- }
+ s->be->be_counters.denied_resp++;
+ s->fe->fe_counters.denied_resp++;
+ if (s->listener->counters)
+ s->listener->counters->denied_resp++;
- 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;
+ 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;
+ }
- /*************************************************************
- * OK, that's finished for the headers. We have done what we *
- * could. Let's switch to the DATA state. *
- ************************************************************/
+ /*
+ * 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 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;
+ 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;
}
- /* Note: we must not try to cheat by jumping directly to DATA,
- * otherwise we would not let the client side wake up.
- */
+ 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;
- return 1;
+ /* 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;
}