diff --git a/include/types/proto_http.h b/include/types/proto_http.h index ba23968fb..89c8f88de 100644 --- a/include/types/proto_http.h +++ b/include/types/proto_http.h @@ -2,7 +2,7 @@ * include/types/proto_http.h * This file contains HTTP protocol definitions. * - * Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu + * Copyright (C) 2000-2010 Willy Tarreau - w@1wt.eu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,28 +27,7 @@ #include #include -/* - * FIXME: break this into HTTP state and TCP socket state. - */ - -/* different possible states for the client side */ -#define CL_STDATA 0 -#define CL_STSHUTR 1 -#define CL_STSHUTW 2 -#define CL_STCLOSE 3 - -/* different possible states for the server side */ -#define SV_STIDLE 0 -#define SV_STCONN 1 -#define SV_STDATA 2 -#define SV_STSHUTR 3 -#define SV_STSHUTW 4 -#define SV_STCLOSE 5 - -/* - * Transaction flags moved from session - */ - +/* These are the flags that are found in txn->flags */ /* action flags */ #define TX_CLDENY 0x00000001 /* a client header matches a deny regex */ @@ -114,6 +93,7 @@ */ #define TX_REQ_XFER_LEN 0x01000000 /* request xfer size can be determined */ #define TX_RES_XFER_LEN 0x02000000 /* response xfer size can be determined */ +#define TX_WAIT_NEXT_RQ 0x04000000 /* waiting for the second request to start, use keep-alive timeout */ /* The HTTP parser is more complex than it looks like, because we have to * support multi-line headers and any number of spaces between the colon and diff --git a/src/proto_http.c b/src/proto_http.c index bb7da5d34..582b56284 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -2234,7 +2234,7 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit) /* 2: have we encountered a read error ? */ else if (req->flags & BF_READ_ERROR) { - if (txn->flags & TX_NOT_FIRST) + if (txn->flags & TX_WAIT_NEXT_RQ) goto failed_keep_alive; /* we cannot return any message on error */ @@ -2256,7 +2256,7 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit) /* 3: has the read timeout expired ? */ else if (req->flags & BF_READ_TIMEOUT || tick_is_expired(req->analyse_exp, now_ms)) { - if (txn->flags & TX_NOT_FIRST) + if (txn->flags & TX_WAIT_NEXT_RQ) goto failed_keep_alive; /* read timeout : give up with an error message. */ @@ -2280,7 +2280,7 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit) /* 4: have we encountered a close ? */ else if (req->flags & BF_SHUTR) { - if (txn->flags & TX_NOT_FIRST) + if (txn->flags & TX_WAIT_NEXT_RQ) goto failed_keep_alive; if (msg->err_pos >= 0) @@ -2304,6 +2304,13 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit) buffer_dont_connect(req); req->flags |= BF_READ_DONTWAIT; /* try to get back here ASAP */ + if ((msg->msg_state != HTTP_MSG_RQBEFORE) && (txn->flags & TX_WAIT_NEXT_RQ)) { + /* If the client starts to talk, let's fall back to + * request timeout processing. + */ + txn->flags &= ~TX_WAIT_NEXT_RQ; + } + /* just set the request timeout once at the beginning of the request */ if (!tick_isset(req->analyse_exp)) req->analyse_exp = tick_add_ifset(now_ms, s->be->timeout.httpreq); @@ -3427,7 +3434,7 @@ void http_end_txn_clean_session(struct session *s) s->flags &= ~(SN_CURR_SESS|SN_REDIRECTABLE); s->txn.meth = 0; http_reset_txn(s); - s->txn.flags |= TX_NOT_FIRST; + s->txn.flags |= TX_NOT_FIRST | TX_WAIT_NEXT_RQ; if (s->be->options2 & PR_O2_INDEPSTR) s->req->cons->flags |= SI_FL_INDEP_STR;