instantiate extensions server accepted
authorAndy Green <andy@warmcat.com>
Sun, 6 Mar 2011 13:15:31 +0000 (13:15 +0000)
committerAndy Green <andy@warmcat.com>
Sun, 6 Mar 2011 13:15:31 +0000 (13:15 +0000)
Signed-off-by: Andy Green <andy@warmcat.com>
lib/libwebsockets.c
lib/libwebsockets.h
libwebsockets-api-doc.html

index 444357b..efce3db 100644 (file)
@@ -552,7 +552,10 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
        char pkt[1024];
        char *p = &pkt[0];
        const char *pc;
+       const char *c;
+       int more = 1;
        int okay = 0;
+       char ext_name[128];
        struct lws_tokens eff_buf;
        int more = 1;
        int ext_count = 0;
@@ -1432,6 +1435,74 @@ select_protocol:
                        goto bail2;
                }
 
+
+               /* instantiate the accepted extensions */
+
+               if (!wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token_len)
+                       goto check_accept;
+
+               /*
+                * break down the list of server accepted extensions
+                * and go through matching them or identifying bogons
+                */
+
+               c = wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token;
+               n = 0;
+               while (more) {
+                       
+                       if (*c && *c != ',') {
+                               ext_name[n] = *c++;
+                               if (n < sizeof(ext_name) - 1)
+                                       n++;
+                               continue;
+                       }
+                       ext_name[n] = '\0';
+                       if (!*c)
+                               more = 0;
+
+                       /* check we actually support it */
+
+                       n = 0;
+                       ext = wsi->protocol->owning_server->extensions;
+                       while (ext && ext->callback) {
+
+                               if (strcmp(ext_name, ext->name)) {
+                                       ext++;
+                                       continue;
+                               }
+
+                               n = 1;
+
+                               /* instantiate the extension on this conn */
+
+                               wsi->active_extensions_user[
+                                       wsi->count_active_extensions] =
+                                            malloc(ext->per_session_data_size);
+                               wsi->active_extensions[
+                                         wsi->count_active_extensions] = ext;
+
+                               /* allow him to construct his context */
+
+                               ext->callback(wsi->protocol->owning_server,
+                                       wsi, LWS_EXT_CALLBACK_CLIENT_CONSTRUCT,
+                                               wsi->active_extensions_user[
+                                       wsi->count_active_extensions], NULL, 0);
+
+                               wsi->count_active_extensions++;
+
+                               ext++;
+                       }
+
+                       if (n == 0) {
+                               fprintf(stderr, "Server said we should use"
+                                     "an unknown extension '%s'!\n", ext_name);
+                               goto bail2;
+                       }
+
+                       n = 0;
+               }
+
+
        check_accept:
 
                if (wsi->ietf_spec_revision == 0) {
index 3b2c11a..21b99b1 100644 (file)
@@ -74,6 +74,7 @@ enum libwebsocket_callback_reasons {
 
 enum libwebsocket_extension_callback_reasons {
        LWS_EXT_CALLBACK_CONSTRUCT,
+       LWS_EXT_CALLBACK_CLIENT_CONSTRUCT,
        LWS_EXT_CALLBACK_DESTROY,
        LWS_EXT_CALLBACK_PACKET_RX_PREPARSE,
        LWS_EXT_CALLBACK_PACKET_TX_PRESEND,
@@ -408,11 +409,17 @@ extern int callback(struct libwebsocket_context * context,
  *             extension a chance to initialize its connection context found
  *             in @user.
  *
+ *     LWS_EXT_CALLBACK_CLIENT_CONSTRUCT: same as LWS_EXT_CALLBACK_CONSTRUCT
+ *             but called when client is instantiating this extension.  Some
+ *             extensions will work the same on client and server side and then
+ *             you can just merge handlers for both CONSTRUCTS.
+ *
  *     LWS_EXT_CALLBACK_DESTROY:  called when the connection the extension was
  *             being used on is about to be closed and deallocated.  It's the
  *             last chance for the extension to deallocate anything it has
  *             allocated in the user data (pointed to by @user) before the
- *             user data is deleted.
+ *             user data is deleted.  This same callback is used whether you
+ *             are in client or server instantiation context.
  *
  *     LWS_EXT_CALLBACK_PACKET_RX_PREPARSE: when this extension was active on
  *             a connection, and a packet of data arrived at the connection,
index a82383b..d3c83d7 100644 (file)
@@ -765,13 +765,21 @@ the connection with this extension active.  This gives the
 extension a chance to initialize its connection context found
 in <tt><b>user</b></tt>.
 </blockquote>
+<h3>LWS_EXT_CALLBACK_CLIENT_CONSTRUCT</h3>
+<blockquote>
+same as LWS_EXT_CALLBACK_CONSTRUCT
+but called when client is instantiating this extension.  Some
+extensions will work the same on client and server side and then
+you can just merge handlers for both CONSTRUCTS.
+</blockquote>
 <h3>LWS_EXT_CALLBACK_DESTROY</h3>
 <blockquote>
 called when the connection the extension was
 being used on is about to be closed and deallocated.  It's the
 last chance for the extension to deallocate anything it has
 allocated in the user data (pointed to by <tt><b>user</b></tt>) before the
-user data is deleted.
+user data is deleted.  This same callback is used whether you
+are in client or server instantiation context.
 </blockquote>
 <h3>LWS_EXT_CALLBACK_PACKET_RX_PREPARSE</h3>
 <blockquote>