From: Christopher Faulet Date: Mon, 15 Jul 2019 13:46:28 +0000 (+0200) Subject: MINOR: proto_htx: Add the function htx_return_srv_error() X-Git-Tag: v2.1-dev2~385 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=304cc40536e839ee53453b93b62892a231e70bec;p=thirdparty%2Fhaproxy.git MINOR: proto_htx: Add the function htx_return_srv_error() Instead of using a function from the legacy HTTP, the HTX code now uses its own one. --- diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h index 102c5ded7f..8683e2625e 100644 --- a/include/proto/proto_http.h +++ b/include/proto/proto_http.h @@ -89,6 +89,7 @@ int htx_send_name_header(struct stream *s, struct proxy *be, const char *srv_nam void htx_perform_server_redirect(struct stream *s, struct stream_interface *si); void htx_server_error(struct stream *s, struct stream_interface *si, int err, int finst, const struct buffer *msg); void htx_reply_and_close(struct stream *s, short status, struct buffer *msg); +void htx_return_srv_error(struct stream *s, struct stream_interface *si); struct buffer *htx_error_message(struct stream *s); void debug_hdr(const char *dir, struct stream *s, const char *start, const char *end); diff --git a/src/proto_htx.c b/src/proto_htx.c index b08f99969a..9f3a4d9bbd 100644 --- a/src/proto_htx.c +++ b/src/proto_htx.c @@ -106,7 +106,7 @@ int htx_wait_for_request(struct stream *s, struct channel *req, int an_bit) } /* we're speaking HTTP here, so let's speak HTTP to the client */ - s->srv_error = http_return_srv_error; + s->srv_error = htx_return_srv_error; /* If there is data available for analysis, log the end of the idle time. */ if (c_data(req) && s->logs.t_idle == -1) { @@ -5412,6 +5412,56 @@ struct buffer *htx_error_message(struct stream *s) return &htx_err_chunks[msgnum]; } +/* Return the error message corresponding to si->err_type. It is assumed + * that the server side is closed. Note that err_type is actually a + * bitmask, where almost only aborts may be cumulated with other + * values. We consider that aborted operations are more important + * than timeouts or errors due to the fact that nobody else in the + * logs might explain incomplete retries. All others should avoid + * being cumulated. It should normally not be possible to have multiple + * aborts at once, but just in case, the first one in sequence is reported. + * Note that connection errors appearing on the second request of a keep-alive + * connection are not reported since this allows the client to retry. + */ +void htx_return_srv_error(struct stream *s, struct stream_interface *si) +{ + int err_type = si->err_type; + + /* set s->txn->status for http_error_message(s) */ + s->txn->status = 503; + + if (err_type & SI_ET_QUEUE_ABRT) + htx_server_error(s, si, SF_ERR_CLICL, SF_FINST_Q, + htx_error_message(s)); + else if (err_type & SI_ET_CONN_ABRT) + htx_server_error(s, si, SF_ERR_CLICL, SF_FINST_C, + (s->txn->flags & TX_NOT_FIRST) ? NULL : + htx_error_message(s)); + else if (err_type & SI_ET_QUEUE_TO) + htx_server_error(s, si, SF_ERR_SRVTO, SF_FINST_Q, + htx_error_message(s)); + else if (err_type & SI_ET_QUEUE_ERR) + htx_server_error(s, si, SF_ERR_SRVCL, SF_FINST_Q, + htx_error_message(s)); + else if (err_type & SI_ET_CONN_TO) + htx_server_error(s, si, SF_ERR_SRVTO, SF_FINST_C, + (s->txn->flags & TX_NOT_FIRST) ? NULL : + htx_error_message(s)); + else if (err_type & SI_ET_CONN_ERR) + htx_server_error(s, si, SF_ERR_SRVCL, SF_FINST_C, + (s->flags & SF_SRV_REUSED) ? NULL : + htx_error_message(s)); + else if (err_type & SI_ET_CONN_RES) + htx_server_error(s, si, SF_ERR_RESOURCE, SF_FINST_C, + (s->txn->flags & TX_NOT_FIRST) ? NULL : + htx_error_message(s)); + else { /* SI_ET_CONN_OTHER and others */ + s->txn->status = 500; + htx_server_error(s, si, SF_ERR_INTERNAL, SF_FINST_C, + htx_error_message(s)); + } +} + /* Handle Expect: 100-continue for HTTP/1.1 messages if necessary. It returns 0 * on success and -1 on error.