[MINOR] http: differentiate waiting for new request and waiting for a complete requst

While waiting in a keep-alive state for a request, we want to silently
close if we don't get anything. However if we get a partial request it's
different because that means the client has started to send something.
This requires a new transaction flag. It will be used to implement a
distinct timeout for keep-alive and requests.
This commit is contained in:
Willy Tarreau 2010-01-10 14:21:19 +01:00
parent 520bbb2b85
commit fcffa6911c
2 changed files with 14 additions and 27 deletions

View File

@ -2,7 +2,7 @@
* include/types/proto_http.h * include/types/proto_http.h
* This file contains HTTP protocol definitions. * 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -27,28 +27,7 @@
#include <types/buffers.h> #include <types/buffers.h>
#include <types/hdr_idx.h> #include <types/hdr_idx.h>
/* /* These are the flags that are found in txn->flags */
* 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
*/
/* action flags */ /* action flags */
#define TX_CLDENY 0x00000001 /* a client header matches a deny regex */ #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_REQ_XFER_LEN 0x01000000 /* request xfer size can be determined */
#define TX_RES_XFER_LEN 0x02000000 /* response 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 /* 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 * support multi-line headers and any number of spaces between the colon and

View File

@ -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 ? */ /* 2: have we encountered a read error ? */
else if (req->flags & BF_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; goto failed_keep_alive;
/* we cannot return any message on error */ /* 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 ? */ /* 3: has the read timeout expired ? */
else if (req->flags & BF_READ_TIMEOUT || tick_is_expired(req->analyse_exp, now_ms)) { 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; goto failed_keep_alive;
/* read timeout : give up with an error message. */ /* 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 ? */ /* 4: have we encountered a close ? */
else if (req->flags & BF_SHUTR) { else if (req->flags & BF_SHUTR) {
if (txn->flags & TX_NOT_FIRST) if (txn->flags & TX_WAIT_NEXT_RQ)
goto failed_keep_alive; goto failed_keep_alive;
if (msg->err_pos >= 0) 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); buffer_dont_connect(req);
req->flags |= BF_READ_DONTWAIT; /* try to get back here ASAP */ 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 */ /* just set the request timeout once at the beginning of the request */
if (!tick_isset(req->analyse_exp)) if (!tick_isset(req->analyse_exp))
req->analyse_exp = tick_add_ifset(now_ms, s->be->timeout.httpreq); 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->flags &= ~(SN_CURR_SESS|SN_REDIRECTABLE);
s->txn.meth = 0; s->txn.meth = 0;
http_reset_txn(s); 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) if (s->be->options2 & PR_O2_INDEPSTR)
s->req->cons->flags |= SI_FL_INDEP_STR; s->req->cons->flags |= SI_FL_INDEP_STR;