]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: proto_htx: Add the function htx_return_srv_error()
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 15 Jul 2019 13:46:28 +0000 (15:46 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 19 Jul 2019 07:18:27 +0000 (09:18 +0200)
Instead of using a function from the legacy HTTP, the HTX code now uses its own
one.

include/proto/proto_http.h
src/proto_htx.c

index 102c5ded7fb45d35a269b378bfce407f3f24851d..8683e2625ed9d475baf42f911cfa243c8533ee3e 100644 (file)
@@ -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);
index b08f99969a0d442a6a2827aafaf776a25fec0cc9..9f3a4d9bbd1170b07ce000b2e41281a4c9e4c26a 100644 (file)
@@ -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.