From fe5966c8b34bed24b6e94aef572d638dc2621e50 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Sun, 20 Jan 2013 17:08:31 +0800 Subject: [PATCH] introduce without extensions The new --without-extensions config flag completely removes all code and data related to extensions from the build throughout the library when given. Signed-off-by: Andy Green --- README.build | 7 ++++++ configure.ac | 11 +++++++++ lib/Makefile.am | 10 +++++--- lib/client-handshake.c | 11 +++++++-- lib/client-parser.c | 10 ++++++-- lib/client.c | 19 +++++++++------ lib/handshake.c | 26 +++++++++++++++----- lib/libwebsockets.c | 58 +++++++++++++++++++++++++++++++++++---------- lib/libwebsockets.h | 10 +++++++- lib/output.c | 24 +++++++++++++++---- lib/parsers.c | 12 ++++++---- lib/private-libwebsockets.h | 15 +++++++----- lib/server-handshake.c | 11 ++++++--- lib/server.c | 4 ++++ libwebsockets-api-doc.html | 3 ++- test-server/test-client.c | 13 +++++++--- test-server/test-fraggle.c | 4 ++++ test-server/test-ping.c | 6 ++++- test-server/test-server.c | 21 +++++++++------- 19 files changed, 211 insertions(+), 64 deletions(-) diff --git a/README.build b/README.build index 48167ff..cdb79af 100644 --- a/README.build +++ b/README.build @@ -88,6 +88,13 @@ There are several other possible configure options from the code -- it's not just defeated from logging but removed from compilation +--without-extensions Remove all code and data around protocol extensions. + This reduces the code footprint considerably but + you will lose extension features like compression. + However that may be irrelevant for embedded use and + the code / data size / speed improvements may be + critical. + Externally configurable important constants ------------------------------------------- diff --git a/configure.ac b/configure.ac index aad4687..5cc5554 100644 --- a/configure.ac +++ b/configure.ac @@ -95,7 +95,18 @@ CFLAGS="$CFLAGS -DLWS_NO_SERVER" fi AM_CONDITIONAL(NO_SERVER, test x$no_server = xyes) +# +# +# +AC_ARG_WITH(extensions, + [ --without-extensions dont build any stuff related to extensions ], + [ no_extensions=yes + ]) +if test "x$no_extensions" = "xyes" ; then +CFLAGS="$CFLAGS -DLWS_NO_EXTENSIONS" +fi +AM_CONDITIONAL(NO_EXTENSIONS, test x$no_extensions = xyes) # # diff --git a/lib/Makefile.am b/lib/Makefile.am index 8b460bc..497ec4e 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -6,11 +6,15 @@ dist_libwebsockets_la_SOURCES=libwebsockets.c \ libwebsockets.h \ base64-decode.c \ output.c \ - extension.c \ - extension-deflate-stream.c extension-deflate-stream.h \ - extension-deflate-frame.c extension-deflate-frame.h\ private-libwebsockets.h +if NO_EXTENSIONS +else +dist_libwebsockets_la_SOURCES+= extension.c \ + extension-deflate-stream.c extension-deflate-stream.h \ + extension-deflate-frame.c extension-deflate-frame.h +endif + if NO_DAEMONIZE else dist_libwebsockets_la_SOURCES+= daemonize.c diff --git a/lib/client-handshake.c b/lib/client-handshake.c index 6faadad..ff20b17 100644 --- a/lib/client-handshake.c +++ b/lib/client-handshake.c @@ -17,8 +17,9 @@ struct libwebsocket *__libwebsocket_client_connect_2( #endif lwsl_client("__libwebsocket_client_connect_2\n"); - +#ifndef LWS_NO_EXTENSIONS wsi->candidate_children_list = NULL; +#endif /* * proxy? @@ -181,9 +182,12 @@ libwebsocket_client_connect(struct libwebsocket_context *context, { struct libwebsocket *wsi; int n; +#ifndef LWS_NO_EXTENSIONS int m; struct libwebsocket_extension *ext; int handled; +#endif + #ifndef LWS_OPENSSL_SUPPORT if (ssl_connection) { lwsl_err("libwebsockets not configured for ssl\n"); @@ -209,7 +213,9 @@ libwebsocket_client_connect(struct libwebsocket_context *context, wsi->pings_vs_pongs = 0; wsi->protocol = NULL; wsi->pending_timeout = NO_PENDING_TIMEOUT; +#ifndef LWS_NO_EXTENSIONS wsi->count_active_extensions = 0; +#endif #ifdef LWS_OPENSSL_SUPPORT wsi->use_ssl = ssl_connection; #endif @@ -297,6 +303,7 @@ libwebsocket_client_connect(struct libwebsocket_context *context, wsi->utf8_token[n].token_len = 0; } +#ifndef LWS_NO_EXTENSIONS /* * Check with each extension if it is able to route and proxy this * connection for us. For example, an extension like x-google-mux @@ -328,7 +335,7 @@ libwebsocket_client_connect(struct libwebsocket_context *context, wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT; return wsi; } - +#endif lwsl_client("libwebsocket_client_connect: direct conn\n"); return __libwebsocket_client_connect_2(context, wsi); diff --git a/lib/client-parser.c b/lib/client-parser.c index 84c6569..8eea869 100644 --- a/lib/client-parser.c +++ b/lib/client-parser.c @@ -32,7 +32,9 @@ int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c) int callback_action = LWS_CALLBACK_CLIENT_RECEIVE; int handled; struct lws_tokens eff_buf; +#ifndef LWS_NO_EXTENSIONS int m; +#endif // lwsl_parser(" CRX: %02X %d\n", c, wsi->lws_rx_parse_state); @@ -433,6 +435,7 @@ spill: default: lwsl_parser("Reserved opcode 0x%2X\n", wsi->opcode); +#ifndef LWS_NO_EXTENSIONS /* * It's something special we can't understand here. * Pass the payload up to the extension's parsing @@ -455,6 +458,9 @@ spill: } if (!handled) { +#else + { +#endif lwsl_ext("Unhandled extended opcode " "0x%x - ignoring frame\n", wsi->opcode); wsi->rx_user_buffer_head = 0; @@ -476,7 +482,7 @@ spill: eff_buf.token = &wsi->rx_user_buffer[ LWS_SEND_BUFFER_PRE_PADDING]; eff_buf.token_len = wsi->rx_user_buffer_head; - +#ifndef LWS_NO_EXTENSIONS for (n = 0; n < wsi->count_active_extensions; n++) { m = wsi->active_extensions[n]->callback( wsi->protocol->owning_server, @@ -491,7 +497,7 @@ spill: return -1; } } - +#endif if (eff_buf.token_len > 0) { eff_buf.token[eff_buf.token_len] = '\0'; diff --git a/lib/client.c b/lib/client.c index 5d96089..a11de1f 100644 --- a/lib/client.c +++ b/lib/client.c @@ -315,12 +315,14 @@ lws_client_interpret_server_handshake(struct libwebsocket_context *context, char pkt[1024]; char *p = &pkt[0]; const char *pc; - const char *c; - int more = 1; int okay = 0; +#ifndef LWS_NO_EXTENSIONS char ext_name[128]; struct libwebsocket_extension *ext; void *v; + int more = 1; + const char *c; +#endif int len = 0; int n; static const char magic_websocket_04_masking_guid[] = @@ -515,7 +517,7 @@ select_protocol: check_extensions: - +#ifndef LWS_NO_EXTENSIONS /* instantiate the accepted extensions */ if (!wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token_len) { @@ -603,8 +605,8 @@ check_extensions: n = 0; } - check_accept: +#endif if (wsi->ietf_spec_revision == 0) { @@ -669,7 +671,7 @@ accept_ok: wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLIENT_ESTABLISHED, wsi->user_space, NULL, 0); - +#ifndef LWS_NO_EXTENSIONS /* * inform all extensions, not just active ones since they * already know @@ -687,6 +689,7 @@ accept_ok: LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED, v, NULL, 0); ext++; } +#endif return 0; @@ -753,9 +756,11 @@ libwebsockets_generate_client_handshake(struct libwebsocket_context *context, char hash[20]; char *p = pkt; int n; +#ifndef LWS_NO_EXTENSIONS struct libwebsocket_extension *ext; struct libwebsocket_extension *ext1; int ext_count = 0; +#endif unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 1 + MAX_BROADCAST_PAYLOAD + LWS_SEND_BUFFER_POST_PADDING]; static const char magic_websocket_guid[] = @@ -928,7 +933,7 @@ libwebsockets_generate_client_handshake(struct libwebsocket_context *context, /* tell the server what extensions we could support */ p += sprintf(p, "Sec-WebSocket-Extensions: "); - +#ifndef LWS_NO_EXTENSIONS ext = context->extensions; while (ext && ext->callback) { @@ -974,7 +979,7 @@ libwebsockets_generate_client_handshake(struct libwebsocket_context *context, ext++; } - +#endif p += sprintf(p, "\x0d\x0a"); if (wsi->ietf_spec_revision) diff --git a/lib/handshake.c b/lib/handshake.c index 2b2765f..b04df7f 100644 --- a/lib/handshake.c +++ b/lib/handshake.c @@ -116,14 +116,17 @@ libwebsocket_read(struct libwebsocket_context *context, if (wsi->protocol->callback(context, wsi, LWS_CALLBACK_HTTP, wsi->user_space, wsi->utf8_token[WSI_TOKEN_GET_URI].token, - wsi->utf8_token[WSI_TOKEN_GET_URI].token_len)) + wsi->utf8_token[WSI_TOKEN_GET_URI].token_len)) { + lwsl_info("LWS_CALLBACK_HTTP wanted to close\n"); goto bail; + } return 0; } if (!wsi->protocol) lwsl_err("NULL protocol at libwebsocket_read\n"); + /* * It's websocket * @@ -187,14 +190,18 @@ libwebsocket_read(struct libwebsocket_context *context, switch (wsi->ietf_spec_revision) { case 0: /* applies to 76 and 00 */ wsi->xor_mask = xor_no_mask; - if (handshake_00(context, wsi)) + if (handshake_00(context, wsi)) { + lwsl_info("handshake_00 has failed the connection\n"); goto bail; + } break; case 4: /* 04 */ wsi->xor_mask = xor_mask_04; lwsl_parser("libwebsocket_parse calling handshake_04\n"); - if (handshake_0405(context, wsi)) + if (handshake_0405(context, wsi)) { + lwsl_info("handshake_0405 has failed the connection\n"); goto bail; + } break; case 5: case 6: @@ -203,8 +210,10 @@ libwebsocket_read(struct libwebsocket_context *context, case 13: wsi->xor_mask = xor_mask_05; lwsl_parser("libwebsocket_parse calling handshake_04\n"); - if (handshake_0405(context, wsi)) + if (handshake_0405(context, wsi)) { + lwsl_info("handshake_0405 xor 05 has failed the connection\n"); goto bail; + } break; default: @@ -226,8 +235,10 @@ libwebsocket_read(struct libwebsocket_context *context, switch (wsi->mode) { case LWS_CONNMODE_WS_CLIENT: for (n = 0; n < len; n++) - if (libwebsocket_client_rx_sm(wsi, *buf++) < 0) + if (libwebsocket_client_rx_sm(wsi, *buf++) < 0) { + lwsl_info("client rx has bailed\n"); goto bail; + } return 0; default: @@ -237,8 +248,10 @@ libwebsocket_read(struct libwebsocket_context *context, #ifndef LWS_NO_SERVER /* LWS_CONNMODE_WS_SERVING */ - if (libwebsocket_interpret_incoming_packet(wsi, buf, len) < 0) + if (libwebsocket_interpret_incoming_packet(wsi, buf, len) < 0) { + lwsl_info("interpret_incoming_packet has bailed\n"); goto bail; + } #endif break; default: @@ -249,6 +262,7 @@ libwebsocket_read(struct libwebsocket_context *context, return 0; bail: + lwsl_info("closing connection at libwebsocket_read bail:\n"); libwebsocket_close_and_free_session(context, wsi, LWS_CLOSE_STATUS_NOSTATUS); diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index 063b673..5102b41 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -48,6 +48,7 @@ int openssl_websocket_private_data_index; #endif #endif + static int log_level = LLL_ERR | LLL_WARN | LLL_NOTICE; static void lwsl_emit_stderr(int level, const char *line); static void (*lwsl_emit)(int level, const char *line) = lwsl_emit_stderr; @@ -140,10 +141,12 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context, int old_state; unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 + LWS_SEND_BUFFER_POST_PADDING]; +#ifndef LWS_NO_EXTENSIONS int ret; int m; struct lws_tokens eff_buf; struct libwebsocket_extension *ext; +#endif if (!wsi) return; @@ -155,12 +158,12 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context, wsi->close_reason = reason; +#ifndef LWS_NO_EXTENSIONS /* * are his extensions okay with him closing? Eg he might be a mux * parent and just his ch1 aspect is closing? */ - for (n = 0; n < wsi->count_active_extensions; n++) { if (!wsi->active_extensions[n]->callback) continue; @@ -182,8 +185,6 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context, } } - - /* * flush any tx pending from extensions, since we may send close packet * if there are problems with send, just nuke the connection @@ -227,6 +228,7 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context, goto just_kill_connection; } } +#endif /* * signal we are closing, libsocket_write will @@ -270,7 +272,9 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context, /* else, the send failed and we should just hang up */ } +#ifndef LWS_NO_EXTENSIONS just_kill_connection: +#endif lwsl_debug("libwebsocket_close_and_free_session: just_kill_connection\n"); @@ -295,6 +299,7 @@ just_kill_connection: } else lwsl_debug("not calling back closed, old_state=%d\n", old_state); +#ifndef LWS_NO_EXTENSIONS /* deallocate any active extension contexts */ for (n = 0; n < wsi->count_active_extensions; n++) { @@ -321,6 +326,7 @@ just_kill_connection: NULL, NULL, 0); ext++; } +#endif /* free up his parsing allocations */ @@ -506,8 +512,9 @@ int lws_handle_POLLOUT_event(struct libwebsocket_context *context, struct libwebsocket *wsi, struct pollfd *pollfd) { - struct lws_tokens eff_buf; int n; +#ifndef LWS_NO_EXTENSIONS + struct lws_tokens eff_buf; int ret; int m; int handled = 0; @@ -605,6 +612,7 @@ lws_handle_POLLOUT_event(struct libwebsocket_context *context, wsi->extension_data_pending = 0; user_service: +#endif /* one shot */ if (pollfd) { @@ -615,8 +623,9 @@ user_service: LWS_CALLBACK_CLEAR_MODE_POLL_FD, (void *)(long)wsi->sock, NULL, POLLOUT); } - +#ifndef LWS_NO_EXTENSIONS notify_action: +#endif if (wsi->mode == LWS_CONNMODE_WS_CLIENT) n = LWS_CALLBACK_CLIENT_WRITEABLE; @@ -635,6 +644,7 @@ void libwebsocket_service_timeout_check(struct libwebsocket_context *context, struct libwebsocket *wsi, unsigned int sec) { +#ifndef LWS_NO_EXTENSIONS int n; /* @@ -648,6 +658,7 @@ libwebsocket_service_timeout_check(struct libwebsocket_context *context, wsi, LWS_EXT_CALLBACK_1HZ, wsi->active_extensions_user[n], NULL, sec); +#endif if (!wsi->pending_timeout) return; @@ -684,7 +695,9 @@ libwebsocket_service_fd(struct libwebsocket_context *context, int n; int m; struct timeval tv; +#ifndef LWS_NO_EXTENSIONS int more = 1; +#endif struct lws_tokens eff_buf; #ifndef LWS_NO_CLIENT extern int lws_client_socket_service(struct libwebsocket_context *context, struct libwebsocket *wsi, struct pollfd *pollfd); @@ -845,7 +858,7 @@ read_pending: */ eff_buf.token = (char *)buf; - +#ifndef LWS_NO_EXTENSIONS more = 1; while (more) { @@ -868,7 +881,7 @@ read_pending: if (m) more = 1; } - +#endif /* service incoming data */ if (eff_buf.token_len) { @@ -879,10 +892,11 @@ read_pending: /* we closed wsi */ return 0; } - +#ifndef LWS_NO_EXTENSIONS eff_buf.token = NULL; eff_buf.token_len = 0; } +#endif #ifdef LWS_OPENSSL_SUPPORT if (wsi->ssl && SSL_pending(wsi->ssl)) @@ -913,6 +927,7 @@ read_pending: void libwebsocket_context_destroy(struct libwebsocket_context *context) { +#ifndef LWS_NO_EXTENSIONS int n; int m; struct libwebsocket_extension *ext; @@ -936,6 +951,7 @@ libwebsocket_context_destroy(struct libwebsocket_context *context) ext->callback(context, ext, NULL, (enum libwebsocket_extension_callback_reasons)m, NULL, NULL, 0); ext++; } +#endif #ifdef WIN32 #else @@ -1027,6 +1043,7 @@ libwebsocket_service(struct libwebsocket_context *context, int timeout_ms) return 0; } +#ifndef LWS_NO_EXTENSIONS int lws_any_extension_handled(struct libwebsocket_context *context, struct libwebsocket *wsi, @@ -1070,6 +1087,7 @@ lws_get_extension_user_matching_ext(struct libwebsocket *wsi, return NULL; } +#endif /** * libwebsocket_callback_on_writable() - Request a callback when this socket @@ -1084,6 +1102,7 @@ int libwebsocket_callback_on_writable(struct libwebsocket_context *context, struct libwebsocket *wsi) { +#ifndef LWS_NO_EXTENSIONS int n; int handled = 0; @@ -1101,7 +1120,7 @@ libwebsocket_callback_on_writable(struct libwebsocket_context *context, if (handled) return 1; - +#endif if (wsi->position_in_fds_table < 0) { lwsl_err("libwebsocket_callback_on_writable: " "failed to find socket %d\n", wsi->sock); @@ -1340,7 +1359,8 @@ int user_callback_handle_rxflow(callback_function callback_function, * entry that has a NULL callback pointer. * It's not const because we write the owning_server member * @extensions: NULL or array of libwebsocket_extension structs listing the - * extensions this context supports + * extensions this context supports. If you configured with + * --without-extensions, you should give NULL here. * @ssl_cert_filepath: If libwebsockets was compiled to use ssl, and you want * to listen using SSL, set to the filepath to fetch the * server cert from, otherwise NULL for unencrypted @@ -1390,7 +1410,6 @@ libwebsocket_create_context(int port, const char *interf, void *user) { int n; - int m; int fd; struct sockaddr_in serv_addr, cli_addr; int opt = 1; @@ -1398,6 +1417,9 @@ libwebsocket_create_context(int port, const char *interf, unsigned int slen; char *p; struct libwebsocket *wsi; +#ifndef LWS_NO_EXTENSIONS + int m; +#endif #ifdef LWS_OPENSSL_SUPPORT SSL_METHOD *method; @@ -1412,7 +1434,11 @@ libwebsocket_create_context(int port, const char *interf, lwsl_info(" MAX_USER_RX_BUFFER: %u\n", MAX_USER_RX_BUFFER); lwsl_info(" MAX_BROADCAST_PAYLOAD: %u\n", MAX_BROADCAST_PAYLOAD); lwsl_info(" LWS_MAX_PROTOCOLS: %u\n", LWS_MAX_PROTOCOLS); +#ifndef LWS_NO_EXTENSIONS lwsl_info(" LWS_MAX_EXTENSIONS_ACTIVE: %u\n", LWS_MAX_EXTENSIONS_ACTIVE); +#else + lwsl_notice(" Configured without extension support\n"); +#endif lwsl_info(" SPEC_LATEST_SUPPORTED: %u\n", SPEC_LATEST_SUPPORTED); lwsl_info(" AWAITING_TIMEOUT: %u\n", AWAITING_TIMEOUT); lwsl_info(" CIPHERS_LIST_STRING: '%s'\n", CIPHERS_LIST_STRING); @@ -1481,7 +1507,9 @@ libwebsocket_create_context(int port, const char *interf, return NULL; } context->fds_count = 0; +#ifndef LWS_NO_EXTENSIONS context->extensions = extensions; +#endif context->last_timeout_check_s = 0; context->user_space = user; @@ -1788,7 +1816,9 @@ libwebsocket_create_context(int port, const char *interf, } memset(wsi, 0, sizeof (struct libwebsocket)); wsi->sock = sockfd; +#ifndef LWS_NO_EXTENSIONS wsi->count_active_extensions = 0; +#endif wsi->mode = LWS_CONNMODE_SERVER_LISTENER; insert_wsi_socket_into_fds(context, wsi); @@ -1877,14 +1907,16 @@ libwebsocket_create_context(int port, const char *interf, memset(wsi, 0, sizeof (struct libwebsocket)); wsi->sock = fd; wsi->mode = LWS_CONNMODE_BROADCAST_PROXY_LISTENER; +#ifndef LWS_NO_EXTENSIONS wsi->count_active_extensions = 0; +#endif /* note which protocol we are proxying */ wsi->protocol_index_for_broadcast_proxy = context->count_protocols; insert_wsi_socket_into_fds(context, wsi); } - +#ifndef LWS_NO_EXTENSIONS /* * give all extensions a chance to create any per-context * allocations they need @@ -1903,7 +1935,7 @@ libwebsocket_create_context(int port, const char *interf, extensions++; } } - +#endif return context; } diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index bc9b0cb..0900fc2 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -144,6 +144,7 @@ enum libwebsocket_callback_reasons { LWS_CALLBACK_CLEAR_MODE_POLL_FD, }; +#ifndef LWS_NO_EXTENSIONS enum libwebsocket_extension_callback_reasons { LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT, LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT, @@ -169,6 +170,7 @@ enum libwebsocket_extension_callback_reasons { LWS_EXT_CALLBACK_PAYLOAD_TX, LWS_EXT_CALLBACK_PAYLOAD_RX, }; +#endif enum libwebsocket_write_protocol { LWS_WRITE_TEXT, @@ -349,6 +351,7 @@ enum lws_close_status { struct libwebsocket; struct libwebsocket_context; +/* needed even with extensions disabled for create context */ struct libwebsocket_extension; /** @@ -566,7 +569,7 @@ typedef int (callback_function)(struct libwebsocket_context * context, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len); - +#ifndef LWS_NO_EXTENSIONS /** * extension_callback_function() - Hooks to allow extensions to operate * @context: Websockets context @@ -636,6 +639,7 @@ typedef int (extension_callback_function)(struct libwebsocket_context * context, struct libwebsocket *wsi, enum libwebsocket_extension_callback_reasons reason, void *user, void *in, size_t len); +#endif /** * struct libwebsocket_protocols - List of protocols and handlers server @@ -681,6 +685,7 @@ struct libwebsocket_protocols { int protocol_index; }; +#ifndef LWS_NO_EXTENSIONS /** * struct libwebsocket_extension - An extension we know how to cope with * @@ -700,6 +705,7 @@ struct libwebsocket_extension { size_t per_session_data_size; void * per_context_private_data; }; +#endif LWS_EXTERN void lws_set_log_level(int level, void (*log_emit_function)(int level, const char *line)); @@ -874,7 +880,9 @@ lws_b64_encode_string(const char *in, int in_len, char *out, int out_size); LWS_EXTERN int lws_b64_decode_string(const char *in, char *out, int out_size); +#ifndef LWS_NO_EXTENSIONS LWS_EXTERN struct libwebsocket_extension libwebsocket_internal_extensions[]; +#endif #ifdef __cplusplus } diff --git a/lib/output.c b/lib/output.c index eff467c..b5cf7ea 100644 --- a/lib/output.c +++ b/lib/output.c @@ -92,7 +92,7 @@ void lwsl_hexdump(void *vbuf, size_t len) p += sprintf(p, " "); for (m = 0; m < 16 && (start + m) < len; m++) { - if (buf[start + m] >= ' ' && buf[start + m] <= 127) + if (buf[start + m] >= ' ' && buf[start + m] < 127) *p++ = buf[start + m]; else *p++ = '.'; @@ -102,7 +102,7 @@ void lwsl_hexdump(void *vbuf, size_t len) *p++ = '\n'; *p = '\0'; - lwsl_debug(line); + lwsl_debug("%s", line); } lwsl_debug("\n"); } @@ -112,6 +112,7 @@ void lwsl_hexdump(void *vbuf, size_t len) int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len) { int n; +#ifndef LWS_NO_EXTENSIONS int m; /* @@ -137,7 +138,7 @@ int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len) return 0; } } - +#endif if (!wsi->sock) lwsl_warn("** error 0 sock but expected to send\n"); @@ -170,6 +171,14 @@ int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len) return 0; } +#ifdef LWS_NO_EXTENSIONS +int +lws_issue_raw_ext_access(struct libwebsocket *wsi, + unsigned char *buf, size_t len) +{ + return lws_issue_raw(wsi, buf, len); +} +#else int lws_issue_raw_ext_access(struct libwebsocket *wsi, unsigned char *buf, size_t len) @@ -255,6 +264,7 @@ lws_issue_raw_ext_access(struct libwebsocket *wsi, return 0; } +#endif /** * libwebsocket_write() - Apply protocol then write data to client @@ -292,8 +302,10 @@ 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; +#ifndef LWS_NO_EXTENSIONS struct lws_tokens eff_buf; int m; +#endif if (lws_confirm_legit_wsi(wsi)) { lwsl_err("libwebsocket_write on illegitimate wsi\n"); @@ -312,6 +324,7 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, if (wsi->state != WSI_STATE_ESTABLISHED) return -1; +#ifndef LWS_NO_EXTENSIONS /* give a change to the extensions to modify payload */ eff_buf.token = (char *)buf; eff_buf.token_len = len; @@ -336,6 +349,7 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, buf = (unsigned char *)eff_buf.token; len = eff_buf.token_len; +#endif switch (wsi->ietf_spec_revision) { /* chrome likes this as of 30 Oct 2010 */ @@ -710,8 +724,10 @@ int libwebsockets_serve_http_file(struct libwebsocket_context *context, close(fd); if (wsi->protocol->callback(context, wsi, LWS_CALLBACK_HTTP_FILE_COMPLETION, wsi->user_space, - wsi->filepath, wsi->filepos)) + wsi->filepath, wsi->filepos)) { + lwsl_info("closing connecton after file_completion returned nonzero\n"); libwebsocket_close_and_free_session(context, wsi, LWS_CLOSE_STATUS_NOSTATUS); + } return 0; } diff --git a/lib/parsers.c b/lib/parsers.c index 5168471..c503534 100644 --- a/lib/parsers.c +++ b/lib/parsers.c @@ -605,8 +605,10 @@ libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c) int n; unsigned char buf[20 + 4]; struct lws_tokens eff_buf; +#ifndef LWS_NO_EXTENSIONS int handled; int m; +#endif #if 0 lwsl_debug("RX: %02X ", c); @@ -1012,6 +1014,7 @@ issue: case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED: + if (wsi->ietf_spec_revision < 4 || (wsi->all_zero_nonce && wsi->ietf_spec_revision >= 5)) wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + @@ -1080,7 +1083,7 @@ spill: break; default: - +#ifndef LWS_NO_EXTENSIONS lwsl_parser("passing opcode %x up to exts\n", wsi->opcode); /* @@ -1106,6 +1109,7 @@ spill: } if (!handled) +#endif lwsl_ext("Unhandled extended opcode " "0x%x - ignoring frame\n", wsi->opcode); @@ -1122,7 +1126,7 @@ spill: eff_buf.token = &wsi->rx_user_buffer[ LWS_SEND_BUFFER_PRE_PADDING]; eff_buf.token_len = wsi->rx_user_buffer_head; - +#ifndef LWS_NO_EXTENSIONS for (n = 0; n < wsi->count_active_extensions; n++) { m = wsi->active_extensions[n]->callback( wsi->protocol->owning_server, @@ -1137,7 +1141,7 @@ spill: return -1; } } - +#endif if (eff_buf.token_len > 0) { eff_buf.token[eff_buf.token_len] = '\0'; @@ -1175,7 +1179,7 @@ int libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi, int clear_rxflow = !!wsi->rxflow_buffer; struct libwebsocket_context *context = wsi->protocol->owning_server; -#ifdef DEBUG +#if 0 lwsl_parser("received %d byte packet\n", (int)len); lwsl_hexdump(buf, len); #endif diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index 8f69cff..bc0567f 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -272,8 +272,9 @@ struct libwebsocket_context { #endif struct libwebsocket_protocols *protocols; int count_protocols; +#ifndef LWS_NO_EXTENSIONS struct libwebsocket_extension *extensions; - +#endif void *user_space; }; @@ -298,11 +299,15 @@ enum pending_timeout { struct libwebsocket { const struct libwebsocket_protocols *protocol; +#ifndef LWS_NO_EXTENSIONS struct libwebsocket_extension * active_extensions[LWS_MAX_EXTENSIONS_ACTIVE]; void *active_extensions_user[LWS_MAX_EXTENSIONS_ACTIVE]; int count_active_extensions; - + char extension_data_pending; + struct libwebsocket *extension_handles; + struct libwebsocket *candidate_children_list; +#endif enum lws_connection_states state; char name_buffer[LWS_MAX_HEADER_NAME_LENGTH]; @@ -328,9 +333,6 @@ struct libwebsocket { int rxflow_change_to; enum lws_rx_parse_state lws_rx_parse_state; - char extension_data_pending; - struct libwebsocket *candidate_children_list; - struct libwebsocket *extension_handles; /* 04 protocol specific */ @@ -442,7 +444,7 @@ libwebsockets_generate_client_handshake(struct libwebsocket_context *context, extern int lws_handle_POLLOUT_event(struct libwebsocket_context *context, struct libwebsocket *wsi, struct pollfd *pollfd); - +#ifndef LWS_NO_EXTENSIONS extern int lws_any_extension_handled(struct libwebsocket_context *context, struct libwebsocket *wsi, @@ -452,6 +454,7 @@ lws_any_extension_handled(struct libwebsocket_context *context, extern void * lws_get_extension_user_matching_ext(struct libwebsocket *wsi, struct libwebsocket_extension *ext); +#endif extern int lws_client_interpret_server_handshake(struct libwebsocket_context *context, diff --git a/lib/server-handshake.c b/lib/server-handshake.c index b91769e..1fdb332 100644 --- a/lib/server-handshake.c +++ b/lib/server-handshake.c @@ -224,11 +224,13 @@ handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi) char *m = mask_summing_buf; int nonce_len = 0; int accept_len; +#ifndef LWS_NO_EXTENSIONS char *c; char ext_name[128]; struct libwebsocket_extension *ext; int ext_count = 0; int more = 1; +#endif if (!wsi->utf8_token[WSI_TOKEN_HOST].token_len || !wsi->utf8_token[WSI_TOKEN_KEY].token_len) { @@ -322,6 +324,7 @@ handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi) LWS_CPYAPP_TOKEN(p, WSI_TOKEN_PROTOCOL); } +#ifndef LWS_NO_EXTENSIONS /* * Figure out which extensions the client has that we want to * enable on this connection, and give him back the list @@ -439,7 +442,7 @@ handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi) n = 0; } } - +#endif /* end of response packet */ LWS_CPYAPP(p, "\x0d\x0a\x0d\x0a"); @@ -468,10 +471,12 @@ handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi) wsi->masking_key_04); } +#ifndef LWS_NO_EXTENSIONS if (!lws_any_extension_handled(context, wsi, LWS_EXT_CALLBACK_HANDSHAKE_REPLY_TX, - response, p - response)) { - + response, p - response)) +#endif + { /* okay send the handshake response accepting the connection */ lwsl_parser("issuing response packet %d len\n", (int)(p - response)); diff --git a/lib/server.c b/lib/server.c index 17f83ae..40cbe20 100644 --- a/lib/server.c +++ b/lib/server.c @@ -94,7 +94,9 @@ libwebsocket_create_new_server_wsi(struct libwebsocket_context *context) } memset(new_wsi, 0, sizeof(struct libwebsocket)); +#ifndef LWS_NO_EXTENSIONS new_wsi->count_active_extensions = 0; +#endif new_wsi->pending_timeout = NO_PENDING_TIMEOUT; /* intialize the instance struct */ @@ -323,7 +325,9 @@ int lws_server_socket_service(struct libwebsocket_context *context, new_wsi->sock = accept_fd; new_wsi->mode = LWS_CONNMODE_BROADCAST_PROXY; new_wsi->state = WSI_STATE_ESTABLISHED; +#ifndef LWS_NO_EXTENSIONS new_wsi->count_active_extensions = 0; +#endif /* note which protocol we are proxying */ new_wsi->protocol_index_for_broadcast_proxy = wsi->protocol_index_for_broadcast_proxy; diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html index fcd92cd..d907e9b 100644 --- a/libwebsockets-api-doc.html +++ b/libwebsockets-api-doc.html @@ -245,7 +245,8 @@ entry that has a NULL callback pointer. It's not const because we write the owning_server member
extensions
NULL or array of libwebsocket_extension structs listing the -extensions this context supports +extensions this context supports. If you configured with +--without-extensions, you should give NULL here.
ssl_cert_filepath
If libwebsockets was compiled to use ssl, and you want to listen using SSL, set to the filepath to fetch the diff --git a/test-server/test-client.c b/test-server/test-client.c index 919f258..348196b 100644 --- a/test-server/test-client.c +++ b/test-server/test-client.c @@ -109,7 +109,8 @@ callback_lws_mirror(struct libwebsocket_context *this, { unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 4096 + LWS_SEND_BUFFER_POST_PADDING]; - int l; + int l = 0; + int n; switch (reason) { @@ -134,7 +135,8 @@ callback_lws_mirror(struct libwebsocket_context *this, case LWS_CALLBACK_CLIENT_WRITEABLE: - l = sprintf((char *)&buf[LWS_SEND_BUFFER_PRE_PADDING], + for (n = 0; n < 1; n++) + l += sprintf((char *)&buf[LWS_SEND_BUFFER_PRE_PADDING + l], "c #%06X %d %d %d;", (int)random() & 0xffffff, (int)random() % 500, @@ -258,7 +260,12 @@ int main(int argc, char **argv) */ context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL, - protocols, libwebsocket_internal_extensions, + protocols, +#ifndef LWS_NO_EXTENSIONS + libwebsocket_internal_extensions, +#else + NULL, +#endif NULL, NULL, NULL, -1, -1, 0, NULL); if (context == NULL) { fprintf(stderr, "Creating libwebsocket context failed\n"); diff --git a/test-server/test-fraggle.c b/test-server/test-fraggle.c index 2e899de..abff7bc 100644 --- a/test-server/test-fraggle.c +++ b/test-server/test-fraggle.c @@ -306,7 +306,11 @@ int main(int argc, char **argv) cert_path = key_path = NULL; context = libwebsocket_create_context(server_port, interface, protocols, +#ifndef LWS_NO_EXTENSIONS libwebsocket_internal_extensions, +#else + NULL, +#endif cert_path, key_path, NULL, -1, -1, opts, NULL); if (context == NULL) { fprintf(stderr, "libwebsocket init failed\n"); diff --git a/test-server/test-ping.c b/test-server/test-ping.c index d768df1..773b792 100644 --- a/test-server/test-ping.c +++ b/test-server/test-ping.c @@ -409,7 +409,11 @@ int main(int argc, char **argv) context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL, protocols, - libwebsocket_internal_extensions, +#ifndef LWS_NO_EXTENSIONS + libwebsocket_internal_extensions, +#else + NULL, +#endif NULL, NULL, NULL, -1, -1, 0, NULL); if (context == NULL) { fprintf(stderr, "Creating libwebsocket context failed\n"); diff --git a/test-server/test-server.c b/test-server/test-server.c index dc5a9cd..c07a9b9 100644 --- a/test-server/test-server.c +++ b/test-server/test-server.c @@ -323,7 +323,7 @@ callback_dumb_increment(struct libwebsocket_context *context, /* lws-mirror_protocol */ -#define MAX_MESSAGE_QUEUE 64 +#define MAX_MESSAGE_QUEUE 128 struct per_session_data__lws_mirror { struct libwebsocket *wsi; @@ -362,7 +362,7 @@ callback_lws_mirror(struct libwebsocket_context *context, case LWS_CALLBACK_SERVER_WRITEABLE: if (close_testing) break; - if (pss->ringbuffer_tail != ringbuffer_head) { + while (pss->ringbuffer_tail != ringbuffer_head) { n = libwebsocket_write(wsi, (unsigned char *) ringbuffer[pss->ringbuffer_tail].payload + @@ -380,16 +380,17 @@ callback_lws_mirror(struct libwebsocket_context *context, pss->ringbuffer_tail++; if (((ringbuffer_head - pss->ringbuffer_tail) & - (MAX_MESSAGE_QUEUE - 1)) < (MAX_MESSAGE_QUEUE - 15)) { + (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 15)) { for (n = 0; n < num_wsi_choked; n++) libwebsocket_rx_flow_control(wsi_choked[n], 1); num_wsi_choked = 0; } + // lwsl_debug("tx fifo %d\n", (ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1)); -// lwsl_debug("tx fifo %d\n", (ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1)); - - libwebsocket_callback_on_writable(context, wsi); - + if (lws_send_pipe_choked(wsi)) { + libwebsocket_callback_on_writable(context, wsi); + return 0; + } } break; @@ -422,7 +423,7 @@ callback_lws_mirror(struct libwebsocket_context *context, ringbuffer_head++; if (((ringbuffer_head - pss->ringbuffer_tail) & - (MAX_MESSAGE_QUEUE - 1)) < (MAX_MESSAGE_QUEUE - 10)) + (MAX_MESSAGE_QUEUE - 1)) != (MAX_MESSAGE_QUEUE - 2)) goto done; choke: @@ -586,7 +587,11 @@ int main(int argc, char **argv) cert_path = key_path = NULL; context = libwebsocket_create_context(port, interface, protocols, +#ifndef LWS_NO_EXTENSIONS libwebsocket_internal_extensions, +#else + NULL, +#endif cert_path, key_path, NULL, -1, -1, opts, NULL); if (context == NULL) { lwsl_err("libwebsocket init failed\n"); -- 2.7.4