1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

Added support for extensions that only manipulate application data.

This commit is contained in:
David Galeano 2013-01-09 18:06:55 +08:00 committed by Andy Green
parent d58c6ab78d
commit e2cf992571
4 changed files with 97 additions and 27 deletions

View file

@ -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)
{

View file

@ -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);

View file

@ -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 */

View file

@ -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);