From: Willy Tarreau Date: Sun, 30 Nov 2008 19:44:17 +0000 (+0100) Subject: [MEDIUM] make the http server error function a pointer in the session X-Git-Tag: v1.3.16-rc1~132 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0cac36f4156fd73802e19352a513f7220865c9df;p=thirdparty%2Fhaproxy.git [MEDIUM] make the http server error function a pointer in the session It was a bit awkward to have session.c call return_srv_error() for HTTP error messages related to servers. The function has been adapted to be passed a pointer to the faulty stream interface, and is now a pointer in the session. It is possible that in the future, it will become a callback in the stream interface itself. --- diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h index 3addf3f252..72a5e3cc07 100644 --- a/include/proto/proto_http.h +++ b/include/proto/proto_http.h @@ -84,7 +84,7 @@ int http_find_header2(const char *name, int len, struct hdr_ctx *ctx); void http_sess_log(struct session *s); void perform_http_redirect(struct session *s, struct stream_interface *si); -void return_srv_error(struct session *s, int err_type); +void http_return_srv_error(struct session *s, struct stream_interface *si); #endif /* _PROTO_PROTO_HTTP_H */ diff --git a/include/types/session.h b/include/types/session.h index 92bfa0626d..83d0a455f7 100644 --- a/include/types/session.h +++ b/include/types/session.h @@ -188,7 +188,9 @@ struct session { long long bytes_in; /* number of bytes transferred from the client to the server */ long long bytes_out; /* number of bytes transferred from the server to the client */ } logs; - void (*do_log)(struct session *s); /* the function to call in order to log */ + void (*do_log)(struct session *s); /* the function to call in order to log (or NULL) */ + void (*srv_error)(struct session *s, /* the function to call upon unrecoverable server errors (or NULL) */ + struct stream_interface *si); short int data_source; /* where to get the data we generate ourselves */ short int data_state; /* where to get the data we generate ourselves */ union { diff --git a/src/client.c b/src/client.c index bc7b2547ea..bf7f55c7e8 100644 --- a/src/client.c +++ b/src/client.c @@ -212,6 +212,11 @@ int event_accept(int fd) { else s->do_log = tcp_sess_log; + if (p->mode == PR_MODE_HTTP) + s->srv_error = http_return_srv_error; + else + s->srv_error = NULL; + s->logs.accept_date = date; /* user-visible date for logging */ s->logs.tv_accept = now; /* corrected date for internal use */ tv_zero(&s->logs.tv_request); diff --git a/src/proto_http.c b/src/proto_http.c index 3991e41e85..b52607675e 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -696,7 +696,7 @@ void perform_http_redirect(struct session *s, struct stream_interface *si) s->srv->cum_sess++; } -/* Return the error message corresponding to err_type. It is assumed +/* 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 @@ -705,9 +705,9 @@ void perform_http_redirect(struct session *s, struct stream_interface *si) * 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. */ -void return_srv_error(struct session *s, int err_type) +void http_return_srv_error(struct session *s, struct stream_interface *si) { - struct stream_interface *si = &s->si[1]; + int err_type = si->err_type; if (err_type & SI_ET_QUEUE_ABRT) http_server_error(s, si, SN_ERR_CLICL, SN_FINST_Q, diff --git a/src/session.c b/src/session.c index 1eb7b69fc5..0550de1a4c 100644 --- a/src/session.c +++ b/src/session.c @@ -246,7 +246,8 @@ int sess_update_st_cer(struct session *s, struct stream_interface *si) si->ib->flags |= BF_READ_ERROR; si->state = SI_ST_CLO; - return_srv_error(s, si->err_type); + if (s->srv_error) + s->srv_error(s, si); return 0; } @@ -397,7 +398,8 @@ void sess_update_stream_int(struct session *s, struct stream_interface *si) /* no session was ever accounted for this server */ si->state = SI_ST_CLO; - return_srv_error(s, si->err_type); + if (s->srv_error) + s->srv_error(s, si); return; } @@ -443,7 +445,8 @@ void sess_update_stream_int(struct session *s, struct stream_interface *si) if (!si->err_type) si->err_type = SI_ET_QUEUE_TO; si->state = SI_ST_CLO; - return_srv_error(s, si->err_type); + if (s->srv_error) + s->srv_error(s, si); return; } @@ -458,7 +461,8 @@ void sess_update_stream_int(struct session *s, struct stream_interface *si) si->shutw(si); si->err_type |= SI_ET_QUEUE_ABRT; si->state = SI_ST_CLO; - return_srv_error(s, si->err_type); + if (s->srv_error) + s->srv_error(s, si); return; } @@ -476,7 +480,8 @@ void sess_update_stream_int(struct session *s, struct stream_interface *si) si->shutw(si); si->err_type |= SI_ET_CONN_ABRT; si->state = SI_ST_CLO; - return_srv_error(s, si->err_type); + if (s->srv_error) + s->srv_error(s, si); return; } @@ -529,7 +534,8 @@ static void sess_prepare_conn_req(struct session *s, struct stream_interface *si if (!si->err_type) si->err_type = SI_ET_CONN_OTHER; si->state = SI_ST_CLO; - return_srv_error(s, si->err_type); + if (s->srv_error) + s->srv_error(s, si); return; }