From 98a717c7ed5f63c2727e5b0856af2c69a6ae9315 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Sun, 6 Mar 2011 13:14:15 +0000 Subject: [PATCH] callback each active extension on packet rx pre parse Signed-off-by: Andy Green --- lib/libwebsockets.c | 64 ++++++++++++++++++++++++++++++++++++++-------- lib/libwebsockets.h | 1 + libwebsockets-api-doc.html | 2 +- 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index b7c9705..a8f2cf1 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -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; diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index eded025..a9627ad 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -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 { diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html index 0a039e9..0169b58 100644 --- a/libwebsockets-api-doc.html +++ b/libwebsockets-api-doc.html @@ -760,7 +760,7 @@ allows as many protocols as you like to be handled by one server.

struct libwebsocket_extension - An extension we know how to cope with

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);
+    int (*callback) (struct libwebsocket_context *context,struct libwebsocket *wsi,enum libwebsocket_extension_callback_reasons reason,void *user, void *in, size_t len);
    size_t per_session_data_size;
};

Members

-- 2.7.4