[MINOR] http: make the conditional redirect support keep-alive

It makes sense to permit a client to keep its connection when
performing a redirect to the same host. We only detect the fact
that the redirect location begins with a slash to use the keep-alive
(if the client supports it).
diff --git a/src/proto_http.c b/src/proto_http.c
index 73f9fd1..c94efff 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -79,18 +79,17 @@
 	.len = sizeof(HTTP_200)-1
 };
 
+/* Warning: no "connection" header is provided with the 3xx messages below */
 const char *HTTP_301 =
 	"HTTP/1.1 301 Moved Permanently\r\n"
 	"Cache-Control: no-cache\r\n"
 	"Content-length: 0\r\n"
-	"Connection: close\r\n"
 	"Location: "; /* not terminated since it will be concatenated with the URL */
 
 const char *HTTP_302 =
 	"HTTP/1.1 302 Found\r\n"
 	"Cache-Control: no-cache\r\n"
 	"Content-length: 0\r\n"
-	"Connection: close\r\n"
 	"Location: "; /* not terminated since it will be concatenated with the URL */
 
 /* same as 302 except that the browser MUST retry with the GET method */
@@ -98,7 +97,6 @@
 	"HTTP/1.1 303 See Other\r\n"
 	"Cache-Control: no-cache\r\n"
 	"Content-length: 0\r\n"
-	"Connection: close\r\n"
 	"Location: "; /* not terminated since it will be concatenated with the URL */
 
 /* Warning: this one is an sprintf() fmt string, with <realm> as its only argument */
@@ -670,8 +668,8 @@
 
 	memcpy(rdr.str + rdr.len, path, len);
 	rdr.len += len;
-	memcpy(rdr.str + rdr.len, "\r\n\r\n", 4);
-	rdr.len += 4;
+	memcpy(rdr.str + rdr.len, "\r\nConnection: close\r\n\r\n", 23);
+	rdr.len += 23;
 
 	/* prepare to return without error. */
 	si->shutr(si);
@@ -2787,15 +2785,38 @@
 				rdr.len += 2;
 			}
 
-			/* add end of headers */
-			memcpy(rdr.str + rdr.len, "\r\n\r\n", 4);
-			rdr.len += 4;
-
+			/* add end of headers and the keep-alive/close status.
+			 * We may choose to set keep-alive if the Location begins
+			 * with a slash, because the client will come back to the
+			 * same server.
+			 */
 			txn->status = rule->code;
 			/* let's log the request time */
 			s->logs.tv_request = now;
-			stream_int_retnclose(req->prod, &rdr);
-			goto return_prx_cond;
+
+			if (rule->rdr_len >= 1 && *rule->rdr_str == '/' &&
+			    (txn->flags & TX_REQ_XFER_LEN) &&
+			    !(txn->flags & TX_REQ_TE_CHNK) && !txn->req.hdr_content_len &&
+			    ((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL ||
+			     (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL)) {
+				/* keep-alive possible */
+				memcpy(rdr.str + rdr.len, "\r\nConnection: keep-alive\r\n\r\n", 28);
+				rdr.len += 28;
+				buffer_write(req->prod->ob, rdr.str, rdr.len);
+				/* "eat" the request */
+				buffer_ignore(req, msg->sov - msg->som);
+				msg->som = msg->sov;
+				req->analysers = AN_REQ_HTTP_XFER_BODY;
+				txn->req.msg_state = HTTP_MSG_DONE;
+				txn->rsp.msg_state = HTTP_MSG_CLOSED;
+				break;
+			} else {
+				/* keep-alive not possible */
+				memcpy(rdr.str + rdr.len, "\r\nConnection: close\r\n\r\n", 23);
+				rdr.len += 23;
+				stream_int_cond_close(req->prod, &rdr);
+				goto return_prx_cond;
+			}
 		}
 	}