introduce-user-handshake-filter-callback.patch

Signed-off-by: Andy Green <andy.green@linaro.org>
diff --git a/lib/handshake.c b/lib/handshake.c
index 28c02ef..7ba9683 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -533,6 +533,19 @@
 				 atoi(wsi->utf8_token[WSI_TOKEN_VERSION].token);
 
 		/*
+		 * Give the user code a chance to study the request and
+		 * have the opportunity to deny it
+		 */
+
+		if ((wsi->protocol->callback)(wsi,
+				LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
+						&wsi->utf8_token[0], NULL, 0)) {
+			fprintf(stderr, "User code denied connection\n");
+			goto bail;
+		}
+
+
+		/*
 		 * Perform the handshake according to the protocol version the
 		 * client announced
 		 */
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index b8a07c9..72962f9 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -41,6 +41,7 @@
 	LWS_CALLBACK_CLIENT_WRITEABLE,
 	LWS_CALLBACK_HTTP,
 	LWS_CALLBACK_BROADCAST,
+	LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
 
 	/* external poll() management support */
 	LWS_CALLBACK_ADD_POLL_FD,
@@ -71,6 +72,52 @@
 	LWS_WRITE_CLIENT_IGNORE_XOR_MASK = 0x80
 };
 
+/*
+ * you need these to look at headers that have been parsed if using the
+ * LWS_CALLBACK_FILTER_CONNECTION callback.  If a header from the enum
+ * list below is absent, .token = NULL and token_len = 0.  Otherwise .token
+ * points to .token_len chars containing that header content.
+ */
+
+struct lws_tokens {
+	char *token;
+	int token_len;
+};
+
+enum lws_token_indexes {
+	WSI_TOKEN_GET_URI,
+	WSI_TOKEN_HOST,
+	WSI_TOKEN_CONNECTION,
+	WSI_TOKEN_KEY1,
+	WSI_TOKEN_KEY2,
+	WSI_TOKEN_PROTOCOL,
+	WSI_TOKEN_UPGRADE,
+	WSI_TOKEN_ORIGIN,
+	WSI_TOKEN_DRAFT,
+	WSI_TOKEN_CHALLENGE,
+
+	/* new for 04 */
+	WSI_TOKEN_KEY,
+	WSI_TOKEN_VERSION,
+	WSI_TOKEN_SWORIGIN,
+
+	/* new for 05 */
+	WSI_TOKEN_EXTENSIONS,
+
+	/* client receives these */
+	WSI_TOKEN_ACCEPT,
+	WSI_TOKEN_NONCE,
+	WSI_TOKEN_HTTP,
+
+	/* always last real token index*/
+	WSI_TOKEN_COUNT,
+	/* parser state additions */
+	WSI_TOKEN_NAME_PART,
+	WSI_TOKEN_SKIPPING,
+	WSI_TOKEN_SKIPPING_SAW_CR,
+	WSI_PARSING_COMPLETE
+};
+
 struct libwebsocket;
 struct libwebsocket_context;
 
@@ -133,6 +180,16 @@
  *		was able to take another packet without blocking, you'll get
  *		this callback at the next call to the service loop function.
  *
+ * 	LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: called when the handshake has
+ * 		been received and parsed from the client, but the response is
+ * 		not sent yet.  Return non-zero to disallow the connection.
+ *		@user is a pointer to an array of struct lws_tokens, you can
+ *		use the header enums lws_token_indexes from libwebsockets.h
+ *		to check for and read the supported header presence and
+ *		content before deciding to allow the handshake to proceed or
+ *		to kill the connection.
+ *
+ *
  *	The next four reasons are optional and only need taking care of if you
  * 	will be integrating libwebsockets sockets into an external polling
  * 	array.
diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h
index bf8d528..9376025 100644
--- a/lib/private-libwebsockets.h
+++ b/lib/private-libwebsockets.h
@@ -99,40 +99,6 @@
 	WSI_STATE_RETURNED_CLOSE_ALREADY
 };
 
-enum lws_token_indexes {
-	WSI_TOKEN_GET_URI,
-	WSI_TOKEN_HOST,
-	WSI_TOKEN_CONNECTION,
-	WSI_TOKEN_KEY1,
-	WSI_TOKEN_KEY2,
-	WSI_TOKEN_PROTOCOL,
-	WSI_TOKEN_UPGRADE,
-	WSI_TOKEN_ORIGIN,
-	WSI_TOKEN_DRAFT,
-	WSI_TOKEN_CHALLENGE,
-
-	/* new for 04 */
-	WSI_TOKEN_KEY,
-	WSI_TOKEN_VERSION,
-	WSI_TOKEN_SWORIGIN,
-
-	/* new for 05 */
-	WSI_TOKEN_EXTENSIONS,
-
-	/* client receives these */
-	WSI_TOKEN_ACCEPT,
-	WSI_TOKEN_NONCE,
-	WSI_TOKEN_HTTP,
-
-	/* always last real token index*/
-	WSI_TOKEN_COUNT,
-	/* parser state additions */
-	WSI_TOKEN_NAME_PART,
-	WSI_TOKEN_SKIPPING,
-	WSI_TOKEN_SKIPPING_SAW_CR,
-	WSI_PARSING_COMPLETE
-};
-
 enum lws_rx_parse_state {
 	LWS_RXPS_NEW,
 
@@ -161,11 +127,6 @@
 };
 
 
-struct lws_tokens {
-	char *token;
-	int token_len;
-};
-
 enum connection_mode {
 	LWS_CONNMODE_WS_SERVING,
 	LWS_CONNMODE_WS_CLIENT,
diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html
index 40a0c0b..2c08d1f 100644
--- a/libwebsockets-api-doc.html
+++ b/libwebsockets-api-doc.html
@@ -485,6 +485,59 @@
 was able to take another packet without blocking, you'll get
 this callback at the next call to the service loop function.
 </blockquote>
+<h3>LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION</h3>
+<blockquote>
+called when the handshake has
+been received and parsed from the client, but the response is
+not sent yet.  Return non-zero to disallow the connection.
+<tt><b>user</b></tt> is a pointer to an array of 
+<p>
+<p>
+The next four reasons are optional and only need taking care of if you
+will be integrating libwebsockets sockets into an external polling
+array.
+</blockquote>
+<h3>LWS_CALLBACK_ADD_POLL_FD</h3>
+<blockquote>
+libwebsocket deals with its <b>poll</b> loop
+internally, but in the case you are integrating with another
+server you will need to have libwebsocket sockets share a
+polling array with the other server.  This and the other
+POLL_FD related callbacks let you put your specialized
+poll array interface code in the callback for protocol 0, the
+first protocol you support, usually the HTTP protocol in the
+serving case.  This callback happens when a socket needs to be
+</blockquote>
+<h3>added to the polling loop</h3>
+<blockquote>
+<tt><b>user</b></tt> contains the fd, and
+<tt><b>len</b></tt> is the events bitmap (like, POLLIN).  If you are using the
+internal polling loop (the "service" callback), you can just
+ignore these callbacks.
+</blockquote>
+<h3>LWS_CALLBACK_DEL_POLL_FD</h3>
+<blockquote>
+This callback happens when a socket descriptor
+needs to be removed from an external polling array.  <tt><b>user</b></tt> is
+the socket desricptor.  If you are using the internal polling
+loop, you can just ignore it.
+</blockquote>
+<h3>LWS_CALLBACK_SET_MODE_POLL_FD</h3>
+<blockquote>
+This callback happens when libwebsockets
+wants to modify the events for the socket descriptor in <tt><b>user</b></tt>.
+The handler should OR <tt><b>len</b></tt> on to the events member of the pollfd
+struct for this socket descriptor.  If you are using the
+internal polling loop, you can just ignore it.
+</blockquote>
+<h3>LWS_CALLBACK_CLEAR_MODE_POLL_FD</h3>
+<blockquote>
+This callback occurs when libwebsockets
+wants to modify the events for the socket descriptor in <tt><b>user</b></tt>.
+The handler should AND ~<tt><b>len</b></tt> on to the events member of the
+pollfd struct for this socket descriptor.  If you are using the
+internal polling loop, you can just ignore it.
+</blockquote>
 <hr>
 <h2>struct libwebsocket_protocols - List of protocols and handlers server supports.</h2>
 <b>struct libwebsocket_protocols</b> {<br>