Skip to content

Commit 2a5da31

Browse files
committed
BUG/MINOR: http-ana: Adjust the server status before the L7 retries
The server status must be adjusted, if necessary, at each retry. It is properly performed when "obersve layer4" directive is set. But for the layer 7, only the last attempt was considered. When the L7 retries were implemented, all retries were added before the server status adjutement. So only the last attempt was considered. To fix the issue, we must adjut the server status first, and then try to perform a L7 retry. This patch should fix the issue #2679. It must be backported to all stable versions.
1 parent 5c15899 commit 2a5da31

File tree

1 file changed

+35
-27
lines changed

1 file changed

+35
-27
lines changed

src/http_ana.c

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,8 +1234,11 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
12341234
htx = htxbuf(&rep->buf);
12351235

12361236
/* Parsing errors are caught here */
1237-
if (htx->flags & HTX_FL_PARSING_ERROR)
1237+
if (htx->flags & HTX_FL_PARSING_ERROR) {
1238+
if (objt_server(s->target))
1239+
health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_HDRRSP);
12381240
goto return_bad_res;
1241+
}
12391242
if (htx->flags & HTX_FL_PROCESSING_ERROR)
12401243
goto return_int_err;
12411244

@@ -1257,6 +1260,8 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
12571260
if (s->scb->flags & SC_FL_ERROR) {
12581261
struct connection *conn = sc_conn(s->scb);
12591262

1263+
if (!(s->flags & SF_SRV_REUSED) && objt_server(s->target))
1264+
health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_READ_ERROR);
12601265

12611266
if ((txn->flags & TX_L7_RETRY) &&
12621267
(s->be->retry_type & PR_RE_DISCONNECTED) &&
@@ -1279,10 +1284,8 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
12791284
goto abort_keep_alive;
12801285

12811286
_HA_ATOMIC_INC(&s->be->be_counters.failed_resp);
1282-
if (objt_server(s->target)) {
1287+
if (objt_server(s->target))
12831288
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_resp);
1284-
health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_READ_ERROR);
1285-
}
12861289

12871290
/* if the server refused the early data, just send a 425 */
12881291
if (conn && conn->err_code == CO_ER_SSL_EARLY_FAILED)
@@ -1306,6 +1309,9 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
13061309

13071310
/* 2: read timeout : return a 504 to the client. */
13081311
else if (rep->flags & CF_READ_TIMEOUT) {
1312+
if (objt_server(s->target))
1313+
health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_READ_TIMEOUT);
1314+
13091315
if ((txn->flags & TX_L7_RETRY) &&
13101316
(s->be->retry_type & PR_RE_TIMEOUT)) {
13111317
if (co_data(rep) || do_l7_retry(s, s->scb) == 0) {
@@ -1315,10 +1321,8 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
13151321
}
13161322
}
13171323
_HA_ATOMIC_INC(&s->be->be_counters.failed_resp);
1318-
if (objt_server(s->target)) {
1324+
if (objt_server(s->target))
13191325
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_resp);
1320-
health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_READ_TIMEOUT);
1321-
}
13221326

13231327
txn->status = 504;
13241328
stream_inc_http_fail_ctr(s);
@@ -1360,6 +1364,9 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
13601364

13611365
/* 4: close from server, capture the response if the server has started to respond */
13621366
else if (s->scb->flags & (SC_FL_EOS|SC_FL_ABRT_DONE)) {
1367+
if (!(s->flags & SF_SRV_REUSED) && objt_server(s->target))
1368+
health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_BROKEN_PIPE);
1369+
13631370
if ((txn->flags & TX_L7_RETRY) &&
13641371
(s->be->retry_type & PR_RE_DISCONNECTED)) {
13651372
if (co_data(rep) || do_l7_retry(s, s->scb) == 0) {
@@ -1373,10 +1380,8 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
13731380
goto abort_keep_alive;
13741381

13751382
_HA_ATOMIC_INC(&s->be->be_counters.failed_resp);
1376-
if (objt_server(s->target)) {
1383+
if (objt_server(s->target))
13771384
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_resp);
1378-
health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_BROKEN_PIPE);
1379-
}
13801385

13811386
txn->status = 502;
13821387
stream_inc_http_fail_ctr(s);
@@ -1427,6 +1432,17 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
14271432
BUG_ON(htx_get_first_type(htx) != HTX_BLK_RES_SL);
14281433
sl = http_get_stline(htx);
14291434

1435+
/* Adjust server's health based on status code. Note: status codes 501
1436+
* and 505 are triggered on demand by client request, so we must not
1437+
* count them as server failures.
1438+
*/
1439+
if (objt_server(s->target)) {
1440+
if (sl->info.res.status >= 100 && (sl->info.res.status < 500 || sl->info.res.status == 501 || sl->info.res.status == 505))
1441+
health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_OK);
1442+
else
1443+
health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_STS);
1444+
}
1445+
14301446
/* Perform a L7 retry because of the status code */
14311447
if ((txn->flags & TX_L7_RETRY) &&
14321448
l7_status_match(s->be, sl->info.res.status) &&
@@ -1499,17 +1515,6 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
14991515
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.p.http.cum_req);
15001516
}
15011517

1502-
/* Adjust server's health based on status code. Note: status codes 501
1503-
* and 505 are triggered on demand by client request, so we must not
1504-
* count them as server failures.
1505-
*/
1506-
if (objt_server(s->target)) {
1507-
if (txn->status >= 100 && (txn->status < 500 || txn->status == 501 || txn->status == 505))
1508-
health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_OK);
1509-
else
1510-
health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_STS);
1511-
}
1512-
15131518
/*
15141519
* We may be facing a 100-continue response, or any other informational
15151520
* 1xx response which is non-final, in which case this is not the right
@@ -1535,8 +1540,11 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
15351540
* header content. But it is probably stronger enough for now.
15361541
*/
15371542
if (txn->status == 101 &&
1538-
(!(txn->req.flags & HTTP_MSGF_CONN_UPG) || !(txn->rsp.flags & HTTP_MSGF_CONN_UPG)))
1543+
(!(txn->req.flags & HTTP_MSGF_CONN_UPG) || !(txn->rsp.flags & HTTP_MSGF_CONN_UPG))) {
1544+
if (objt_server(s->target))
1545+
health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_HDRRSP);
15391546
goto return_bad_res;
1547+
}
15401548

15411549
/*
15421550
* 2: check for cacheability.
@@ -1657,18 +1665,18 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
16571665
goto return_prx_cond;
16581666

16591667
return_bad_res:
1660-
_HA_ATOMIC_INC(&s->be->be_counters.failed_resp);
1661-
if (objt_server(s->target)) {
1662-
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_resp);
1663-
health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_HDRRSP);
1664-
}
16651668
if ((s->be->retry_type & PR_RE_JUNK_REQUEST) &&
16661669
(txn->flags & TX_L7_RETRY) &&
16671670
do_l7_retry(s, s->scb) == 0) {
16681671
DBG_TRACE_DEVEL("leaving on L7 retry",
16691672
STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA, s, txn);
16701673
return 0;
16711674
}
1675+
1676+
_HA_ATOMIC_INC(&s->be->be_counters.failed_resp);
1677+
if (objt_server(s->target))
1678+
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_resp);
1679+
16721680
txn->status = 502;
16731681
stream_inc_http_fail_ctr(s);
16741682
/* fall through */

0 commit comments

Comments
 (0)