introduce-user-handshake-filter-callback.patch
authorAndy Green <andy.green@linaro.org>
Sun, 13 Feb 2011 08:25:26 +0000 (08:25 +0000)
committerAndy Green <andy.green@linaro.org>
Sun, 13 Feb 2011 08:25:26 +0000 (08:25 +0000)
Signed-off-by: Andy Green <andy.green@linaro.org>
lib/handshake.c
lib/libwebsockets.h
lib/private-libwebsockets.h
libwebsockets-api-doc.html

index 28c02ef..7ba9683 100644 (file)
@@ -533,6 +533,19 @@ libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len)
                                 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
                 */
index b8a07c9..72962f9 100644 (file)
@@ -41,6 +41,7 @@ enum libwebsocket_callback_reasons {
        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 @@ enum libwebsocket_write_protocol {
        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 @@ struct libwebsocket_context;
  *             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.
index bf8d528..9376025 100644 (file)
@@ -99,40 +99,6 @@ enum lws_connection_states {
        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 @@ enum lws_rx_parse_state {
 };
 
 
-struct lws_tokens {
-       char *token;
-       int token_len;
-};
-
 enum connection_mode {
        LWS_CONNMODE_WS_SERVING,
        LWS_CONNMODE_WS_CLIENT,
index 40a0c0b..2c08d1f 100644 (file)
@@ -485,6 +485,59 @@ accept another write packet without blocking.  If it already
 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>