[MAJOR] implement parameter hashing for POST requests

This patch extends the "url_param" load balancing method by introducing
the "check_post" option. Using this option enables analysis of the beginning
of POST requests to search for the specified URL parameter.

The patch also fixes a few minor typos in comments that were discovered
during code review.
diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h
index 523471d..68b3f11 100644
--- a/include/proto/proto_http.h
+++ b/include/proto/proto_http.h
@@ -81,6 +81,9 @@
 void check_response_for_cacheability(struct session *t, struct buffer *rtr);
 int stats_check_uri_auth(struct session *t, struct proxy *backend);
 void init_proto_http();
+int http_find_header2(const char *name, int len,
+		      const char *sol, struct hdr_idx *idx,
+		      struct hdr_ctx *ctx);
 
 #endif /* _PROTO_PROTO_HTTP_H */
 
diff --git a/include/types/backend.h b/include/types/backend.h
index 2d62722..6d576b8 100644
--- a/include/types/backend.h
+++ b/include/types/backend.h
@@ -1,6 +1,6 @@
 /*
   include/types/backend.h
-  This file rassembles definitions for backends
+  This file assembles definitions for backends
 
   Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
   
@@ -46,7 +46,7 @@
 
 /* various constants */
 
-/* The scale factor between user weight an effective weight allows smooth
+/* The scale factor between user weight and effective weight allows smooth
  * weight modulation even with small weights (eg: 1). It should not be too high
  * though because it limits the number of servers in FWRR mode in order to
  * prevent any integer overflow. The max number of servers per backend is
diff --git a/include/types/proto_http.h b/include/types/proto_http.h
index 50d12d6..885fbc6 100644
--- a/include/types/proto_http.h
+++ b/include/types/proto_http.h
@@ -29,29 +29,18 @@
 
 /*
  * FIXME: break this into HTTP state and TCP socket state.
- * See server.h for the other end.
- */
-
-/* different possible states for the client side */
-#define CL_STHEADERS	0
-#define CL_STDATA	1
-#define CL_STSHUTR	2
-#define CL_STSHUTW	3
-#define CL_STCLOSE	4
-
-/*
- * FIXME: break this into HTTP state and TCP socket state.
  * See client.h for the other end.
  */
 
 /* different possible states for the server side */
 #define SV_STIDLE	0
-#define SV_STCONN	1
-#define SV_STHEADERS	2
-#define SV_STDATA	3
-#define SV_STSHUTR	4
-#define SV_STSHUTW	5
-#define SV_STCLOSE	6
+#define SV_STANALYZE	1  /* this server state is set by the client to study the body for server assignment */
+#define SV_STCONN	2
+#define SV_STHEADERS	3
+#define SV_STDATA	4
+#define SV_STSHUTR	5
+#define SV_STSHUTW	6
+#define SV_STCLOSE	7
 
 /*
  * Transaction flags moved from session
@@ -204,27 +193,28 @@
  *                             which marks the end of the line (LF or CRLF).
  */
 struct http_msg {
-	unsigned int msg_state;         /* where we are in the current message parsing */
-	char *sol;                      /* start of line, also start of message when fully parsed */
-	char *eol;                      /* end of line */
-	unsigned int som;		/* Start Of Message, relative to buffer */
-	unsigned int col, sov;		/* current header: colon, start of value */
-	unsigned int eoh;		/* End Of Headers, relative to buffer */
-	char **cap;			/* array of captured headers (may be NULL) */
-	union {				/* useful start line pointers, relative to buffer */
+	unsigned int msg_state;                /* where we are in the current message parsing */
+	char *sol;                             /* start of line, also start of message when fully parsed */
+	char *eol;                             /* end of line */
+	unsigned int som;                      /* Start Of Message, relative to buffer */
+	unsigned int col, sov;                 /* current header: colon, start of value */
+	unsigned int eoh;                      /* End Of Headers, relative to buffer */
+	char **cap;                            /* array of captured headers (may be NULL) */
+	union {                                /* useful start line pointers, relative to buffer */
 		struct {
-			int l;		/* request line length (not including CR) */
-			int m_l;	/* METHOD length (method starts at ->som) */
-			int u, u_l;	/* URI, length */
-			int v, v_l;	/* VERSION, length */
-		} rq;			/* request line : field, length */
+			int l;                 /* request line length (not including CR) */
+			int m_l;               /* METHOD length (method starts at ->som) */
+			int u, u_l;            /* URI, length */
+			int v, v_l;            /* VERSION, length */
+		} rq;                          /* request line : field, length */
 		struct {
-			int l;		/* status line length (not including CR) */
-			int v_l;	/* VERSION length (version starts at ->som) */
-			int c, c_l;	/* CODE, length */
-			int r, r_l;	/* REASON, length */
-		} st;			/* status line : field, length */
-	} sl;				/* start line */
+			int l;                 /* status line length (not including CR) */
+			int v_l;               /* VERSION length (version starts at ->som) */
+			int c, c_l;            /* CODE, length */
+			int r, r_l;            /* REASON, length */
+		} st;                          /* status line : field, length */
+	} sl;                                  /* start line */
+	unsigned long long hdr_content_len;    /* cache for parsed header value */
 };
 
 /* This is an HTTP transaction. It contains both a request message and a
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 98baf53..091be57 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -165,6 +165,7 @@
 	int  cookie_len;			/* strlen(cookie_name), computed only once */
 	char *url_param_name;			/* name of the URL parameter used for hashing */
 	int  url_param_len;			/* strlen(url_param_name), computed only once */
+	unsigned url_param_post_limit;		/* if checking POST body for URI parameter, max body to wait for */
 	char *appsession_name;			/* name of the cookie to look for */
 	int  appsession_name_len;		/* strlen(appsession_name), computed only once */
 	int  appsession_len;			/* length of the appsession cookie value to be used */