From 078272e1152649f7b4d298a937b785f99fd717c2 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 12 Dec 2010 12:46:33 +0100 Subject: [PATCH] [MINOR] stats: report HTTP message state and buffer flags in error dumps Debugging parsing errors can be greatly improved if we know what the parser state was and what the buffer flags were (especially for closed inputs/outputs and full buffers). Let's add that to the error snapshots. --- include/proto/proto_http.h | 2 +- include/types/proxy.h | 2 ++ src/dumpstats.c | 4 ++++ src/proto_http.c | 30 ++++++++++++++++-------------- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h index e7181ec97..417d5e6fd 100644 --- a/include/proto/proto_http.h +++ b/include/proto/proto_http.h @@ -91,7 +91,7 @@ void perform_http_redirect(struct session *s, struct stream_interface *si); void http_return_srv_error(struct session *s, struct stream_interface *si); void http_capture_bad_message(struct error_snapshot *es, struct session *s, struct buffer *buf, struct http_msg *msg, - struct proxy *other_end); + int state, struct proxy *other_end); unsigned int get_ip_from_hdr2(struct http_msg *msg, const char *hname, int hlen, struct hdr_idx *idx, int occ); diff --git a/include/types/proxy.h b/include/types/proxy.h index 9704783e2..89cb09b77 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -161,6 +161,8 @@ struct error_snapshot { unsigned int len; /* original length of the last invalid request/response */ unsigned int pos; /* position of the first invalid character */ unsigned int sid; /* ID of the faulty session */ + unsigned int state; /* message state before the error (when saved) */ + unsigned int flags; /* buffer flags */ struct server *srv; /* server associated with the error (or NULL) */ struct proxy *oe; /* other end = frontend or backend involved */ struct sockaddr_storage src; /* client's address */ diff --git a/src/dumpstats.c b/src/dumpstats.c index 269518456..da2980970 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -3477,23 +3477,27 @@ int stats_dump_errors_to_buffer(struct session *s, struct buffer *rep) chunk_printf(&msg, " frontend %s (#%d): invalid request\n" " src %s, session #%d, backend %s (#%d), server %s (#%d)\n" + " HTTP internal state %d, buffer flags 0x%08x\n" " request length %d bytes, error at position %d:\n \n", s->data_ctx.errors.px->id, s->data_ctx.errors.px->uuid, pn, es->sid, (es->oe->cap & PR_CAP_BE) ? es->oe->id : "", (es->oe->cap & PR_CAP_BE) ? es->oe->uuid : -1, es->srv ? es->srv->id : "", es->srv ? es->srv->puid : -1, + es->state, es->flags, es->len, es->pos); break; case 1: chunk_printf(&msg, " backend %s (#%d) : invalid response\n" " src %s, session #%d, frontend %s (#%d), server %s (#%d)\n" + " HTTP internal state %d, buffer flags 0x%08x\n" " response length %d bytes, error at position %d:\n \n", s->data_ctx.errors.px->id, s->data_ctx.errors.px->uuid, pn, es->sid, es->oe->id, es->oe->uuid, es->srv ? es->srv->id : "", es->srv ? es->srv->puid : -1, + es->state, es->flags, es->len, es->pos); break; } diff --git a/src/proto_http.c b/src/proto_http.c index 4dcefca2d..893f8da29 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -2487,7 +2487,7 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit) /* we cannot return any message on error */ if (msg->err_pos >= 0) { - http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe); + http_capture_bad_message(&s->fe->invalid_req, s, req, msg, msg->msg_state, s->fe); session_inc_http_err_ctr(s); } @@ -2515,7 +2515,7 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit) /* read timeout : give up with an error message. */ if (msg->err_pos >= 0) { - http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe); + http_capture_bad_message(&s->fe->invalid_req, s, req, msg, msg->msg_state, s->fe); session_inc_http_err_ctr(s); } txn->status = 408; @@ -2543,7 +2543,7 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit) goto failed_keep_alive; if (msg->err_pos >= 0) - http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe); + http_capture_bad_message(&s->fe->invalid_req, s, req, msg, msg->msg_state, s->fe); txn->status = 400; stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_400)); msg->msg_state = HTTP_MSG_ERROR; @@ -2625,7 +2625,7 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit) * to block on that, so we have to capture it now. */ if (unlikely(msg->err_pos >= 0)) - http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe); + http_capture_bad_message(&s->fe->invalid_req, s, req, msg, msg->msg_state, s->fe); /* * 1: identify the method @@ -2821,7 +2821,7 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit) /* we detected a parsing error. We want to archive this request * in the dedicated proxy area for later troubleshooting. */ - http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe); + http_capture_bad_message(&s->fe->invalid_req, s, req, msg, msg->msg_state, s->fe); } txn->req.msg_state = HTTP_MSG_ERROR; @@ -3375,7 +3375,7 @@ int http_process_req_common(struct session *s, struct buffer *req, int an_bit, s /* we detected a parsing error. We want to archive this request * in the dedicated proxy area for later troubleshooting. */ - http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe); + http_capture_bad_message(&s->fe->invalid_req, s, req, msg, msg->msg_state, s->fe); } txn->req.msg_state = HTTP_MSG_ERROR; @@ -3626,7 +3626,7 @@ int http_process_request(struct session *s, struct buffer *req, int an_bit) /* we detected a parsing error. We want to archive this request * in the dedicated proxy area for later troubleshooting. */ - http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe); + http_capture_bad_message(&s->fe->invalid_req, s, req, msg, msg->msg_state, s->fe); } txn->req.msg_state = HTTP_MSG_ERROR; @@ -4591,7 +4591,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit) */ hdr_response_bad: if (msg->msg_state == HTTP_MSG_ERROR || msg->err_pos >= 0) - http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, s->fe); + http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, msg->msg_state, s->fe); s->be->counters.failed_resp++; if (s->srv) { @@ -4622,7 +4622,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit) /* read error */ else if (rep->flags & BF_READ_ERROR) { if (msg->err_pos >= 0) - http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, s->fe); + http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, msg->msg_state, s->fe); s->be->counters.failed_resp++; if (s->srv) { @@ -4647,7 +4647,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit) /* read timeout : return a 504 to the client. */ else if (rep->flags & BF_READ_TIMEOUT) { if (msg->err_pos >= 0) - http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, s->fe); + http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, msg->msg_state, s->fe); s->be->counters.failed_resp++; if (s->srv) { @@ -4672,7 +4672,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit) /* close from server */ else if (rep->flags & BF_SHUTR) { if (msg->err_pos >= 0) - http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, s->fe); + http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, msg->msg_state, s->fe); s->be->counters.failed_resp++; if (s->srv) { @@ -4697,7 +4697,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit) /* write error to client (we don't send any message then) */ else if (rep->flags & BF_WRITE_ERROR) { if (msg->err_pos >= 0) - http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, s->fe); + http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, msg->msg_state, s->fe); s->be->counters.failed_resp++; rep->analysers = 0; @@ -4722,7 +4722,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit) */ if (unlikely(msg->err_pos >= 0)) - http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, s->fe); + http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, msg->msg_state, s->fe); /* * 1: get the status code @@ -7200,7 +7200,7 @@ int stats_check_uri(struct session *t, struct proxy *backend) */ void http_capture_bad_message(struct error_snapshot *es, struct session *s, struct buffer *buf, struct http_msg *msg, - struct proxy *other_end) + int state, struct proxy *other_end) { es->len = buf->r - (buf->data + msg->som); memcpy(es->buf, buf->data + msg->som, MIN(es->len, sizeof(es->buf))); @@ -7213,6 +7213,8 @@ void http_capture_bad_message(struct error_snapshot *es, struct session *s, es->srv = s->srv; es->oe = other_end; es->src = s->cli_addr; + es->state = state; + es->flags = buf->flags; } /* return the IP address pointed to by occurrence of header in