From: David Galeano Date: Wed, 9 Jan 2013 10:06:55 +0000 (+0800) Subject: Added support for extensions that only manipulate application data. X-Git-Tag: accepted/2.0/20130307.220733~316 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F45%2F2845%2F1;p=profile%2Fivi%2Flibwebsockets.git Added support for extensions that only manipulate application data. --- diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index 51a6b44..ee20327 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -3201,6 +3201,12 @@ libwebsocket_is_final_fragment(struct libwebsocket *wsi) return wsi->final; } +unsigned char +libwebsocket_get_reserved_bits(struct libwebsocket *wsi) +{ + return wsi->rsv; +} + void * libwebsocket_ensure_user_space(struct libwebsocket *wsi) { diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index 6a612e6..0e06670 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -117,6 +117,8 @@ enum libwebsocket_extension_callback_reasons { LWS_EXT_CALLBACK_1HZ, LWS_EXT_CALLBACK_REQUEST_ON_WRITEABLE, LWS_EXT_CALLBACK_IS_WRITEABLE, + LWS_EXT_CALLBACK_PAYLOAD_TX, + LWS_EXT_CALLBACK_PAYLOAD_RX, }; enum libwebsocket_write_protocol { @@ -699,7 +701,7 @@ libwebsocket_context_user(struct libwebsocket_context *context); */ #define LWS_SEND_BUFFER_PRE_PADDING (4 + 10 + (2 * MAX_MUX_RECURSION)) -#define LWS_SEND_BUFFER_POST_PADDING 1 +#define LWS_SEND_BUFFER_POST_PADDING 4 LWS_EXTERN int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, size_t len, @@ -732,6 +734,9 @@ libwebsocket_get_socket_fd(struct libwebsocket *wsi); LWS_EXTERN int libwebsocket_is_final_fragment(struct libwebsocket *wsi); +LWS_EXTERN unsigned char +libwebsocket_get_reserved_bits(struct libwebsocket *wsi); + LWS_EXTERN void * libwebsocket_ensure_user_space(struct libwebsocket *wsi); diff --git a/lib/parsers.c b/lib/parsers.c index 40aa0e2..0f4c2c7 100644 --- a/lib/parsers.c +++ b/lib/parsers.c @@ -462,10 +462,6 @@ handle_first: if (wsi->ietf_spec_revision < 7) c = wsi->xor_mask(wsi, c); - if (c & 0x70) - fprintf(stderr, - "Frame has unknown extension bits set 1 %02X\n", c); - /* translate all incoming opcodes into v7+ map */ if (wsi->ietf_spec_revision < 7) switch (c & 0xf) { @@ -494,7 +490,7 @@ handle_first: } else wsi->opcode = c & 0xf; - + wsi->rsv = (c & 0x70); wsi->final = !!((c >> 7) & 1); wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN; @@ -813,17 +809,37 @@ spill: * so it can be sent straight out again using libwebsocket_write */ - wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + - wsi->rx_user_buffer_head] = '\0'; + eff_buf.token = &wsi->rx_user_buffer[ + LWS_SEND_BUFFER_PRE_PADDING]; + eff_buf.token_len = wsi->rx_user_buffer_head; - if (wsi->protocol->callback) - wsi->protocol->callback(wsi->protocol->owning_server, - wsi, LWS_CALLBACK_RECEIVE, - wsi->user_space, - &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING], - wsi->rx_user_buffer_head); - else - fprintf(stderr, "No callback on payload spill!\n"); + for (n = 0; n < wsi->count_active_extensions; n++) { + m = wsi->active_extensions[n]->callback( + wsi->protocol->owning_server, + wsi->active_extensions[n], wsi, + LWS_EXT_CALLBACK_PAYLOAD_RX, + wsi->active_extensions_user[n], + &eff_buf, 0); + if (m < 0) { + fprintf(stderr, + "Extension '%s' failed to handle payload!", + wsi->active_extensions[n]->name); + return -1; + } + } + + if (eff_buf.token_len > 0) { + eff_buf.token[eff_buf.token_len] = '\0'; + + if (wsi->protocol->callback) + wsi->protocol->callback(wsi->protocol->owning_server, + wsi, LWS_CALLBACK_RECEIVE, + wsi->user_space, + eff_buf.token, + eff_buf.token_len); + else + fprintf(stderr, "No callback on payload spill!"); + } wsi->rx_user_buffer_head = 0; break; @@ -922,10 +938,6 @@ int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c) * FIN (b7) */ - if (c & 0x70) - fprintf(stderr, "Frame has unknown extension " - "bits set on first framing byte %02X\n", c); - if (wsi->ietf_spec_revision < 7) switch (c & 0xf) { case LWS_WS_OPCODE_04__CONTINUATION: @@ -956,7 +968,7 @@ int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c) } else wsi->opcode = c & 0xf; - + wsi->rsv = (c & 0x70); wsi->final = !!((c >> 7) & 1); wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN; @@ -1281,13 +1293,40 @@ spill: * It's nicely buffered with the pre-padding taken care of * so it can be sent straight out again using libwebsocket_write */ + if (handled) + goto already_done; - if (!handled && wsi->protocol->callback) - wsi->protocol->callback(wsi->protocol->owning_server, + eff_buf.token = &wsi->rx_user_buffer[ + LWS_SEND_BUFFER_PRE_PADDING]; + eff_buf.token_len = wsi->rx_user_buffer_head; + + for (n = 0; n < wsi->count_active_extensions; n++) { + m = wsi->active_extensions[n]->callback( + wsi->protocol->owning_server, + wsi->active_extensions[n], wsi, + LWS_EXT_CALLBACK_PAYLOAD_RX, + wsi->active_extensions_user[n], + &eff_buf, 0); + if (m < 0) { + fprintf(stderr, + "Extension '%s' failed to handle payload!", + wsi->active_extensions[n]->name); + return -1; + } + } + + if (eff_buf.token_len > 0) { + eff_buf.token[eff_buf.token_len] = '\0'; + + if (wsi->protocol->callback) + wsi->protocol->callback( + wsi->protocol->owning_server, wsi, callback_action, wsi->user_space, - &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING], - wsi->rx_user_buffer_head); + eff_buf.token, + eff_buf.token_len); + } +already_done: wsi->rx_user_buffer_head = 0; break; default: @@ -1519,6 +1558,8 @@ lws_issue_raw_ext_access(struct libwebsocket *wsi, eff_buf.token_len)) return -1; + debug("written %d bytes to client\n", eff_buf.token_len); + /* we used up what we had */ eff_buf.token = NULL; @@ -1544,8 +1585,6 @@ lws_issue_raw_ext_access(struct libwebsocket *wsi, ret = 0; } - debug("written %d bytes to client\n", eff_buf.token_len); - return 0; } @@ -1585,6 +1624,8 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, wsi->xor_mask != xor_no_mask; unsigned char *dropmask = NULL; unsigned char is_masked_bit = 0; + struct lws_tokens eff_buf; + int m; if (len == 0 && protocol != LWS_WRITE_CLOSE) { fprintf(stderr, "zero length libwebsocket_write attempt\n"); @@ -1599,6 +1640,23 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, if (wsi->state != WSI_STATE_ESTABLISHED) return -1; + /* give a change to the extensions to modify payload */ + eff_buf.token = (char *)buf; + eff_buf.token_len = len; + + for (n = 0; n < wsi->count_active_extensions; n++) { + m = wsi->active_extensions[n]->callback( + wsi->protocol->owning_server, + wsi->active_extensions[n], wsi, + LWS_EXT_CALLBACK_PAYLOAD_TX, + wsi->active_extensions_user[n], &eff_buf, 0); + if (m < 0) + return -1; + } + + buf = (unsigned char *)eff_buf.token; + len = eff_buf.token_len; + switch (wsi->ietf_spec_revision) { /* chrome likes this as of 30 Oct 2010 */ /* Firefox 4.0b6 likes this as of 30 Oct 2010 */ diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index ed398d2..bc55125 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -321,6 +321,7 @@ struct libwebsocket { size_t rx_packet_length; unsigned char opcode; unsigned char final; + unsigned char rsv; int pings_vs_pongs; unsigned char (*xor_mask)(struct libwebsocket *, unsigned char);