introduce struct libwebsocket_extension

Signed-off-by: Andy Green <andy@warmcat.com>
diff --git a/lib/client-handshake.c b/lib/client-handshake.c
index 05959a7..74f894d 100644
--- a/lib/client-handshake.c
+++ b/lib/client-handshake.c
@@ -64,6 +64,7 @@
 	wsi->pings_vs_pongs = 0;
 	wsi->protocol = NULL;
 	wsi->pending_timeout = NO_PENDING_TIMEOUT;
+	wsi->count_active_extensions = 0;
 #ifdef LWS_OPENSSL_SUPPORT
 	wsi->use_ssl = ssl_connection;
 #endif
diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c
index c00a8ea..c59bbdd 100644
--- a/lib/libwebsockets.c
+++ b/lib/libwebsockets.c
@@ -516,6 +516,7 @@
 
 		memset(new_wsi, 0, sizeof (struct libwebsocket));
 		new_wsi->sock = accept_fd;
+		new_wsi->count_active_extensions = 0;
 		new_wsi->pending_timeout = NO_PENDING_TIMEOUT;
 
 #ifdef LWS_OPENSSL_SUPPORT
@@ -644,6 +645,7 @@
 		new_wsi->sock = accept_fd;
 		new_wsi->mode = LWS_CONNMODE_BROADCAST_PROXY;
 		new_wsi->state = WSI_STATE_ESTABLISHED;
+		new_wsi->count_active_extensions = 0;
 		/* note which protocol we are proxying */
 		new_wsi->protocol_index_for_broadcast_proxy =
 					wsi->protocol_index_for_broadcast_proxy;
@@ -1769,6 +1771,7 @@
 struct libwebsocket_context *
 libwebsocket_create_context(int port, const char *interf,
 			       struct libwebsocket_protocols *protocols,
+			       struct libwebsocket_extension *extensions,
 			       const char *ssl_cert_filepath,
 			       const char *ssl_private_key_filepath,
 			       int gid, int uid, unsigned int options)
@@ -1822,6 +1825,7 @@
 	context->http_proxy_address[0] = '\0';
 	context->options = options;
 	context->fds_count = 0;
+	context->extensions = extensions;
 
 #ifdef WIN32
 	context->fd_random = 0;
@@ -2067,6 +2071,7 @@
 		wsi = malloc(sizeof(struct libwebsocket));
 		memset(wsi, 0, sizeof (struct libwebsocket));
 		wsi->sock = sockfd;
+		wsi->count_active_extensions = 0;
 		wsi->mode = LWS_CONNMODE_SERVER_LISTENER;
 		insert_wsi(context, wsi);
 
@@ -2146,6 +2151,7 @@
 		memset(wsi, 0, sizeof (struct libwebsocket));
 		wsi->sock = fd;
 		wsi->mode = LWS_CONNMODE_BROADCAST_PROXY_LISTENER;
+		wsi->count_active_extensions = 0;
 		/* note which protocol we are proxying */
 		wsi->protocol_index_for_broadcast_proxy =
 						       context->count_protocols;
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index 1bf43bf..5402ee1 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -401,9 +401,31 @@
 	int protocol_index;
 };
 
+/**
+ * struct libwebsocket_extension -	An extension we know how to cope with
+ *
+ * @name:			Formal extension name, eg, "deflate-stream"
+ * @callback:			Service callback
+ * @per_session_data_size: 	Libwebsockets will auto-malloc this much
+ * 				memory for the use of the extension, a pointer
+ *				to it comes in the @user callback parameter
+ */
+
+struct libwebsocket_extension {
+	const char *name;
+	int (*callback)(struct libwebsocket_context *context,
+			struct libwebsocket *wsi,
+			enum libwebsocket_callback_reasons reason, void *user,
+							  void *in, size_t len);
+	size_t per_session_data_size;
+};
+
+
+
 extern struct libwebsocket_context *
 libwebsocket_create_context(int port, const char * interf,
 		  struct libwebsocket_protocols *protocols,
+		  struct libwebsocket_extension *extensions,
 		  const char *ssl_cert_filepath,
 		  const char *ssl_private_key_filepath, int gid, int uid,
 		  unsigned int options);
diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h
index 0504c07..94802ae 100644
--- a/lib/private-libwebsockets.h
+++ b/lib/private-libwebsockets.h
@@ -107,6 +107,7 @@
 #define MAX_USER_RX_BUFFER 4096
 #define MAX_BROADCAST_PAYLOAD 2048
 #define LWS_MAX_PROTOCOLS 10
+#define LWS_MAX_EXTENSIONS_ACTIVE 10
 #define SPEC_LATEST_SUPPORTED 6
 
 #define MAX_WEBSOCKET_04_KEY_LEN 128
@@ -203,6 +204,7 @@
 #endif
 	struct libwebsocket_protocols *protocols;
 	int count_protocols;
+	struct libwebsocket_extension *extensions;
 };
 
 
@@ -223,6 +225,10 @@
 
 struct libwebsocket {
 	const struct libwebsocket_protocols *protocol;
+	const struct libwebsocket_extension *
+				   active_extensions[LWS_MAX_EXTENSIONS_ACTIVE];
+	void * active_extensions_user[LWS_MAX_EXTENSIONS_ACTIVE];
+	int count_active_extensions;
 
 	enum lws_connection_states state;
 
diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html
index 70bf4f2..239f393 100644
--- a/libwebsockets-api-doc.html
+++ b/libwebsockets-api-doc.html
@@ -221,6 +221,7 @@
 (<i>int</i> <b>port</b>,
 <i>const char *</i> <b>interf</b>,
 <i>struct libwebsocket_protocols *</i> <b>protocols</b>,
+<i>struct libwebsocket_extension *</i> <b>extensions</b>,
 <i>const char *</i> <b>ssl_cert_filepath</b>,
 <i>const char *</i> <b>ssl_private_key_filepath</b>,
 <i>int</i> <b>gid</b>,
@@ -740,3 +741,21 @@
 allows as many protocols as you like to be handled by one server.
 </blockquote>
 <hr>
+<h2>struct libwebsocket_extension - An extension we know how to cope with</h2>
+<b>struct libwebsocket_extension</b> {<br>
+&nbsp; &nbsp; <i>const char *</i> <b>name</b>;<br>
+&nbsp; &nbsp; <i>int (*</i><b>callback</b>) <i>(struct libwebsocket_context *context,struct libwebsocket *wsi,enum libwebsocket_callback_reasons reason, void *user,void *in, size_t len)</i>;<br>
+&nbsp; &nbsp; <i>size_t</i> <b>per_session_data_size</b>;<br>
+};<br>
+<h3>Members</h3>
+<dl>
+<dt><b>name</b>
+<dd>Formal extension name, eg, "deflate-stream"
+<dt><b>callback</b>
+<dd>Service callback
+<dt><b>per_session_data_size</b>
+<dd>Libwebsockets will auto-malloc this much
+memory for the use of the extension, a pointer
+to it comes in the <tt><b>user</b></tt> callback parameter
+</dl>
+<hr>
diff --git a/test-server/test-client.c b/test-server/test-client.c
index c1abff7..0f67c12 100644
--- a/test-server/test-client.c
+++ b/test-server/test-client.c
@@ -227,7 +227,8 @@
 	 */
 
 	context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL,
-					      protocols, NULL, NULL, -1, -1, 0);
+					      protocols, NULL,
+					      NULL, NULL, -1, -1, 0);
 	if (context == NULL) {
 		fprintf(stderr, "Creating libwebsocket context failed\n");
 		return 1;
diff --git a/test-server/test-ping.c b/test-server/test-ping.c
index 1ecfb4d..7bbaf24 100644
--- a/test-server/test-ping.c
+++ b/test-server/test-ping.c
@@ -401,7 +401,8 @@
 				screen_width = w.ws_col;
 
 	context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL,
-					      protocols, NULL, NULL, -1, -1, 0);
+					      protocols, NULL,
+					      NULL, NULL, -1, -1, 0);
 	if (context == NULL) {
 		fprintf(stderr, "Creating libwebsocket context failed\n");
 		return 1;
diff --git a/test-server/test-server-extpoll.c b/test-server/test-server-extpoll.c
index 803d5dc..023ee96 100644
--- a/test-server/test-server-extpoll.c
+++ b/test-server/test-server-extpoll.c
@@ -474,6 +474,7 @@
 		cert_path = key_path = NULL;
 
 	context = libwebsocket_create_context(port, interface, protocols,
+					NULL,
 					cert_path, key_path, -1, -1, opts);
 	if (context == NULL) {
 		fprintf(stderr, "libwebsocket init failed\n");
diff --git a/test-server/test-server.c b/test-server/test-server.c
index 3cecb7f..1035fe5 100644
--- a/test-server/test-server.c
+++ b/test-server/test-server.c
@@ -426,6 +426,7 @@
 		cert_path = key_path = NULL;
 
 	context = libwebsocket_create_context(port, interface, protocols,
+				NULL,
 				cert_path, key_path, -1, -1, opts);
 	if (context == NULL) {
 		fprintf(stderr, "libwebsocket init failed\n");