MEDIUM: HTTP compression (zlib library support)

This commit introduces HTTP compression using the zlib library.

http_response_forward_body has been modified to call the compression
functions.

This feature includes 3 algorithms: identity, gzip and deflate:

  * identity: this is mostly for debugging, and it was useful for
  developping the compression feature. With Content-Length in input, it
  is making each chunk with the data available in the current buffer.
  With chunks in input, it is rechunking, the output chunks will be
  bigger or smaller depending of the size of the input chunk and the
  size of the buffer. Identity does not apply any change on data.

  * gzip: same as identity, but applying a gzip compression. The data
  are deflated using the Z_NO_FLUSH flag in zlib. When there is no more
  data in the input buffer, it flushes the data in the output buffer
  (Z_SYNC_FLUSH). At the end of data, when it receives the last chunk in
  input, or when there is no more data to read, it writes the end of
  data with Z_FINISH and the ending chunk.

  * deflate: same as gzip, but with deflate algorithm and zlib format.
  Note that this algorithm has ambiguous support on many browsers and
  no support at all from recent ones. It is strongly recommended not
  to use it for anything else than experimentation.

You can't choose the compression ratio at the moment, it will be set to
Z_BEST_SPEED (1), as tests have shown very little benefit in terms of
compression ration when going above for HTML contents, at the cost of
a massive CPU impact.

Compression will be activated depending of the Accept-Encoding request
header. With identity, it does not take care of that header.

To build HAProxy with zlib support, use USE_ZLIB=1 in the make
parameters.

This work was initially started by David Du Colombier at Exceliance.
diff --git a/include/types/compression.h b/include/types/compression.h
new file mode 100644
index 0000000..96dd107
--- /dev/null
+++ b/include/types/compression.h
@@ -0,0 +1,63 @@
+/*
+ * include/types/compression.h
+ * This file defines everything related to compression.
+ *
+ * Copyright 2012 Exceliance, David Du Colombier <dducolombier@exceliance.fr>
+                              William Lallemand <wlallemand@exceliance.fr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, version 2.1
+ * exclusively.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TYPES_COMP_H
+#define _TYPES_COMP_H
+
+#include <zlib.h>
+
+struct comp {
+	struct comp_algo *algos;
+	struct comp_type *types;
+};
+
+struct comp_algo {
+	char *name;
+	int name_len;
+	int (*init)(void *, int);
+	int (*add_data)(void *v, const char *in_data, int in_len, char *out_data, int out_len);
+	int (*flush)(void *v, struct buffer *out, int flag);
+	int (*reset)(void *v);
+	int (*end)(void *v);
+	struct comp_algo *next;
+};
+
+union comp_ctx {
+	z_stream strm; /* zlib */
+};
+
+struct comp_type {
+	char *name;
+	int name_len;
+	struct comp_type *next;
+};
+
+
+#endif /* _TYPES_COMP_H */
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ * End:
+ */
+
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 9bfa68d..343d4ad 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -363,6 +363,7 @@
 		struct list listeners;		/* list of listeners belonging to this frontend */
 	} conf;					/* config information */
 	void *parent;				/* parent of the proxy when applicable */
+	struct comp *comp;			/* http compression */
 };
 
 struct switching_rule {
diff --git a/include/types/session.h b/include/types/session.h
index e3ccde8..4726a19 100644
--- a/include/types/session.h
+++ b/include/types/session.h
@@ -32,6 +32,7 @@
 #include <common/mini-clist.h>
 
 #include <types/channel.h>
+#include <types/compression.h>
 #include <types/proto_http.h>
 #include <types/proxy.h>
 #include <types/queue.h>
@@ -155,6 +156,8 @@
 	void (*srv_error)(struct session *s,	/* the function to call upon unrecoverable server errors (or NULL) */
 			  struct stream_interface *si);
 	unsigned int uniq_id;			/* unique ID used for the traces */
+	struct comp_algo *comp_algo;		/* HTTP compression algorithm if not NULL */
+	union comp_ctx comp_ctx;		/* HTTP compression context */
 	char *unique_id;			/* custom unique ID */
 };