]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MINOR] http: differentiate waiting for new request and waiting for a complete requst
authorWilly Tarreau <w@1wt.eu>
Sun, 10 Jan 2010 13:21:19 +0000 (14:21 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 10 Jan 2010 13:24:53 +0000 (14:24 +0100)
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.

include/types/proto_http.h
src/proto_http.c

index ba23968fb46e629c8541d4fe0542747e82e26983..89c8f88de3ab0e7f3ada695ca872990e8ddf9307 100644 (file)
@@ -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
 #include <types/buffers.h>
 #include <types/hdr_idx.h>
 
-/*
- * 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 */
  */
 #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
index bb7da5d34644f3d2f3d07b53000b225c7e8926bc..582b562846a0a0e290f65e95ac5881903d83b019 100644 (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 ? */
                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;