callback each active extension on packet rx pre parse
authorAndy Green <andy@warmcat.com>
Sun, 6 Mar 2011 13:14:15 +0000 (13:14 +0000)
committerAndy Green <andy@warmcat.com>
Sun, 6 Mar 2011 13:14:15 +0000 (13:14 +0000)
Signed-off-by: Andy Green <andy@warmcat.com>
lib/libwebsockets.c
lib/libwebsockets.h
libwebsockets-api-doc.html

index b7c9705..a8f2cf1 100644 (file)
@@ -448,6 +448,8 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
        char *p = &pkt[0];
        const char *pc;
        int okay = 0;
+       struct lws_tokens eff_buf;
+       int more = 1;
 #ifdef LWS_OPENSSL_SUPPORT
        char ssl_err_buf[512];
 #endif
@@ -1417,30 +1419,70 @@ bail2:
 
 #ifdef LWS_OPENSSL_SUPPORT
                if (wsi->ssl)
-                       n = SSL_read(wsi->ssl, buf, sizeof buf);
+                       eff_buf.token_len = SSL_read(wsi->ssl, buf, sizeof buf);
                else
 #endif
-                       n = recv(pollfd->fd, buf, sizeof buf, 0);
+                       eff_buf.token_len =
+                                          recv(pollfd->fd, buf, sizeof buf, 0);
 
-               if (n < 0) {
-                       fprintf(stderr, "Socket read returned %d\n", n);
+               if (eff_buf.token_len < 0) {
+                       fprintf(stderr, "Socket read returned %d\n",
+                                                           eff_buf.token_len);
                        break;
                }
-               if (!n) {
+               if (!eff_buf.token_len) {
                        libwebsocket_close_and_free_session(context, wsi,
                                                     LWS_CLOSE_STATUS_NOSTATUS);
                        return 1;
                }
 
-               /* service incoming data */
+               /*
+                * give any active extensions a chance to munge the buffer
+                * before parse.  We pass in a pointer to an lws_tokens struct
+                * prepared with the default buffer and content length that's in
+                * there.  Rather than rewrite the default buffer, extensions
+                * that expect to grow the buffer can adapt .token to
+                * point to their own per-connection buffer in the extension
+                * user allocation.  By default with no extensions or no
+                * extension callback handling, just the normal input buffer is
+                * used then so it is efficient.
+                */
 
-               n = libwebsocket_read(context, wsi, buf, n);
-               if (n >= 0)
-                       break;
+               eff_buf.token = (char *)buf;
+
+               more = 1;
+               while (more) {
+
+                       more = 0;
+
+                       for (n = 0; n < wsi->count_active_extensions; n++) {
+                               m = wsi->active_extensions[n]->callback(context, wsi,
+                                       LWS_EXT_CALLBACK_PACKET_RX_PREPARSE,
+                                    wsi->active_extensions_user[n], &eff_buf, 0);
+                               if (m < 0) {
+                                       fprintf(stderr, "Extension reports fatal error\n");
+                                       libwebsocket_close_and_free_session(context, wsi,
+                                                            LWS_CLOSE_STATUS_NOSTATUS);
+                                       return 1;
+                               }
+                               if (m)
+                                       more = 1;
+                       }
 
-               /* we closed wsi */
+                       /* service incoming data */
 
-               return 1;
+                       if (eff_buf.token_len) {
+                               n = libwebsocket_read(context, wsi,
+                                    (unsigned char *)eff_buf.token, eff_buf.token_len);
+                               if (n < 0)
+                                       /* we closed wsi */
+                                       return 1;
+                       }
+
+                       eff_buf.token = NULL;
+                       eff_buf.token_len = 0;
+               }
+               break;
        }
 
        return 0;
index eded025..a9627ad 100644 (file)
@@ -74,6 +74,7 @@ enum libwebsocket_callback_reasons {
 enum libwebsocket_extension_callback_reasons {
        LWS_EXT_CALLBACK_CONSTRUCT,
        LWS_EXT_CALLBACK_DESTROY,
+       LWS_EXT_CALLBACK_PACKET_RX_PREPARSE,
 };
 
 enum libwebsocket_write_protocol {
index 0a039e9..0169b58 100644 (file)
@@ -760,7 +760,7 @@ allows as many protocols as you like to be handled by one server.
 <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>int (*</i><b>callback</b>) <i>(struct libwebsocket_context *context,struct libwebsocket *wsi,enum libwebsocket_extension_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>