From: Willy Tarreau Date: Thu, 24 Apr 2014 19:13:57 +0000 (+0200) Subject: CLEANUP: http: remove the useless "if (1)" inherited from version 1.4 X-Git-Tag: v1.5-dev24~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=589756727366f83b3cde070d75905f1791a75b37;p=thirdparty%2Fhaproxy.git 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 7b478fd552..746caed4be 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -5856,270 +5856,254 @@ 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 */ 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; - - /* 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; + 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); + + /* 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=/"); } + 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; + 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 : ""); - 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 : ""); - 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 : ""); + 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 : ""); + 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); + } - return 1; + 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; }