diff --git a/.travis.yml b/.travis.yml index 13d5453d0..e504f2ea4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ env: # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created # via the "travis encrypt" command using the project repo's public key global: - - secure: "amfzN1OzBBZYPJVx8TCYsV1nQ5SPm7QswgGpuHcNKaMAixn1s4tKliR0wyVs1aiMqKco1zrJ3vXll+D5gknKr5obWOeZ61T3PYyZmhjB0n/D+7Y41EikNa1Hn1pP6etcHh3ciJ0qe8FC+9YB5yEII3G/jHsltge8Nu+5o2YCSCw=" + - secure: "KhAdQ9ja+LBObWNQTYO7Df5J4DyOih6S+eerDMu8UPSO+CoWV2pWoQzbOfocjyOscGOwC+2PrrHDNZyGfqkCLDXg1BxynXPCFerHC1yc2IajvKpGXmAAygNIvp4KACDfGv/dkXrViqIzr/CdcNaU4vIMHSVb5xkeLi0W1dPnQOI=" matrix: - LWS_METHOD=default - LWS_METHOD=noserver CMAKE_ARGS="-DLWS_WITHOUT_SERVER=ON" @@ -29,3 +29,4 @@ addons: build_command_prepend: "mkdir build && cd build && cmake .." build_command: "cmake --build ." branch_pattern: coverity_scan + diff --git a/CMakeLists.txt b/CMakeLists.txt index 2660709a1..ee1507db3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ set(CPACK_PACKAGE_VERSION_MINOR "5") set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}") set(CPACK_PACKAGE_VENDOR "andy@warmcat.com") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PACKAGE} ${PACKAGE_VERSION}") -set(SOVERSION "5") +set(SOVERSION "6") set(CPACK_SOURCE_GENERATOR "TGZ") set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") set(VERSION "${CPACK_PACKAGE_VERSION}") @@ -68,6 +68,7 @@ option(LWS_WITHOUT_DAEMONIZE "Don't build the daemonization api" ON) option(LWS_IPV6 "Compile with support for ipv6" OFF) option(LWS_WITH_HTTP2 "Compile with support for http2" OFF) option(LWS_MBED3 "Platform is MBED3" OFF) +option(LWS_WITH_OLD_API_WRAPPERS "Compile with binary compatibility with pre-v1.6 apis" OFF) if (DEFINED YOTTA_WEBSOCKETS_VERSION_STRING) @@ -475,7 +476,7 @@ if (UNIX) endif() endif() -if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) +if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) include (CheckCCompilerFlag) CHECK_C_COMPILER_FLAG(-fvisibility=hidden LWS_HAVE_VISIBILITY) if (LWS_HAVE_VISIBILITY) @@ -488,6 +489,19 @@ if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) endif(UNIX) endif () +if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) + if (UNIX) + # jeez clang understands -pthread but dies if he sees it at link time! + # http://stackoverflow.com/questions/2391194/what-is-gs-pthread-equiv-in-clang + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread" ) + endif() +endif() + +if ((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) + # otherwise osx blows a bunch of openssl deprecated api errors + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations" ) +endif() + source_group("Headers Private" FILES ${HDR_PRIVATE}) source_group("Headers Public" FILES ${HDR_PUBLIC}) source_group("Sources" FILES ${SOURCES}) @@ -542,7 +556,7 @@ endif() # Set the so version of the lib. # Equivalent to LDFLAGS=-version-info x:x:x -if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) +if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) foreach(lib ${LWS_LIBRARIES}) set_target_properties(${lib} PROPERTIES @@ -614,7 +628,7 @@ if (LWS_WITH_SSL) # Additional to the root directory we need to include # the wolfssl/ subdirectory which contains the OpenSSL - # compatability layer headers. + # compatibility layer headers. if (LWS_USE_CYASSL) foreach(inc ${WOLFSSL_INCLUDE_DIRS}) @@ -756,6 +770,9 @@ if (NOT LWS_WITHOUT_TESTAPPS) # if (NOT LWS_WITHOUT_TEST_SERVER) create_test_app(test-server "test-server/test-server.c" "test-server/test-server-http.c" "test-server/test-server-dumb-increment.c" "test-server/test-server-mirror.c") + if (UNIX AND NOT ((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))) + create_test_app(test-server-pthreads "test-server/test-server-pthreads.c" "test-server/test-server-http.c" "test-server/test-server-dumb-increment.c" "test-server/test-server-mirror.c") + endif() endif() # @@ -1032,6 +1049,12 @@ if (NOT LWS_WITHOUT_TESTAPPS AND NOT LWS_WITHOUT_SERVER) COMPONENT examples) endif() +# Install the LibwebsocketsConfig.cmake and LibwebsocketsConfigVersion.cmake +install(FILES + "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/LibwebsocketsConfig.cmake" + "${PROJECT_BINARY_DIR}/LibwebsocketsConfigVersion.cmake" + DESTINATION "${LWS_INSTALL_CMAKE_DIR}" COMPONENT dev) + # build subdir is not part of sources set(CPACK_SOURCE_IGNORE_FILES $(CPACK_SOURCE_IGNORE_FILES) ".git" "build" "tgz" "tar.gz") @@ -1073,6 +1096,7 @@ message(" LWS_USE_LIBEV = ${LWS_USE_LIBEV}") message(" LWS_IPV6 = ${LWS_IPV6}") message(" LWS_WITH_HTTP2 = ${LWS_WITH_HTTP2}") message(" LWS_MBED3 = ${LWS_MBED3}") +message(" LWS_WITH_OLD_API_WRAPPERS = ${LWS_WITH_OLD_API_WRAPPERS}") message("---------------------------------------------------------------------") # These will be available to parent projects including libwebsockets using add_subdirectory() diff --git a/README.coding.md b/README.coding.md index c221347fd..28be02c5b 100644 --- a/README.coding.md +++ b/README.coding.md @@ -61,8 +61,8 @@ clients). If you want to send something, do not just send it but request a callback when the socket is writeable using - - `libwebsocket_callback_on_writable(context, wsi)`` for a specific `wsi`, or - - `libwebsocket_callback_on_writable_all_protocol(protocol)` for all connections + - `lws_callback_on_writable(context, wsi)`` for a specific `wsi`, or + - `lws_callback_on_writable_all_protocol(protocol)` for all connections using that protocol to get a callback when next writeable. Usually you will get called back immediately next time around the service @@ -93,7 +93,7 @@ Closing connections from the user side When you want to close a connection, you do it by returning `-1` from a callback for that connection. -You can provoke a callback by calling `libwebsocket_callback_on_writable` on +You can provoke a callback by calling `lws_callback_on_writable` on the wsi, then notice in the callback you want to close it and just return -1. But usually, the decision to close is made in a callback already and returning -1 is simple. @@ -112,7 +112,7 @@ Fragmented messages ------------------- To support fragmented messages you need to check for the final -frame of a message with `libwebsocket_is_final_fragment`. This +frame of a message with `lws_is_final_fragment`. This check can be combined with `libwebsockets_remaining_packet_payload` to gather the whole contents of a message, eg: @@ -120,9 +120,9 @@ to gather the whole contents of a message, eg: case LWS_CALLBACK_RECEIVE: { Client * const client = (Client *)user; - const size_t remaining = libwebsockets_remaining_packet_payload(wsi); + const size_t remaining = lws_remaining_packet_payload(wsi); - if (!remaining && libwebsocket_is_final_fragment(wsi)) { + if (!remaining && lws_is_final_fragment(wsi)) { if (client->HasFragments()) { client->AppendMessageFragment(in, len, 0); in = (void *)client->GetMessage(); @@ -178,7 +178,7 @@ Four callbacks `LWS_CALLBACK_ADD_POLL_FD`, `LWS_CALLBACK_DEL_POLL_FD`, appear in the callback for protocol 0 and allow interface code to manage socket descriptors in other poll loops. -You can pass all pollfds that need service to `libwebsocket_service_fd()`, even +You can pass all pollfds that need service to `lws_service_fd()`, even if the socket or file does not belong to **libwebsockets** it is safe. If **libwebsocket** handled it, it zeros the pollfd `revents` field before returning. @@ -261,7 +261,7 @@ if left `NULL`, then the "DEFAULT" set of ciphers are all possible to select. Async nature of client connections ---------------------------------- -When you call `libwebsocket_client_connect(..)` and get a `wsi` back, it does not +When you call `lws_client_connect(..)` and get a `wsi` back, it does not mean your connection is active. It just mean it started trying to connect. Your client connection is actually active only when you receive @@ -273,6 +273,6 @@ other reasons, if any of that happens you'll get a `wsi`. After attempting the connection and getting back a non-`NULL` `wsi` you should -loop calling `libwebsocket_service()` until one of the above callbacks occurs. +loop calling `lws_service()` until one of the above callbacks occurs. As usual, see [test-client.c](test-server/test-client.c) for example code. diff --git a/changelog b/changelog index 62f1ca50e..583f8dd13 100644 --- a/changelog +++ b/changelog @@ -1,6 +1,27 @@ Changelog --------- +User api changes +---------------- + +Several older apis start with libwebsocket_ or libwebsockets_ while newer ones +all begin lws_. These apis have been changed to all begin with lws_. + +However compatibility defines have been added in libwebsockets.h, so it is +perfectly build-compatible with older sources using the old api names. + +If you are using lws with a distro, or otherwise can't rebuild the user code, +you should add + + -DLWS_WITH_OLD_API_WRAPPERS=1 + +to your cmake args. This builds lws with all the old apis as wrappers around +the new apis, so the library still exports the old apis. + +In this way you can have lws export both the new and old apis simultaneously +for compatibility. + + v1.5-chrome47-firefox41 ======================= @@ -97,7 +118,7 @@ User api removal ---------------- protocols struct member no_buffer_all_partial_tx is removed. Under some -conditions like rewriting extention such as compression in use, the built-in +conditions like rewriting extension such as compression in use, the built-in partial send buffering is the only way to deal with the problem, so turning it off is deprecated. @@ -348,7 +369,7 @@ User api additions - if your OS does not support the http_proxy environment variable convention (eg, reportedly OSX), you can use a new api libwebsocket_set_proxy() - to set the proxy details inbetween context creation and the connection + to set the proxy details in between context creation and the connection action. For OSes that support http_proxy, that's used automatically. User api changes diff --git a/lib/client-handshake.c b/lib/client-handshake.c index 3a8de9b1e..9e4bd7641 100644 --- a/lib/client-handshake.c +++ b/lib/client-handshake.c @@ -1,10 +1,8 @@ #include "private-libwebsockets.h" -struct libwebsocket *libwebsocket_client_connect_2( - struct libwebsocket_context *context, - struct libwebsocket *wsi -) { - struct libwebsocket_pollfd pfd; +struct lws * +lws_client_connect_2(struct lws_context *context, struct lws *wsi) +{ #ifdef LWS_USE_IPV6 struct sockaddr_in6 server_addr6; struct sockaddr_in6 client_addr6; @@ -12,17 +10,14 @@ struct libwebsocket *libwebsocket_client_connect_2( #endif struct sockaddr_in server_addr4; struct sockaddr_in client_addr4; - + struct lws_pollfd pfd; struct sockaddr *v; - int n; - int plen = 0; + int n, plen = 0; const char *ads; - lwsl_client("libwebsocket_client_connect_2\n"); + lwsl_client("lws_client_connect_2\n"); - /* - * proxy? - */ + /* proxy? */ if (context->http_proxy_port) { plen = sprintf((char *)context->service_buffer, @@ -42,18 +37,20 @@ struct libwebsocket *libwebsocket_client_connect_2( ads = context->http_proxy_address; #ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) + if (LWS_IPV6_ENABLED(context)) { + memset(&server_addr6, 0, sizeof(struct sockaddr_in6)); server_addr6.sin6_port = htons(context->http_proxy_port); - else + } else #endif server_addr4.sin_port = htons(context->http_proxy_port); } else { ads = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS); #ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) + if (LWS_IPV6_ENABLED(context)) { + memset(&server_addr6, 0, sizeof(struct sockaddr_in6)); server_addr6.sin6_port = htons(wsi->u.hdr.ah->c_port); - else + } else #endif server_addr4.sin_port = htons(wsi->u.hdr.ah->c_port); } @@ -169,7 +166,7 @@ struct libwebsocket *libwebsocket_client_connect_2( * handling as oom4 does. We have to run the whole close flow. */ - libwebsocket_set_timeout(wsi, + lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE, AWAITING_TIMEOUT); #ifdef LWS_USE_IPV6 @@ -216,14 +213,13 @@ struct libwebsocket *libwebsocket_client_connect_2( if (connect(wsi->sock, v, n) == -1 || LWS_ERRNO == LWS_EISCONN) { - if (LWS_ERRNO == LWS_EALREADY - || LWS_ERRNO == LWS_EINPROGRESS - || LWS_ERRNO == LWS_EWOULDBLOCK + if (LWS_ERRNO == LWS_EALREADY || + LWS_ERRNO == LWS_EINPROGRESS || + LWS_ERRNO == LWS_EWOULDBLOCK #ifdef _WIN32 || LWS_ERRNO == WSAEINVAL #endif - ) - { + ) { lwsl_client("nonblocking connect retry\n"); /* @@ -249,26 +245,26 @@ struct libwebsocket *libwebsocket_client_connect_2( if (context->http_proxy_port) { - /* OK from now on we talk via the proxy, so connect to that */ - /* + * OK from now on we talk via the proxy, so connect to that + * * (will overwrite existing pointer, * leaving old string/frag there but unreferenced) */ if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, - context->http_proxy_address)) + context->http_proxy_address)) goto failed; wsi->u.hdr.ah->c_port = context->http_proxy_port; - n = send(wsi->sock, (char *)context->service_buffer, plen, MSG_NOSIGNAL); + n = send(wsi->sock, (char *)context->service_buffer, plen, + MSG_NOSIGNAL); if (n < 0) { lwsl_debug("ERROR writing to proxy socket\n"); goto failed; } - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE, - AWAITING_TIMEOUT); + lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE, + AWAITING_TIMEOUT); wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY; @@ -285,14 +281,14 @@ struct libwebsocket *libwebsocket_client_connect_2( * cover with a timeout. */ - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE, AWAITING_TIMEOUT); + lws_set_timeout(wsi, PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE, + AWAITING_TIMEOUT); wsi->mode = LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE; pfd.fd = wsi->sock; pfd.revents = LWS_POLLIN; - n = libwebsocket_service_fd(context, &pfd); + n = lws_service_fd(context, &pfd); if (n < 0) goto failed; @@ -308,13 +304,13 @@ oom4: return NULL; failed: - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); + lws_close_and_free_session(context, wsi, LWS_CLOSE_STATUS_NOSTATUS); + return NULL; } /** - * libwebsocket_client_connect() - Connect to another websocket server + * lws_client_connect() - Connect to another websocket server * @context: Websocket context * @address: Remote server address, eg, "myserver.com" * @port: Port to connect to on the remote server, eg, 80 @@ -333,20 +329,15 @@ failed: * This function creates a connection to a remote server */ -LWS_VISIBLE struct libwebsocket * -libwebsocket_client_connect(struct libwebsocket_context *context, - const char *address, - int port, - int ssl_connection, - const char *path, - const char *host, - const char *origin, - const char *protocol, - int ietf_version_or_minus_one) +LWS_VISIBLE struct lws * +lws_client_connect(struct lws_context *context, const char *address, + int port, int ssl_connection, const char *path, + const char *host, const char *origin, + const char *protocol, int ietf_version_or_minus_one) { - struct libwebsocket *wsi; + struct lws *wsi; - wsi = lws_zalloc(sizeof(struct libwebsocket)); + wsi = lws_zalloc(sizeof(struct lws)); if (wsi == NULL) goto bail; @@ -392,16 +383,15 @@ libwebsocket_client_connect(struct libwebsocket_context *context, goto bail1; if (origin) - if (lws_hdr_simple_create(wsi, - _WSI_TOKEN_CLIENT_ORIGIN, origin)) + if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ORIGIN, origin)) goto bail1; /* * this is a list of protocols we tell the server we're okay with * stash it for later when we compare server response with it */ if (protocol) - if (lws_hdr_simple_create(wsi, - _WSI_TOKEN_CLIENT_SENT_PROTOCOLS, protocol)) + if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS, + protocol)) goto bail1; wsi->protocol = &context->protocols[0]; @@ -415,19 +405,19 @@ libwebsocket_client_connect(struct libwebsocket_context *context, if (lws_ext_callback_for_each_extension_type(context, wsi, LWS_EXT_CALLBACK_CAN_PROXY_CLIENT_CONNECTION, - (void *)address, port) > 0) { - lwsl_client("libwebsocket_client_connect: ext handling conn\n"); + (void *)address, port) > 0) { + lwsl_client("lws_client_connect: ext handling conn\n"); - libwebsocket_set_timeout(wsi, + lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE, - AWAITING_TIMEOUT); + AWAITING_TIMEOUT); wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT; return wsi; } - lwsl_client("libwebsocket_client_connect: direct conn\n"); + lwsl_client("lws_client_connect: direct conn\n"); - return libwebsocket_client_connect_2(context, wsi); + return lws_client_connect_2(context, wsi); bail1: lws_free(wsi->u.hdr.ah); @@ -439,7 +429,7 @@ bail: /** - * libwebsocket_client_connect_extended() - Connect to another websocket server + * lws_client_connect_extended() - Connect to another websocket server * @context: Websocket context * @address: Remote server address, eg, "myserver.com" * @port: Port to connect to on the remote server, eg, 80 @@ -458,27 +448,23 @@ bail: * This function creates a connection to a remote server */ -LWS_VISIBLE struct libwebsocket * -libwebsocket_client_connect_extended(struct libwebsocket_context *context, - const char *address, - int port, - int ssl_connection, - const char *path, - const char *host, - const char *origin, - const char *protocol, - int ietf_version_or_minus_one, - void *userdata) +LWS_VISIBLE struct lws * +lws_client_connect_extended(struct lws_context *context, const char *address, + int port, int ssl_connection, const char *path, + const char *host, const char *origin, + const char *protocol, int ietf_version_or_minus_one, + void *userdata) { - struct libwebsocket *ws = - libwebsocket_client_connect(context, address, port, - ssl_connection, path, host, origin, protocol, - ietf_version_or_minus_one); + struct lws *wsi; - if (ws && !ws->user_space && userdata) { - ws->user_space_externally_allocated = 1; - ws->user_space = userdata ; + wsi = lws_client_connect(context, address, port, ssl_connection, path, + host, origin, protocol, + ietf_version_or_minus_one); + + if (wsi && !wsi->user_space && userdata) { + wsi->user_space_externally_allocated = 1; + wsi->user_space = userdata ; } - return ws ; + return wsi; } diff --git a/lib/client-parser.c b/lib/client-parser.c index 30fc47d03..29a34c073 100644 --- a/lib/client-parser.c +++ b/lib/client-parser.c @@ -21,12 +21,11 @@ #include "private-libwebsockets.h" -int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c) +int lws_client_rx_sm(struct lws *wsi, unsigned char c) { int callback_action = LWS_CALLBACK_CLIENT_RECEIVE; - int handled; struct lws_tokens eff_buf; - int m; + int handled, m; switch (wsi->lws_rx_parse_state) { case LWS_RXPS_NEW: @@ -54,7 +53,6 @@ int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c) } break; - case LWS_RXPS_04_FRAME_HDR_LEN: wsi->u.ws.this_frame_masked = !!(c & 0x80); @@ -277,7 +275,7 @@ spill: * we do not care about how it went, we are closing * immediately afterwards */ - libwebsocket_write(wsi, (unsigned char *) + lws_write(wsi, (unsigned char *) &wsi->u.ws.rx_user_buffer[ LWS_SEND_BUFFER_PRE_PADDING], wsi->u.ws.rx_user_buffer_head, LWS_WRITE_CLOSE); @@ -287,7 +285,7 @@ spill: case LWS_WS_OPCODE_07__PING: lwsl_info("received %d byte ping, sending pong\n", - wsi->u.ws.rx_user_buffer_head); + wsi->u.ws.rx_user_buffer_head); if (wsi->u.ws.ping_pending_flag) { /* @@ -306,13 +304,15 @@ spill: /* if existing buffer is too small, drop it */ if (wsi->u.ws.ping_payload_buf && - wsi->u.ws.ping_payload_alloc < wsi->u.ws.rx_user_buffer_head) + wsi->u.ws.ping_payload_alloc < + wsi->u.ws.rx_user_buffer_head) lws_free2(wsi->u.ws.ping_payload_buf); /* if no buffer, allocate it */ if (!wsi->u.ws.ping_payload_buf) { - wsi->u.ws.ping_payload_buf = lws_malloc(wsi->u.ws.rx_user_buffer_head - + LWS_SEND_BUFFER_PRE_PADDING); + wsi->u.ws.ping_payload_buf = + lws_malloc(wsi->u.ws.rx_user_buffer_head + + LWS_SEND_BUFFER_PRE_PADDING); wsi->u.ws.ping_payload_alloc = wsi->u.ws.rx_user_buffer_head; } @@ -326,7 +326,7 @@ spill: wsi->u.ws.ping_pending_flag = 1; /* get it sent as soon as possible */ - libwebsocket_callback_on_writable(wsi->protocol->owning_server, wsi); + lws_callback_on_writable(wsi->protocol->owning_server, wsi); ping_drop: wsi->u.ws.rx_user_buffer_head = 0; handled = 1; @@ -334,9 +334,8 @@ ping_drop: case LWS_WS_OPCODE_07__PONG: lwsl_info("client receied pong\n"); - lwsl_hexdump(&wsi->u.ws.rx_user_buffer[ - LWS_SEND_BUFFER_PRE_PADDING], - wsi->u.ws.rx_user_buffer_head); + lwsl_hexdump(&wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING], + wsi->u.ws.rx_user_buffer_head); /* issue it */ callback_action = LWS_CALLBACK_CLIENT_RECEIVE_PONG; @@ -366,7 +365,7 @@ ping_drop: &eff_buf, 0) <= 0) { /* not handle or fail */ lwsl_ext("Unhandled ext opc 0x%x\n", - wsi->u.ws.opcode); + wsi->u.ws.opcode); wsi->u.ws.rx_user_buffer_head = 0; return 0; @@ -378,7 +377,7 @@ ping_drop: /* * No it's real payload, pass it up to the user callback. * It's nicely buffered with the pre-padding taken care of - * so it can be sent straight out again using libwebsocket_write + * so it can be sent straight out again using lws_write */ if (handled) goto already_done; @@ -388,12 +387,12 @@ ping_drop: eff_buf.token_len = wsi->u.ws.rx_user_buffer_head; if (lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_PAYLOAD_RX, - &eff_buf, 0) < 0) /* fail */ + LWS_EXT_CALLBACK_PAYLOAD_RX, + &eff_buf, 0) < 0) /* fail */ return -1; if (eff_buf.token_len <= 0 && - callback_action != LWS_CALLBACK_CLIENT_RECEIVE_PONG) + callback_action != LWS_CALLBACK_CLIENT_RECEIVE_PONG) goto already_done; eff_buf.token[eff_buf.token_len] = '\0'; @@ -404,13 +403,9 @@ ping_drop: if (callback_action == LWS_CALLBACK_CLIENT_RECEIVE_PONG) lwsl_info("Client doing pong callback\n"); - m = wsi->protocol->callback( - wsi->protocol->owning_server, - wsi, - (enum libwebsocket_callback_reasons)callback_action, - wsi->user_space, - eff_buf.token, - eff_buf.token_len); + m = wsi->protocol->callback(wsi->protocol->owning_server, + wsi, (enum lws_callback_reasons)callback_action, + wsi->user_space, eff_buf.token, eff_buf.token_len); /* if user code wants to close, let caller know */ if (m) diff --git a/lib/client.c b/lib/client.c index d9d9623e8..830acee03 100644 --- a/lib/client.c +++ b/lib/client.c @@ -21,9 +21,9 @@ #include "private-libwebsockets.h" -int lws_handshake_client(struct libwebsocket *wsi, unsigned char **buf, size_t len) +int lws_handshake_client(struct lws *wsi, unsigned char **buf, size_t len) { - int n; + unsigned int n; switch (wsi->mode) { case LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY: @@ -32,7 +32,7 @@ int lws_handshake_client(struct libwebsocket *wsi, unsigned char **buf, size_t l case LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT: case LWS_CONNMODE_WS_CLIENT: for (n = 0; n < len; n++) - if (libwebsocket_client_rx_sm(wsi, *(*buf)++)) { + if (lws_client_rx_sm(wsi, *(*buf)++)) { lwsl_debug("client_rx_sm failed\n"); return 1; } @@ -43,13 +43,12 @@ int lws_handshake_client(struct libwebsocket *wsi, unsigned char **buf, size_t l return 0; } -int lws_client_socket_service(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd) +int lws_client_socket_service(struct lws_context *context, + struct lws *wsi, struct lws_pollfd *pollfd) { - int n; char *p = (char *)&context->service_buffer[0]; - int len; unsigned char c; + int n, len; switch (wsi->mode) { @@ -60,7 +59,7 @@ int lws_client_socket_service(struct libwebsocket_context *context, * timeout protection set in client-handshake.c */ - if (libwebsocket_client_connect_2(context, wsi) == NULL) { + if (lws_client_connect_2(context, wsi) == NULL) { /* closed */ lwsl_client("closed\n"); return -1; @@ -78,7 +77,7 @@ int lws_client_socket_service(struct libwebsocket_context *context, lwsl_warn("Proxy connection %p (fd=%d) dead\n", (void *)wsi, pollfd->fd); - libwebsocket_close_and_free_session(context, wsi, + lws_close_and_free_session(context, wsi, LWS_CLOSE_STATUS_NOSTATUS); return 0; } @@ -88,13 +87,12 @@ int lws_client_socket_service(struct libwebsocket_context *context, if (n < 0) { if (LWS_ERRNO == LWS_EAGAIN) { - lwsl_debug( - "Proxy read returned EAGAIN... retrying\n"); + lwsl_debug("Proxy read returned EAGAIN... retrying\n"); return 0; } - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); + lws_close_and_free_session(context, wsi, + LWS_CLOSE_STATUS_NOSTATUS); lwsl_err("ERROR reading from proxy socket\n"); return 0; } @@ -103,15 +101,15 @@ int lws_client_socket_service(struct libwebsocket_context *context, if (strcmp((char *)context->service_buffer, "HTTP/1.0 200 ") && strcmp((char *)context->service_buffer, "HTTP/1.1 200 ") ) { - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); + lws_close_and_free_session(context, wsi, + LWS_CLOSE_STATUS_NOSTATUS); lwsl_err("ERROR proxy: %s\n", context->service_buffer); return 0; } /* clear his proxy connection timeout */ - libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); + lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); /* fallthru */ @@ -123,7 +121,7 @@ int lws_client_socket_service(struct libwebsocket_context *context, */ /* - * take care of our libwebsocket_callback_on_writable + * take care of our lws_callback_on_writable * happening at a time when there's no real connection yet */ if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) @@ -215,8 +213,10 @@ int lws_client_socket_service(struct libwebsocket_context *context, if (n < 0) { n = SSL_get_error(wsi->ssl, n); - if (n == SSL_ERROR_WANT_READ || - n == SSL_ERROR_WANT_WRITE) { + if (n == SSL_ERROR_WANT_READ) + goto some_wait; + + if (n == SSL_ERROR_WANT_WRITE) { /* * wants us to retry connect due to * state of the underlying ssl layer... @@ -231,10 +231,10 @@ int lws_client_socket_service(struct libwebsocket_context *context, */ lwsl_info( - "SSL_connect WANT_... retrying\n"); - libwebsocket_callback_on_writable( + "SSL_connect WANT_WRITE... retrying\n"); + lws_callback_on_writable( context, wsi); - +some_wait: wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_SSL; return 0; /* no error */ @@ -270,14 +270,16 @@ int lws_client_socket_service(struct libwebsocket_context *context, lws_latency_pre(context, wsi); n = SSL_connect(wsi->ssl); lws_latency(context, wsi, - "SSL_connect LWS_CONNMODE_WS_CLIENT_WAITING_SSL", - n, n > 0); + "SSL_connect LWS_CONNMODE_WS_CLIENT_WAITING_SSL", + n, n > 0); if (n < 0) { n = SSL_get_error(wsi->ssl, n); - if (n == SSL_ERROR_WANT_READ || - n == SSL_ERROR_WANT_WRITE) { + if (n == SSL_ERROR_WANT_READ) + goto some_wait; + + if (n == SSL_ERROR_WANT_WRITE) { /* * wants us to retry connect due to * state of the underlying ssl layer... @@ -291,14 +293,10 @@ int lws_client_socket_service(struct libwebsocket_context *context, * us to get called back when writable. */ - lwsl_info( - "SSL_connect WANT_... retrying\n"); - libwebsocket_callback_on_writable( - context, wsi); + lwsl_info("SSL_connect WANT_WRITE... retrying\n"); + lws_callback_on_writable(context, wsi); - wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_SSL; - - return 0; /* no error */ + goto some_wait; } n = -1; } @@ -311,9 +309,8 @@ int lws_client_socket_service(struct libwebsocket_context *context, n = ERR_get_error(); if (n != SSL_ERROR_NONE) { lwsl_err("SSL connect error %lu: %s\n", - n, - ERR_error_string(n, - (char *)context->service_buffer)); + n, ERR_error_string(n, + (char *)context->service_buffer)); return 0; } } @@ -337,7 +334,7 @@ int lws_client_socket_service(struct libwebsocket_context *context, } else { lwsl_err("server's cert didn't look good, X509_V_ERR = %d: %s\n", n, ERR_error_string(n, (char *)context->service_buffer)); - libwebsocket_close_and_free_session(context, + lws_close_and_free_session(context, wsi, LWS_CLOSE_STATUS_NOSTATUS); return 0; } @@ -348,18 +345,17 @@ int lws_client_socket_service(struct libwebsocket_context *context, #endif wsi->mode = LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE2; - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND, - AWAITING_TIMEOUT); + lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND, + AWAITING_TIMEOUT); /* fallthru */ case LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE2: - p = libwebsockets_generate_client_handshake(context, wsi, p); + p = lws_generate_client_handshake(context, wsi, p); if (p == NULL) { lwsl_err("Failed to generate handshake for client\n"); - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); + lws_close_and_free_session(context, wsi, + LWS_CLOSE_STATUS_NOSTATUS); return 0; } @@ -367,25 +363,26 @@ int lws_client_socket_service(struct libwebsocket_context *context, lws_latency_pre(context, wsi); - n = lws_ssl_capable_write(wsi, context->service_buffer, p - (char *)context->service_buffer); - lws_latency(context, wsi, "send lws_issue_raw", n, n == p - (char *)context->service_buffer); + n = lws_ssl_capable_write(wsi, context->service_buffer, + p - (char *)context->service_buffer); + lws_latency(context, wsi, "send lws_issue_raw", n, + n == p - (char *)context->service_buffer); switch (n) { case LWS_SSL_CAPABLE_ERROR: lwsl_debug("ERROR writing to client socket\n"); - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); + lws_close_and_free_session(context, wsi, + LWS_CLOSE_STATUS_NOSTATUS); return 0; case LWS_SSL_CAPABLE_MORE_SERVICE: - libwebsocket_callback_on_writable(context, wsi); + lws_callback_on_writable(context, wsi); break; } wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART; wsi->u.hdr.lextable_pos = 0; wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY; - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, - AWAITING_TIMEOUT); + lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, + AWAITING_TIMEOUT); break; case LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY: @@ -424,9 +421,10 @@ int lws_client_socket_service(struct libwebsocket_context *context, */ len = 1; while (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE && - len > 0) { + len > 0) { n = lws_ssl_capable_read(context, wsi, &c, 1); - lws_latency(context, wsi, "send lws_issue_raw", n, n == 1); + lws_latency(context, wsi, "send lws_issue_raw", n, + n == 1); switch (n) { case LWS_SSL_CAPABLE_ERROR: goto bail3; @@ -434,7 +432,7 @@ int lws_client_socket_service(struct libwebsocket_context *context, return 0; } - if (libwebsocket_parse(context, wsi, c)) { + if (lws_parse(context, wsi, c)) { lwsl_warn("problems parsing header\n"); goto bail3; } @@ -458,10 +456,9 @@ int lws_client_socket_service(struct libwebsocket_context *context, return lws_client_interpret_server_handshake(context, wsi); bail3: - lwsl_info( - "closing connection at LWS_CONNMODE...SERVER_REPLY\n"); - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); + lwsl_info("closing conn at LWS_CONNMODE...SERVER_REPLY\n"); + lws_close_and_free_session(context, wsi, + LWS_CLOSE_STATUS_NOSTATUS); return -1; case LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT: @@ -493,23 +490,20 @@ strtolower(char *s) } int -lws_client_interpret_server_handshake(struct libwebsocket_context *context, - struct libwebsocket *wsi) +lws_client_interpret_server_handshake(struct lws_context *context, + struct lws *wsi) { - const char *pc; - int okay = 0; - char *p; - int len; - int isErrorCodeReceived = 0; -#ifndef LWS_NO_EXTENSIONS - char ext_name[128]; - struct libwebsocket_extension *ext; - void *v; - int more = 1; - const char *c; -#endif - int n; int close_reason = LWS_CLOSE_STATUS_PROTOCOL_ERR; + int n, len, okay = 0, isErrorCodeReceived = 0; + const char *pc; + char *p; +#ifndef LWS_NO_EXTENSIONS + struct lws_extension *ext; + char ext_name[128]; + const char *c; + int more = 1; + void *v; +#endif /* * well, what the server sent looked reasonable for syntax. @@ -558,7 +552,7 @@ lws_client_interpret_server_handshake(struct libwebsocket_context *context, } pc = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS); - if (pc == NULL) { + if (!pc) { lwsl_parser("lws_client_int_s_hs: no protocol list\n"); } else lwsl_parser("lws_client_int_s_hs: protocol list '%s'\n", pc); @@ -665,14 +659,12 @@ check_extensions: n = 0; ext = wsi->protocol->owning_server->extensions; while (ext && ext->callback) { - if (strcmp(ext_name, ext->name)) { ext++; continue; } n = 1; - lwsl_ext("instantiating client ext %s\n", ext_name); /* instantiate the extension on this conn */ @@ -690,12 +682,11 @@ check_extensions: /* allow him to construct his context */ - ext->callback(wsi->protocol->owning_server, - ext, wsi, - LWS_EXT_CALLBACK_CLIENT_CONSTRUCT, - wsi->active_extensions_user[ + ext->callback(wsi->protocol->owning_server, ext, wsi, + LWS_EXT_CALLBACK_CLIENT_CONSTRUCT, + wsi->active_extensions_user[ wsi->count_active_extensions], - NULL, 0); + NULL, 0); wsi->count_active_extensions++; @@ -725,7 +716,7 @@ check_accept: } /* allocate the per-connection user memory (if any) */ - if (libwebsocket_ensure_user_space(wsi)) { + if (lws_ensure_user_space(wsi)) { lwsl_err("Problem allocating wsi user mem\n"); goto bail2; } @@ -734,14 +725,13 @@ check_accept: * we seem to be good to go, give client last chance to check * headers and OK it */ - wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH, - wsi->user_space, NULL, 0); + wsi->user_space, NULL, 0); /* clear his proxy connection timeout */ - libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); + lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); /* free up his parsing allocations */ @@ -769,7 +759,8 @@ check_accept: } lwsl_info("Allocating client RX buffer %d\n", n); - if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF, (const char *)&n, sizeof n)) { + if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF, (const char *)&n, + sizeof n)) { lwsl_warn("Failed to set SNDBUF to %d", n); goto bail3; } @@ -778,9 +769,8 @@ check_accept: /* call him back to inform him he is up */ - wsi->protocol->callback(context, wsi, - LWS_CALLBACK_CLIENT_ESTABLISHED, - wsi->user_space, NULL, 0); + 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 @@ -812,50 +802,45 @@ bail2: if (isErrorCodeReceived && p) { wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - wsi->user_space, p, (unsigned int)strlen(p)); + wsi->user_space, p, + (unsigned int)strlen(p)); } else { wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - wsi->user_space, NULL, 0); + wsi->user_space, NULL, 0); } } lwsl_info("closing connection due to bail2 connection error\n"); /* free up his parsing allocations */ - lws_free2(wsi->u.hdr.ah); - - libwebsocket_close_and_free_session(context, wsi, close_reason); + lws_close_and_free_session(context, wsi, close_reason); return 1; } char * -libwebsockets_generate_client_handshake(struct libwebsocket_context *context, - struct libwebsocket *wsi, char *pkt) +lws_generate_client_handshake(struct lws_context *context, + struct lws *wsi, char *pkt) { - char buf[128]; - char hash[20]; - char key_b64[40]; - char *p = pkt; + char buf[128], hash[20], key_b64[40], *p = pkt; int n; #ifndef LWS_NO_EXTENSIONS - struct libwebsocket_extension *ext; + struct lws_extension *ext; int ext_count = 0; #endif /* * create the random key */ - - n = libwebsockets_get_random(context, hash, 16); + n = lws_get_random(context, hash, 16); if (n != 16) { lwsl_err("Unable to read from random dev %s\n", - SYSTEM_RANDOM_FILEPATH); - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); + SYSTEM_RANDOM_FILEPATH); + lws_close_and_free_session(context, wsi, + LWS_CLOSE_STATUS_NOSTATUS); return NULL; } @@ -888,15 +873,16 @@ libwebsockets_generate_client_handshake(struct libwebsocket_context *context, */ p += sprintf(p, "GET %s HTTP/1.1\x0d\x0a", - lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_URI)); + lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_URI)); - p += sprintf(p, - "Pragma: no-cache\x0d\x0a""Cache-Control: no-cache\x0d\x0a"); + p += sprintf(p, "Pragma: no-cache\x0d\x0a" + "Cache-Control: no-cache\x0d\x0a"); p += sprintf(p, "Host: %s\x0d\x0a", - lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_HOST)); - p += sprintf(p, -"Upgrade: websocket\x0d\x0a""Connection: Upgrade\x0d\x0a""Sec-WebSocket-Key: "); + lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_HOST)); + p += sprintf(p, "Upgrade: websocket\x0d\x0a" + "Connection: Upgrade\x0d\x0a" + "Sec-WebSocket-Key: "); strcpy(p, key_b64); p += strlen(key_b64); p += sprintf(p, "\x0d\x0a"); @@ -917,7 +903,7 @@ libwebsockets_generate_client_handshake(struct libwebsocket_context *context, n = lws_ext_callback_for_each_extension_type(context, wsi, LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION, - (char *)ext->name, 0); + (char *)ext->name, 0); if (n) { /* an extension vetos us */ lwsl_ext("ext %s vetoed\n", (char *)ext->name); ext++; @@ -954,13 +940,14 @@ libwebsockets_generate_client_handshake(struct libwebsocket_context *context, if (wsi->ietf_spec_revision) p += sprintf(p, "Sec-WebSocket-Version: %d\x0d\x0a", - wsi->ietf_spec_revision); + wsi->ietf_spec_revision); /* give userland a chance to append, eg, cookies */ context->protocols[0].callback(context, wsi, - LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER, - NULL, &p, (pkt + sizeof(context->service_buffer)) - p - 12); + LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER, + NULL, &p, + (pkt + sizeof(context->service_buffer)) - p - 12); p += sprintf(p, "\x0d\x0a"); @@ -969,11 +956,11 @@ libwebsockets_generate_client_handshake(struct libwebsocket_context *context, key_b64[39] = '\0'; /* enforce composed length below buf sizeof */ n = sprintf(buf, "%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11", key_b64); - libwebsockets_SHA1((unsigned char *)buf, n, (unsigned char *)hash); + lws_SHA1((unsigned char *)buf, n, (unsigned char *)hash); lws_b64_encode_string(hash, 20, - wsi->u.hdr.ah->initial_handshake_hash_base64, - sizeof(wsi->u.hdr.ah->initial_handshake_hash_base64)); + wsi->u.hdr.ah->initial_handshake_hash_base64, + sizeof(wsi->u.hdr.ah->initial_handshake_hash_base64)); return p; } diff --git a/lib/context.c b/lib/context.c index ef0362e5a..ec70e7be7 100644 --- a/lib/context.c +++ b/lib/context.c @@ -42,15 +42,15 @@ lws_get_library_version(void) } /** - * libwebsocket_create_context() - Create the websocket handler + * lws_create_context() - Create the websocket handler * @info: pointer to struct with parameters * * This function creates the listening socket (if serving) and takes care * of all initialization in one step. * - * After initialization, it returns a struct libwebsocket_context * that + * After initialization, it returns a struct lws_context * that * represents this server. After calling, user code needs to take care - * of calling libwebsocket_service() with the context pointer to get the + * of calling lws_service() with the context pointer to get the * server's sockets serviced. This must be done in the same process * context as the initialization call. * @@ -71,14 +71,14 @@ lws_get_library_version(void) * one place; they're all handled in the user callback. */ -LWS_VISIBLE struct libwebsocket_context * -libwebsocket_create_context(struct lws_context_creation_info *info) +LWS_VISIBLE struct lws_context * +lws_create_context(struct lws_context_creation_info *info) { - struct libwebsocket_context *context = NULL; - char *p; -#if LWS_POSIX + struct lws_context *context = NULL; +#ifndef LWS_NO_DAEMONIZE int pid_daemon = get_daemonize_pid(); #endif + char *p; lwsl_notice("Initial logging level %d\n", log_level); @@ -91,9 +91,9 @@ libwebsocket_create_context(struct lws_context_creation_info *info) lwsl_notice("IPV6 compiled in but disabled\n"); #else lwsl_notice("IPV6 not compiled in\n"); -#endif #endif lws_feature_status_libev(info); +#endif lwsl_info(" LWS_MAX_HEADER_LEN: %u\n", LWS_MAX_HEADER_LEN); lwsl_info(" LWS_MAX_PROTOCOLS: %u\n", LWS_MAX_PROTOCOLS); @@ -106,18 +106,17 @@ libwebsocket_create_context(struct lws_context_creation_info *info) if (lws_plat_context_early_init()) return NULL; - context = lws_zalloc(sizeof(struct libwebsocket_context)); + context = lws_zalloc(sizeof(struct lws_context)); if (!context) { lwsl_err("No memory for websocket context\n"); return NULL; } -#if LWS_POSIX +#ifndef LWS_NO_DAEMONIZE if (pid_daemon) { context->started_with_parent = pid_daemon; lwsl_notice(" Started with daemon pid %d\n", pid_daemon); } #endif - context->listen_service_extraseen = 0; context->protocols = info->protocols; context->token_limits = info->token_limits; @@ -138,41 +137,31 @@ libwebsocket_create_context(struct lws_context_creation_info *info) #ifdef LWS_USE_LIBEV /* (Issue #264) In order to *avoid breaking backwards compatibility*, we * enable libev mediated SIGINT handling with a default handler of - * libwebsocket_sigint_cb. The handler can be overridden or disabled - * by invoking libwebsocket_sigint_cfg after creating the context, but - * before invoking libwebsocket_initloop: + * lws_sigint_cb. The handler can be overridden or disabled + * by invoking lws_sigint_cfg after creating the context, but + * before invoking lws_initloop: */ context->use_ev_sigint = 1; - context->lws_ev_sigint_cb = &libwebsocket_sigint_cb; + context->lws_ev_sigint_cb = &lws_sigint_cb; #endif /* LWS_USE_LIBEV */ /* to reduce this allocation, */ context->max_fds = getdtablesize(); - lwsl_notice(" static allocation: %u + (%u x %u fds) = %u bytes\n", - sizeof(struct libwebsocket_context), - sizeof(struct libwebsocket_pollfd) + - sizeof(struct libwebsocket *), - context->max_fds, - sizeof(struct libwebsocket_context) + - ((sizeof(struct libwebsocket_pollfd) + - sizeof(struct libwebsocket *)) * - context->max_fds)); + lwsl_notice(" ctx mem: %u bytes\n", sizeof(struct lws_context) + + ((sizeof(struct lws_pollfd) + sizeof(struct lws *)) * + context->max_fds)); - context->fds = lws_zalloc(sizeof(struct libwebsocket_pollfd) * - context->max_fds); + context->fds = lws_zalloc(sizeof(struct lws_pollfd) * context->max_fds); if (context->fds == NULL) { - lwsl_err("Unable to allocate fds array for %d connections\n", - context->max_fds); + lwsl_err("OOM allocating %d fds\n", context->max_fds); goto bail; } - if (lws_plat_init_lookup(context)) { + if (lws_plat_init_lookup(context)) goto bail; - } - if (lws_plat_init_fd_tables(context)) { + if (lws_plat_init_fd_tables(context)) goto bail; - } lws_context_init_file_callbacks(info, context); @@ -190,19 +179,17 @@ libwebsocket_create_context(struct lws_context_creation_info *info) /* override for backwards compatibility */ if (info->http_proxy_port) context->http_proxy_port = info->http_proxy_port; - libwebsocket_set_proxy(context, info->http_proxy_address); + lws_set_proxy(context, info->http_proxy_address); } else { #ifdef LWS_HAVE_GETENV p = getenv("http_proxy"); if (p) - libwebsocket_set_proxy(context, p); + lws_set_proxy(context, p); #endif } - lwsl_notice( - " per-conn mem: %u + %u headers + protocol rx buf\n", - sizeof(struct libwebsocket), - sizeof(struct allocated_headers)); + lwsl_notice(" per-conn mem: %u + %u headers + protocol rx buf\n", + sizeof(struct lws), sizeof(struct allocated_headers)); if (lws_context_init_server_ssl(info, context)) goto bail; @@ -223,12 +210,8 @@ libwebsocket_create_context(struct lws_context_creation_info *info) /* initialize supported protocols */ for (context->count_protocols = 0; - info->protocols[context->count_protocols].callback; - context->count_protocols++) { - -// lwsl_notice(" Protocol: %s\n", -// info->protocols[context->count_protocols].name); - + info->protocols[context->count_protocols].callback; + context->count_protocols++) { info->protocols[context->count_protocols].owning_server = context; info->protocols[context->count_protocols].protocol_index = @@ -246,27 +229,24 @@ libwebsocket_create_context(struct lws_context_creation_info *info) * give all extensions a chance to create any per-context * allocations they need */ - if (info->port != CONTEXT_PORT_NO_LISTEN) { if (lws_ext_callback_for_each_extension_type(context, NULL, - LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT, - NULL, 0) < 0) + LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT, NULL, 0) < 0) goto bail; } else if (lws_ext_callback_for_each_extension_type(context, NULL, - LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT, - NULL, 0) < 0) + LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT, NULL, 0) < 0) goto bail; return context; bail: - libwebsocket_context_destroy(context); + lws_context_destroy(context); return NULL; } /** - * libwebsocket_context_destroy() - Destroy the websocket context + * lws_context_destroy() - Destroy the websocket context * @context: Websocket context * * This function closes any active connections and then frees the @@ -274,12 +254,10 @@ bail: * undefined. */ LWS_VISIBLE void -libwebsocket_context_destroy(struct libwebsocket_context *context) +lws_context_destroy(struct lws_context *context) { - /* Note that this is used for freeing partially allocated structs as well - * so make sure you don't try to free something uninitialized */ + struct lws_protocols *protocol = NULL; int n; - struct libwebsocket_protocols *protocol = NULL; lwsl_notice("%s\n", __func__); @@ -292,12 +270,12 @@ libwebsocket_context_destroy(struct libwebsocket_context *context) #endif for (n = 0; n < context->fds_count; n++) { - struct libwebsocket *wsi = - wsi_from_fd(context, context->fds[n].fd); + struct lws *wsi = wsi_from_fd(context, context->fds[n].fd); if (!wsi) continue; - libwebsocket_close_and_free_session(context, - wsi, LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY /* no protocol close */); + lws_close_and_free_session(context, wsi, + LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY + /* no protocol close */); n--; } @@ -305,20 +283,12 @@ libwebsocket_context_destroy(struct libwebsocket_context *context) * give all extensions a chance to clean up any per-context * allocations they might have made */ - // TODO: I am not sure, but are we never supposed to be able to run a server - // and client at the same time for a given context? - // Otherwise both of these callbacks should always be called! - if (context->listen_port != CONTEXT_PORT_NO_LISTEN) { - if (lws_ext_callback_for_each_extension_type(context, NULL, - LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT, NULL, 0) < 0) { - lwsl_err("Got error from server extension callback on cleanup"); - } - } else { - if (lws_ext_callback_for_each_extension_type(context, NULL, - LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT, NULL, 0) < 0) { - lwsl_err("Got error from client extension callback on cleanup"); - } - } + + n = lws_ext_callback_for_each_extension_type(context, NULL, + LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT, NULL, 0); + + n = lws_ext_callback_for_each_extension_type(context, NULL, + LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT, NULL, 0); /* * inform all the protocols that they are done and will have no more @@ -327,14 +297,14 @@ libwebsocket_context_destroy(struct libwebsocket_context *context) protocol = context->protocols; if (protocol) { while (protocol->callback) { - protocol->callback(context, NULL, LWS_CALLBACK_PROTOCOL_DESTROY, - NULL, NULL, 0); + protocol->callback(context, NULL, + LWS_CALLBACK_PROTOCOL_DESTROY, + NULL, NULL, 0); protocol++; } } lws_plat_context_early_destroy(context); - lws_ssl_context_destroy(context); if (context->fds) diff --git a/lib/daemonize.c b/lib/daemonize.c index 0892cb06e..7e79bb041 100644 --- a/lib/daemonize.c +++ b/lib/daemonize.c @@ -34,9 +34,7 @@ int get_daemonize_pid() static void child_handler(int signum) { - int fd; - int len; - int sent; + int fd, len, sent; char sz[20]; switch (signum) { @@ -93,11 +91,10 @@ static void lws_daemon_closing(int sigact) LWS_VISIBLE int lws_daemonize(const char *_lock_path) { - pid_t sid, parent; - int fd; - char buf[10]; - int n, ret; struct sigaction act; + pid_t sid, parent; + int n, fd, ret; + char buf[10]; /* already a daemon */ if (getppid() == 1) diff --git a/lib/extension-deflate-frame.c b/lib/extension-deflate-frame.c index 96285a9a1..87eac8b4e 100644 --- a/lib/extension-deflate-frame.c +++ b/lib/extension-deflate-frame.c @@ -8,10 +8,10 @@ #define LWS_ZLIB_MEMLEVEL 8 int lws_extension_callback_deflate_frame( - struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, + struct lws_context *context, + struct lws_extension *ext, + struct lws *wsi, + enum lws_extension_callback_reasons reason, void *user, void *in, size_t len) { struct lws_ext_deflate_frame_conn *conn = diff --git a/lib/extension-deflate-frame.h b/lib/extension-deflate-frame.h index 00a4447aa..5e5b3f1f8 100644 --- a/lib/extension-deflate-frame.h +++ b/lib/extension-deflate-frame.h @@ -18,8 +18,8 @@ struct lws_ext_deflate_frame_conn { }; extern int lws_extension_callback_deflate_frame( - struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, + struct lws_context *context, + struct lws_extension *ext, + struct lws *wsi, + enum lws_extension_callback_reasons reason, void *user, void *in, size_t len); diff --git a/lib/extension-deflate-stream.c b/lib/extension-deflate-stream.c index addaa2c7e..f69b12be7 100644 --- a/lib/extension-deflate-stream.c +++ b/lib/extension-deflate-stream.c @@ -8,10 +8,10 @@ #define LWS_ZLIB_MEMLEVEL 8 int lws_extension_callback_deflate_stream( - struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, + struct lws_context *context, + struct lws_extension *ext, + struct lws *wsi, + enum lws_extension_callback_reasons reason, void *user, void *in, size_t len) { struct lws_ext_deflate_stream_conn *conn = diff --git a/lib/extension-deflate-stream.h b/lib/extension-deflate-stream.h index fcadc07ab..b41779061 100644 --- a/lib/extension-deflate-stream.h +++ b/lib/extension-deflate-stream.h @@ -13,8 +13,8 @@ struct lws_ext_deflate_stream_conn { }; extern int lws_extension_callback_deflate_stream( - struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, + struct lws_context *context, + struct lws_extension *ext, + struct lws *wsi, + enum lws_extension_callback_reasons reason, void *user, void *in, size_t len); diff --git a/lib/extension.c b/lib/extension.c index b7a5792bf..ad6a37ece 100644 --- a/lib/extension.c +++ b/lib/extension.c @@ -3,7 +3,7 @@ #include "extension-deflate-frame.h" #include "extension-deflate-stream.h" -struct libwebsocket_extension libwebsocket_internal_extensions[] = { +struct lws_extension lws_internal_extensions[] = { #ifdef LWS_EXT_DEFLATE_STREAM { "deflate-stream", @@ -29,21 +29,21 @@ struct libwebsocket_extension libwebsocket_internal_extensions[] = { LWS_VISIBLE void lws_context_init_extensions(struct lws_context_creation_info *info, - struct libwebsocket_context *context) + struct lws_context *context) { context->extensions = info->extensions; lwsl_info(" LWS_MAX_EXTENSIONS_ACTIVE: %u\n", LWS_MAX_EXTENSIONS_ACTIVE); } -LWS_VISIBLE struct libwebsocket_extension *libwebsocket_get_internal_extensions() +LWS_VISIBLE struct lws_extension *lws_get_internal_extensions() { - return libwebsocket_internal_extensions; + return lws_internal_extensions; } /* 0 = nobody had nonzero return, 1 = somebody had positive return, -1 = fail */ -int lws_ext_callback_for_each_active(struct libwebsocket *wsi, int reason, +int lws_ext_callback_for_each_active(struct lws *wsi, int reason, void *arg, int len) { int n, m, handled = 0; @@ -69,11 +69,11 @@ int lws_ext_callback_for_each_active(struct libwebsocket *wsi, int reason, } int lws_ext_callback_for_each_extension_type( - struct libwebsocket_context *context, struct libwebsocket *wsi, + struct lws_context *context, struct lws *wsi, int reason, void *arg, int len) { int n = 0, m, handled = 0; - struct libwebsocket_extension *ext = context->extensions; + struct lws_extension *ext = context->extensions; while (ext && ext->callback && !handled) { m = ext->callback(context, ext, wsi, reason, @@ -95,7 +95,7 @@ int lws_ext_callback_for_each_extension_type( } int -lws_issue_raw_ext_access(struct libwebsocket *wsi, +lws_issue_raw_ext_access(struct lws *wsi, unsigned char *buf, size_t len) { int ret; @@ -175,7 +175,7 @@ lws_issue_raw_ext_access(struct libwebsocket *wsi, * Yes, he's choked. Don't spill the rest now get a callback * when he is ready to send and take care of it there */ - libwebsocket_callback_on_writable( + lws_callback_on_writable( wsi->protocol->owning_server, wsi); wsi->extension_data_pending = 1; ret = 0; @@ -185,9 +185,9 @@ lws_issue_raw_ext_access(struct libwebsocket *wsi, } int -lws_any_extension_handled(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons r, +lws_any_extension_handled(struct lws_context *context, + struct lws *wsi, + enum lws_extension_callback_reasons r, void *v, size_t len) { int n; diff --git a/lib/handshake.c b/lib/handshake.c index df898c649..2446a75a4 100644 --- a/lib/handshake.c +++ b/lib/handshake.c @@ -1,7 +1,7 @@ /* * libwebsockets - small server side websockets and web server implementation * - * Copyright (C) 2010-2013 Andy Green + * Copyright (C) 2010-2015 Andy Green * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -49,6 +49,7 @@ #ifndef min #define min(a, b) ((a) < (b) ? (a) : (b)) #endif + /* * We have to take care about parsing because the headers may be split * into multiple fragments. They may contain unknown headers with arbitrary @@ -57,12 +58,12 @@ */ LWS_VISIBLE int -libwebsocket_read(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char *buf, size_t len) +lws_read(struct lws_context *context, struct lws *wsi, unsigned char *buf, + size_t len) { - size_t n; - int body_chunk_len; unsigned char *last_char; + int body_chunk_len; + size_t n; switch (wsi->state) { #ifdef LWS_USE_HTTP2 @@ -124,8 +125,13 @@ http_new: case WSI_STATE_HTTP_ISSUING_FILE: goto read_ok; case WSI_STATE_HTTP_BODY: - wsi->u.http.content_remain = wsi->u.http.content_length; - goto http_postbody; + wsi->u.http.content_remain = + wsi->u.http.content_length; + if (wsi->u.http.content_remain) + goto http_postbody; + + /* there is no POST content */ + goto postbody_completion; default: break; } @@ -142,32 +148,31 @@ http_postbody: wsi->u.http.content_remain -= body_chunk_len; len -= body_chunk_len; - if (wsi->protocol->callback) { - n = wsi->protocol->callback( - wsi->protocol->owning_server, wsi, - LWS_CALLBACK_HTTP_BODY, wsi->user_space, - buf, body_chunk_len); - if (n) - goto bail; - } + n = wsi->protocol->callback( + wsi->protocol->owning_server, wsi, + LWS_CALLBACK_HTTP_BODY, wsi->user_space, + buf, body_chunk_len); + if (n) + goto bail; + buf += body_chunk_len; - if (!wsi->u.http.content_remain) { - /* he sent the content in time */ - libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - if (wsi->protocol->callback) { - n = wsi->protocol->callback( - wsi->protocol->owning_server, wsi, - LWS_CALLBACK_HTTP_BODY_COMPLETION, - wsi->user_space, NULL, 0); - if (n) - goto bail; - } - goto http_complete; - } else - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_HTTP_CONTENT, - AWAITING_TIMEOUT); + if (wsi->u.http.content_remain) { + lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT, + AWAITING_TIMEOUT); + break; + } + /* he sent all the content in time */ +postbody_completion: + lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); + n = wsi->protocol->callback( + wsi->protocol->owning_server, wsi, + LWS_CALLBACK_HTTP_BODY_COMPLETION, + wsi->user_space, NULL, 0); + if (n) + goto bail; + + goto http_complete; } break; @@ -178,7 +183,7 @@ http_postbody: switch (wsi->mode) { case LWS_CONNMODE_WS_SERVING: - if (libwebsocket_interpret_incoming_packet(wsi, buf, len) < 0) { + if (lws_interpret_incoming_packet(wsi, buf, len) < 0) { lwsl_info("interpret_incoming_packet has bailed\n"); goto bail; } @@ -186,18 +191,18 @@ http_postbody: } break; default: - lwsl_err("libwebsocket_read: Unhandled state\n"); + lwsl_err("lws_read: Unhandled state\n"); break; } read_ok: - /* Nothing more to do for now. */ - lwsl_debug("libwebsocket_read: read_ok\n"); + /* Nothing more to do for now */ + lwsl_debug("lws_read: read_ok\n"); return 0; http_complete: - lwsl_debug("libwebsocket_read: http_complete\n"); + lwsl_debug("lws_read: http_complete\n"); #ifndef LWS_NO_SERVER /* Did the client want to keep the HTTP connection going? */ @@ -211,10 +216,8 @@ http_complete: return 0; bail: - lwsl_debug("closing connection at libwebsocket_read bail:\n"); - - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); + lwsl_debug("closing connection at lws_read bail:\n"); + lws_close_and_free_session(context, wsi, LWS_CLOSE_STATUS_NOSTATUS); return -1; } diff --git a/lib/header.c b/lib/header.c index 56c8fc05f..5daf0d84b 100644 --- a/lib/header.c +++ b/lib/header.c @@ -24,22 +24,25 @@ const unsigned char *lws_token_to_string(enum lws_token_indexes token) { + if (token == WSI_TOKEN_HTTP_URI_ARGS) + return (unsigned char *)"Uri-Args:"; + if ((unsigned int)token >= ARRAY_SIZE(set)) return NULL; + return (unsigned char *)set[token]; } -int lws_add_http_header_by_name(struct libwebsocket_context *context, - struct libwebsocket *wsi, +int +lws_add_http_header_by_name(struct lws_context *context, struct lws *wsi, const unsigned char *name, - const unsigned char *value, - int length, - unsigned char **p, - unsigned char *end) + const unsigned char *value, int length, + unsigned char **p, unsigned char *end) { #ifdef LWS_USE_HTTP2 if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING) - return lws_add_http2_header_by_name(context, wsi, name, value, length, p, end); + return lws_add_http2_header_by_name(context, wsi, name, + value, length, p, end); #else (void)wsi; (void)context; @@ -58,13 +61,12 @@ int lws_add_http_header_by_name(struct libwebsocket_context *context, *p += length; *((*p)++) = '\x0d'; *((*p)++) = '\x0a'; + return 0; } -int lws_finalize_http_header(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned char **p, - unsigned char *end) +int lws_finalize_http_header(struct lws_context *context, struct lws *wsi, + unsigned char **p, unsigned char *end) { (void)context; #ifdef LWS_USE_HTTP2 @@ -77,16 +79,15 @@ int lws_finalize_http_header(struct libwebsocket_context *context, return 1; *((*p)++) = '\x0d'; *((*p)++) = '\x0a'; + return 0; } -int lws_add_http_header_by_token(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum lws_token_indexes token, - const unsigned char *value, - int length, - unsigned char **p, - unsigned char *end) +int +lws_add_http_header_by_token(struct lws_context *context, struct lws *wsi, + enum lws_token_indexes token, + const unsigned char *value, int length, + unsigned char **p, unsigned char *end) { const unsigned char *name; #ifdef LWS_USE_HTTP2 @@ -99,11 +100,10 @@ int lws_add_http_header_by_token(struct libwebsocket_context *context, return lws_add_http_header_by_name(context, wsi, name, value, length, p, end); } -int lws_add_http_header_content_length(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned long content_length, - unsigned char **p, - unsigned char *end) +int lws_add_http_header_content_length(struct lws_context *context, + struct lws *wsi, + unsigned long content_length, + unsigned char **p, unsigned char *end) { char b[24]; int n; @@ -147,11 +147,10 @@ static const char *err500[] = { "HTTP Version Not Supported" }; -int lws_add_http_header_status(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned int code, - unsigned char **p, - unsigned char *end) +int +lws_add_http_header_status(struct lws_context *context, struct lws *wsi, + unsigned int code, unsigned char **p, + unsigned char *end) { unsigned char code_and_desc[60]; const char *description = ""; @@ -168,11 +167,12 @@ int lws_add_http_header_status(struct libwebsocket_context *context, n = sprintf((char *)code_and_desc, "HTTP/1.0 %u %s", code, description); - return lws_add_http_header_by_name(context, wsi, NULL, code_and_desc, n, p, end); + return lws_add_http_header_by_name(context, wsi, NULL, code_and_desc, + n, p, end); } /** - * libwebsockets_return_http_status() - Return simple http status + * lws_return_http_status() - Return simple http status * @context: libwebsockets context * @wsi: Websocket instance (available from user callback) * @code: Status index, eg, 404 @@ -181,35 +181,42 @@ int lws_add_http_header_status(struct libwebsocket_context *context, * Helper to report HTTP errors back to the client cleanly and * consistently */ -LWS_VISIBLE int libwebsockets_return_http_status( - struct libwebsocket_context *context, struct libwebsocket *wsi, - unsigned int code, const char *html_body) +LWS_VISIBLE int +lws_return_http_status(struct lws_context *context, struct lws *wsi, + unsigned int code, const char *html_body) { int n, m; - unsigned char *p = context->service_buffer + LWS_SEND_BUFFER_PRE_PADDING; + unsigned char *p = context->service_buffer + + LWS_SEND_BUFFER_PRE_PADDING; unsigned char *start = p; unsigned char *end = p + sizeof(context->service_buffer) - - LWS_SEND_BUFFER_PRE_PADDING; + LWS_SEND_BUFFER_PRE_PADDING; if (!html_body) html_body = ""; if (lws_add_http_header_status(context, wsi, code, &p, end)) return 1; - if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_SERVER, (unsigned char *)"libwebsockets", 13, &p, end)) + if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_SERVER, + (unsigned char *)"libwebsockets", 13, + &p, end)) return 1; - if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, (unsigned char *)"text/html", 9, &p, end)) + if (lws_add_http_header_by_token(context, wsi, + WSI_TOKEN_HTTP_CONTENT_TYPE, + (unsigned char *)"text/html", 9, + &p, end)) return 1; if (lws_finalize_http_header(context, wsi, &p, end)) return 1; - m = libwebsocket_write(wsi, start, p - start, LWS_WRITE_HTTP_HEADERS); + m = lws_write(wsi, start, p - start, LWS_WRITE_HTTP_HEADERS); if (m != (int)(p - start)) return 1; - n = sprintf((char *)start, "

%u

%s", code, html_body); - m = libwebsocket_write(wsi, start, n, LWS_WRITE_HTTP); + n = sprintf((char *)start, "

%u

%s", + code, html_body); + m = lws_write(wsi, start, n, LWS_WRITE_HTTP); return m != n; } diff --git a/lib/hpack.c b/lib/hpack.c index 3ac01b031..ba69374fd 100644 --- a/lib/hpack.c +++ b/lib/hpack.c @@ -189,13 +189,13 @@ static int huftable_decode(int pos, char c) return pos + (lextable[q] << 1); } -static int lws_hpack_update_table_size(struct libwebsocket *wsi, int idx) +static int lws_hpack_update_table_size(struct lws *wsi, int idx) { lwsl_info("hpack set table size %d\n", idx); return 0; } -static int lws_frag_start(struct libwebsocket *wsi, int hdr_token_idx) +static int lws_frag_start(struct lws *wsi, int hdr_token_idx) { struct allocated_headers * ah = wsi->u.http2.http.ah; @@ -214,7 +214,7 @@ static int lws_frag_start(struct libwebsocket *wsi, int hdr_token_idx) return 0; } -static int lws_frag_append(struct libwebsocket *wsi, unsigned char c) +static int lws_frag_append(struct lws *wsi, unsigned char c) { struct allocated_headers * ah = wsi->u.http2.http.ah; @@ -224,7 +224,7 @@ static int lws_frag_append(struct libwebsocket *wsi, unsigned char c) return ah->pos >= sizeof(ah->data); } -static int lws_frag_end(struct libwebsocket *wsi) +static int lws_frag_end(struct lws *wsi) { if (lws_frag_append(wsi, 0)) return 1; @@ -233,7 +233,7 @@ static int lws_frag_end(struct libwebsocket *wsi) return 0; } -static void lws_dump_header(struct libwebsocket *wsi, int hdr) +static void lws_dump_header(struct lws *wsi, int hdr) { char s[200]; int len = lws_hdr_copy(wsi, s, sizeof(s) - 1, hdr); @@ -241,7 +241,8 @@ static void lws_dump_header(struct libwebsocket *wsi, int hdr) lwsl_info(" hdr tok %d (%s) = '%s'\n", hdr, lws_token_to_string(hdr), s); } -static int lws_token_from_index(struct libwebsocket *wsi, int index, char **arg, int *len) +static int +lws_token_from_index(struct lws *wsi, int index, char **arg, int *len) { struct hpack_dynamic_table *dyn; @@ -269,7 +270,8 @@ static int lws_token_from_index(struct libwebsocket *wsi, int index, char **arg, return dyn->entries[index].token; } -static int lws_hpack_add_dynamic_header(struct libwebsocket *wsi, int token, char *arg, int len) +static int +lws_hpack_add_dynamic_header(struct lws *wsi, int token, char *arg, int len) { struct hpack_dynamic_table *dyn; int ret = 1; @@ -305,7 +307,8 @@ static int lws_hpack_add_dynamic_header(struct libwebsocket *wsi, int token, cha memcpy(dyn->args + dyn->pos, arg, len); dyn->entries[dyn->next].arg_len = len; - lwsl_info("%s: added dynamic hdr %d, token %d (%s), len %d\n", __func__, dyn->next, token, lws_token_to_string(token), len); + lwsl_info("%s: added dynamic hdr %d, token %d (%s), len %d\n", + __func__, dyn->next, token, lws_token_to_string(token), len); dyn->pos += len; dyn->next++; @@ -321,12 +324,13 @@ bail1: return ret; } -static int lws_write_indexed_hdr(struct libwebsocket *wsi, int idx) +static int lws_write_indexed_hdr(struct lws *wsi, int idx) { const char *p; int tok = lws_token_from_index(wsi, idx, NULL, 0); - lwsl_info("writing indexed hdr %d (tok %d '%s')\n", idx, tok, lws_token_to_string(tok)); + lwsl_info("writing indexed hdr %d (tok %d '%s')\n", idx, tok, + lws_token_to_string(tok)); if (lws_frag_start(wsi, tok)) return 1; @@ -345,8 +349,8 @@ static int lws_write_indexed_hdr(struct libwebsocket *wsi, int idx) return 0; } -int lws_hpack_interpret(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char c) +int lws_hpack_interpret(struct lws_context *context, + struct lws *wsi, unsigned char c) { unsigned int prev; unsigned char c1; @@ -492,9 +496,9 @@ int lws_hpack_interpret(struct libwebsocket_context *context, if (wsi->u.http2.hpack_len < 0x7f) { pre_data: if (wsi->u.http2.value) { - if (lws_frag_start(wsi, - lws_token_from_index(wsi, - wsi->u.http2.header_index, NULL, NULL))) + if (lws_frag_start(wsi, lws_token_from_index(wsi, + wsi->u.http2.header_index, + NULL, NULL))) return 1; } else wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART; @@ -518,10 +522,9 @@ pre_data: for (n = 0; n < 8; n++) { if (wsi->u.http2.huff) { prev = wsi->u.http2.hpack_pos; - wsi->u.http2.hpack_pos = - huftable_decode( + wsi->u.http2.hpack_pos = huftable_decode( wsi->u.http2.hpack_pos, - (c >> 7) & 1); + (c >> 7) & 1); c <<= 1; if (wsi->u.http2.hpack_pos == 0xffff) return 1; @@ -540,7 +543,7 @@ pre_data: if (lws_frag_append(wsi, c1)) return 1; } else { /* name */ - if (libwebsocket_parse(context, wsi, c1)) + if (lws_parse(context, wsi, c1)) return 1; } @@ -550,7 +553,10 @@ pre_data: switch (wsi->u.http2.hpack_type) { case HPKT_LITERAL_HDR_VALUE_INCR: case HPKT_INDEXED_HDR_6_VALUE_INCR: // !!! - if (lws_hpack_add_dynamic_header(wsi, lws_token_from_index(wsi, wsi->u.http2.header_index, NULL, NULL), NULL, 0)) + if (lws_hpack_add_dynamic_header(wsi, + lws_token_from_index(wsi, + wsi->u.http2.header_index, + NULL, NULL), NULL, 0)) return 1; break; default: @@ -562,8 +568,11 @@ pre_data: if (lws_frag_end(wsi)) return 1; - lws_dump_header(wsi, lws_token_from_index(wsi, wsi->u.http2.header_index, NULL, NULL)); - if (wsi->u.http2.count + wsi->u.http2.padding == wsi->u.http2.length) + lws_dump_header(wsi, lws_token_from_index( + wsi, wsi->u.http2.header_index, + NULL, NULL)); + if (wsi->u.http2.count + wsi->u.http2.padding == + wsi->u.http2.length) wsi->u.http2.hpack = HKPS_OPT_DISCARD_PADDING; else wsi->u.http2.hpack = HPKS_TYPE; @@ -585,7 +594,8 @@ pre_data: return 0; } -static int lws_http2_num(int starting_bits, unsigned long num, unsigned char **p, unsigned char *end) +static int lws_http2_num(int starting_bits, unsigned long num, + unsigned char **p, unsigned char *end) { int mask = (1 << starting_bits) - 1; @@ -609,13 +619,10 @@ static int lws_http2_num(int starting_bits, unsigned long num, unsigned char **p return 0; } -int lws_add_http2_header_by_name(struct libwebsocket_context *context, - struct libwebsocket *wsi, - const unsigned char *name, - const unsigned char *value, - int length, - unsigned char **p, - unsigned char *end) +int lws_add_http2_header_by_name(struct lws_context *context, struct lws *wsi, + const unsigned char *name, + const unsigned char *value, int length, + unsigned char **p, unsigned char *end) { int len; @@ -647,13 +654,10 @@ int lws_add_http2_header_by_name(struct libwebsocket_context *context, return 0; } -int lws_add_http2_header_by_token(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum lws_token_indexes token, - const unsigned char *value, - int length, - unsigned char **p, - unsigned char *end) +int lws_add_http2_header_by_token(struct lws_context *context, struct lws *wsi, + enum lws_token_indexes token, + const unsigned char *value, int length, + unsigned char **p, unsigned char *end) { const unsigned char *name; @@ -661,14 +665,13 @@ int lws_add_http2_header_by_token(struct libwebsocket_context *context, if (!name) return 1; - return lws_add_http2_header_by_name(context, wsi, name, value, length, p, end); + return lws_add_http2_header_by_name(context, wsi, name, value, + length, p, end); } -int lws_add_http2_header_status(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned int code, - unsigned char **p, - unsigned char *end) +int lws_add_http2_header_status(struct lws_context *context, struct lws *wsi, + unsigned int code, unsigned char **p, + unsigned char *end) { unsigned char status[10]; int n; @@ -676,7 +679,9 @@ int lws_add_http2_header_status(struct libwebsocket_context *context, wsi->u.http2.send_END_STREAM = !!(code >= 400); n = sprintf((char *)status, "%u", code); - if (lws_add_http2_header_by_token(context, wsi, WSI_TOKEN_HTTP_COLON_STATUS, status, n, p, end)) + if (lws_add_http2_header_by_token(context, wsi, + WSI_TOKEN_HTTP_COLON_STATUS, status, + n, p, end)) return 1; return 0; diff --git a/lib/http2.c b/lib/http2.c index aa2189c73..f77940499 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -38,8 +38,8 @@ void lws_http2_init(struct http2_settings *settings) memcpy(settings, lws_http2_default_settings.setting, sizeof(*settings)); } -struct libwebsocket * -lws_http2_wsi_from_id(struct libwebsocket *wsi, unsigned int sid) +struct lws * +lws_http2_wsi_from_id(struct lws *wsi, unsigned int sid) { do { if (wsi->u.http2.my_stream_id == sid) @@ -51,16 +51,19 @@ lws_http2_wsi_from_id(struct libwebsocket *wsi, unsigned int sid) return NULL; } -struct libwebsocket * -lws_create_server_child_wsi(struct libwebsocket_context *context, struct libwebsocket *parent_wsi, unsigned int sid) +struct lws * +lws_create_server_child_wsi(struct lws_context *context, struct lws *parent_wsi, + unsigned int sid) { - struct libwebsocket *wsi = libwebsocket_create_new_server_wsi(context); + struct lws *wsi = lws_create_new_server_wsi(context); if (!wsi) return NULL; /* no more children allowed by parent */ - if (parent_wsi->u.http2.child_count + 1 == parent_wsi->u.http2.peer_settings.setting[LWS_HTTP2_SETTINGS__MAX_CONCURRENT_STREAMS]) + if (parent_wsi->u.http2.child_count + 1 == + parent_wsi->u.http2.peer_settings.setting[ + LWS_HTTP2_SETTINGS__MAX_CONCURRENT_STREAMS]) return NULL; lws_http2_init(&wsi->u.http2.peer_settings); @@ -80,16 +83,17 @@ lws_create_server_child_wsi(struct libwebsocket_context *context, struct libwebs wsi->mode = parent_wsi->mode; wsi->protocol = &context->protocols[0]; - libwebsocket_ensure_user_space(wsi); + lws_ensure_user_space(wsi); - lwsl_info("%s: %p new child %p, sid %d, user_space=%p\n", __func__, parent_wsi, wsi, sid, wsi->user_space); + lwsl_info("%s: %p new child %p, sid %d, user_space=%p\n", __func__, + parent_wsi, wsi, sid, wsi->user_space); return wsi; } -int lws_remove_server_child_wsi(struct libwebsocket_context *context, struct libwebsocket *wsi) +int lws_remove_server_child_wsi(struct lws_context *context, struct lws *wsi) { - struct libwebsocket **w = &wsi->u.http2.parent_wsi; + struct lws **w = &wsi->u.http2.parent_wsi; do { if (*w == wsi) { *w = wsi->u.http2.next_child_wsi; @@ -105,7 +109,8 @@ int lws_remove_server_child_wsi(struct libwebsocket_context *context, struct lib } int -lws_http2_interpret_settings_payload(struct http2_settings *settings, unsigned char *buf, int len) +lws_http2_interpret_settings_payload(struct http2_settings *settings, + unsigned char *buf, int len) { unsigned int a, b; @@ -132,7 +137,7 @@ lws_http2_interpret_settings_payload(struct http2_settings *settings, unsigned c return 0; } -struct libwebsocket *lws_http2_get_network_wsi(struct libwebsocket *wsi) +struct lws *lws_http2_get_network_wsi(struct lws *wsi) { while (wsi->u.http2.parent_wsi) wsi = wsi->u.http2.parent_wsi; @@ -140,9 +145,10 @@ struct libwebsocket *lws_http2_get_network_wsi(struct libwebsocket *wsi) return wsi; } -int lws_http2_frame_write(struct libwebsocket *wsi, int type, int flags, unsigned int sid, unsigned int len, unsigned char *buf) +int lws_http2_frame_write(struct lws *wsi, int type, int flags, + unsigned int sid, unsigned int len, unsigned char *buf) { - struct libwebsocket *wsi_eff = lws_http2_get_network_wsi(wsi); + struct lws *wsi_eff = lws_http2_get_network_wsi(wsi); unsigned char *p = &buf[-LWS_HTTP2_FRAME_HEADER_LENGTH]; int n; @@ -157,22 +163,26 @@ int lws_http2_frame_write(struct libwebsocket *wsi, int type, int flags, unsigne *p++ = sid; lwsl_info("%s: %p (eff %p). type %d, flags 0x%x, sid=%d, len=%d\n", - __func__, wsi, wsi_eff, type, flags, sid, len, wsi->u.http2.tx_credit); + __func__, wsi, wsi_eff, type, flags, sid, len, + wsi->u.http2.tx_credit); if (type == LWS_HTTP2_FRAME_TYPE_DATA) { if (wsi->u.http2.tx_credit < len) - lwsl_err("%s: %p: sending payload len %d but tx_credit only %d!\n", len, wsi->u.http2.tx_credit); + lwsl_err("%s: %p: sending payload len %d" + " but tx_credit only %d!\n", len, + wsi->u.http2.tx_credit); wsi->u.http2.tx_credit -= len; } - n = lws_issue_raw(wsi_eff, &buf[-LWS_HTTP2_FRAME_HEADER_LENGTH], len + LWS_HTTP2_FRAME_HEADER_LENGTH); + n = lws_issue_raw(wsi_eff, &buf[-LWS_HTTP2_FRAME_HEADER_LENGTH], + len + LWS_HTTP2_FRAME_HEADER_LENGTH); if (n >= LWS_HTTP2_FRAME_HEADER_LENGTH) return n - LWS_HTTP2_FRAME_HEADER_LENGTH; return n; } -static void lws_http2_settings_write(struct libwebsocket *wsi, int n, unsigned char *buf) +static void lws_http2_settings_write(struct lws *wsi, int n, unsigned char *buf) { *buf++ = n >> 8; *buf++ = n; @@ -186,12 +196,11 @@ static const char * https_client_preface = "PRI * HTTP/2.0\x0d\x0a\x0d\x0aSM\x0d\x0a\x0d\x0a"; int -lws_http2_parser(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char c) +lws_http2_parser(struct lws_context *context, struct lws *wsi, unsigned char c) { - struct libwebsocket *swsi; + struct lws *swsi; int n; - //dstruct libwebsocket *wsi_new; + //dstruct lws *wsi_new; switch (wsi->state) { case WSI_STATE_HTTP2_AWAIT_CLIENT_PREFACE: @@ -210,7 +219,8 @@ lws_http2_parser(struct libwebsocket_context *context, * and the peer must send a SETTINGS with ACK flag... */ - lws_set_protocol_write_pending(context, wsi, LWS_PPS_HTTP2_MY_SETTINGS); + lws_set_protocol_write_pending(context, wsi, + LWS_PPS_HTTP2_MY_SETTINGS); } break; @@ -303,7 +313,7 @@ lws_http2_parser(struct libwebsocket_context *context, if (swsi->u.http2.waiting_tx_credit && swsi->u.http2.tx_credit > 0) { lwsl_info("%s: %p: waiting_tx_credit -> wait on writeable\n", __func__, wsi); swsi->u.http2.waiting_tx_credit = 0; - libwebsocket_callback_on_writable(context, swsi); + lws_callback_on_writable(context, swsi); } break; } @@ -413,10 +423,10 @@ update_end_headers: return 0; } -int lws_http2_do_pps_send(struct libwebsocket_context *context, struct libwebsocket *wsi) +int lws_http2_do_pps_send(struct lws_context *context, struct lws *wsi) { unsigned char settings[LWS_SEND_BUFFER_PRE_PADDING + 6 * LWS_HTTP2_SETTINGS__COUNT]; - struct libwebsocket *swsi; + struct lws *swsi; int n, m = 0; lwsl_debug("%s: %p: %d\n", __func__, wsi, wsi->pps); @@ -497,7 +507,7 @@ int lws_http2_do_pps_send(struct libwebsocket_context *context, struct libwebsoc return 0; } -struct libwebsocket * lws_http2_get_nth_child(struct libwebsocket *wsi, int n) +struct lws * lws_http2_get_nth_child(struct lws *wsi, int n) { do { wsi = wsi->u.http2.next_child_wsi; diff --git a/lib/libev.c b/lib/libev.c index 8cda4483c..d6858e1ae 100644 --- a/lib/libev.c +++ b/lib/libev.c @@ -30,11 +30,11 @@ void lws_feature_status_libev(struct lws_context_creation_info *info) } static void -libwebsocket_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) +lws_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) { - struct libwebsocket_pollfd eventfd; + struct lws_pollfd eventfd; struct lws_io_watcher *lws_io = container_of(watcher, struct lws_io_watcher, watcher); - struct libwebsocket_context *context = lws_io->context; + struct lws_context *context = lws_io->context; if (revents & EV_ERROR) return; @@ -47,18 +47,18 @@ libwebsocket_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) if (revents & EV_WRITE) eventfd.revents |= LWS_POLLOUT; - libwebsocket_service_fd(context, &eventfd); + lws_service_fd(context, &eventfd); } LWS_VISIBLE void -libwebsocket_sigint_cb(struct ev_loop *loop, +lws_sigint_cb(struct ev_loop *loop, struct ev_signal *watcher, int revents) { ev_break(loop, EVBREAK_ALL); } -LWS_VISIBLE int libwebsocket_sigint_cfg( - struct libwebsocket_context *context, +LWS_VISIBLE int lws_sigint_cfg( + struct lws_context *context, int use_ev_sigint, lws_ev_signal_cb* cb) { @@ -67,14 +67,14 @@ LWS_VISIBLE int libwebsocket_sigint_cfg( context->lws_ev_sigint_cb = cb; } else { - context->lws_ev_sigint_cb = &libwebsocket_sigint_cb; + context->lws_ev_sigint_cb = &lws_sigint_cb; }; return 0; }; LWS_VISIBLE int -libwebsocket_initloop( - struct libwebsocket_context *context, +lws_initloop( + struct lws_context *context, struct ev_loop *loop) { int status = 0; @@ -92,7 +92,7 @@ libwebsocket_initloop( * Initialize the accept w_accept with the listening socket * and register a callback for read operations: */ - ev_io_init(w_accept, libwebsocket_accept_cb, + ev_io_init(w_accept, lws_accept_cb, context->listen_service_fd, EV_READ); ev_io_start(context->io_loop,w_accept); @@ -133,8 +133,8 @@ libwebsocket_initloop( } LWS_VISIBLE void -lws_libev_accept(struct libwebsocket_context *context, - struct libwebsocket *new_wsi, int accept_fd) +lws_libev_accept(struct lws_context *context, + struct lws *new_wsi, int accept_fd) { struct ev_io *r = &new_wsi->w_read.watcher; struct ev_io *w = &new_wsi->w_write.watcher; @@ -144,13 +144,13 @@ lws_libev_accept(struct libwebsocket_context *context, new_wsi->w_read.context = context; new_wsi->w_write.context = context; - ev_io_init(r, libwebsocket_accept_cb, accept_fd, EV_READ); - ev_io_init(w, libwebsocket_accept_cb, accept_fd, EV_WRITE); + ev_io_init(r, lws_accept_cb, accept_fd, EV_READ); + ev_io_init(w, lws_accept_cb, accept_fd, EV_WRITE); } LWS_VISIBLE void -lws_libev_io(struct libwebsocket_context *context, - struct libwebsocket *wsi, int flags) +lws_libev_io(struct lws_context *context, + struct lws *wsi, int flags) { if (!LWS_LIBEV_ENABLED(context)) return; @@ -175,7 +175,7 @@ lws_libev_io(struct libwebsocket_context *context, } LWS_VISIBLE int -lws_libev_init_fd_table(struct libwebsocket_context *context) +lws_libev_init_fd_table(struct lws_context *context) { if (!LWS_LIBEV_ENABLED(context)) return 0; @@ -187,7 +187,7 @@ lws_libev_init_fd_table(struct libwebsocket_context *context) } LWS_VISIBLE void -lws_libev_run(struct libwebsocket_context *context) +lws_libev_run(struct lws_context *context) { if (context->io_loop && LWS_LIBEV_ENABLED(context)) ev_run(context->io_loop, 0); diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index f378f0534..16b50273b 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -38,43 +38,46 @@ static const char * const log_level_names[] = { }; void -lws_free_wsi(struct libwebsocket *wsi) +lws_free_wsi(struct lws *wsi) { if (!wsi) return; /* Protocol user data may be allocated either internally by lws - * or by specified the user. Important we don't free external user data */ - if (wsi->protocol && wsi->protocol->per_session_data_size - && wsi->user_space && !wsi->user_space_externally_allocated) { + * or by specified the user. + * We should only free what we allocated. */ + if (wsi->protocol && wsi->protocol->per_session_data_size && + wsi->user_space && !wsi->user_space_externally_allocated) lws_free(wsi->user_space); - } lws_free2(wsi->rxflow_buffer); lws_free2(wsi->truncated_send_malloc); - - // TODO: Probably should handle the union structs in wsi->u here depending - // on connection mode as well. Too spaghetti for me to follow however... - lws_free_header_table(wsi); lws_free(wsi); } void -libwebsocket_close_and_free_session(struct libwebsocket_context *context, - struct libwebsocket *wsi, enum lws_close_status reason) +lws_close_and_free_session(struct lws_context *context, + struct lws *wsi, enum lws_close_status reason) { - int n, m, ret; - int old_state; - unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 + - LWS_SEND_BUFFER_POST_PADDING]; + int n, m, ret, old_state; struct lws_tokens eff_buf; + unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 + + LWS_SEND_BUFFER_POST_PADDING]; if (!wsi) return; old_state = wsi->state; + if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED && + wsi->u.http.fd != LWS_INVALID_FILE) { + lwsl_debug("closing http file\n"); + compatible_file_close(wsi->u.http.fd); + wsi->u.http.fd = LWS_INVALID_FILE; + context->protocols[0].callback(context, wsi, + LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0); + } if (wsi->socket_is_permanently_unusable || reason == LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY) goto just_kill_connection; @@ -89,7 +92,7 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context, case WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE: if (wsi->truncated_send_len) { - libwebsocket_callback_on_writable(context, wsi); + lws_callback_on_writable(context, wsi); return; } lwsl_info("wsi %p completed WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi); @@ -98,7 +101,7 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context, if (wsi->truncated_send_len) { lwsl_info("wsi %p entering WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi); wsi->state = WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE; - libwebsocket_set_timeout(wsi, PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE, 5); + lws_set_timeout(wsi, PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE, 5); return; } break; @@ -107,24 +110,13 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context, wsi->u.ws.close_reason = reason; if (wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT || - wsi->mode == LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE) + wsi->mode == LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE) goto just_kill_connection; if (wsi->mode == LWS_CONNMODE_HTTP_SERVING) context->protocols[0].callback(context, wsi, LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0); - if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED) { - if (wsi->u.http.fd != LWS_INVALID_FILE) { - // TODO: If we're just closing with LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY this file descriptor might leak? - lwsl_debug("closing http file\n"); - context->file_callbacks.pfn_close(wsi->u.http.fd); - wsi->u.http.fd = LWS_INVALID_FILE; - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0); - } - } - /* * are his extensions okay with him closing? Eg he might be a mux * parent and just his ch1 aspect is closing? @@ -165,14 +157,15 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context, if (eff_buf.token_len) if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token, - eff_buf.token_len) != eff_buf.token_len) { + eff_buf.token_len) != + eff_buf.token_len) { lwsl_debug("close: ext spill failed\n"); goto just_kill_connection; } } while (ret); /* - * signal we are closing, libwebsocket_write will + * signal we are closing, lws_write will * add any necessary version-specific stuff. If the write fails, * no worries we are closing anyway. If we didn't initiate this * close, then our state has been changed to @@ -191,25 +184,20 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context, /* make valgrind happy */ memset(buf, 0, sizeof(buf)); - n = libwebsocket_write(wsi, - &buf[LWS_SEND_BUFFER_PRE_PADDING + 2], - 0, LWS_WRITE_CLOSE); + n = lws_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING + 2], + 0, LWS_WRITE_CLOSE); if (n >= 0) { /* * we have sent a nice protocol level indication we * now wish to close, we should not send anything more */ - wsi->state = WSI_STATE_AWAITING_CLOSE_ACK; /* * ...and we should wait for a reply for a bit * out of politeness */ - - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_CLOSE_ACK, 1); - + lws_set_timeout(wsi, PENDING_TIMEOUT_CLOSE_ACK, 1); lwsl_debug("sent close indication, awaiting ack\n"); return; @@ -228,10 +216,9 @@ just_kill_connection: * we won't be servicing or receiving anything further from this guy * delete socket from the internal poll list if still present */ - lws_ssl_remove_wsi_from_buffered_list(context, wsi); - // checking return redundant since we anyway close + /* checking return redundant since we anyway close */ remove_wsi_socket_from_fds(context, wsi); wsi->state = WSI_STATE_DEAD_SOCKET; @@ -245,11 +232,10 @@ just_kill_connection: lws_free2(wsi->u.ws.rx_user_buffer); - if (wsi->truncated_send_malloc) { + if (wsi->truncated_send_malloc) /* not going to be completed... nuke it */ lws_free2(wsi->truncated_send_malloc); - wsi->truncated_send_len = 0; - } + if (wsi->u.ws.ping_payload_buf) { lws_free2(wsi->u.ws.ping_payload_buf); wsi->u.ws.ping_payload_alloc = 0; @@ -261,13 +247,13 @@ just_kill_connection: /* tell the user it's all over for this guy */ if (wsi->protocol && wsi->protocol->callback && - ((old_state == WSI_STATE_ESTABLISHED) || - (old_state == WSI_STATE_RETURNED_CLOSE_ALREADY) || - (old_state == WSI_STATE_AWAITING_CLOSE_ACK) || - (old_state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE))) { + ((old_state == WSI_STATE_ESTABLISHED) || + (old_state == WSI_STATE_RETURNED_CLOSE_ALREADY) || + (old_state == WSI_STATE_AWAITING_CLOSE_ACK) || + (old_state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE))) { lwsl_debug("calling back CLOSED\n"); wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLOSED, - wsi->user_space, NULL, 0); + wsi->user_space, NULL, 0); } else if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED) { lwsl_debug("calling back CLOSED_HTTP\n"); context->protocols[0].callback(context, wsi, @@ -276,15 +262,16 @@ just_kill_connection: wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT) { lwsl_debug("Connection closed before server reply\n"); context->protocols[0].callback(context, wsi, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - wsi->user_space, NULL, 0 ); + LWS_CALLBACK_CLIENT_CONNECTION_ERROR, + wsi->user_space, NULL, 0); } else lwsl_debug("not calling back closed mode=%d state=%d\n", wsi->mode, old_state); /* deallocate any active extension contexts */ - if (lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_DESTROY, NULL, 0) < 0) + if (lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_DESTROY, + NULL, 0) < 0) lwsl_warn("extension destruction failed\n"); #ifndef LWS_NO_EXTENSIONS for (n = 0; n < wsi->count_active_extensions; n++) @@ -298,8 +285,6 @@ just_kill_connection: LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING, NULL, 0) < 0) lwsl_warn("ext destroy wsi failed\n"); -/* lwsl_info("closing fd=%d\n", wsi->sock); */ - if (!lws_ssl_close(wsi) && lws_socket_is_valid(wsi->sock)) { #if LWS_POSIX n = shutdown(wsi->sock, SHUT_RDWR); @@ -317,22 +302,22 @@ just_kill_connection: } /* outermost destroy notification for wsi (user_space still intact) */ - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_WSI_DESTROY, wsi->user_space, NULL, 0); + context->protocols[0].callback(context, wsi, LWS_CALLBACK_WSI_DESTROY, + wsi->user_space, NULL, 0); lws_free_wsi(wsi); } LWS_VISIBLE int -libwebsockets_get_addresses(struct libwebsocket_context *context, - void *ads, char *name, int name_len, - char *rip, int rip_len) +lws_get_addresses(struct lws_context *context, void *ads, char *name, + int name_len, char *rip, int rip_len) { #if LWS_POSIX struct addrinfo ai, *res; struct sockaddr_in addr4; - rip[0] = '\0'; + if (rip) + rip[0] = '\0'; name[0] = '\0'; addr4.sin_family = AF_UNSPEC; @@ -406,9 +391,9 @@ libwebsockets_get_addresses(struct libwebsocket_context *context, } /** - * libwebsockets_get_peer_addresses() - Get client address information + * lws_get_peer_addresses() - Get client address information * @context: Libwebsockets context - * @wsi: Local struct libwebsocket associated with + * @wsi: Local struct lws associated with * @fd: Connection socket descriptor * @name: Buffer to take client address name * @name_len: Length of client address name buffer @@ -422,9 +407,9 @@ libwebsockets_get_addresses(struct libwebsocket_context *context, */ LWS_VISIBLE void -libwebsockets_get_peer_addresses(struct libwebsocket_context *context, - struct libwebsocket *wsi, lws_sockfd_type fd, char *name, int name_len, - char *rip, int rip_len) +lws_get_peer_addresses(struct lws_context *context, struct lws *wsi, + lws_sockfd_type fd, char *name, int name_len, + char *rip, int rip_len) { #if LWS_POSIX socklen_t len; @@ -456,10 +441,10 @@ libwebsockets_get_peer_addresses(struct libwebsocket_context *context, goto bail; } - ret = libwebsockets_get_addresses(context, p, name, name_len, rip, rip_len); + ret = lws_get_addresses(context, p, name, name_len, rip, rip_len); bail: - lws_latency(context, wsi, "libwebsockets_get_peer_addresses", ret, 1); + lws_latency(context, wsi, "lws_get_peer_addresses", ret, 1); #else (void)context; (void)wsi; @@ -472,7 +457,7 @@ bail: } /** - * libwebsocket_context_user() - get the user data associated with the context + * lws_context_user() - get the user data associated with the context * @context: Websocket context * * This returns the optional user allocation that can be attached to @@ -481,14 +466,14 @@ bail: * using globals statics in the user code. */ LWS_EXTERN void * -libwebsocket_context_user(struct libwebsocket_context *context) +lws_context_user(struct lws_context *context) { return context->user_space; } /** - * libwebsocket_callback_all_protocol() - Callback all connections using + * lws_callback_all_protocol() - Callback all connections using * the given protocol with the given reason * * @protocol: Protocol whose connections will get callbacks @@ -496,12 +481,11 @@ libwebsocket_context_user(struct libwebsocket_context *context) */ LWS_VISIBLE int -libwebsocket_callback_all_protocol( - const struct libwebsocket_protocols *protocol, int reason) +lws_callback_all_protocol(const struct lws_protocols *protocol, int reason) { - struct libwebsocket_context *context = protocol->owning_server; + struct lws_context *context = protocol->owning_server; + struct lws *wsi; int n; - struct libwebsocket *wsi; for (n = 0; n < context->fds_count; n++) { wsi = wsi_from_fd(context, context->fds[n].fd); @@ -509,14 +493,14 @@ libwebsocket_callback_all_protocol( continue; if (wsi->protocol == protocol) protocol->callback(context, wsi, - reason, wsi->user_space, NULL, 0); + reason, wsi->user_space, NULL, 0); } return 0; } /** - * libwebsocket_set_timeout() - marks the wsi as subject to a timeout + * lws_set_timeout() - marks the wsi as subject to a timeout * * You will not need this unless you are doing something special * @@ -526,8 +510,7 @@ libwebsocket_callback_all_protocol( */ LWS_VISIBLE void -libwebsocket_set_timeout(struct libwebsocket *wsi, - enum pending_timeout reason, int secs) +lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs) { time_t now; @@ -541,7 +524,7 @@ libwebsocket_set_timeout(struct libwebsocket *wsi, #if LWS_POSIX /** - * libwebsocket_get_socket_fd() - returns the socket file descriptor + * lws_get_socket_fd() - returns the socket file descriptor * * You will not need this unless you are doing something special * @@ -549,7 +532,7 @@ libwebsocket_set_timeout(struct libwebsocket *wsi, */ LWS_VISIBLE int -libwebsocket_get_socket_fd(struct libwebsocket *wsi) +lws_get_socket_fd(struct lws *wsi) { return wsi->sock; } @@ -558,8 +541,8 @@ libwebsocket_get_socket_fd(struct libwebsocket *wsi) #ifdef LWS_LATENCY void -lws_latency(struct libwebsocket_context *context, struct libwebsocket *wsi, - const char *action, int ret, int completed) +lws_latency(struct lws_context *context, struct lws *wsi, const char *action, + int ret, int completed) { unsigned long long u; char buf[256]; @@ -600,7 +583,7 @@ lws_latency(struct libwebsocket_context *context, struct libwebsocket *wsi, /** - * libwebsocket_rx_flow_control() - Enable and disable socket servicing for + * lws_rx_flow_control() - Enable and disable socket servicing for * received packets. * * If the output side of a server process becomes choked, this allows flow @@ -611,19 +594,19 @@ lws_latency(struct libwebsocket_context *context, struct libwebsocket *wsi, */ LWS_VISIBLE int -libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable) +lws_rx_flow_control(struct lws *wsi, int enable) { if (enable == (wsi->rxflow_change_to & LWS_RXFLOW_ALLOW)) return 0; - lwsl_info("libwebsocket_rx_flow_control(0x%p, %d)\n", wsi, enable); + lwsl_info("%s: (0x%p, %d)\n", __func__, wsi, enable); wsi->rxflow_change_to = LWS_RXFLOW_PENDING_CHANGE | !!enable; return 0; } /** - * libwebsocket_rx_flow_allow_all_protocol() - Allow all connections with this protocol to receive + * lws_rx_flow_allow_all_protocol() - Allow all connections with this protocol to receive * * When the user server code realizes it can accept more input, it can * call this to have the RX flow restriction removed from all connections using @@ -633,25 +616,24 @@ libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable) */ LWS_VISIBLE void -libwebsocket_rx_flow_allow_all_protocol( - const struct libwebsocket_protocols *protocol) +lws_rx_flow_allow_all_protocol(const struct lws_protocols *protocol) { - struct libwebsocket_context *context = protocol->owning_server; + struct lws_context *context = protocol->owning_server; int n; - struct libwebsocket *wsi; + struct lws *wsi; for (n = 0; n < context->fds_count; n++) { wsi = wsi_from_fd(context, context->fds[n].fd); if (!wsi) continue; if (wsi->protocol == protocol) - libwebsocket_rx_flow_control(wsi, LWS_RXFLOW_ALLOW); + lws_rx_flow_control(wsi, LWS_RXFLOW_ALLOW); } } /** - * libwebsocket_canonical_hostname() - returns this host's hostname + * lws_canonical_hostname() - returns this host's hostname * * This is typically used by client code to fill in the host parameter * when making a client connection. You can only call it after the context @@ -660,30 +642,29 @@ libwebsocket_rx_flow_allow_all_protocol( * @context: Websocket context */ LWS_VISIBLE extern const char * -libwebsocket_canonical_hostname(struct libwebsocket_context *context) +lws_canonical_hostname(struct lws_context *context) { return (const char *)context->canonical_hostname; } int user_callback_handle_rxflow(callback_function callback_function, - struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, - void *in, size_t len) + struct lws_context *context, struct lws *wsi, + enum lws_callback_reasons reason, void *user, + void *in, size_t len) { int n; n = callback_function(context, wsi, reason, user, in, len); if (!n) - n = _libwebsocket_rx_flow_control(wsi); + n = _lws_rx_flow_control(wsi); return n; } /** - * libwebsocket_set_proxy() - Setups proxy to libwebsocket_context. - * @context: pointer to struct libwebsocket_context you want set proxy to + * lws_set_proxy() - Setups proxy to lws_context. + * @context: pointer to struct lws_context you want set proxy to * @proxy: pointer to c string containing proxy in format address:port * * Returns 0 if proxy string was parsed and proxy was setup. @@ -693,14 +674,14 @@ int user_callback_handle_rxflow(callback_function callback_function, * environment variable (eg, OSX) * * IMPORTANT! You should call this function right after creation of the - * libwebsocket_context and before call to connect. If you call this + * lws_context and before call to connect. If you call this * function after connect behavior is undefined. - * This function will override proxy settings made on libwebsocket_context + * This function will override proxy settings made on lws_context * creation with genenv() call. */ LWS_VISIBLE int -libwebsocket_set_proxy(struct libwebsocket_context *context, const char *proxy) +lws_set_proxy(struct lws_context *context, const char *proxy) { char *p; char authstring[96]; @@ -738,8 +719,10 @@ libwebsocket_set_proxy(struct libwebsocket_context *context, const char *proxy) return -1; } else { - *p = '\0'; - context->http_proxy_port = atoi(p + 1); + if (p) { + *p = '\0'; + context->http_proxy_port = atoi(p + 1); + } } lwsl_notice(" Proxy %s:%u\n", context->http_proxy_address, @@ -754,7 +737,7 @@ auth_too_long: } /** - * libwebsockets_get_protocol() - Returns a protocol pointer from a websocket + * lws_get_protocol() - Returns a protocol pointer from a websocket * connection. * @wsi: pointer to struct websocket you want to know the protocol of * @@ -763,26 +746,26 @@ auth_too_long: * this is how you can get a pointer to the active protocol if needed. */ -LWS_VISIBLE const struct libwebsocket_protocols * -libwebsockets_get_protocol(struct libwebsocket *wsi) +LWS_VISIBLE const struct lws_protocols * +lws_get_protocol(struct lws *wsi) { return wsi->protocol; } LWS_VISIBLE int -libwebsocket_is_final_fragment(struct libwebsocket *wsi) +lws_is_final_fragment(struct lws *wsi) { return wsi->u.ws.final; } LWS_VISIBLE unsigned char -libwebsocket_get_reserved_bits(struct libwebsocket *wsi) +lws_get_reserved_bits(struct lws *wsi) { return wsi->u.ws.rsv; } int -libwebsocket_ensure_user_space(struct libwebsocket *wsi) +lws_ensure_user_space(struct lws *wsi) { lwsl_info("%s: %p protocol %p\n", __func__, wsi, wsi->protocol); if (!wsi->protocol) @@ -797,28 +780,33 @@ libwebsocket_ensure_user_space(struct libwebsocket *wsi) return 1; } } else - lwsl_info("%s: %p protocol pss %u, user_space=%d\n", __func__, wsi, wsi->protocol->per_session_data_size, wsi->user_space); + lwsl_info("%s: %p protocol pss %u, user_space=%d\n", + __func__, wsi, wsi->protocol->per_session_data_size, + wsi->user_space); return 0; } +#if LWS_POSIX LWS_VISIBLE void lwsl_emit_stderr(int level, const char *line) { - char buf[300]; unsigned long long now; + char buf[300]; int n; buf[0] = '\0'; - for (n = 0; n < LLL_COUNT; n++) - if (level == (1 << n)) { - now = time_in_microseconds() / 100; - sprintf(buf, "[%llu:%04d] %s: ", (unsigned long long) now / 10000, - (int)(now % 10000), log_level_names[n]); - break; - } + for (n = 0; n < LLL_COUNT; n++) { + if (level != (1 << n)) + continue; + now = time_in_microseconds() / 100; + sprintf(buf, "[%llu:%04d] %s: ", + (unsigned long long) now / 10000, + (int)(now % 10000), log_level_names[n]); + break; + } fprintf(stderr, "%s%s", buf, line); } - +#endif LWS_VISIBLE void _lws_logv(int filter, const char *format, va_list vl) { @@ -853,12 +841,12 @@ LWS_VISIBLE void _lws_log(int filter, const char *format, ...) * emission on stderr. */ -LWS_VISIBLE void lws_set_log_level(int level, void (*log_emit_function)(int level, - const char *line)) +LWS_VISIBLE void lws_set_log_level(int level, + void (*func)(int level, const char *line)) { log_level = level; - if (log_emit_function) - lwsl_emit = log_emit_function; + if (func) + lwsl_emit = func; } /** @@ -870,7 +858,7 @@ LWS_VISIBLE void lws_set_log_level(int level, void (*log_emit_function)(int leve * checked (appears for client wsi told to skip check on connection) */ LWS_VISIBLE int -lws_is_ssl(struct libwebsocket *wsi) +lws_is_ssl(struct lws *wsi) { #ifdef LWS_OPENSSL_SUPPORT return wsi->use_ssl; @@ -884,12 +872,12 @@ lws_is_ssl(struct libwebsocket *wsi) * lws_partial_buffered() - find out if lws buffered the last write * @wsi: websocket connection to check * - * Returns 1 if you cannot use libwebsocket_write because the last + * Returns 1 if you cannot use lws_write because the last * write on this connection is still buffered, and can't be cleared without * returning to the service loop and waiting for the connection to be * writeable again. * - * If you will try to do >1 libwebsocket_write call inside a single + * If you will try to do >1 lws_write call inside a single * WRITEABLE callback, you must check this after every write and bail if * set, ask for a new writeable callback and continue writing from there. * @@ -898,13 +886,13 @@ lws_is_ssl(struct libwebsocket *wsi) */ LWS_VISIBLE int -lws_partial_buffered(struct libwebsocket *wsi) +lws_partial_buffered(struct lws *wsi) { return !!wsi->truncated_send_len; } -void lws_set_protocol_write_pending(struct libwebsocket_context *context, - struct libwebsocket *wsi, +void lws_set_protocol_write_pending(struct lws_context *context, + struct lws *wsi, enum lws_pending_protocol_send pend) { lwsl_info("setting pps %d\n", pend); @@ -912,12 +900,12 @@ void lws_set_protocol_write_pending(struct libwebsocket_context *context, if (wsi->pps) lwsl_err("pps overwrite\n"); wsi->pps = pend; - libwebsocket_rx_flow_control(wsi, 0); - libwebsocket_callback_on_writable(context, wsi); + lws_rx_flow_control(wsi, 0); + lws_callback_on_writable(context, wsi); } LWS_VISIBLE size_t -lws_get_peer_write_allowance(struct libwebsocket *wsi) +lws_get_peer_write_allowance(struct lws *wsi) { #ifdef LWS_USE_HTTP2 /* only if we are using HTTP2 on this connection */ @@ -935,8 +923,304 @@ lws_get_peer_write_allowance(struct libwebsocket *wsi) } LWS_VISIBLE void -lws_union_transition(struct libwebsocket *wsi, enum connection_mode mode) +lws_union_transition(struct lws *wsi, enum connection_mode mode) { memset(&wsi->u, 0, sizeof(wsi->u)); wsi->mode = mode; } + + +#ifdef LWS_WITH_OLD_API_WRAPPERS + +/* + * To maintain .so abi, also produce wrappers using old api naming. + * + * This is disabled by default, use "LWS_WITH_OLD_API_WRAPPERS" on cmake to + * enable. + * + * You only need these if you have existing binary applications using the old + * api names and you don't want to / can't recompile them against new lws. + * With these new lws .so is compatible with old and new api names. + * + * If you can recompile your application (using old api names still) against + * current lws, you don't need these compatibility helpers since + * libwebsockets.h will map them at compile time. + */ + +#undef libwebsocket + +#undef libwebsocket_create_context +LWS_VISIBLE LWS_EXTERN struct lws_context * +libwebsocket_create_context(struct lws_context_creation_info *info) +{ + return lws_create_context(info); +} + +#undef libwebsocket_set_proxy +LWS_VISIBLE LWS_EXTERN int +libwebsocket_set_proxy(struct lws_context *context, const char *proxy) +{ + return lws_set_proxy(context, proxy); +} + +#undef libwebsocket_context_destroy +LWS_VISIBLE LWS_EXTERN void +libwebsocket_context_destroy(struct lws_context *context) +{ + lws_context_destroy(context); +} + +#undef libwebsocket_service +LWS_VISIBLE LWS_EXTERN int +libwebsocket_service(struct lws_context *context, int timeout_ms) +{ + return lws_service(context, timeout_ms); +} + +#undef libwebsocket_cancel_service +LWS_VISIBLE LWS_EXTERN void +libwebsocket_cancel_service(struct lws_context *context) +{ + lws_cancel_service(context); +} + +#ifdef LWS_USE_LIBEV +#undef libwebsocket_sigint_cfg +LWS_VISIBLE LWS_EXTERN int +libwebsocket_sigint_cfg(struct lws_context *context, int use_ev_sigint, + lws_ev_signal_cb* cb) +{ + return lws_sigint_cfg(context, use_ev_sigint, cb); +} + +#undef libwebsocket_initloop +LWS_VISIBLE LWS_EXTERN int +libwebsocket_initloop(struct lws_context *context, struct ev_loop *loop) +{ + return lws_initloop(context, loop); +} + +#undef libwebsocket_sigint_cb +LWS_VISIBLE void +libwebsocket_sigint_cb( + struct ev_loop *loop, struct ev_signal *watcher, int revents) +{ + lws_sigint_cb(loop, watcher, revents); +} +#endif /* LWS_USE_LIBEV */ + +#undef libwebsocket_service_fd +LWS_VISIBLE LWS_EXTERN int +libwebsocket_service_fd(struct lws_context *context, + struct lws_pollfd *pollfd) +{ + return lws_service_fd(context, pollfd); +} + +#undef libwebsocket_context_user +LWS_VISIBLE LWS_EXTERN void * +libwebsocket_context_user(struct lws_context *context) +{ + return lws_context_user(context); +} + +#undef libwebsocket_set_timeout +LWS_VISIBLE LWS_EXTERN void +libwebsocket_set_timeout(struct lws *wsi, + enum pending_timeout reason, int secs) +{ + lws_set_timeout(wsi, reason, secs); +} + +#undef libwebsocket_write +LWS_VISIBLE LWS_EXTERN int +libwebsocket_write(struct lws *wsi, unsigned char *buf, size_t len, + enum lws_write_protocol protocol) +{ + return lws_write(wsi, buf, len, protocol); +} + +#undef libwebsockets_serve_http_file_fragment +LWS_VISIBLE LWS_EXTERN int +libwebsockets_serve_http_file_fragment(struct lws_context *context, + struct lws *wsi) +{ + return lws_serve_http_file_fragment(context, wsi); +} + +#undef libwebsockets_serve_http_file +LWS_VISIBLE LWS_EXTERN int +libwebsockets_serve_http_file(struct lws_context *context, + struct lws *wsi, const char *file, + const char *content_type, const char *other_headers, + int other_headers_len) +{ + return lws_serve_http_file(context, wsi, file, content_type, + other_headers, other_headers_len); +} + +#undef libwebsockets_return_http_status +LWS_VISIBLE LWS_EXTERN int +libwebsockets_return_http_status( + struct lws_context *context, + struct lws *wsi, unsigned int code, + const char *html_body) +{ + return lws_return_http_status(context, wsi, code, html_body); +} + +#undef libwebsockets_get_protocol +LWS_VISIBLE LWS_EXTERN const struct lws_protocols * +libwebsockets_get_protocol(struct lws *wsi) +{ + return lws_get_protocol(wsi); +} + +#undef libwebsocket_callback_on_writable_all_protocol +LWS_VISIBLE LWS_EXTERN int +libwebsocket_callback_on_writable_all_protocol( + const struct lws_protocols *protocol) +{ + return lws_callback_on_writable_all_protocol(protocol); +} + +#undef libwebsocket_callback_on_writable +LWS_VISIBLE LWS_EXTERN int +libwebsocket_callback_on_writable(struct lws_context *context, + struct lws *wsi) +{ + return lws_callback_on_writable(context, wsi); +} + +#undef libwebsocket_callback_all_protocol +LWS_VISIBLE LWS_EXTERN int +libwebsocket_callback_all_protocol( + const struct lws_protocols *protocol, int reason) +{ + return lws_callback_all_protocol(protocol, reason); +} + +#undef libwebsocket_get_socket_fd +LWS_VISIBLE LWS_EXTERN int +libwebsocket_get_socket_fd(struct lws *wsi) +{ + return lws_get_socket_fd(wsi); +} + +#undef libwebsocket_is_final_fragment +LWS_VISIBLE LWS_EXTERN int +libwebsocket_is_final_fragment(struct lws *wsi) +{ + return lws_is_final_fragment(wsi); +} + +#undef libwebsocket_get_reserved_bits +LWS_VISIBLE LWS_EXTERN unsigned char +libwebsocket_get_reserved_bits(struct lws *wsi) +{ + return lws_get_reserved_bits(wsi); +} + +#undef libwebsocket_rx_flow_control +LWS_VISIBLE LWS_EXTERN int +libwebsocket_rx_flow_control(struct lws *wsi, int enable) +{ + return lws_rx_flow_control(wsi, enable); +} + +#undef libwebsocket_rx_flow_allow_all_protocol +LWS_VISIBLE LWS_EXTERN void +libwebsocket_rx_flow_allow_all_protocol(const struct lws_protocols *protocol) +{ + lws_rx_flow_allow_all_protocol(protocol); +} + +#undef libwebsockets_remaining_packet_payload +LWS_VISIBLE LWS_EXTERN size_t +libwebsockets_remaining_packet_payload(struct lws *wsi) +{ + return lws_remaining_packet_payload(wsi); +} + +#undef libwebsocket_client_connect +LWS_VISIBLE LWS_EXTERN struct lws * +libwebsocket_client_connect(struct lws_context *clients, + const char *address, + int port, + int ssl_connection, + const char *path, + const char *host, + const char *origin, + const char *protocol, + int ietf_version_or_minus_one) +{ + return lws_client_connect(clients, address, port, ssl_connection, + path, host, origin, protocol, ietf_version_or_minus_one); +} +LWS_VISIBLE LWS_EXTERN struct lws * +libwebsocket_client_connect_extended(struct lws_context *clients, + const char *address, + int port, + int ssl_connection, + const char *path, + const char *host, + const char *origin, + const char *protocol, + int ietf_version_or_minus_one, void *userdata) +{ + return lws_client_connect_extended(clients, address, port, ssl_connection, + path, host, origin, protocol, ietf_version_or_minus_one, + userdata); +} + +#undef libwebsocket_canonical_hostname +LWS_VISIBLE LWS_EXTERN const char * +libwebsocket_canonical_hostname(struct lws_context *context) +{ + return lws_canonical_hostname(context); +} + +#undef libwebsockets_get_peer_addresses +LWS_VISIBLE LWS_EXTERN void +libwebsockets_get_peer_addresses(struct lws_context *context, + struct lws *wsi, lws_sockfd_type fd, char *name, + int name_len, char *rip, int rip_len) +{ + lws_get_peer_addresses(context, wsi, fd, name, name_len, rip, rip_len); +} + +#undef libwebsockets_get_random +LWS_VISIBLE LWS_EXTERN int +libwebsockets_get_random(struct lws_context *context, void *buf, int len) +{ + return lws_get_random(context, buf, len); +} + +#ifndef LWS_SHA1_USE_OPENSSL_NAME +#undef libwebsockets_SHA1 +LWS_VISIBLE LWS_EXTERN unsigned char * +libwebsockets_SHA1(const unsigned char *d, size_t n, unsigned char *md) +{ + return lws_SHA1(d, n, md); +} +#endif + +#undef libwebsocket_read +LWS_VISIBLE LWS_EXTERN int +libwebsocket_read(struct lws_context *context, struct lws *wsi, + unsigned char *buf, size_t len) +{ + return lws_read(context, wsi, buf, len); +} + +#ifndef LWS_NO_EXTENSIONS +#undef libwebsocket_get_internal_extensions +LWS_VISIBLE LWS_EXTERN struct lws_extension * +libwebsocket_get_internal_extensions() +{ + return lws_get_internal_extensions(); +} +#endif + +#endif + diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index 961199fc3..87c45e66b 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -22,6 +22,49 @@ #ifndef LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C #define LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C +/* old (pre 1.6) api name compatibility defines */ + +#define libwebsocket_create_context lws_create_context +#define libwebsocket_set_proxy lws_set_proxy +#define libwebsocket_context_destroy lws_context_destroy +#define libwebsocket_service lws_service +#define libwebsocket_cancel_service lws_cancel_service +#define libwebsocket_sigint_cfg lws_sigint_cfg +#define libwebsocket_initloop lws_initloop +#define libwebsocket_sigint_cb lws_sigint_cb +#define libwebsocket_service_fd lws_service_fd +#define libwebsocket_context_user lws_context_user +#define libwebsocket_set_timeout lws_set_timeout +#define libwebsocket_write lws_write +#define libwebsockets_serve_http_file_fragment lws_serve_http_file_fragment +#define libwebsockets_serve_http_file lws_serve_http_file +#define libwebsockets_return_http_status lws_return_http_status +#define libwebsockets_get_protocol lws_get_protocol +#define libwebsocket_callback_on_writable_all_protocol lws_callback_on_writable_all_protocol +#define libwebsocket_callback_on_writable lws_callback_on_writable +#define libwebsocket_callback_all_protocol lws_callback_all_protocol +#define libwebsocket_get_socket_fd lws_get_socket_fd +#define libwebsocket_is_final_fragment lws_is_final_fragment +#define libwebsocket_get_reserved_bits lws_get_reserved_bits +#define libwebsocket_rx_flow_control lws_rx_flow_control +#define libwebsocket_rx_flow_allow_all_protocol lws_rx_flow_allow_all_protocol +#define libwebsockets_remaining_packet_payload lws_remaining_packet_payload +#define libwebsocket_client_connect lws_client_connect +#define libwebsocket_canonical_hostname lws_canonical_hostname +#define libwebsockets_get_peer_addresses lws_get_peer_addresses +#define libwebsockets_get_random lws_get_random +#define libwebsockets_SHA1 lws_SHA1 +#define libwebsocket_read lws_read +#define libwebsocket_get_internal_extensions lws_get_internal_extensions +#define libwebsocket_write_protocol lws_write_protocol + +#define libwebsocket_protocols lws_protocols +#define libwebsocket_extension lws_extension +#define libwebsocket_context lws_context +#define libwebsocket_pollfd lws_pollfd +#define libwebsocket_callback_reasons lws_callback_reasons +#define libwebsocket lws + #ifdef __cplusplus #include #include @@ -37,31 +80,36 @@ namespace { } using namespace mbed::Sockets::v0; -struct libwebsocket; +struct lws; +struct lws_context; class lws_conn { public: lws_conn(): ts(NULL), - wsi(NULL) + wsi(NULL), + writeable(1), + awaiting_on_writeable(0) { } public: - void set_wsi(struct libwebsocket *_wsi) { wsi = _wsi; } + void set_wsi(struct lws *_wsi) { wsi = _wsi; } int actual_onRX(Socket *s); void onRX(Socket *s); void onError(Socket *s, socket_error_t err); void onDisconnect(TCPStream *s); void onSent(Socket *s, uint16_t len); + void serialized_writeable(struct lws *wsi); public: TCPStream *ts; - Socket *s_HACK; public: - struct libwebsocket *wsi; + struct lws *wsi; char buffer[BUFFER_SIZE]; + char writeable; + char awaiting_on_writeable; }; class lws_conn_listener : lws_conn { @@ -137,7 +185,7 @@ extern "C" { #include #include #else -#define getdtablesize() (10) +#define getdtablesize() (20) #endif #if defined(__GNUC__) @@ -156,8 +204,6 @@ extern "C" { #include #endif /* LWS_USE_LIBEV */ -#include - #ifndef LWS_EXTERN #define LWS_EXTERN extern #endif @@ -241,7 +287,7 @@ LWS_VISIBLE LWS_EXTERN void lwsl_hexdump(void *buf, size_t len); #define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_ARG -/* the struct libwebsocket_protocols has the id field present */ +/* the struct lws_protocols has the id field present */ #define LWS_FEATURE_PROTOCOLS_HAS_ID_FIELD /* you can call lws_get_peer_write_allowance */ @@ -250,7 +296,11 @@ LWS_VISIBLE LWS_EXTERN void lwsl_hexdump(void *buf, size_t len); /* extra parameter introduced in 917f43ab821 */ #define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_LEN -enum libwebsocket_context_options { +/* + * NOTE: These public enums are part of the abi. If you want to add one, + * add it at where specified so existing users are unaffected. + */ +enum lws_context_options { LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = 2, LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = 4, LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT = 8, @@ -258,51 +308,59 @@ enum libwebsocket_context_options { LWS_SERVER_OPTION_DISABLE_IPV6 = 32, LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS = 64, LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED = 128, + + /****** add new things just above ---^ ******/ }; -enum libwebsocket_callback_reasons { - LWS_CALLBACK_ESTABLISHED, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH, - LWS_CALLBACK_CLIENT_ESTABLISHED, - LWS_CALLBACK_CLOSED, - LWS_CALLBACK_CLOSED_HTTP, - LWS_CALLBACK_RECEIVE, - LWS_CALLBACK_RECEIVE_PONG, - LWS_CALLBACK_CLIENT_RECEIVE, - LWS_CALLBACK_CLIENT_RECEIVE_PONG, - LWS_CALLBACK_CLIENT_WRITEABLE, - LWS_CALLBACK_SERVER_WRITEABLE, - LWS_CALLBACK_HTTP, - LWS_CALLBACK_HTTP_BODY, - LWS_CALLBACK_HTTP_BODY_COMPLETION, - LWS_CALLBACK_HTTP_FILE_COMPLETION, - LWS_CALLBACK_HTTP_WRITEABLE, - LWS_CALLBACK_FILTER_NETWORK_CONNECTION, - LWS_CALLBACK_FILTER_HTTP_CONNECTION, - LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED, - LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION, - LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS, - LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS, - LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION, - LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER, - LWS_CALLBACK_CONFIRM_EXTENSION_OKAY, - LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED, - LWS_CALLBACK_PROTOCOL_INIT, - LWS_CALLBACK_PROTOCOL_DESTROY, - LWS_CALLBACK_WSI_CREATE, /* always protocol[0] */ - LWS_CALLBACK_WSI_DESTROY, /* always protocol[0] */ - LWS_CALLBACK_GET_THREAD_ID, +/* + * NOTE: These public enums are part of the abi. If you want to add one, + * add it at where specified so existing users are unaffected. + */ +enum lws_callback_reasons { + LWS_CALLBACK_ESTABLISHED = 0, + LWS_CALLBACK_CLIENT_CONNECTION_ERROR = 1, + LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH = 2, + LWS_CALLBACK_CLIENT_ESTABLISHED = 3, + LWS_CALLBACK_CLOSED = 4, + LWS_CALLBACK_CLOSED_HTTP = 5, + LWS_CALLBACK_RECEIVE = 6, + LWS_CALLBACK_RECEIVE_PONG = 7, + LWS_CALLBACK_CLIENT_RECEIVE = 8, + LWS_CALLBACK_CLIENT_RECEIVE_PONG = 9, + LWS_CALLBACK_CLIENT_WRITEABLE = 10, + LWS_CALLBACK_SERVER_WRITEABLE = 11, + LWS_CALLBACK_HTTP = 12, + LWS_CALLBACK_HTTP_BODY = 13, + LWS_CALLBACK_HTTP_BODY_COMPLETION = 14, + LWS_CALLBACK_HTTP_FILE_COMPLETION = 15, + LWS_CALLBACK_HTTP_WRITEABLE = 16, + LWS_CALLBACK_FILTER_NETWORK_CONNECTION = 17, + LWS_CALLBACK_FILTER_HTTP_CONNECTION = 18, + LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED = 19, + LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION = 20, + LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS = 21, + LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS = 22, + LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION = 23, + LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER = 24, + LWS_CALLBACK_CONFIRM_EXTENSION_OKAY = 25, + LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED = 26, + LWS_CALLBACK_PROTOCOL_INIT = 27, + LWS_CALLBACK_PROTOCOL_DESTROY = 28, + LWS_CALLBACK_WSI_CREATE /* always protocol[0] */ = 29, + LWS_CALLBACK_WSI_DESTROY /* always protocol[0] */ = 30, + LWS_CALLBACK_GET_THREAD_ID = 31, /* external poll() management support */ - LWS_CALLBACK_ADD_POLL_FD, - LWS_CALLBACK_DEL_POLL_FD, - LWS_CALLBACK_CHANGE_MODE_POLL_FD, - LWS_CALLBACK_LOCK_POLL, - LWS_CALLBACK_UNLOCK_POLL, + LWS_CALLBACK_ADD_POLL_FD = 32, + LWS_CALLBACK_DEL_POLL_FD = 33, + LWS_CALLBACK_CHANGE_MODE_POLL_FD = 34, + LWS_CALLBACK_LOCK_POLL = 35, + LWS_CALLBACK_UNLOCK_POLL = 36, + + LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY = 37, + + /****** add new things just above ---^ ******/ - LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY, - LWS_CALLBACK_USER = 1000, /* user code can use any including / above */ }; @@ -310,12 +368,12 @@ enum libwebsocket_callback_reasons { #if defined(_WIN32) && (_WIN32_WINNT < 0x0600) typedef SOCKET lws_sockfd_type; #define lws_sockfd_valid(sfd) (!!sfd) -struct libwebsocket_pollfd { +struct lws_pollfd { lws_sockfd_type fd; SHORT events; SHORT revents; }; -WINSOCK_API_LINKAGE int WSAAPI WSAPoll(struct libwebsocket_pollfd fdArray[], ULONG fds, INT timeout); +WINSOCK_API_LINKAGE int WSAAPI WSAPoll(struct lws_pollfd fdArray[], ULONG fds, INT timeout); #else #if defined(MBED_OPERATORS) @@ -334,72 +392,84 @@ struct pollfd { #define POLLHUP 0x0010 #define POLLNVAL 0x0020 -struct libwebsocket; +struct lws; void * mbed3_create_tcp_stream_socket(void); void mbed3_delete_tcp_stream_socket(void *sockfd); -void mbed3_tcp_stream_bind(void *sock, int port, struct libwebsocket *); -void mbed3_tcp_stream_accept(void *sock, struct libwebsocket *); +void mbed3_tcp_stream_bind(void *sock, int port, struct lws *); +void mbed3_tcp_stream_accept(void *sock, struct lws *); #else typedef int lws_sockfd_type; #define lws_sockfd_valid(sfd) (sfd >= 0) #endif -#define libwebsocket_pollfd pollfd +#define lws_pollfd pollfd #endif // argument structure for all external poll related calls // passed in via 'in' -struct libwebsocket_pollargs { +struct lws_pollargs { lws_sockfd_type fd; // applicable file descriptor int events; // the new event mask int prev_events; // the previous event mask }; -enum libwebsocket_extension_callback_reasons { - LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT, - LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT, - LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT, - LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT, - LWS_EXT_CALLBACK_CONSTRUCT, - LWS_EXT_CALLBACK_CLIENT_CONSTRUCT, - LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE, - LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION, - LWS_EXT_CALLBACK_DESTROY, - LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING, - LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED, - LWS_EXT_CALLBACK_PACKET_RX_PREPARSE, - LWS_EXT_CALLBACK_PACKET_TX_PRESEND, - LWS_EXT_CALLBACK_PACKET_TX_DO_SEND, - LWS_EXT_CALLBACK_HANDSHAKE_REPLY_TX, - LWS_EXT_CALLBACK_FLUSH_PENDING_TX, - LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX, - LWS_EXT_CALLBACK_CAN_PROXY_CLIENT_CONNECTION, - 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, +/* + * NOTE: These public enums are part of the abi. If you want to add one, + * add it at where specified so existing users are unaffected. + */ +enum lws_extension_callback_reasons { + LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT = 0, + LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT = 1, + LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT = 2, + LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT = 3, + LWS_EXT_CALLBACK_CONSTRUCT = 4, + LWS_EXT_CALLBACK_CLIENT_CONSTRUCT = 5, + LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE = 6, + LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION = 7, + LWS_EXT_CALLBACK_DESTROY = 8, + LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING = 9, + LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED = 10, + LWS_EXT_CALLBACK_PACKET_RX_PREPARSE = 11, + LWS_EXT_CALLBACK_PACKET_TX_PRESEND = 12, + LWS_EXT_CALLBACK_PACKET_TX_DO_SEND = 13, + LWS_EXT_CALLBACK_HANDSHAKE_REPLY_TX = 14, + LWS_EXT_CALLBACK_FLUSH_PENDING_TX = 15, + LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX = 16, + LWS_EXT_CALLBACK_CAN_PROXY_CLIENT_CONNECTION = 17, + LWS_EXT_CALLBACK_1HZ = 18, + LWS_EXT_CALLBACK_REQUEST_ON_WRITEABLE = 19, + LWS_EXT_CALLBACK_IS_WRITEABLE = 20, + LWS_EXT_CALLBACK_PAYLOAD_TX = 21, + LWS_EXT_CALLBACK_PAYLOAD_RX = 22, + + /****** add new things just above ---^ ******/ }; -enum libwebsocket_write_protocol { - LWS_WRITE_TEXT, - LWS_WRITE_BINARY, - LWS_WRITE_CONTINUATION, - LWS_WRITE_HTTP, +/* + * NOTE: These public enums are part of the abi. If you want to add one, + * add it at where specified so existing users are unaffected. + */ +enum lws_write_protocol { + LWS_WRITE_TEXT = 0, + LWS_WRITE_BINARY = 1, + LWS_WRITE_CONTINUATION = 2, + LWS_WRITE_HTTP = 3, /* special 04+ opcodes */ - LWS_WRITE_CLOSE, - LWS_WRITE_PING, - LWS_WRITE_PONG, + LWS_WRITE_CLOSE = 4, + LWS_WRITE_PING = 5, + LWS_WRITE_PONG = 6, /* Same as write_http but we know this write ends the transaction */ - LWS_WRITE_HTTP_FINAL, + LWS_WRITE_HTTP_FINAL = 7, /* HTTP2 */ - LWS_WRITE_HTTP_HEADERS, + LWS_WRITE_HTTP_HEADERS = 8, + + /****** add new things just above ---^ ******/ /* flags */ @@ -428,102 +498,107 @@ struct lws_tokens { * don't forget to update test server header dump accordingly * * these have to be kept in sync with lextable.h / minilex.c + * + * NOTE: These public enums are part of the abi. If you want to add one, + * add it at where specified so existing users are unaffected. */ - enum lws_token_indexes { - WSI_TOKEN_GET_URI, - WSI_TOKEN_POST_URI, - WSI_TOKEN_OPTIONS_URI, - WSI_TOKEN_HOST, - WSI_TOKEN_CONNECTION, - WSI_TOKEN_UPGRADE, - WSI_TOKEN_ORIGIN, - WSI_TOKEN_DRAFT, - WSI_TOKEN_CHALLENGE, - WSI_TOKEN_EXTENSIONS, - WSI_TOKEN_KEY1, - WSI_TOKEN_KEY2, - WSI_TOKEN_PROTOCOL, - WSI_TOKEN_ACCEPT, - WSI_TOKEN_NONCE, - WSI_TOKEN_HTTP, - WSI_TOKEN_HTTP2_SETTINGS, - WSI_TOKEN_HTTP_ACCEPT, - WSI_TOKEN_HTTP_AC_REQUEST_HEADERS, - WSI_TOKEN_HTTP_IF_MODIFIED_SINCE, - WSI_TOKEN_HTTP_IF_NONE_MATCH, - WSI_TOKEN_HTTP_ACCEPT_ENCODING, - WSI_TOKEN_HTTP_ACCEPT_LANGUAGE, - WSI_TOKEN_HTTP_PRAGMA, - WSI_TOKEN_HTTP_CACHE_CONTROL, - WSI_TOKEN_HTTP_AUTHORIZATION, - WSI_TOKEN_HTTP_COOKIE, - WSI_TOKEN_HTTP_CONTENT_LENGTH, - WSI_TOKEN_HTTP_CONTENT_TYPE, - WSI_TOKEN_HTTP_DATE, - WSI_TOKEN_HTTP_RANGE, - WSI_TOKEN_HTTP_REFERER, - WSI_TOKEN_KEY, - WSI_TOKEN_VERSION, - WSI_TOKEN_SWORIGIN, + WSI_TOKEN_GET_URI = 0, + WSI_TOKEN_POST_URI = 1, + WSI_TOKEN_OPTIONS_URI = 2, + WSI_TOKEN_HOST = 3, + WSI_TOKEN_CONNECTION = 4, + WSI_TOKEN_UPGRADE = 5, + WSI_TOKEN_ORIGIN = 6, + WSI_TOKEN_DRAFT = 7, + WSI_TOKEN_CHALLENGE = 8, + WSI_TOKEN_EXTENSIONS = 9, + WSI_TOKEN_KEY1 = 10, + WSI_TOKEN_KEY2 = 11, + WSI_TOKEN_PROTOCOL = 12, + WSI_TOKEN_ACCEPT = 13, + WSI_TOKEN_NONCE = 14, + WSI_TOKEN_HTTP = 15, + WSI_TOKEN_HTTP2_SETTINGS = 16, + WSI_TOKEN_HTTP_ACCEPT = 17, + WSI_TOKEN_HTTP_AC_REQUEST_HEADERS = 18, + WSI_TOKEN_HTTP_IF_MODIFIED_SINCE = 19, + WSI_TOKEN_HTTP_IF_NONE_MATCH = 20, + WSI_TOKEN_HTTP_ACCEPT_ENCODING = 21, + WSI_TOKEN_HTTP_ACCEPT_LANGUAGE = 22, + WSI_TOKEN_HTTP_PRAGMA = 23, + WSI_TOKEN_HTTP_CACHE_CONTROL = 24, + WSI_TOKEN_HTTP_AUTHORIZATION = 25, + WSI_TOKEN_HTTP_COOKIE = 26, + WSI_TOKEN_HTTP_CONTENT_LENGTH = 27, + WSI_TOKEN_HTTP_CONTENT_TYPE = 28, + WSI_TOKEN_HTTP_DATE = 29, + WSI_TOKEN_HTTP_RANGE = 30, + WSI_TOKEN_HTTP_REFERER = 31, + WSI_TOKEN_KEY = 32, + WSI_TOKEN_VERSION = 33, + WSI_TOKEN_SWORIGIN = 34, - WSI_TOKEN_HTTP_COLON_AUTHORITY, - WSI_TOKEN_HTTP_COLON_METHOD, - WSI_TOKEN_HTTP_COLON_PATH, - WSI_TOKEN_HTTP_COLON_SCHEME, - WSI_TOKEN_HTTP_COLON_STATUS, + WSI_TOKEN_HTTP_COLON_AUTHORITY = 35, + WSI_TOKEN_HTTP_COLON_METHOD = 36, + WSI_TOKEN_HTTP_COLON_PATH = 37, + WSI_TOKEN_HTTP_COLON_SCHEME = 38, + WSI_TOKEN_HTTP_COLON_STATUS = 39, - WSI_TOKEN_HTTP_ACCEPT_CHARSET, - WSI_TOKEN_HTTP_ACCEPT_RANGES, - WSI_TOKEN_HTTP_ACCESS_CONTROL_ALLOW_ORIGIN, - WSI_TOKEN_HTTP_AGE, - WSI_TOKEN_HTTP_ALLOW, - WSI_TOKEN_HTTP_CONTENT_DISPOSITION, - WSI_TOKEN_HTTP_CONTENT_ENCODING, - WSI_TOKEN_HTTP_CONTENT_LANGUAGE, - WSI_TOKEN_HTTP_CONTENT_LOCATION, - WSI_TOKEN_HTTP_CONTENT_RANGE, - WSI_TOKEN_HTTP_ETAG, - WSI_TOKEN_HTTP_EXPECT, - WSI_TOKEN_HTTP_EXPIRES, - WSI_TOKEN_HTTP_FROM, - WSI_TOKEN_HTTP_IF_MATCH, - WSI_TOKEN_HTTP_IF_RANGE, - WSI_TOKEN_HTTP_IF_UNMODIFIED_SINCE, - WSI_TOKEN_HTTP_LAST_MODIFIED, - WSI_TOKEN_HTTP_LINK, - WSI_TOKEN_HTTP_LOCATION, - WSI_TOKEN_HTTP_MAX_FORWARDS, - WSI_TOKEN_HTTP_PROXY_AUTHENTICATE, - WSI_TOKEN_HTTP_PROXY_AUTHORIZATION, - WSI_TOKEN_HTTP_REFRESH, - WSI_TOKEN_HTTP_RETRY_AFTER, - WSI_TOKEN_HTTP_SERVER, - WSI_TOKEN_HTTP_SET_COOKIE, - WSI_TOKEN_HTTP_STRICT_TRANSPORT_SECURITY, - WSI_TOKEN_HTTP_TRANSFER_ENCODING, - WSI_TOKEN_HTTP_USER_AGENT, - WSI_TOKEN_HTTP_VARY, - WSI_TOKEN_HTTP_VIA, - WSI_TOKEN_HTTP_WWW_AUTHENTICATE, + WSI_TOKEN_HTTP_ACCEPT_CHARSET = 40, + WSI_TOKEN_HTTP_ACCEPT_RANGES = 41, + WSI_TOKEN_HTTP_ACCESS_CONTROL_ALLOW_ORIGIN = 42, + WSI_TOKEN_HTTP_AGE = 43, + WSI_TOKEN_HTTP_ALLOW = 44, + WSI_TOKEN_HTTP_CONTENT_DISPOSITION = 45, + WSI_TOKEN_HTTP_CONTENT_ENCODING = 46, + WSI_TOKEN_HTTP_CONTENT_LANGUAGE = 47, + WSI_TOKEN_HTTP_CONTENT_LOCATION = 48, + WSI_TOKEN_HTTP_CONTENT_RANGE = 49, + WSI_TOKEN_HTTP_ETAG = 50, + WSI_TOKEN_HTTP_EXPECT = 51, + WSI_TOKEN_HTTP_EXPIRES = 52, + WSI_TOKEN_HTTP_FROM = 53, + WSI_TOKEN_HTTP_IF_MATCH = 54, + WSI_TOKEN_HTTP_IF_RANGE = 55, + WSI_TOKEN_HTTP_IF_UNMODIFIED_SINCE = 56, + WSI_TOKEN_HTTP_LAST_MODIFIED = 57, + WSI_TOKEN_HTTP_LINK = 58, + WSI_TOKEN_HTTP_LOCATION = 59, + WSI_TOKEN_HTTP_MAX_FORWARDS = 60, + WSI_TOKEN_HTTP_PROXY_AUTHENTICATE = 61, + WSI_TOKEN_HTTP_PROXY_AUTHORIZATION = 62, + WSI_TOKEN_HTTP_REFRESH = 63, + WSI_TOKEN_HTTP_RETRY_AFTER = 64, + WSI_TOKEN_HTTP_SERVER = 65, + WSI_TOKEN_HTTP_SET_COOKIE = 66, + WSI_TOKEN_HTTP_STRICT_TRANSPORT_SECURITY = 67, + WSI_TOKEN_HTTP_TRANSFER_ENCODING = 68, + WSI_TOKEN_HTTP_USER_AGENT = 69, + WSI_TOKEN_HTTP_VARY = 70, + WSI_TOKEN_HTTP_VIA = 71, + WSI_TOKEN_HTTP_WWW_AUTHENTICATE = 72, WSI_TOKEN_PROXY, - WSI_TOKEN_PATCH_URI, - WSI_TOKEN_PUT_URI, - WSI_TOKEN_DELETE_URI, + WSI_TOKEN_PATCH_URI = 73, + WSI_TOKEN_PUT_URI = 74, + WSI_TOKEN_DELETE_URI = 75, - WSI_TOKEN_HTTP_URI_ARGS, + WSI_TOKEN_HTTP_URI_ARGS = 76, /* use token storage to stash these */ - _WSI_TOKEN_CLIENT_SENT_PROTOCOLS, - _WSI_TOKEN_CLIENT_PEER_ADDRESS, - _WSI_TOKEN_CLIENT_URI, - _WSI_TOKEN_CLIENT_HOST, - _WSI_TOKEN_CLIENT_ORIGIN, + _WSI_TOKEN_CLIENT_SENT_PROTOCOLS = 77, + _WSI_TOKEN_CLIENT_PEER_ADDRESS = 78, + _WSI_TOKEN_CLIENT_URI = 79, + _WSI_TOKEN_CLIENT_HOST = 80, + _WSI_TOKEN_CLIENT_ORIGIN = 81, + + /****** add new things just above ---^ ******/ /* always last real token index*/ WSI_TOKEN_COUNT, + /* parser state additions */ WSI_TOKEN_NAME_PART, WSI_TOKEN_SKIPPING, @@ -532,7 +607,7 @@ enum lws_token_indexes { WSI_INIT_TOKEN_MUXURL, }; -struct lws_token_limits { +struct lws_token_limits {// unsigned short token_limit[WSI_TOKEN_COUNT]; }; @@ -625,6 +700,10 @@ struct lws_token_limits { (e.g., the server certificate can't be verified). */ +/* + * NOTE: These public enums are part of the abi. If you want to add one, + * add it at where specified so existing users are unaffected. + */ enum lws_close_status { LWS_CLOSE_STATUS_NOSTATUS = 0, LWS_CLOSE_STATUS_NORMAL = 1000, @@ -640,6 +719,8 @@ enum lws_close_status { LWS_CLOSE_STATUS_EXTENSION_REQUIRED = 1010, LWS_CLOSE_STATUS_UNEXPECTED_CONDITION = 1011, LWS_CLOSE_STATUS_TLS_FAILURE = 1015, + + /****** add new things just above ---^ ******/ LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY = 9999, }; @@ -675,10 +756,10 @@ enum http_status { HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED, }; -struct libwebsocket; -struct libwebsocket_context; +struct lws; +struct lws_context; /* needed even with extensions disabled for create context */ -struct libwebsocket_extension; +struct lws_extension; /** * callback_function() - User server actions @@ -694,13 +775,16 @@ struct libwebsocket_extension; * * For each connection / session there is user data allocated that is * pointed to by "user". You set the size of this user data area when - * the library is initialized with libwebsocket_create_server. + * the library is initialized with lws_create_server. * * You get an opportunity to initialize user data when called back with * LWS_CALLBACK_ESTABLISHED reason. * * LWS_CALLBACK_ESTABLISHED: after the server completes a handshake with - * an incoming client + * an incoming client. If you built the library + * with ssl support, @in is a pointer to the + * ssl struct associated with the connection or + * NULL. * * LWS_CALLBACK_CLIENT_CONNECTION_ERROR: the request client connection has * been unable to complete a handshake with the remote server. If @@ -740,7 +824,7 @@ struct libwebsocket_extension; * for example, to send a script to the client * which will then open the websockets connection. * @in points to the URI path requested and - * libwebsockets_serve_http_file() makes it very + * lws_serve_http_file() makes it very * simple to send back a file to the client. * Normally after sending the file you are done * with the http connection, since the rest of the @@ -765,7 +849,7 @@ struct libwebsocket_extension; * * LWS_CALLBACK_CLIENT_WRITEABLE: * LWS_CALLBACK_SERVER_WRITEABLE: If you call - * libwebsocket_callback_on_writable() on a connection, you will + * lws_callback_on_writable() on a connection, you will * get one of these callbacks coming when the connection socket * is able to accept another write packet without blocking. * If it already was able to take another packet without blocking, @@ -917,7 +1001,7 @@ struct libwebsocket_extension; * will be integrating libwebsockets sockets into an external polling * array. * - * For these calls, @in points to a struct libwebsocket_pollargs that + * For these calls, @in points to a struct lws_pollargs that * contains @fd, @events and @prev_events members * * LWS_CALLBACK_ADD_POLL_FD: libwebsocket deals with its poll() loop @@ -930,7 +1014,7 @@ struct libwebsocket_extension; * serving case. * This callback happens when a socket needs to be * added to the polling loop: @in points to a struct - * libwebsocket_pollargs; the @fd member of the struct is the file + * lws_pollargs; the @fd member of the struct is the file * descriptor, and @events contains the active events. * * If you are using the internal polling loop (the "service" @@ -938,13 +1022,13 @@ struct libwebsocket_extension; * * LWS_CALLBACK_DEL_POLL_FD: This callback happens when a socket descriptor * needs to be removed from an external polling array. @in is - * again the struct libwebsocket_pollargs containing the @fd member + * again the struct lws_pollargs containing the @fd member * to be removed. If you are using the internal polling * loop, you can just ignore it. * * LWS_CALLBACK_CHANGE_MODE_POLL_FD: This callback happens when * libwebsockets wants to modify the events for a connectiion. - * @in is the struct libwebsocket_pollargs with the @fd to change. + * @in is the struct lws_pollargs with the @fd to change. * The new event mask is in @events member and the old mask is in * the @prev_events member. * If you are using the internal polling loop, you can just ignore @@ -954,16 +1038,22 @@ struct libwebsocket_extension; * LWS_CALLBACK_UNLOCK_POLL: These allow the external poll changes driven * by libwebsockets to participate in an external thread locking * scheme around the changes, so the whole thing is threadsafe. + * These are called around three activities in the library, + * - inserting a new wsi in the wsi / fd table (len=1) + * - deleting a wsi from the wsi / fd table (len=1) + * - changing a wsi's POLLIN/OUT state (len=0) + * Locking and unlocking external synchronization objects when + * len == 1 allows external threads to be synchronized against + * wsi lifecycle changes if it acquires the same lock for the + * duration of wsi dereference from the other thread context. */ -LWS_VISIBLE LWS_EXTERN int callback(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, - void *in, size_t len); +LWS_VISIBLE LWS_EXTERN int +callback(struct lws_context *context, struct lws *wsi, + enum lws_callback_reasons reason, void *user, void *in, size_t len); -typedef int (callback_function)(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, - void *in, size_t len); +typedef int (callback_function)(struct lws_context *context, struct lws *wsi, + enum lws_callback_reasons reason, void *user, + void *in, size_t len); #ifndef LWS_NO_EXTENSIONS /** @@ -1024,21 +1114,19 @@ typedef int (callback_function)(struct libwebsocket_context *context, * buffer safely, it should copy the data into its own buffer and * set the lws_tokens token pointer to it. */ -LWS_VISIBLE LWS_EXTERN int extension_callback(struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, - void *user, void *in, size_t len); +LWS_VISIBLE LWS_EXTERN int +extension_callback(struct lws_context *context, struct lws_extension *ext, + struct lws *wsi, enum lws_extension_callback_reasons reason, + void *user, void *in, size_t len); -typedef int (extension_callback_function)(struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, +typedef int (extension_callback_function)(struct lws_context *context, + struct lws_extension *ext, struct lws *wsi, + enum lws_extension_callback_reasons reason, void *user, void *in, size_t len); #endif /** - * struct libwebsocket_protocols - List of protocols and handlers server + * struct lws_protocols - List of protocols and handlers server * supports. * @name: Protocol name that must match the one given in the client * Javascript new WebSocket(url, 'protocol') name. @@ -1054,7 +1142,7 @@ typedef int (extension_callback_function)(struct libwebsocket_context *context, * you support. If the frame size is exceeded, there is no * error, but the buffer will spill to the user callback when * full, which you can detect by using - * libwebsockets_remaining_packet_payload(). Notice that you + * lws_remaining_packet_payload(). Notice that you * just talk about frame size here, the LWS_SEND_BUFFER_PRE_PADDING * and post-padding are automatically also allocated on top. * @id: ignored by lws, but useful to contain user information bound @@ -1064,7 +1152,7 @@ typedef int (extension_callback_function)(struct libwebsocket_context *context, * switch (wsi->protocol->id), user code might use some bits as * capability flags based on selected protocol version, etc. * @user: User provided context data at the protocol level. - * Accessible via libwebsockets_get_protocol(wsi)->user + * Accessible via lws_get_protocol(wsi)->user * This should not be confused with wsi->user, it is not the same. * The library completely ignores any value in here. * @owning_server: the server init call fills in this opaque pointer when @@ -1072,7 +1160,7 @@ typedef int (extension_callback_function)(struct libwebsocket_context *context, * @protocol_index: which protocol we are starting from zero * * This structure represents one protocol supported by the server. An - * array of these structures is passed to libwebsocket_create_server() + * array of these structures is passed to lws_create_server() * allows as many protocols as you like to be handled by one server. * * The first protocol given has its callback used for user callbacks when @@ -1080,7 +1168,7 @@ typedef int (extension_callback_function)(struct libwebsocket_context *context, * connection and true if the client did not send a Protocol: header. */ -struct libwebsocket_protocols { +struct lws_protocols { const char *name; callback_function *callback; size_t per_session_data_size; @@ -1093,13 +1181,13 @@ struct libwebsocket_protocols { * no need for user to use them directly either */ - struct libwebsocket_context *owning_server; + struct lws_context *owning_server; int protocol_index; }; #ifndef LWS_NO_EXTENSIONS /** - * struct libwebsocket_extension - An extension we know how to cope with + * struct lws_extension - An extension we know how to cope with * * @name: Formal extension name, eg, "deflate-stream" * @callback: Service callback @@ -1111,7 +1199,7 @@ struct libwebsocket_protocols { * all sessions, etc, if it wants */ -struct libwebsocket_extension { +struct lws_extension { const char *name; extension_callback_function *callback; size_t per_session_data_size; @@ -1150,7 +1238,7 @@ struct libwebsocket_file_callbacks { * specific callback for each one. The list is ended with an * 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: NULL or array of lws_extension structs listing the * extensions this context supports. If you configured with * --without-extensions, you should give NULL here. * @file_callbacks: custom file operation callbacks @@ -1176,7 +1264,7 @@ struct libwebsocket_file_callbacks { * @uid: user id to change to after setting listen socket, or -1. * @options: 0, or LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK * @user: optional user pointer that can be recovered via the context - * pointer using libwebsocket_context_user + * pointer using lws_context_user * @ka_time: 0 for no keepalive, otherwise apply this keepalive timeout to * all libwebsocket sockets, client or server * @ka_probes: if ka_time was nonzero, after the timeout expires how many @@ -1218,110 +1306,117 @@ struct lws_context_creation_info { #endif }; -LWS_VISIBLE LWS_EXTERN -void lws_set_log_level(int level, - void (*log_emit_function)(int level, const char *line)); +LWS_VISIBLE LWS_EXTERN void +lws_set_log_level(int level, + void (*log_emit_function)(int level, const char *line)); LWS_VISIBLE LWS_EXTERN void lwsl_emit_syslog(int level, const char *line); -LWS_VISIBLE LWS_EXTERN struct libwebsocket_context * -libwebsocket_create_context(struct lws_context_creation_info *info); +LWS_VISIBLE LWS_EXTERN struct lws_context * +lws_create_context(struct lws_context_creation_info *info); LWS_VISIBLE LWS_EXTERN int -libwebsocket_set_proxy(struct libwebsocket_context *context, const char *proxy); +lws_set_proxy(struct lws_context *context, const char *proxy); LWS_VISIBLE LWS_EXTERN void -libwebsocket_context_destroy(struct libwebsocket_context *context); +lws_context_destroy(struct lws_context *context); LWS_VISIBLE LWS_EXTERN int -libwebsocket_service(struct libwebsocket_context *context, int timeout_ms); +lws_service(struct lws_context *context, int timeout_ms); LWS_VISIBLE LWS_EXTERN void -libwebsocket_cancel_service(struct libwebsocket_context *context); +lws_cancel_service(struct lws_context *context); LWS_VISIBLE LWS_EXTERN const unsigned char * lws_token_to_string(enum lws_token_indexes token); LWS_VISIBLE LWS_EXTERN int -lws_add_http_header_by_name(struct libwebsocket_context *context, - struct libwebsocket *wsi, +lws_add_http_header_by_name(struct lws_context *context, + struct lws *wsi, const unsigned char *name, const unsigned char *value, int length, unsigned char **p, unsigned char *end); LWS_VISIBLE LWS_EXTERN int -lws_finalize_http_header(struct libwebsocket_context *context, - struct libwebsocket *wsi, +lws_finalize_http_header(struct lws_context *context, + struct lws *wsi, unsigned char **p, unsigned char *end); LWS_VISIBLE LWS_EXTERN int -lws_add_http_header_by_token(struct libwebsocket_context *context, - struct libwebsocket *wsi, +lws_add_http_header_by_token(struct lws_context *context, + struct lws *wsi, enum lws_token_indexes token, const unsigned char *value, int length, unsigned char **p, unsigned char *end); -LWS_VISIBLE LWS_EXTERN int lws_add_http_header_content_length(struct libwebsocket_context *context, - struct libwebsocket *wsi, +LWS_VISIBLE LWS_EXTERN int +lws_add_http_header_content_length(struct lws_context *context, + struct lws *wsi, unsigned long content_length, unsigned char **p, unsigned char *end); LWS_VISIBLE LWS_EXTERN int -lws_add_http_header_status(struct libwebsocket_context *context, - struct libwebsocket *wsi, +lws_add_http_header_status(struct lws_context *context, + struct lws *wsi, unsigned int code, unsigned char **p, unsigned char *end); -LWS_EXTERN int lws_http_transaction_completed(struct libwebsocket *wsi); +LWS_EXTERN int +lws_http_transaction_completed(struct lws *wsi); #ifdef LWS_USE_LIBEV typedef void (lws_ev_signal_cb)(EV_P_ struct ev_signal *w, int revents); LWS_VISIBLE LWS_EXTERN int -libwebsocket_sigint_cfg( - struct libwebsocket_context *context, +lws_sigint_cfg( + struct lws_context *context, int use_ev_sigint, lws_ev_signal_cb* cb); LWS_VISIBLE LWS_EXTERN int -libwebsocket_initloop( - struct libwebsocket_context *context, struct ev_loop *loop); +lws_initloop( + struct lws_context *context, struct ev_loop *loop); LWS_VISIBLE void -libwebsocket_sigint_cb( +lws_sigint_cb( struct ev_loop *loop, struct ev_signal *watcher, int revents); #endif /* LWS_USE_LIBEV */ LWS_VISIBLE LWS_EXTERN int -libwebsocket_service_fd(struct libwebsocket_context *context, - struct libwebsocket_pollfd *pollfd); +lws_service_fd(struct lws_context *context, + struct lws_pollfd *pollfd); LWS_VISIBLE LWS_EXTERN void * -libwebsocket_context_user(struct libwebsocket_context *context); +lws_context_user(struct lws_context *context); +/* + * NOTE: These public enums are part of the abi. If you want to add one, + * add it at where specified so existing users are unaffected. + */ enum pending_timeout { - NO_PENDING_TIMEOUT = 0, - PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE, - PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE, - PENDING_TIMEOUT_ESTABLISH_WITH_SERVER, - PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, - PENDING_TIMEOUT_AWAITING_PING, - PENDING_TIMEOUT_CLOSE_ACK, - PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE, - PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE, - PENDING_TIMEOUT_SSL_ACCEPT, - PENDING_TIMEOUT_HTTP_CONTENT, - PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND, - PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE, + NO_PENDING_TIMEOUT = 0, + PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE = 1, + PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE = 2, + PENDING_TIMEOUT_ESTABLISH_WITH_SERVER = 3, + PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE = 4, + PENDING_TIMEOUT_AWAITING_PING = 5, + PENDING_TIMEOUT_CLOSE_ACK = 6, + PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE = 7, + PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE = 8, + PENDING_TIMEOUT_SSL_ACCEPT = 9, + PENDING_TIMEOUT_HTTP_CONTENT = 10, + PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND = 11, + PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE = 12, + + /****** add new things just above ---^ ******/ }; LWS_VISIBLE LWS_EXTERN void -libwebsocket_set_timeout(struct libwebsocket *wsi, - enum pending_timeout reason, int secs); +lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs); /* * IMPORTANT NOTICE! @@ -1333,7 +1428,7 @@ libwebsocket_set_timeout(struct libwebsocket *wsi, * This allows us to add protocol info before and after the data, and send as * one packet on the network without payload copying, for maximum efficiency. * - * So for example you need this kind of code to use libwebsocket_write with a + * So for example you need this kind of code to use lws_write with a * 128-byte payload * * char buf[LWS_SEND_BUFFER_PRE_PADDING + 128 + LWS_SEND_BUFFER_POST_PADDING]; @@ -1341,7 +1436,7 @@ libwebsocket_set_timeout(struct libwebsocket *wsi, * // fill your part of the buffer... for example here it's all zeros * memset(&buf[LWS_SEND_BUFFER_PRE_PADDING], 0, 128); * - * libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 128, + * lws_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 128, * LWS_WRITE_TEXT); * * When sending LWS_WRITE_HTTP, there is no protocol addition and you can just @@ -1355,14 +1450,12 @@ libwebsocket_set_timeout(struct libwebsocket *wsi, * the big length style */ -// Pad LWS_SEND_BUFFER_PRE_PADDING to the CPU word size, so that word references -// to the address immediately after the padding won't cause an unaligned access -// error. Sometimes the recommended padding is even larger than the size of a void *. -// For example, for the X86-64 architecture, in Intel's document -// https://software.intel.com/en-us/articles/data-alignment-when-migrating-to-64-bit-intel-architecture -// they recommend that structures larger than 16 bytes be aligned to 16-byte -// boundaries. -// +/* + * Pad LWS_SEND_BUFFER_PRE_PADDING to the CPU word size, so that word references + * to the address immediately after the padding won't cause an unaligned access + * error. Sometimes for performance reasons the recommended padding is even + * larger than sizeof(void *). + */ #if !defined(LWS_SIZEOFPTR) #define LWS_SIZEOFPTR (sizeof (void *)) @@ -1376,68 +1469,62 @@ libwebsocket_set_timeout(struct libwebsocket *wsi, #else #define _LWS_PAD_SIZE LWS_SIZEOFPTR /* Size of a pointer on the target architecture */ #endif -#define _LWS_PAD(n) (((n) % _LWS_PAD_SIZE) ? ((n) + (_LWS_PAD_SIZE - ((n) % _LWS_PAD_SIZE))) : (n)) +#define _LWS_PAD(n) (((n) % _LWS_PAD_SIZE) ? \ + ((n) + (_LWS_PAD_SIZE - ((n) % _LWS_PAD_SIZE))) : (n)) #define LWS_SEND_BUFFER_PRE_PADDING _LWS_PAD(4 + 10 + (2 * MAX_MUX_RECURSION)) #define LWS_SEND_BUFFER_POST_PADDING 4 LWS_VISIBLE LWS_EXTERN int -libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, size_t len, - enum libwebsocket_write_protocol protocol); +lws_write(struct lws *wsi, unsigned char *buf, size_t len, + enum lws_write_protocol protocol); /* helper for case where buffer may be const */ -#define libwebsocket_write_http(wsi, buf, len) \ - libwebsocket_write(wsi, (unsigned char *)(buf), len, LWS_WRITE_HTTP) +#define lws_write_http(wsi, buf, len) \ + lws_write(wsi, (unsigned char *)(buf), len, LWS_WRITE_HTTP) LWS_VISIBLE LWS_EXTERN int -libwebsockets_serve_http_file(struct libwebsocket_context *context, - struct libwebsocket *wsi, const char *file, - const char *content_type, const char *other_headers, - int other_headers_len); +lws_serve_http_file(struct lws_context *context, struct lws *wsi, + const char *file, const char *content_type, + const char *other_headers, int other_headers_len); LWS_VISIBLE LWS_EXTERN int -libwebsockets_serve_http_file_fragment(struct libwebsocket_context *context, - struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN int libwebsockets_return_http_status( - struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned int code, - const char *html_body); - -LWS_VISIBLE LWS_EXTERN const struct libwebsocket_protocols * -libwebsockets_get_protocol(struct libwebsocket *wsi); +lws_serve_http_file_fragment(struct lws_context *context, struct lws *wsi); LWS_VISIBLE LWS_EXTERN int -libwebsocket_callback_on_writable(struct libwebsocket_context *context, - struct libwebsocket *wsi); +lws_return_http_status(struct lws_context *context, struct lws *wsi, + unsigned int code, const char *html_body); + +LWS_VISIBLE LWS_EXTERN const struct lws_protocols * +lws_get_protocol(struct lws *wsi); LWS_VISIBLE LWS_EXTERN int -libwebsocket_callback_on_writable_all_protocol( - const struct libwebsocket_protocols *protocol); +lws_callback_on_writable(struct lws_context *context, struct lws *wsi); LWS_VISIBLE LWS_EXTERN int -libwebsocket_callback_all_protocol( - const struct libwebsocket_protocols *protocol, int reason); +lws_callback_on_writable_all_protocol(const struct lws_protocols *protocol); LWS_VISIBLE LWS_EXTERN int -libwebsocket_get_socket_fd(struct libwebsocket *wsi); +lws_callback_all_protocol(const struct lws_protocols *protocol, int reason); LWS_VISIBLE LWS_EXTERN int -libwebsocket_is_final_fragment(struct libwebsocket *wsi); +lws_get_socket_fd(struct lws *wsi); + +LWS_VISIBLE LWS_EXTERN int +lws_is_final_fragment(struct lws *wsi); LWS_VISIBLE LWS_EXTERN unsigned char -libwebsocket_get_reserved_bits(struct libwebsocket *wsi); +lws_get_reserved_bits(struct lws *wsi); LWS_VISIBLE LWS_EXTERN int -libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable); +lws_rx_flow_control(struct lws *wsi, int enable); LWS_VISIBLE LWS_EXTERN void -libwebsocket_rx_flow_allow_all_protocol( - const struct libwebsocket_protocols *protocol); +lws_rx_flow_allow_all_protocol(const struct lws_protocols *protocol); LWS_VISIBLE LWS_EXTERN size_t -libwebsockets_remaining_packet_payload(struct libwebsocket *wsi); +lws_remaining_packet_payload(struct lws *wsi); /* - * if the protocol does not have any guidence, returns -1. Currently only + * if the protocol does not have any guidance, returns -1. Currently only * http2 connections get send window information from this API. But your code * should use it so it can work properly with any protocol. * @@ -1453,63 +1540,52 @@ libwebsockets_remaining_packet_payload(struct libwebsocket *wsi); * intermediary dynamically. */ LWS_VISIBLE LWS_EXTERN size_t -lws_get_peer_write_allowance(struct libwebsocket *wsi); +lws_get_peer_write_allowance(struct lws *wsi); -LWS_VISIBLE LWS_EXTERN struct libwebsocket * -libwebsocket_client_connect(struct libwebsocket_context *clients, - const char *address, - int port, - int ssl_connection, - const char *path, - const char *host, - const char *origin, - const char *protocol, - int ietf_version_or_minus_one); +LWS_VISIBLE LWS_EXTERN struct lws * +lws_client_connect(struct lws_context *clients, const char *address, + int port, int ssl_connection, const char *path, + const char *host, const char *origin, const char *protocol, + int ietf_version_or_minus_one); -LWS_VISIBLE LWS_EXTERN struct libwebsocket * -libwebsocket_client_connect_extended(struct libwebsocket_context *clients, - const char *address, - int port, - int ssl_connection, - const char *path, - const char *host, - const char *origin, - const char *protocol, - int ietf_version_or_minus_one, - void *userdata); +LWS_VISIBLE LWS_EXTERN struct lws * +lws_client_connect_extended(struct lws_context *clients, const char *address, + int port, int ssl_connection, const char *path, + const char *host, const char *origin, + const char *protocol, int ietf_version_or_minus_one, + void *userdata); LWS_VISIBLE LWS_EXTERN const char * -libwebsocket_canonical_hostname(struct libwebsocket_context *context); +lws_canonical_hostname(struct lws_context *context); LWS_VISIBLE LWS_EXTERN void -libwebsockets_get_peer_addresses(struct libwebsocket_context *context, - struct libwebsocket *wsi, lws_sockfd_type fd, char *name, int name_len, - char *rip, int rip_len); +lws_get_peer_addresses(struct lws_context *context, struct lws *wsi, + lws_sockfd_type fd, char *name, int name_len, + char *rip, int rip_len); LWS_VISIBLE LWS_EXTERN int -libwebsockets_get_random(struct libwebsocket_context *context, - void *buf, int len); +lws_get_random(struct lws_context *context, void *buf, int len); LWS_VISIBLE LWS_EXTERN int lws_daemonize(const char *_lock_path); LWS_VISIBLE LWS_EXTERN int -lws_send_pipe_choked(struct libwebsocket *wsi); +lws_send_pipe_choked(struct lws *wsi); LWS_VISIBLE LWS_EXTERN int -lws_partial_buffered(struct libwebsocket *wsi); +lws_partial_buffered(struct lws *wsi); LWS_VISIBLE LWS_EXTERN int -lws_frame_is_binary(struct libwebsocket *wsi); +lws_frame_is_binary(struct lws *wsi); LWS_VISIBLE LWS_EXTERN int -lws_is_ssl(struct libwebsocket *wsi); +lws_is_ssl(struct lws *wsi); #ifdef LWS_SHA1_USE_OPENSSL_NAME -#define libwebsockets_SHA1 SHA1 +#define lws_SHA1 SHA1 #else LWS_VISIBLE LWS_EXTERN unsigned char * -libwebsockets_SHA1(const unsigned char *d, size_t n, unsigned char *md); +lws_SHA1(const unsigned char *d, size_t n, unsigned char *md); #endif LWS_VISIBLE LWS_EXTERN int @@ -1524,11 +1600,11 @@ lws_get_library_version(void); /* access to headers... only valid while headers valid */ LWS_VISIBLE LWS_EXTERN int -lws_hdr_total_length(struct libwebsocket *wsi, enum lws_token_indexes h); +lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h); LWS_VISIBLE LWS_EXTERN int -lws_hdr_copy(struct libwebsocket *wsi, char *dest, int len, - enum lws_token_indexes h); +lws_hdr_copy(struct lws *wsi, char *dest, int len, + enum lws_token_indexes h); /* * Note: this is not normally needed as a user api. It's provided in case it is @@ -1536,12 +1612,11 @@ lws_hdr_copy(struct libwebsocket *wsi, char *dest, int len, */ LWS_VISIBLE LWS_EXTERN int -libwebsocket_read(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned char *buf, size_t len); +lws_read(struct lws_context *context, struct lws *wsi, + unsigned char *buf, size_t len); #ifndef LWS_NO_EXTENSIONS -LWS_VISIBLE LWS_EXTERN struct libwebsocket_extension *libwebsocket_get_internal_extensions(); +LWS_VISIBLE LWS_EXTERN struct lws_extension *lws_get_internal_extensions(); #endif /* diff --git a/lib/lws-plat-mbed3.c b/lib/lws-plat-mbed3.c index 264ee9c55..06d3ca8f5 100644 --- a/lib/lws-plat-mbed3.c +++ b/lib/lws-plat-mbed3.c @@ -12,7 +12,7 @@ unsigned long long time_in_microseconds(void) return 0; } -LWS_VISIBLE int libwebsockets_get_random(struct libwebsocket_context *context, +LWS_VISIBLE int lws_get_random(struct lws_context *context, void *buf, int len) { (void)context; @@ -38,10 +38,10 @@ LWS_VISIBLE int libwebsockets_get_random(struct libwebsocket_context *context, * get their turn at the network device. */ -LWS_VISIBLE int lws_send_pipe_choked(struct libwebsocket *wsi) +LWS_VISIBLE int lws_send_pipe_choked(struct lws *wsi) { #if 0 - struct libwebsocket_pollfd fds; + struct lws_pollfd fds; /* treat the fact we got a truncated send pending as if we're choked */ if (wsi->truncated_send_len) @@ -64,24 +64,24 @@ LWS_VISIBLE int lws_send_pipe_choked(struct libwebsocket *wsi) } LWS_VISIBLE int -lws_poll_listen_fd(struct libwebsocket_pollfd *fd) +lws_poll_listen_fd(struct lws_pollfd *fd) { (void)fd; return -1; } /** - * libwebsocket_cancel_service() - Cancel servicing of pending websocket activity + * lws_cancel_service() - Cancel servicing of pending websocket activity * @context: Websocket context * - * This function let a call to libwebsocket_service() waiting for a timeout + * This function let a call to lws_service() waiting for a timeout * immediately return. * * There is no poll() in MBED3, he will fire callbacks when he feels like * it. */ LWS_VISIBLE void -libwebsocket_cancel_service(struct libwebsocket_context *context) +lws_cancel_service(struct lws_context *context) { (void)context; } @@ -92,77 +92,7 @@ LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line) } LWS_VISIBLE int -lws_plat_service(struct libwebsocket_context *context, int timeout_ms) -{ - (void)context; - (void)timeout_ms; -#if 0 - int n; - int m; - char buf; -#ifdef LWS_OPENSSL_SUPPORT - struct libwebsocket *wsi, *wsi_next; -#endif - - /* stay dead once we are dead */ - - if (!context) - return 1; - - lws_libev_run(context); - - context->service_tid = context->protocols[0].callback(context, NULL, - LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0); - -#ifdef LWS_OPENSSL_SUPPORT - /* if we know we have non-network pending data, do not wait in poll */ - if (lws_ssl_anybody_has_buffered_read(context)) - timeout_ms = 0; -#endif - n = poll(context->fds, context->fds_count, timeout_ms); - context->service_tid = 0; - -#ifdef LWS_OPENSSL_SUPPORT - if (!lws_ssl_anybody_has_buffered_read(context) && n == 0) { -#else - if (n == 0) /* poll timeout */ { -#endif - libwebsocket_service_fd(context, NULL); - return 0; - } - - if (n < 0) { - if (LWS_ERRNO != LWS_EINTR) - return -1; - return 0; - } - - /* any socket with events to service? */ - - for (n = 0; n < context->fds_count; n++) { - - if (!context->fds[n].revents) - continue; - - if (context->fds[n].fd == context->dummy_pipe_fds[0]) { - if (read(context->fds[n].fd, &buf, 1) != 1) - lwsl_err("Cannot read from dummy pipe."); - continue; - } - - m = libwebsocket_service_fd(context, &context->fds[n]); - if (m < 0) - return -1; - /* if something closed, retry this slot */ - if (m) - n--; - } -#endif - return 0; -} - -LWS_VISIBLE int -lws_plat_set_socket_options(struct libwebsocket_context *context, lws_sockfd_type fd) +lws_plat_set_socket_options(struct lws_context *context, lws_sockfd_type fd) { (void)context; (void)fd; @@ -176,14 +106,14 @@ lws_plat_drop_app_privileges(struct lws_context_creation_info *info) } LWS_VISIBLE int -lws_plat_init_lookup(struct libwebsocket_context *context) +lws_plat_init_lookup(struct lws_context *context) { (void)context; return 0; } LWS_VISIBLE int -lws_plat_init_fd_tables(struct libwebsocket_context *context) +lws_plat_init_fd_tables(struct lws_context *context) { (void)context; return 0; @@ -197,35 +127,24 @@ lws_plat_context_early_init(void) } LWS_VISIBLE void -lws_plat_context_early_destroy(struct libwebsocket_context *context) +lws_plat_context_early_destroy(struct lws_context *context) { (void)context; } LWS_VISIBLE void -lws_plat_context_late_destroy(struct libwebsocket_context *context) +lws_plat_context_late_destroy(struct lws_context *context) { (void)context; } LWS_VISIBLE void -lws_plat_service_periodic(struct libwebsocket_context *context) +lws_plat_service_periodic(struct lws_context *context) { (void)context; } -LWS_VISIBLE int -lws_plat_change_pollfd(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd) -{ - (void)context; - (void)wsi; - (void)pfd; - - return 0; -} - LWS_VISIBLE int lws_plat_open_file(const char* filename, unsigned long* filelen) { @@ -245,7 +164,7 @@ lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt) } LWS_VISIBLE int -insert_wsi(struct libwebsocket_context *context, struct libwebsocket *wsi) +insert_wsi(struct lws_context *context, struct lws *wsi) { (void)context; (void)wsi; @@ -254,7 +173,7 @@ insert_wsi(struct libwebsocket_context *context, struct libwebsocket *wsi) } LWS_VISIBLE int -delete_from_fd(struct libwebsocket_context *context, lws_sockfd_type fd) +delete_from_fd(struct lws_context *context, lws_sockfd_type fd) { (void)context; (void)fd; diff --git a/lib/lws-plat-mbed3.cpp b/lib/lws-plat-mbed3.cpp index b8033c2c3..fa6b8d5f4 100644 --- a/lib/lws-plat-mbed3.cpp +++ b/lib/lws-plat-mbed3.cpp @@ -21,11 +21,28 @@ extern "C" void mbed3_delete_tcp_stream_socket(void *sock) delete conn; } -extern "C" void mbed3_tcp_stream_bind(void *sock, int port, struct libwebsocket *wsi) +void lws_conn::serialized_writeable(struct lws *_wsi) +{ + struct lws *wsi = (struct lws *)_wsi; + struct lws_pollfd pollfd; + lws_conn *conn = (lws_conn *)wsi->sock; + + conn->awaiting_on_writeable = 0; + + pollfd.fd = wsi->sock; + pollfd.events = POLLOUT; + pollfd.revents = POLLOUT; + + lwsl_debug("%s: wsi %p\r\n", __func__, (void *)wsi); + + lws_service_fd(wsi->protocol->owning_server, &pollfd); +} + +extern "C" void mbed3_tcp_stream_bind(void *sock, int port, struct lws *wsi) { lws_conn_listener *srv = (lws_conn_listener *)sock; - lwsl_info("%s\r\n", __func__); + lwsl_debug("%s\r\n", __func__); /* associate us with the listening wsi */ ((lws_conn *)srv)->set_wsi(wsi); @@ -33,26 +50,48 @@ extern "C" void mbed3_tcp_stream_bind(void *sock, int port, struct libwebsocket minar::Scheduler::postCallback(fp.bind(port)); } -extern "C" void mbed3_tcp_stream_accept(void *sock, struct libwebsocket *wsi) +extern "C" void mbed3_tcp_stream_accept(void *sock, struct lws *wsi) { lws_conn *conn = (lws_conn *)sock; - lwsl_info("%s\r\n", __func__); + lwsl_debug("%s\r\n", __func__); conn->set_wsi(wsi); } extern "C" LWS_VISIBLE int -lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char *buf, int len) +lws_plat_change_pollfd(struct lws_context *context, + struct lws *wsi, struct lws_pollfd *pfd) +{ + lws_conn *conn = (lws_conn *)wsi->sock; + + (void)context; + if (pfd->events & POLLOUT) { + conn->awaiting_on_writeable = 1; + if (conn->writeable) { + mbed::util::FunctionPointer1 book(conn, &lws_conn::serialized_writeable); + minar::Scheduler::postCallback(book.bind(wsi)); + lwsl_debug("%s: wsi %p (booked callback)\r\n", __func__, (void *)wsi); + } else { + + lwsl_debug("%s: wsi %p (set awaiting_on_writeable)\r\n", __func__, (void *)wsi); + } + } else + conn->awaiting_on_writeable = 0; + + return 0; +} + +extern "C" LWS_VISIBLE int +lws_ssl_capable_read_no_ssl(struct lws_context *context, + struct lws *wsi, unsigned char *buf, int len) { socket_error_t err; size_t _len = len; - + lwsl_debug("%s\r\n", __func__); (void)context; - /* s/s_HACK/ts/g when mbed3 listen payload bug fixed */ - err = ((lws_conn *)wsi->sock)->s_HACK->recv((char *)buf, &_len); + err = ((lws_conn *)wsi->sock)->ts->recv((char *)buf, &_len); if (err == SOCKET_ERROR_NONE) { lwsl_info("%s: got %d bytes\n", __func__, _len); return _len; @@ -66,22 +105,22 @@ lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context, #endif return LWS_SSL_CAPABLE_MORE_SERVICE; - // !!! while listen payload mbed3 bug, don't error out if nothing */ -// if (((lws_conn *)wsi->sock)->s_HACK != ((Socket *)((lws_conn *)wsi->sock)->ts)) -// return 0; - lwsl_warn("error on reading from skt: %d\n", err); return LWS_SSL_CAPABLE_ERROR; } extern "C" LWS_VISIBLE int -lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len) +lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len) { socket_error_t err; + lws_conn *conn = (lws_conn *)wsi->sock; lwsl_debug("%s: wsi %p: write %d (from %p)\n", __func__, (void *)wsi, len, (void *)buf); - err = ((lws_conn *)wsi->sock)->ts->send((char *)buf, len); + lwsl_debug("%s: wsi %p: clear writeable\n", __func__, (void *)wsi); + conn->writeable = 0; + + err = conn->ts->send((char *)buf, len); if (err == SOCKET_ERROR_NONE) return len; @@ -118,9 +157,11 @@ void lws_conn_listener::start(const uint16_t port) srv.error_check(err); } -int lws_conn::actual_onRX(Socket *s) +void lws_conn::onRX(Socket *s) { - struct libwebsocket_pollfd pollfd; + struct lws_pollfd pollfd; + + (void)s; pollfd.fd = this; pollfd.events = POLLIN; @@ -128,9 +169,7 @@ int lws_conn::actual_onRX(Socket *s) lwsl_debug("%s: lws %p\n", __func__, wsi); - s_HACK = s; - - return libwebsocket_service_fd(wsi->protocol->owning_server, &pollfd); + lws_service_fd(wsi->protocol->owning_server, &pollfd); } /* @@ -141,10 +180,9 @@ int lws_conn::actual_onRX(Socket *s) void lws_conn_listener::onIncoming(TCPListener *tl, void *impl) { mbed::util::CriticalSectionLock lock; - TCPStream *ts = srv.accept(impl); lws_conn *conn; - if (!impl || !ts) { + if (!impl) { onError(tl, SOCKET_ERROR_NULL_PTR); return; } @@ -154,7 +192,9 @@ void lws_conn_listener::onIncoming(TCPListener *tl, void *impl) lwsl_err("OOM\n"); return; } - conn->ts = ts; + conn->ts = srv.accept(impl); + if (!conn->ts) + return; /* * we use the listen socket wsi to get started, but a new wsi is @@ -164,23 +204,19 @@ void lws_conn_listener::onIncoming(TCPListener *tl, void *impl) lws_server_socket_service(wsi->protocol->owning_server, wsi, (struct pollfd *)conn); - ts->setOnSent(Socket::SentHandler_t(conn, &lws_conn::onSent)); - ts->setOnReadable(TCPStream::ReadableHandler_t(conn, &lws_conn::onRX)); - ts->setOnError(TCPStream::ErrorHandler_t(conn, &lws_conn::onError)); - ts->setOnDisconnect(TCPStream::DisconnectHandler_t(conn, + conn->ts->setOnError(TCPStream::ErrorHandler_t(conn, &lws_conn::onError)); + conn->ts->setOnDisconnect(TCPStream::DisconnectHandler_t(conn, &lws_conn::onDisconnect)); - /* - * mbed3 is messed up as of 2015-11-08, data packets may - * appear on the listening socket initially - */ - conn->actual_onRX((Socket *)tl); - conn->actual_onRX((Socket *)conn->ts); + conn->ts->setOnSent(Socket::SentHandler_t(conn, &lws_conn::onSent)); + conn->ts->setOnReadable(TCPStream::ReadableHandler_t(conn, &lws_conn::onRX)); + + conn->onRX((Socket *)conn->ts); lwsl_debug("%s: exit\n", __func__); } -extern "C" LWS_VISIBLE struct libwebsocket * -wsi_from_fd(struct libwebsocket_context *context, lws_sockfd_type fd) +extern "C" LWS_VISIBLE struct lws * +wsi_from_fd(struct lws_context *context, lws_sockfd_type fd) { lws_conn *conn = (lws_conn *)fd; (void)context; @@ -189,8 +225,8 @@ wsi_from_fd(struct libwebsocket_context *context, lws_sockfd_type fd) } extern "C" LWS_VISIBLE void -lws_plat_insert_socket_into_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi) +lws_plat_insert_socket_into_fds(struct lws_context *context, + struct lws *wsi) { (void)wsi; lws_libev_io(context, wsi, LWS_EV_START | LWS_EV_READ); @@ -198,19 +234,14 @@ lws_plat_insert_socket_into_fds(struct libwebsocket_context *context, } extern "C" LWS_VISIBLE void -lws_plat_delete_socket_from_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi, int m) +lws_plat_delete_socket_from_fds(struct lws_context *context, + struct lws *wsi, int m) { (void)context; (void)wsi; (void)m; } -void lws_conn::onRX(Socket *s) -{ - actual_onRX(s); -} - void lws_conn_listener::onDisconnect(TCPStream *s) { lwsl_info("%s\r\n", __func__); @@ -218,22 +249,39 @@ void lws_conn_listener::onDisconnect(TCPStream *s) //if (s) //delete this; } + +extern "C" LWS_VISIBLE int +lws_plat_service(struct lws_context *context, int timeout_ms) +{ + (void)context; + (void)timeout_ms; + + return 0; +} + void lws_conn::onSent(Socket *s, uint16_t len) { - struct libwebsocket_pollfd pollfd; + struct lws_pollfd pollfd; (void)s; (void)len; + + if (!awaiting_on_writeable) { + lwsl_debug("%s: wsi %p (setting writable=1)\r\n", + __func__, (void *)wsi); + writeable = 1; + return; + } + + writeable = 1; - pollfd.fd = this; + pollfd.fd = wsi->sock; pollfd.events = POLLOUT; pollfd.revents = POLLOUT; - - s_HACK = s; - lwsl_debug("%s: wsi %p\r\n", __func__, (void *)wsi); + lwsl_debug("%s: wsi %p (servicing now)\r\n", __func__, (void *)wsi); - libwebsocket_service_fd(wsi->protocol->owning_server, &pollfd); + lws_service_fd(wsi->protocol->owning_server, &pollfd); } void lws_conn_listener::onError(Socket *s, socket_error_t err) @@ -246,8 +294,9 @@ void lws_conn_listener::onError(Socket *s, socket_error_t err) void lws_conn::onDisconnect(TCPStream *s) { + lwsl_notice("%s:\r\n", __func__); (void)s; - libwebsocket_close_and_free_session(wsi->protocol->owning_server, wsi, + lws_close_and_free_session(wsi->protocol->owning_server, wsi, LWS_CLOSE_STATUS_NOSTATUS); } @@ -256,6 +305,5 @@ void lws_conn::onError(Socket *s, socket_error_t err) { (void) s; lwsl_notice("Socket Error: %s (%d)\r\n", socket_strerror(err), err); - if (ts) - ts->close(); -} \ No newline at end of file + s->close(); +} diff --git a/lib/lws-plat-unix.c b/lib/lws-plat-unix.c index bc1338093..a087439ca 100644 --- a/lib/lws-plat-unix.c +++ b/lib/lws-plat-unix.c @@ -14,15 +14,15 @@ unsigned long long time_in_microseconds(void) return ((unsigned long long)tv.tv_sec * 1000000LL) + tv.tv_usec; } -LWS_VISIBLE int libwebsockets_get_random(struct libwebsocket_context *context, +LWS_VISIBLE int lws_get_random(struct lws_context *context, void *buf, int len) { return read(context->fd_random, (char *)buf, len); } -LWS_VISIBLE int lws_send_pipe_choked(struct libwebsocket *wsi) +LWS_VISIBLE int lws_send_pipe_choked(struct lws *wsi) { - struct libwebsocket_pollfd fds; + struct lws_pollfd fds; /* treat the fact we got a truncated send pending as if we're choked */ if (wsi->truncated_send_len) @@ -44,7 +44,7 @@ LWS_VISIBLE int lws_send_pipe_choked(struct libwebsocket *wsi) } LWS_VISIBLE int -lws_poll_listen_fd(struct libwebsocket_pollfd *fd) +lws_poll_listen_fd(struct lws_pollfd *fd) { return poll(fd, 1, 0); } @@ -58,14 +58,14 @@ static void lws_sigusr2(int sig) } /** - * libwebsocket_cancel_service() - Cancel servicing of pending websocket activity + * lws_cancel_service() - Cancel servicing of pending websocket activity * @context: Websocket context * - * This function let a call to libwebsocket_service() waiting for a timeout + * This function let a call to lws_service() waiting for a timeout * immediately return. */ LWS_VISIBLE void -libwebsocket_cancel_service(struct libwebsocket_context *context) +lws_cancel_service(struct lws_context *context) { char buf = 0; @@ -95,13 +95,13 @@ LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line) } LWS_VISIBLE int -lws_plat_service(struct libwebsocket_context *context, int timeout_ms) +lws_plat_service(struct lws_context *context, int timeout_ms) { int n; int m; char buf; #ifdef LWS_OPENSSL_SUPPORT - struct libwebsocket *wsi, *wsi_next; + struct lws *wsi, *wsi_next; #endif /* stay dead once we are dead */ @@ -127,7 +127,7 @@ lws_plat_service(struct libwebsocket_context *context, int timeout_ms) #else if (n == 0) /* poll timeout */ { #endif - libwebsocket_service_fd(context, NULL); + lws_service_fd(context, NULL); return 0; } @@ -176,7 +176,7 @@ lws_plat_service(struct libwebsocket_context *context, int timeout_ms) continue; } - m = libwebsocket_service_fd(context, &context->fds[n]); + m = lws_service_fd(context, &context->fds[n]); if (m < 0) return -1; /* if something closed, retry this slot */ @@ -188,7 +188,7 @@ lws_plat_service(struct libwebsocket_context *context, int timeout_ms) } LWS_VISIBLE int -lws_plat_set_socket_options(struct libwebsocket_context *context, int fd) +lws_plat_set_socket_options(struct lws_context *context, int fd) { int optval = 1; socklen_t optlen = sizeof(optval); @@ -272,9 +272,9 @@ lws_plat_drop_app_privileges(struct lws_context_creation_info *info) } LWS_VISIBLE int -lws_plat_init_lookup(struct libwebsocket_context *context) +lws_plat_init_lookup(struct lws_context *context) { - context->lws_lookup = lws_zalloc(sizeof(struct libwebsocket *) * context->max_fds); + context->lws_lookup = lws_zalloc(sizeof(struct lws *) * context->max_fds); if (context->lws_lookup == NULL) { lwsl_err( "Unable to allocate lws_lookup array for %d connections\n", @@ -286,7 +286,7 @@ lws_plat_init_lookup(struct libwebsocket_context *context) } LWS_VISIBLE int -lws_plat_init_fd_tables(struct libwebsocket_context *context) +lws_plat_init_fd_tables(struct lws_context *context) { context->fd_random = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY); if (context->fd_random < 0) { @@ -335,12 +335,12 @@ lws_plat_context_early_init(void) } LWS_VISIBLE void -lws_plat_context_early_destroy(struct libwebsocket_context *context) +lws_plat_context_early_destroy(struct lws_context *context) { } LWS_VISIBLE void -lws_plat_context_late_destroy(struct libwebsocket_context *context) +lws_plat_context_late_destroy(struct lws_context *context) { if (context->lws_lookup) lws_free(context->lws_lookup); @@ -353,7 +353,7 @@ lws_plat_context_late_destroy(struct libwebsocket_context *context) /* cast a struct sockaddr_in6 * into addr for ipv6 */ LWS_VISIBLE int -interface_to_sa(struct libwebsocket_context *context, +interface_to_sa(struct lws_context *context, const char *ifname, struct sockaddr_in *addr, size_t addrlen) { int rc = -1; @@ -422,21 +422,21 @@ interface_to_sa(struct libwebsocket_context *context, } LWS_VISIBLE void -lws_plat_insert_socket_into_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi) +lws_plat_insert_socket_into_fds(struct lws_context *context, + struct lws *wsi) { lws_libev_io(context, wsi, LWS_EV_START | LWS_EV_READ); context->fds[context->fds_count++].revents = 0; } LWS_VISIBLE void -lws_plat_delete_socket_from_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi, int m) +lws_plat_delete_socket_from_fds(struct lws_context *context, + struct lws *wsi, int m) { } LWS_VISIBLE void -lws_plat_service_periodic(struct libwebsocket_context *context) +lws_plat_service_periodic(struct lws_context *context) { /* if our parent went down, don't linger around */ if (context->started_with_parent && @@ -445,8 +445,8 @@ lws_plat_service_periodic(struct libwebsocket_context *context) } LWS_VISIBLE int -lws_plat_change_pollfd(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd) +lws_plat_change_pollfd(struct lws_context *context, + struct lws *wsi, struct lws_pollfd *pfd) { return 0; } diff --git a/lib/lws-plat-win.c b/lib/lws-plat-win.c index 3fcfb1ebf..f4fef9f33 100644 --- a/lib/lws-plat-win.c +++ b/lib/lws-plat-win.c @@ -35,8 +35,8 @@ time_t time(time_t *t) /* file descriptor hash management */ -struct libwebsocket * -wsi_from_fd(struct libwebsocket_context *context, int fd) +struct lws * +wsi_from_fd(struct lws_context *context, lws_sockfd_type fd) { int h = LWS_FD_HASH(fd); int n = 0; @@ -49,7 +49,7 @@ wsi_from_fd(struct libwebsocket_context *context, int fd) } int -insert_wsi(struct libwebsocket_context *context, struct libwebsocket *wsi) +insert_wsi(struct lws_context *context, struct lws *wsi) { int h = LWS_FD_HASH(wsi->sock); @@ -64,7 +64,7 @@ insert_wsi(struct libwebsocket_context *context, struct libwebsocket *wsi) } int -delete_from_fd(struct libwebsocket_context *context, int fd) +delete_from_fd(struct lws_context *context, lws_sockfd_type fd) { int h = LWS_FD_HASH(fd); int n = 0; @@ -86,7 +86,7 @@ delete_from_fd(struct libwebsocket_context *context, int fd) return 1; } -LWS_VISIBLE int libwebsockets_get_random(struct libwebsocket_context *context, +LWS_VISIBLE int lws_get_random(struct lws_context *context, void *buf, int len) { int n; @@ -98,12 +98,12 @@ LWS_VISIBLE int libwebsockets_get_random(struct libwebsocket_context *context, return n; } -LWS_VISIBLE int lws_send_pipe_choked(struct libwebsocket *wsi) +LWS_VISIBLE int lws_send_pipe_choked(struct lws *wsi) { return wsi->sock_send_blocking; } -LWS_VISIBLE int lws_poll_listen_fd(struct libwebsocket_pollfd *fd) +LWS_VISIBLE int lws_poll_listen_fd(struct lws_pollfd *fd) { fd_set readfds; struct timeval tv = { 0, 0 }; @@ -117,14 +117,14 @@ LWS_VISIBLE int lws_poll_listen_fd(struct libwebsocket_pollfd *fd) } /** - * libwebsocket_cancel_service() - Cancel servicing of pending websocket activity + * lws_cancel_service() - Cancel servicing of pending websocket activity * @context: Websocket context * - * This function let a call to libwebsocket_service() waiting for a timeout + * This function let a call to lws_service() waiting for a timeout * immediately return. */ LWS_VISIBLE void -libwebsocket_cancel_service(struct libwebsocket_context *context) +lws_cancel_service(struct lws_context *context) { WSASetEvent(context->events[0]); } @@ -135,14 +135,14 @@ LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line) } LWS_VISIBLE int -lws_plat_service(struct libwebsocket_context *context, int timeout_ms) +lws_plat_service(struct lws_context *context, int timeout_ms) { int n; int i; DWORD ev; WSANETWORKEVENTS networkevents; - struct libwebsocket_pollfd *pfd; - struct libwebsocket *wsi; + struct lws_pollfd *pfd; + struct lws *wsi; /* stay dead once we are dead */ @@ -162,9 +162,12 @@ lws_plat_service(struct libwebsocket_context *context, int timeout_ms) if (!wsi || wsi->sock_send_blocking) continue; pfd->revents = LWS_POLLOUT; - n = libwebsocket_service_fd(context, pfd); + n = lws_service_fd(context, pfd); if (n < 0) - return n; + return -1; + /* if something closed, retry this slot */ + if (n) + i--; } } @@ -173,7 +176,7 @@ lws_plat_service(struct libwebsocket_context *context, int timeout_ms) context->service_tid = 0; if (ev == WSA_WAIT_TIMEOUT) { - libwebsocket_service_fd(context, NULL); + lws_service_fd(context, NULL); return 0; } @@ -195,7 +198,7 @@ lws_plat_service(struct libwebsocket_context *context, int timeout_ms) return -1; } - pfd->revents = networkevents.lNetworkEvents; + pfd->revents = (short)networkevents.lNetworkEvents; if (pfd->revents & LWS_POLLOUT) { wsi = wsi_from_fd(context, pfd->fd); @@ -203,11 +206,11 @@ lws_plat_service(struct libwebsocket_context *context, int timeout_ms) wsi->sock_send_blocking = FALSE; } - return libwebsocket_service_fd(context, pfd); + return lws_service_fd(context, pfd); } LWS_VISIBLE int -lws_plat_set_socket_options(struct libwebsocket_context *context, int fd) +lws_plat_set_socket_options(struct lws_context *context, lws_sockfd_type fd) { int optval = 1; int optlen = sizeof(optval); @@ -254,12 +257,12 @@ lws_plat_drop_app_privileges(struct lws_context_creation_info *info) } LWS_VISIBLE int -lws_plat_init_lookup(struct libwebsocket_context *context) +lws_plat_init_lookup(struct lws_context *context) { int i; for (i = 0; i < FD_HASHTABLE_MODULUS; i++) { - context->fd_hashtable[i].wsi = lws_zalloc(sizeof(struct libwebsocket*) * context->max_fds); + context->fd_hashtable[i].wsi = lws_zalloc(sizeof(struct lws*) * context->max_fds); if (!context->fd_hashtable[i].wsi) { return -1; @@ -270,7 +273,7 @@ lws_plat_init_lookup(struct libwebsocket_context *context) } LWS_VISIBLE int -lws_plat_init_fd_tables(struct libwebsocket_context *context) +lws_plat_init_fd_tables(struct lws_context *context) { context->events = lws_malloc(sizeof(WSAEVENT) * (context->max_fds + 1)); if (context->events == NULL) { @@ -310,7 +313,7 @@ lws_plat_context_early_init(void) } LWS_VISIBLE void -lws_plat_context_early_destroy(struct libwebsocket_context *context) +lws_plat_context_early_destroy(struct lws_context *context) { if (context->events) { WSACloseEvent(context->events[0]); @@ -319,7 +322,7 @@ lws_plat_context_early_destroy(struct libwebsocket_context *context) } LWS_VISIBLE void -lws_plat_context_late_destroy(struct libwebsocket_context *context) +lws_plat_context_late_destroy(struct lws_context *context) { int n; @@ -332,7 +335,7 @@ lws_plat_context_late_destroy(struct libwebsocket_context *context) } LWS_VISIBLE int -interface_to_sa(struct libwebsocket_context *context, +interface_to_sa(struct lws_context *context, const char *ifname, struct sockaddr_in *addr, size_t addrlen) { long long address = inet_addr(ifname); @@ -346,14 +349,14 @@ interface_to_sa(struct libwebsocket_context *context, if (address == INADDR_NONE) return -1; - addr->sin_addr.s_addr = address; + addr->sin_addr.s_addr = (unsigned long)address; return 0; } LWS_VISIBLE void -lws_plat_insert_socket_into_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi) +lws_plat_insert_socket_into_fds(struct lws_context *context, + struct lws *wsi) { context->fds[context->fds_count++].revents = 0; context->events[context->fds_count] = WSACreateEvent(); @@ -361,21 +364,21 @@ lws_plat_insert_socket_into_fds(struct libwebsocket_context *context, } LWS_VISIBLE void -lws_plat_delete_socket_from_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi, int m) +lws_plat_delete_socket_from_fds(struct lws_context *context, + struct lws *wsi, int m) { WSACloseEvent(context->events[m + 1]); context->events[m + 1] = context->events[context->fds_count + 1]; } LWS_VISIBLE void -lws_plat_service_periodic(struct libwebsocket_context *context) +lws_plat_service_periodic(struct lws_context *context) { } LWS_VISIBLE int -lws_plat_change_pollfd(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd) +lws_plat_change_pollfd(struct lws_context *context, + struct lws *wsi, struct lws_pollfd *pfd) { long networkevents = LWS_POLLHUP; diff --git a/lib/output.c b/lib/output.c index 9628d35d3..469aaf16c 100644 --- a/lib/output.c +++ b/lib/output.c @@ -22,13 +22,13 @@ #include "private-libwebsockets.h" static int -libwebsocket_0405_frame_mask_generate(struct libwebsocket *wsi) +lws_0405_frame_mask_generate(struct lws *wsi) { int n; /* fetch the per-frame nonce */ - n = libwebsockets_get_random(wsi->protocol->owning_server, + n = lws_get_random(wsi->protocol->owning_server, wsi->u.ws.frame_masking_nonce_04, 4); if (n != 4) { lwsl_parser("Unable to read from random device %s %d\n", @@ -46,10 +46,8 @@ libwebsocket_0405_frame_mask_generate(struct libwebsocket *wsi) LWS_VISIBLE void lwsl_hexdump(void *vbuf, size_t len) { - unsigned int n; - unsigned int m; - unsigned int start; unsigned char *buf = (unsigned char *)vbuf; + unsigned int n, m, start; char line[80]; char *p; @@ -90,12 +88,11 @@ LWS_VISIBLE void lwsl_hexdump(void *vbuf, size_t len) * notice this returns number of bytes consumed, or -1 */ -int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len) +int lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len) { - struct libwebsocket_context *context = wsi->protocol->owning_server; - int n; + struct lws_context *context = wsi->protocol->owning_server; size_t real_len = len; - int m; + int n, m; if (!len) return 0; @@ -123,9 +120,7 @@ int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len) if (!lws_socket_is_valid(wsi->sock)) lwsl_warn("** error invalid sock but expected to send\n"); - /* - * nope, send it on the socket directly - */ + /* nope, send it on the socket directly */ lws_latency_pre(context, wsi); n = lws_ssl_capable_write(wsi, buf, len); lws_latency(context, wsi, "send lws_issue_raw", n, (unsigned int)n == len); @@ -162,8 +157,7 @@ handle_truncated_send: } } /* always callback on writeable */ - libwebsocket_callback_on_writable( - wsi->protocol->owning_server, wsi); + lws_callback_on_writable(wsi->protocol->owning_server, wsi); return n; } @@ -187,7 +181,7 @@ handle_truncated_send: * first priority next time the socket is writable) */ lwsl_info("***** %x new partial sent %d from %d total\n", - wsi, n, real_len); + wsi, n, real_len); /* * - if we still have a suitable malloc lying around, use it @@ -195,14 +189,14 @@ handle_truncated_send: * - or, if no buffer, create it */ if (!wsi->truncated_send_malloc || - real_len - n > wsi->truncated_send_allocation) { + real_len - n > wsi->truncated_send_allocation) { lws_free(wsi->truncated_send_malloc); wsi->truncated_send_allocation = real_len - n; wsi->truncated_send_malloc = lws_malloc(real_len - n); if (!wsi->truncated_send_malloc) { lwsl_err("truncated send: unable to malloc %d\n", - real_len - n); + real_len - n); return -1; } } @@ -211,13 +205,13 @@ handle_truncated_send: memcpy(wsi->truncated_send_malloc, buf + n, real_len - n); /* since something buffered, force it to get another chance to send */ - libwebsocket_callback_on_writable(wsi->protocol->owning_server, wsi); + lws_callback_on_writable(wsi->protocol->owning_server, wsi); return real_len; } /** - * libwebsocket_write() - Apply protocol then write data to client + * lws_write() - Apply protocol then write data to client * @wsi: Websocket instance (available from user callback) * @buf: The data to send. For data being sent on a websocket * connection (ie, not default http), this buffer MUST have @@ -246,21 +240,19 @@ handle_truncated_send: * pressure at any given time. */ -LWS_VISIBLE int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, - size_t len, enum libwebsocket_write_protocol protocol) +LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, + size_t len, enum lws_write_protocol protocol) { - int n; - int pre = 0; - int post = 0; int masked7 = wsi->mode == LWS_CONNMODE_WS_CLIENT; - unsigned char *dropmask = NULL; unsigned char is_masked_bit = 0; - size_t orig_len = len; + unsigned char *dropmask = NULL; struct lws_tokens eff_buf; + int post = 0, pre = 0, n; + size_t orig_len = len; if (len == 0 && protocol != LWS_WRITE_CLOSE && - protocol != LWS_WRITE_PING && protocol != LWS_WRITE_PONG) { - lwsl_warn("zero length libwebsocket_write attempt\n"); + protocol != LWS_WRITE_PING && protocol != LWS_WRITE_PONG) { + lwsl_warn("zero length lws_write attempt\n"); return 0; } @@ -318,7 +310,6 @@ LWS_VISIBLE int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, switch (wsi->ietf_spec_revision) { case 13: - if (masked7) { pre += 4; dropmask = &buf[0 - pre]; @@ -347,8 +338,8 @@ LWS_VISIBLE int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, if (wsi->u.ws.close_reason) { /* reason codes count as data bytes */ buf -= 2; - buf[0] = wsi->u.ws.close_reason >> 8; - buf[1] = wsi->u.ws.close_reason; + buf[0] = (unsigned char)(wsi->u.ws.close_reason >> 8); + buf[1] = (unsigned char)wsi->u.ws.close_reason; len += 2; } break; @@ -369,14 +360,14 @@ LWS_VISIBLE int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, if (len < 126) { pre += 2; buf[-pre] = n; - buf[-pre + 1] = len | is_masked_bit; + buf[-pre + 1] = (unsigned char)(len | is_masked_bit); } else { if (len < 65536) { pre += 4; buf[-pre] = n; buf[-pre + 1] = 126 | is_masked_bit; - buf[-pre + 2] = len >> 8; - buf[-pre + 3] = len; + buf[-pre + 2] = (unsigned char)(len >> 8); + buf[-pre + 3] = (unsigned char)len; } else { pre += 10; buf[-pre] = n; @@ -392,10 +383,10 @@ LWS_VISIBLE int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, buf[-pre + 4] = 0; buf[-pre + 5] = 0; #endif - buf[-pre + 6] = len >> 24; - buf[-pre + 7] = len >> 16; - buf[-pre + 8] = len >> 8; - buf[-pre + 9] = len; + buf[-pre + 6] = (unsigned char)(len >> 24); + buf[-pre + 7] = (unsigned char)(len >> 16); + buf[-pre + 8] = (unsigned char)(len >> 8); + buf[-pre + 9] = (unsigned char)len; } } break; @@ -411,7 +402,7 @@ do_more_inside_frame: if (wsi->mode == LWS_CONNMODE_WS_CLIENT) { if (!wsi->u.ws.inside_frame) - if (libwebsocket_0405_frame_mask_generate(wsi)) { + if (lws_0405_frame_mask_generate(wsi)) { lwsl_err("frame mask generation failed\n"); return -1; } @@ -508,15 +499,15 @@ send_raw: /* * it is how many bytes of user buffer got sent... may be < orig_len * in which case callback when writable has already been arranged - * and user code can call libwebsocket_write() again with the rest + * and user code can call lws_write() again with the rest * later. */ return n - (pre + post); } -LWS_VISIBLE int libwebsockets_serve_http_file_fragment( - struct libwebsocket_context *context, struct libwebsocket *wsi) +LWS_VISIBLE int lws_serve_http_file_fragment(struct lws_context *context, + struct lws *wsi) { int n; int m; @@ -525,9 +516,9 @@ LWS_VISIBLE int libwebsockets_serve_http_file_fragment( if (wsi->truncated_send_len) { if (lws_issue_raw(wsi, wsi->truncated_send_malloc + - wsi->truncated_send_offset, - wsi->truncated_send_len) < 0) { - lwsl_info("closing from libwebsockets_serve_http_file_fragment\n"); + wsi->truncated_send_offset, + wsi->truncated_send_len) < 0) { + lwsl_info("closing from lws_serve_http_file_fragment\n"); return -1; } continue; @@ -538,13 +529,16 @@ LWS_VISIBLE int libwebsockets_serve_http_file_fragment( context->file_callbacks.pfn_read(&n, wsi->u.http.fd, context->service_buffer, sizeof(context->service_buffer)); + if (n < 0) return -1; /* caller will close */ if (n) { - libwebsocket_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT, AWAITING_TIMEOUT); + lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT, + AWAITING_TIMEOUT); wsi->u.http.filepos += n; - m = libwebsocket_write(wsi, context->service_buffer, n, - wsi->u.http.filepos == wsi->u.http.filelen ? LWS_WRITE_HTTP_FINAL : LWS_WRITE_HTTP); + m = lws_write(wsi, context->service_buffer, n, + wsi->u.http.filepos == wsi->u.http.filelen ? + LWS_WRITE_HTTP_FINAL : LWS_WRITE_HTTP); if (m < 0) return -1; @@ -555,7 +549,7 @@ LWS_VISIBLE int libwebsockets_serve_http_file_fragment( } all_sent: if (!wsi->truncated_send_len && - wsi->u.http.filepos == wsi->u.http.filelen) { + wsi->u.http.filepos == wsi->u.http.filelen) { wsi->state = WSI_STATE_HTTP; /* we might be in keepalive, so close it off here */ @@ -573,15 +567,15 @@ all_sent: } lwsl_info("choked before able to send whole file (post)\n"); - libwebsocket_callback_on_writable(context, wsi); + lws_callback_on_writable(context, wsi); return 0; /* indicates further processing must be done */ } #if LWS_POSIX LWS_VISIBLE int -lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char *buf, int len) +lws_ssl_capable_read_no_ssl(struct lws_context *context, + struct lws *wsi, unsigned char *buf, int len) { int n; @@ -601,7 +595,7 @@ lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context, } LWS_VISIBLE int -lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len) +lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len) { int n = 0; @@ -631,7 +625,7 @@ lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int l } #endif LWS_VISIBLE int -lws_ssl_pending_no_ssl(struct libwebsocket *wsi) +lws_ssl_pending_no_ssl(struct lws *wsi) { (void)wsi; return 0; diff --git a/lib/parsers.c b/lib/parsers.c index 2330a2a64..3e8e35936 100644 --- a/lib/parsers.c +++ b/lib/parsers.c @@ -59,7 +59,7 @@ int lextable_decode(int pos, char c) } } -int lws_allocate_header_table(struct libwebsocket *wsi) +int lws_allocate_header_table(struct lws *wsi) { /* Be sure to free any existing header data to avoid mem leak: */ lws_free_header_table(wsi); @@ -75,14 +75,14 @@ int lws_allocate_header_table(struct libwebsocket *wsi) return 0; } -int lws_free_header_table(struct libwebsocket *wsi) +int lws_free_header_table(struct lws *wsi) { lws_free2(wsi->u.hdr.ah); wsi->u.hdr.ah = NULL; return 0; }; -LWS_VISIBLE int lws_hdr_total_length(struct libwebsocket *wsi, enum lws_token_indexes h) +LWS_VISIBLE int lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h) { int n; int len = 0; @@ -98,8 +98,8 @@ LWS_VISIBLE int lws_hdr_total_length(struct libwebsocket *wsi, enum lws_token_in return len; } -LWS_VISIBLE int lws_hdr_copy(struct libwebsocket *wsi, char *dest, int len, - enum lws_token_indexes h) +LWS_VISIBLE int lws_hdr_copy(struct lws *wsi, char *dest, int len, + enum lws_token_indexes h) { int toklen = lws_hdr_total_length(wsi, h); int n; @@ -121,7 +121,7 @@ LWS_VISIBLE int lws_hdr_copy(struct libwebsocket *wsi, char *dest, int len, return toklen; } -char *lws_hdr_simple_ptr(struct libwebsocket *wsi, enum lws_token_indexes h) +char *lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h) { int n; @@ -132,8 +132,8 @@ char *lws_hdr_simple_ptr(struct libwebsocket *wsi, enum lws_token_indexes h) return &wsi->u.hdr.ah->data[wsi->u.hdr.ah->frags[n].offset]; } -int lws_hdr_simple_create(struct libwebsocket *wsi, - enum lws_token_indexes h, const char *s) +int lws_hdr_simple_create(struct lws *wsi, + enum lws_token_indexes h, const char *s) { wsi->u.hdr.ah->next_frag_index++; if (wsi->u.hdr.ah->next_frag_index == @@ -178,29 +178,35 @@ static signed char char_to_hex(const char c) return -1; } -static int issue_char(struct libwebsocket *wsi, unsigned char c) +static int issue_char(struct lws *wsi, unsigned char c) { + unsigned short frag_len; if (wsi->u.hdr.ah->pos == sizeof(wsi->u.hdr.ah->data)) { lwsl_warn("excessive header content\n"); return -1; } - if( wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len >= - wsi->u.hdr.current_token_limit) { - lwsl_warn("header %i exceeds limit\n", wsi->u.hdr.parser_state); - return 1; + frag_len = \ + wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len; + /* If we haven't hit the token limit, just copy the character into + * the header: */ + if( frag_len < wsi->u.hdr.current_token_limit ) { + wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = c; + if (c) + wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len++; + return 0; + } + else { + /* Insert a null character when we *hit* the limit: */ + if( frag_len == wsi->u.hdr.current_token_limit ) { + wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = '\0'; + lwsl_warn("header %i exceeds limit\n", wsi->u.hdr.parser_state); + }; }; - - wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = c; - if (c) - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len++; - - return 0; + return 1; } -int libwebsocket_parse( - struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char c) +int lws_parse(struct lws_context *context, struct lws *wsi, unsigned char c) { static const unsigned char methods[] = { WSI_TOKEN_GET_URI, @@ -273,7 +279,7 @@ int libwebsocket_parse( issue_char(wsi, '%'); wsi->u.hdr.ues = URIES_IDLE; /* regurgitate + assess */ - if (libwebsocket_parse(context, wsi, wsi->u.hdr.esc_stash) < 0) + if (lws_parse(context, wsi, wsi->u.hdr.esc_stash) < 0) return -1; /* continue on to assess c */ break; @@ -564,13 +570,13 @@ set_parsing_complete: * mode. */ -LWS_VISIBLE int lws_frame_is_binary(struct libwebsocket *wsi) +LWS_VISIBLE int lws_frame_is_binary(struct lws *wsi) { return wsi->u.ws.frame_is_binary; } int -libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c) +lws_rx_sm(struct lws *wsi, unsigned char c) { struct lws_tokens eff_buf; int ret = 0; @@ -921,7 +927,7 @@ process_as_ping: wsi->u.ws.ping_pending_flag = 1; /* get it sent as soon as possible */ - libwebsocket_callback_on_writable(wsi->protocol->owning_server, wsi); + lws_callback_on_writable(wsi->protocol->owning_server, wsi); ping_drop: wsi->u.ws.rx_user_buffer_head = 0; return 0; @@ -966,7 +972,7 @@ ping_drop: /* * No it's real payload, pass it up to the user callback. * It's nicely buffered with the pre-padding taken care of - * so it can be sent straight out again using libwebsocket_write + * so it can be sent straight out again using lws_write */ eff_buf.token = &wsi->u.ws.rx_user_buffer[ @@ -977,7 +983,8 @@ ping_drop: LWS_EXT_CALLBACK_PAYLOAD_RX, &eff_buf, 0) < 0) return -1; - if (eff_buf.token_len > 0) { + if (eff_buf.token_len > 0 || + callback_action == LWS_CALLBACK_RECEIVE_PONG) { eff_buf.token[eff_buf.token_len] = '\0'; if (wsi->protocol->callback) { @@ -989,7 +996,7 @@ ping_drop: wsi->protocol->callback, wsi->protocol->owning_server, wsi, - (enum libwebsocket_callback_reasons)callback_action, + (enum lws_callback_reasons)callback_action, wsi->user_space, eff_buf.token, eff_buf.token_len); @@ -1013,7 +1020,7 @@ illegal_ctl_length: /** - * libwebsockets_remaining_packet_payload() - Bytes to come before "overall" + * lws_remaining_packet_payload() - Bytes to come before "overall" * rx packet is complete * @wsi: Websocket instance (available from user callback) * @@ -1023,14 +1030,14 @@ illegal_ctl_length: * additionally when it hits a built-in limit. The LWS_CALLBACK_RECEIVE * callback handler can use this API to find out if the buffer it has just * been given is the last piece of a "complete packet" from the client -- - * when that is the case libwebsockets_remaining_packet_payload() will return + * when that is the case lws_remaining_packet_payload() will return * 0. * * Many protocols won't care becuse their packets are always small. */ LWS_VISIBLE size_t -libwebsockets_remaining_packet_payload(struct libwebsocket *wsi) +lws_remaining_packet_payload(struct lws *wsi) { return wsi->u.ws.rx_packet_length; } diff --git a/lib/pollfd.c b/lib/pollfd.c index 08fc40582..79a2c8827 100644 --- a/lib/pollfd.c +++ b/lib/pollfd.c @@ -22,10 +22,10 @@ #include "private-libwebsockets.h" int -insert_wsi_socket_into_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi) +insert_wsi_socket_into_fds(struct lws_context *context, + struct lws *wsi) { - struct libwebsocket_pollargs pa = { wsi->sock, LWS_POLLIN, 0 }; + struct lws_pollargs pa = { wsi->sock, LWS_POLLIN, 0 }; if (context->fds_count >= context->max_fds) { lwsl_err("Too many fds (%d)\n", context->max_fds); @@ -47,7 +47,7 @@ insert_wsi_socket_into_fds(struct libwebsocket_context *context, // wsi, wsi->sock, context->fds_count); if (context->protocols[0].callback(context, wsi, - LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *) &pa, 0)) + LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *) &pa, 1)) return -1; insert_wsi(context, wsi); @@ -63,18 +63,18 @@ insert_wsi_socket_into_fds(struct libwebsocket_context *context, return -1; if (context->protocols[0].callback(context, wsi, - LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *)&pa, 0)) + LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *)&pa, 1)) return -1; return 0; } int -remove_wsi_socket_from_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi) +remove_wsi_socket_from_fds(struct lws_context *context, + struct lws *wsi) { int m; - struct libwebsocket_pollargs pa = { wsi->sock, 0, 0 }; + struct lws_pollargs pa = { wsi->sock, 0, 0 }; lws_libev_io(context, wsi, LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE); @@ -92,7 +92,7 @@ remove_wsi_socket_from_fds(struct libwebsocket_context *context, wsi, wsi->sock, wsi->position_in_fds_table); if (context->protocols[0].callback(context, wsi, - LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *)&pa, 0)) + LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *)&pa, 1)) return -1; m = wsi->position_in_fds_table; /* replace the contents for this */ @@ -123,20 +123,20 @@ remove_wsi_socket_from_fds(struct libwebsocket_context *context, } if (context->protocols[0].callback(context, wsi, LWS_CALLBACK_UNLOCK_POLL, - wsi->user_space, (void *) &pa, 0)) + wsi->user_space, (void *) &pa, 1)) return -1; return 0; } int -lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or) +lws_change_pollfd(struct lws *wsi, int _and, int _or) { - struct libwebsocket_context *context; + struct lws_context *context; int tid; int sampled_tid; - struct libwebsocket_pollfd *pfd; - struct libwebsocket_pollargs pa; + struct lws_pollfd *pfd; + struct lws_pollargs pa; if (!wsi || !wsi->protocol || wsi->position_in_fds_table < 0) return 1; @@ -167,7 +167,10 @@ lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or) * ... and the service thread is waiting ... * then cancel it to force a restart with our changed events */ - if (pa.prev_events != pa.events) { +#if LWS_POSIX + if (pa.prev_events != pa.events) +#endif + { if (lws_plat_change_pollfd(context, wsi, pfd)) { lwsl_info("%s failed\n", __func__); @@ -181,7 +184,7 @@ lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or) if (tid == -1) return -1; if (tid != sampled_tid) - libwebsocket_cancel_service(context); + lws_cancel_service(context); } } @@ -194,7 +197,7 @@ lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or) /** - * libwebsocket_callback_on_writable() - Request a callback when this socket + * lws_callback_on_writable() - Request a callback when this socket * becomes able to be written to without * blocking * @@ -203,11 +206,11 @@ lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or) */ LWS_VISIBLE int -libwebsocket_callback_on_writable(struct libwebsocket_context *context, - struct libwebsocket *wsi) +lws_callback_on_writable(struct lws_context *context, + struct lws *wsi) { #ifdef LWS_USE_HTTP2 - struct libwebsocket *network_wsi, *wsi2; + struct lws *network_wsi, *wsi2; int already; lwsl_info("%s: %p\n", __func__, wsi); @@ -272,7 +275,7 @@ network_sock: } /** - * libwebsocket_callback_on_writable_all_protocol() - Request a callback for + * lws_callback_on_writable_all_protocol() - Request a callback for * all connections using the given protocol when it * becomes possible to write to each socket without * blocking in turn. @@ -281,19 +284,19 @@ network_sock: */ LWS_VISIBLE int -libwebsocket_callback_on_writable_all_protocol( - const struct libwebsocket_protocols *protocol) +lws_callback_on_writable_all_protocol( + const struct lws_protocols *protocol) { - struct libwebsocket_context *context = protocol->owning_server; + struct lws_context *context = protocol->owning_server; int n; - struct libwebsocket *wsi; + struct lws *wsi; for (n = 0; n < context->fds_count; n++) { wsi = wsi_from_fd(context,context->fds[n].fd); if (!wsi) continue; if (wsi->protocol == protocol) - libwebsocket_callback_on_writable(context, wsi); + lws_callback_on_writable(context, wsi); } return 0; diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index 0d2ca2ba8..c91ff9928 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef LWS_HAVE_SYS_STAT_H #include @@ -294,7 +295,7 @@ extern "C" { #define SPEC_LATEST_SUPPORTED 13 #endif #ifndef AWAITING_TIMEOUT -#define AWAITING_TIMEOUT 20 +#define AWAITING_TIMEOUT 5 #endif #ifndef CIPHERS_LIST_STRING #define CIPHERS_LIST_STRING "DEFAULT" @@ -429,39 +430,39 @@ enum { LWS_RXFLOW_PENDING_CHANGE = (1 << 1), }; -struct libwebsocket_protocols; -struct libwebsocket; +struct lws_protocols; +struct lws; #ifdef LWS_USE_LIBEV struct lws_io_watcher { struct ev_io watcher; - struct libwebsocket_context* context; + struct lws_context* context; }; struct lws_signal_watcher { struct ev_signal watcher; - struct libwebsocket_context* context; + struct lws_context* context; }; #endif /* LWS_USE_LIBEV */ #ifdef _WIN32 #define LWS_FD_HASH(fd) ((fd ^ (fd >> 8) ^ (fd >> 16)) % FD_HASHTABLE_MODULUS) -struct libwebsocket_fd_hashtable { - struct libwebsocket **wsi; +struct lws_fd_hashtable { + struct lws **wsi; int length; }; #endif -struct libwebsocket_context { +struct lws_context { #ifdef _WIN32 WSAEVENT *events; #endif - struct libwebsocket_pollfd *fds; + struct lws_pollfd *fds; #ifdef _WIN32 /* different implementation between unix and windows */ - struct libwebsocket_fd_hashtable fd_hashtable[FD_HASHTABLE_MODULUS]; + struct lws_fd_hashtable fd_hashtable[FD_HASHTABLE_MODULUS]; #else - struct libwebsocket **lws_lookup; /* fd to wsi */ + struct lws **lws_lookup; /* fd to wsi */ #endif int fds_count; #ifdef LWS_USE_LIBEV @@ -522,15 +523,15 @@ struct libwebsocket_context { unsigned int user_supplied_ssl_ctx:1; SSL_CTX *ssl_ctx; SSL_CTX *ssl_client_ctx; - struct libwebsocket *pending_read_list; /* linked list */ + struct lws *pending_read_list; /* linked list */ #define lws_ssl_anybody_has_buffered_read(ctx) (ctx->use_ssl && ctx->pending_read_list) #else #define lws_ssl_anybody_has_buffered_read(ctx) (0) #endif - struct libwebsocket_protocols *protocols; + struct lws_protocols *protocols; int count_protocols; #ifndef LWS_NO_EXTENSIONS - struct libwebsocket_extension *extensions; + struct lws_extension *extensions; #endif struct libwebsocket_file_callbacks file_callbacks; struct lws_token_limits *token_limits; @@ -548,15 +549,15 @@ enum { #define LWS_LIBEV_ENABLED(context) (context->options & LWS_SERVER_OPTION_LIBEV) LWS_EXTERN void lws_feature_status_libev(struct lws_context_creation_info *info); LWS_EXTERN void -lws_libev_accept(struct libwebsocket_context *context, - struct libwebsocket *new_wsi, lws_sockfd_type accept_fd); +lws_libev_accept(struct lws_context *context, + struct lws *new_wsi, lws_sockfd_type accept_fd); LWS_EXTERN void -lws_libev_io(struct libwebsocket_context *context, - struct libwebsocket *wsi, int flags); +lws_libev_io(struct lws_context *context, + struct lws *wsi, int flags); LWS_EXTERN int -lws_libev_init_fd_table(struct libwebsocket_context *context); +lws_libev_init_fd_table(struct lws_context *context); LWS_EXTERN void -lws_libev_run(struct libwebsocket_context *context); +lws_libev_run(struct lws_context *context); #else #define LWS_LIBEV_ENABLED(context) (0) #ifdef LWS_POSIX @@ -572,7 +573,8 @@ lws_libev_run(struct libwebsocket_context *context); #endif #ifdef LWS_USE_IPV6 -#define LWS_IPV6_ENABLED(context) (!(context->options & LWS_SERVER_OPTION_DISABLE_IPV6)) +#define LWS_IPV6_ENABLED(context) \ + (!(context->options & LWS_SERVER_OPTION_DISABLE_IPV6)) #else #define LWS_IPV6_ENABLED(context) (0) #endif @@ -612,11 +614,11 @@ struct lws_fragments { * all have a pointer to allocated_headers struct as their first member. * * It means for allocated_headers access, the three union paths can all be - * used interchangably to access the same data + * used interchangeably to access the same data */ struct allocated_headers { - unsigned short next_frag_index; + unsigned char next_frag_index; unsigned short pos; unsigned char frag_index[WSI_TOKEN_COUNT]; struct lws_fragments frags[WSI_TOKEN_COUNT * 2]; @@ -644,7 +646,6 @@ struct _lws_http_mode_related { unsigned int content_remain; }; - #ifdef LWS_USE_HTTP2 enum lws_http2_settings { @@ -746,8 +747,8 @@ struct _lws_http2_related { struct http2_settings my_settings; struct http2_settings peer_settings; - struct libwebsocket *parent_wsi; - struct libwebsocket *next_child_wsi; + struct lws *parent_wsi; + struct lws *next_child_wsi; struct hpack_dynamic_table *hpack_dyn_table; @@ -756,7 +757,7 @@ struct _lws_http2_related { /* frame */ unsigned int length; unsigned int stream_id; - struct libwebsocket *stream_wsi; + struct lws *stream_wsi; unsigned char type; unsigned char flags; unsigned char frame_state; @@ -833,7 +834,7 @@ struct _lws_websocket_related { unsigned char ping_pending_flag; }; -struct libwebsocket { +struct lws { /* lifetime members */ @@ -841,10 +842,9 @@ struct libwebsocket { struct lws_io_watcher w_read; struct lws_io_watcher w_write; #endif /* LWS_USE_LIBEV */ - const struct libwebsocket_protocols *protocol; + const struct lws_protocols *protocol; #ifndef LWS_NO_EXTENSIONS - struct libwebsocket_extension * - active_extensions[LWS_MAX_EXTENSIONS_ACTIVE]; + struct lws_extension *active_extensions[LWS_MAX_EXTENSIONS_ACTIVE]; void *active_extensions_user[LWS_MAX_EXTENSIONS_ACTIVE]; unsigned char count_active_extensions; unsigned int extension_data_pending:1; @@ -855,7 +855,7 @@ struct libwebsocket { char mode; /* enum connection_mode */ char state; /* enum lws_connection_states */ char lws_rx_parse_state; /* enum lws_rx_parse_state */ - char rx_frame_type; /* enum libwebsocket_write_protocol */ + char rx_frame_type; /* enum lws_write_protocol */ unsigned int hdr_parsing_completed:1; unsigned int user_space_externally_allocated:1; @@ -897,7 +897,7 @@ struct libwebsocket { #ifdef LWS_OPENSSL_SUPPORT SSL *ssl; BIO *client_bio; - struct libwebsocket *pending_read_list_prev, *pending_read_list_next; + struct lws *pending_read_list_prev, *pending_read_list_next; unsigned int use_ssl:2; unsigned int upgraded:1; #endif @@ -910,54 +910,56 @@ struct libwebsocket { LWS_EXTERN int log_level; LWS_EXTERN void -libwebsocket_close_and_free_session(struct libwebsocket_context *context, - struct libwebsocket *wsi, enum lws_close_status); +lws_close_and_free_session(struct lws_context *context, + struct lws *wsi, enum lws_close_status); LWS_EXTERN int -remove_wsi_socket_from_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi); +remove_wsi_socket_from_fds(struct lws_context *context, struct lws *wsi); LWS_EXTERN int -lws_rxflow_cache(struct libwebsocket *wsi, unsigned char *buf, int n, int len); +lws_rxflow_cache(struct lws *wsi, unsigned char *buf, int n, int len); #ifndef LWS_LATENCY -static inline void lws_latency(struct libwebsocket_context *context, - struct libwebsocket *wsi, const char *action, - int ret, int completion) { do { (void)context; (void)wsi; (void)action; (void)ret; (void)completion; } while (0); } -static inline void lws_latency_pre(struct libwebsocket_context *context, - struct libwebsocket *wsi) { do { (void)context; (void)wsi; } while (0); } +static inline void +lws_latency(struct lws_context *context, struct lws *wsi, const char *action, + int ret, int completion) { + do { (void)context; (void)wsi; (void)action; (void)ret; (void)completion; + } while (0); +} +static inline void +lws_latency_pre(struct lws_context *context, struct lws *wsi) { + do { (void)context; (void)wsi; } while (0); +} #else #define lws_latency_pre(_context, _wsi) lws_latency(_context, _wsi, NULL, 0, 0) extern void -lws_latency(struct libwebsocket_context *context, - struct libwebsocket *wsi, const char *action, - int ret, int completion); +lws_latency(struct lws_context *context, struct lws *wsi, const char *action, + int ret, int completion); #endif -LWS_EXTERN void lws_set_protocol_write_pending(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum lws_pending_protocol_send pend); +LWS_EXTERN void +lws_set_protocol_write_pending(struct lws_context *context, struct lws *wsi, + enum lws_pending_protocol_send pend); LWS_EXTERN int -libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c); +lws_client_rx_sm(struct lws *wsi, unsigned char c); LWS_EXTERN int -libwebsocket_parse(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char c); +lws_parse(struct lws_context *context, struct lws *wsi, unsigned char c); LWS_EXTERN int -lws_http_action(struct libwebsocket_context *context, struct libwebsocket *wsi); +lws_http_action(struct lws_context *context, struct lws *wsi); LWS_EXTERN int lws_b64_selftest(void); #if defined(_WIN32) || defined(MBED_OPERATORS) -LWS_EXTERN struct libwebsocket * -wsi_from_fd(struct libwebsocket_context *context, lws_sockfd_type fd); +LWS_EXTERN struct lws * +wsi_from_fd(struct lws_context *context, lws_sockfd_type fd); LWS_EXTERN int -insert_wsi(struct libwebsocket_context *context, struct libwebsocket *wsi); +insert_wsi(struct lws_context *context, struct lws *wsi); LWS_EXTERN int -delete_from_fd(struct libwebsocket_context *context, lws_sockfd_type fd); +delete_from_fd(struct lws_context *context, lws_sockfd_type fd); #else #define wsi_from_fd(A,B) A->lws_lookup[B] #define insert_wsi(A,B) A->lws_lookup[B->sock]=B @@ -965,31 +967,29 @@ delete_from_fd(struct libwebsocket_context *context, lws_sockfd_type fd); #endif LWS_EXTERN int -insert_wsi_socket_into_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi); +insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi); LWS_EXTERN int -lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len); +lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len); LWS_EXTERN int -libwebsocket_service_timeout_check(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned int sec); +lws_service_timeout_check(struct lws_context *context, + struct lws *wsi, unsigned int sec); -LWS_EXTERN struct libwebsocket * -libwebsocket_client_connect_2(struct libwebsocket_context *context, - struct libwebsocket *wsi); +LWS_EXTERN struct lws * +lws_client_connect_2(struct lws_context *context, struct lws *wsi); -LWS_EXTERN struct libwebsocket * -libwebsocket_create_new_server_wsi(struct libwebsocket_context *context); +LWS_EXTERN struct lws * +lws_create_new_server_wsi(struct lws_context *context); LWS_EXTERN char * -libwebsockets_generate_client_handshake(struct libwebsocket_context *context, - struct libwebsocket *wsi, char *pkt); +lws_generate_client_handshake(struct lws_context *context, struct lws *wsi, + char *pkt); LWS_EXTERN int -lws_handle_POLLOUT_event(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd); +lws_handle_POLLOUT_event(struct lws_context *context, struct lws *wsi, + struct lws_pollfd *pollfd); /* * EXTENSIONS @@ -998,20 +998,19 @@ lws_handle_POLLOUT_event(struct libwebsocket_context *context, #ifndef LWS_NO_EXTENSIONS LWS_VISIBLE void lws_context_init_extensions(struct lws_context_creation_info *info, - struct libwebsocket_context *context); + struct lws_context *context); LWS_EXTERN int -lws_any_extension_handled(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons r, +lws_any_extension_handled(struct lws_context *context, struct lws *wsi, + enum lws_extension_callback_reasons r, void *v, size_t len); LWS_EXTERN int -lws_ext_callback_for_each_active(struct libwebsocket *wsi, int reason, - void *buf, int len); +lws_ext_callback_for_each_active(struct lws *wsi, int reason, + void *buf, int len); LWS_EXTERN int -lws_ext_callback_for_each_extension_type( - struct libwebsocket_context *context, struct libwebsocket *wsi, - int reason, void *arg, int len); +lws_ext_callback_for_each_extension_type(struct lws_context *context, + struct lws *wsi, int reason, + void *arg, int len); #else #define lws_any_extension_handled(_a, _b, _c, _d, _e) (0) #define lws_ext_callback_for_each_active(_a, _b, _c, _d) (0) @@ -1025,108 +1024,100 @@ lws_context_init_file_callbacks(struct lws_context_creation_info *info, struct libwebsocket_context *context); LWS_EXTERN int -lws_client_interpret_server_handshake(struct libwebsocket_context *context, - struct libwebsocket *wsi); +lws_client_interpret_server_handshake(struct lws_context *context, + struct lws *wsi); LWS_EXTERN int -libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c); +lws_rx_sm(struct lws *wsi, unsigned char c); LWS_EXTERN int -lws_issue_raw_ext_access(struct libwebsocket *wsi, - unsigned char *buf, size_t len); +lws_issue_raw_ext_access(struct lws *wsi, unsigned char *buf, size_t len); LWS_EXTERN int -_libwebsocket_rx_flow_control(struct libwebsocket *wsi); +_lws_rx_flow_control(struct lws *wsi); LWS_EXTERN void -lws_union_transition(struct libwebsocket *wsi, enum connection_mode mode); +lws_union_transition(struct lws *wsi, enum connection_mode mode); LWS_EXTERN int -user_callback_handle_rxflow(callback_function, - struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, - void *in, size_t len); +user_callback_handle_rxflow(callback_function, struct lws_context *context, + struct lws *wsi, enum lws_callback_reasons reason, + void *user, void *in, size_t len); #ifdef LWS_USE_HTTP2 -LWS_EXTERN struct libwebsocket *lws_http2_get_network_wsi(struct libwebsocket *wsi); -struct libwebsocket * lws_http2_get_nth_child(struct libwebsocket *wsi, int n); +LWS_EXTERN struct lws *lws_http2_get_network_wsi(struct lws *wsi); +struct lws * lws_http2_get_nth_child(struct lws *wsi, int n); LWS_EXTERN int -lws_http2_interpret_settings_payload(struct http2_settings *settings, unsigned char *buf, int len); +lws_http2_interpret_settings_payload(struct http2_settings *settings, + unsigned char *buf, int len); LWS_EXTERN void lws_http2_init(struct http2_settings *settings); LWS_EXTERN int -lws_http2_parser(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char c); -LWS_EXTERN int lws_http2_do_pps_send(struct libwebsocket_context *context, struct libwebsocket *wsi); -LWS_EXTERN int lws_http2_frame_write(struct libwebsocket *wsi, int type, int flags, unsigned int sid, unsigned int len, unsigned char *buf); -LWS_EXTERN struct libwebsocket * -lws_http2_wsi_from_id(struct libwebsocket *wsi, unsigned int sid); -LWS_EXTERN int lws_hpack_interpret(struct libwebsocket_context *context, - struct libwebsocket *wsi, +lws_http2_parser(struct lws_context *context, + struct lws *wsi, unsigned char c); +LWS_EXTERN int lws_http2_do_pps_send(struct lws_context *context, + struct lws *wsi); +LWS_EXTERN int lws_http2_frame_write(struct lws *wsi, int type, int flags, + unsigned int sid, unsigned int len, + unsigned char *buf); +LWS_EXTERN struct lws * +lws_http2_wsi_from_id(struct lws *wsi, unsigned int sid); +LWS_EXTERN int lws_hpack_interpret(struct lws_context *context, + struct lws *wsi, unsigned char c); LWS_EXTERN int -lws_add_http2_header_by_name(struct libwebsocket_context *context, - struct libwebsocket *wsi, - const unsigned char *name, - const unsigned char *value, - int length, - unsigned char **p, - unsigned char *end); +lws_add_http2_header_by_name(struct lws_context *context, struct lws *wsi, + const unsigned char *name, + const unsigned char *value, int length, + unsigned char **p, unsigned char *end); LWS_EXTERN int -lws_add_http2_header_by_token(struct libwebsocket_context *context, - struct libwebsocket *wsi, +lws_add_http2_header_by_token(struct lws_context *context, struct lws *wsi, enum lws_token_indexes token, - const unsigned char *value, - int length, - unsigned char **p, - unsigned char *end); + const unsigned char *value, int length, + unsigned char **p, unsigned char *end); LWS_EXTERN int -lws_add_http2_header_status(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned int code, - unsigned char **p, +lws_add_http2_header_status(struct lws_context *context, struct lws *wsi, + unsigned int code, unsigned char **p, unsigned char *end); LWS_EXTERN -void lws_http2_configure_if_upgraded(struct libwebsocket *wsi); +void lws_http2_configure_if_upgraded(struct lws *wsi); #else #define lws_http2_configure_if_upgraded(x) #endif LWS_EXTERN int -lws_plat_set_socket_options(struct libwebsocket_context *context, lws_sockfd_type fd); +lws_plat_set_socket_options(struct lws_context *context, lws_sockfd_type fd); LWS_EXTERN int -lws_allocate_header_table(struct libwebsocket *wsi); +lws_allocate_header_table(struct lws *wsi); LWS_EXTERN int -lws_free_header_table(struct libwebsocket *wsi); +lws_free_header_table(struct lws *wsi); LWS_EXTERN char * -lws_hdr_simple_ptr(struct libwebsocket *wsi, enum lws_token_indexes h); +lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h); LWS_EXTERN int -lws_hdr_simple_create(struct libwebsocket *wsi, +lws_hdr_simple_create(struct lws *wsi, enum lws_token_indexes h, const char *s); LWS_EXTERN int -libwebsocket_ensure_user_space(struct libwebsocket *wsi); +lws_ensure_user_space(struct lws *wsi); LWS_EXTERN int -lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or); +lws_change_pollfd(struct lws *wsi, int _and, int _or); #ifndef LWS_NO_SERVER int lws_context_init_server(struct lws_context_creation_info *info, - struct libwebsocket_context *context); -LWS_EXTERN int handshake_0405(struct libwebsocket_context *context, - struct libwebsocket *wsi); + struct lws_context *context); LWS_EXTERN int -libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi, - unsigned char *buf, size_t len); +handshake_0405(struct lws_context *context, struct lws *wsi); +LWS_EXTERN int +lws_interpret_incoming_packet(struct lws *wsi, unsigned char *buf, size_t len); LWS_EXTERN void -lws_server_get_canonical_hostname(struct libwebsocket_context *context, - struct lws_context_creation_info *info); +lws_server_get_canonical_hostname(struct lws_context *context, + struct lws_context_creation_info *info); #else #define lws_context_init_server(_a, _b) (0) -#define libwebsocket_interpret_incoming_packet(_a, _b, _c) (0) +#define lws_interpret_incoming_packet(_a, _b, _c) (0) #define lws_server_get_canonical_hostname(_a, _b) #endif @@ -1137,8 +1128,9 @@ LWS_EXTERN int get_daemonize_pid(); #endif #if !defined(MBED_OPERATORS) -LWS_EXTERN int interface_to_sa(struct libwebsocket_context *context, - const char *ifname, struct sockaddr_in *addr, size_t addrlen); +LWS_EXTERN int +interface_to_sa(struct lws_context *context, const char *ifname, + struct sockaddr_in *addr, size_t addrlen); #endif LWS_EXTERN void lwsl_emit_stderr(int level, const char *line); @@ -1163,86 +1155,90 @@ enum lws_ssl_capable_status { #define LWS_SSL_ENABLED(context) (context->use_ssl) LWS_EXTERN int openssl_websocket_private_data_index; LWS_EXTERN int -lws_ssl_capable_read(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char *buf, int len); +lws_ssl_capable_read(struct lws_context *context, + struct lws *wsi, unsigned char *buf, int len); LWS_EXTERN int -lws_ssl_capable_write(struct libwebsocket *wsi, unsigned char *buf, int len); +lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, int len); LWS_EXTERN int -lws_ssl_pending(struct libwebsocket *wsi); +lws_ssl_pending(struct lws *wsi); LWS_EXTERN int -lws_server_socket_service_ssl(struct libwebsocket_context *context, - struct libwebsocket **wsi, struct libwebsocket *new_wsi, - lws_sockfd_type accept_fd, struct libwebsocket_pollfd *pollfd); +lws_server_socket_service_ssl(struct lws_context *context, struct lws **wsi, + struct lws *new_wsi, lws_sockfd_type accept_fd, + struct lws_pollfd *pollfd); LWS_EXTERN int -lws_ssl_close(struct libwebsocket *wsi); +lws_ssl_close(struct lws *wsi); LWS_EXTERN void -lws_ssl_context_destroy(struct libwebsocket_context *context); +lws_ssl_context_destroy(struct lws_context *context); LWS_VISIBLE void -lws_ssl_remove_wsi_from_buffered_list(struct libwebsocket_context *context, - struct libwebsocket *wsi); +lws_ssl_remove_wsi_from_buffered_list(struct lws_context *context, + struct lws *wsi); #ifndef LWS_NO_SERVER LWS_EXTERN int lws_context_init_server_ssl(struct lws_context_creation_info *info, - struct libwebsocket_context *context); + struct lws_context *context); #else #define lws_context_init_server_ssl(_a, _b) (0) #endif LWS_EXTERN void -lws_ssl_destroy(struct libwebsocket_context *context); +lws_ssl_destroy(struct lws_context *context); /* HTTP2-related */ #ifdef LWS_USE_HTTP2 LWS_EXTERN void -lws_context_init_http2_ssl(struct libwebsocket_context *context); +lws_context_init_http2_ssl(struct lws_context *context); #else #define lws_context_init_http2_ssl(_a) #endif #endif LWS_EXTERN int -lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char *buf, int len); +lws_ssl_capable_read_no_ssl(struct lws_context *context, + struct lws *wsi, unsigned char *buf, int len); LWS_EXTERN int -lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len); +lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len); LWS_EXTERN int -lws_ssl_pending_no_ssl(struct libwebsocket *wsi); +lws_ssl_pending_no_ssl(struct lws *wsi); #ifndef LWS_NO_CLIENT - LWS_EXTERN int lws_client_socket_service( - struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd); +LWS_EXTERN int lws_client_socket_service(struct lws_context *context, + struct lws *wsi, + struct lws_pollfd *pollfd); #ifdef LWS_OPENSSL_SUPPORT - LWS_EXTERN int lws_context_init_client_ssl(struct lws_context_creation_info *info, - struct libwebsocket_context *context); +LWS_EXTERN int +lws_context_init_client_ssl(struct lws_context_creation_info *info, + struct lws_context *context); #else #define lws_context_init_client_ssl(_a, _b) (0) #endif - LWS_EXTERN int lws_handshake_client(struct libwebsocket *wsi, unsigned char **buf, size_t len); - LWS_EXTERN void - libwebsockets_decode_ssl_error(void); +LWS_EXTERN int +lws_handshake_client(struct lws *wsi, unsigned char **buf, size_t len); +LWS_EXTERN void +lws_decode_ssl_error(void); #else #define lws_context_init_client_ssl(_a, _b) (0) #define lws_handshake_client(_a, _b, _c) (0) #endif #ifndef LWS_NO_SERVER - LWS_EXTERN int lws_server_socket_service( - struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd); - LWS_EXTERN int _libwebsocket_rx_flow_control(struct libwebsocket *wsi); - LWS_EXTERN int lws_handshake_server(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char **buf, size_t len); +LWS_EXTERN int +lws_server_socket_service(struct lws_context *context, struct lws *wsi, + struct lws_pollfd *pollfd); +LWS_EXTERN int +_lws_rx_flow_control(struct lws *wsi); +LWS_EXTERN int +lws_handshake_server(struct lws_context *context, + struct lws *wsi, unsigned char **buf, size_t len); #else #define lws_server_socket_service(_a, _b, _c) (0) -#define _libwebsocket_rx_flow_control(_a) (0) +#define _lws_rx_flow_control(_a) (0) #define lws_handshake_server(_a, _b, _c, _d) (0) #endif -LWS_EXTERN int libwebsockets_get_addresses(struct libwebsocket_context *context, - void *ads, char *name, int name_len, - char *rip, int rip_len); +LWS_EXTERN int +lws_get_addresses(struct lws_context *context, void *ads, char *name, + int name_len, char *rip, int rip_len); /* * custom allocator @@ -1257,35 +1253,33 @@ lws_zalloc(size_t size); #define lws_free(P) lws_realloc(P, 0) #define lws_free2(P) do { lws_realloc(P, 0); (P) = NULL; } while(0) -/* - * lws_plat_ - */ +/* lws_plat_ */ LWS_EXTERN void -lws_plat_delete_socket_from_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi, int m); +lws_plat_delete_socket_from_fds(struct lws_context *context, + struct lws *wsi, int m); LWS_EXTERN void -lws_plat_insert_socket_into_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi); +lws_plat_insert_socket_into_fds(struct lws_context *context, + struct lws *wsi); LWS_EXTERN void -lws_plat_service_periodic(struct libwebsocket_context *context); +lws_plat_service_periodic(struct lws_context *context); LWS_EXTERN int -lws_plat_change_pollfd(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd); +lws_plat_change_pollfd(struct lws_context *context, struct lws *wsi, + struct lws_pollfd *pfd); LWS_EXTERN int lws_plat_context_early_init(void); LWS_EXTERN void -lws_plat_context_early_destroy(struct libwebsocket_context *context); +lws_plat_context_early_destroy(struct lws_context *context); LWS_EXTERN void -lws_plat_context_late_destroy(struct libwebsocket_context *context); +lws_plat_context_late_destroy(struct lws_context *context); LWS_EXTERN int -lws_poll_listen_fd(struct libwebsocket_pollfd *fd); +lws_poll_listen_fd(struct lws_pollfd *fd); LWS_EXTERN int -lws_plat_service(struct libwebsocket_context *context, int timeout_ms); +lws_plat_service(struct lws_context *context, int timeout_ms); LWS_EXTERN int -lws_plat_init_lookup(struct libwebsocket_context *context); +lws_plat_init_lookup(struct lws_context *context); LWS_EXTERN int -lws_plat_init_fd_tables(struct libwebsocket_context *context); +lws_plat_init_fd_tables(struct lws_context *context); LWS_EXTERN void lws_plat_drop_app_privileges(struct lws_context_creation_info *info); LWS_EXTERN unsigned long long diff --git a/lib/server-handshake.c b/lib/server-handshake.c index 298fae438..9862eff9a 100644 --- a/lib/server-handshake.c +++ b/lib/server-handshake.c @@ -24,13 +24,13 @@ #define LWS_CPYAPP(ptr, str) { strcpy(ptr, str); ptr += strlen(str); } #ifndef LWS_NO_EXTENSIONS LWS_VISIBLE int -lws_extension_server_handshake(struct libwebsocket_context *context, - struct libwebsocket *wsi, char **p) +lws_extension_server_handshake(struct lws_context *context, + struct lws *wsi, char **p) { int n; char *c; char ext_name[128]; - struct libwebsocket_extension *ext; + struct lws_extension *ext; int ext_count = 0; int more = 1; @@ -156,7 +156,7 @@ lws_extension_server_handshake(struct libwebsocket_context *context, } #endif int -handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi) +handshake_0405(struct lws_context *context, struct lws *wsi) { unsigned char hash[20]; int n; @@ -185,7 +185,7 @@ handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi) "%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11", lws_hdr_simple_ptr(wsi, WSI_TOKEN_KEY)); - libwebsockets_SHA1(context->service_buffer, n, hash); + lws_SHA1(context->service_buffer, n, hash); accept_len = lws_b64_encode_string((char *)hash, 20, (char *)context->service_buffer, @@ -196,7 +196,7 @@ handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi) } /* allocate the per-connection user memory (if any) */ - if (libwebsocket_ensure_user_space(wsi)) + if (lws_ensure_user_space(wsi)) goto bail; /* create the response packet */ @@ -245,7 +245,7 @@ handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi) #ifdef DEBUG fwrite(response, 1, p - response, stderr); #endif - n = libwebsocket_write(wsi, (unsigned char *)response, + n = lws_write(wsi, (unsigned char *)response, p - response, LWS_WRITE_HTTP_HEADERS); if (n != (p - response)) { lwsl_debug("handshake_0405: ERROR writing to socket\n"); @@ -264,7 +264,13 @@ handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi) if (wsi->protocol->callback) wsi->protocol->callback(wsi->protocol->owning_server, wsi, LWS_CALLBACK_ESTABLISHED, - wsi->user_space, NULL, 0); + wsi->user_space, +#ifdef LWS_OPENSSL_SUPPORT + wsi->ssl, +#else + NULL, +#endif + 0); return 0; diff --git a/lib/server.c b/lib/server.c index d5d23bd49..3757d80f5 100644 --- a/lib/server.c +++ b/lib/server.c @@ -23,21 +23,20 @@ #include "private-libwebsockets.h" int lws_context_init_server(struct lws_context_creation_info *info, - struct libwebsocket_context *context) + struct lws_context *context) { - lws_sockfd_type sockfd; -#if LWS_POSIX - int n; - struct sockaddr_in sin; - socklen_t len = sizeof(sin); #ifdef LWS_USE_IPV6 struct sockaddr_in6 serv_addr6; #endif +#if LWS_POSIX struct sockaddr_in serv_addr4; + socklen_t len = sizeof(struct sockaddr); + struct sockaddr_in sin; struct sockaddr *v; - int opt = 1; + int n, opt = 1; #endif - struct libwebsocket *wsi; + lws_sockfd_type sockfd; + struct lws *wsi; /* set up our external listening socket we serve on */ @@ -57,7 +56,6 @@ int lws_context_init_server(struct lws_context_creation_info *info, sockfd = mbed3_create_tcp_stream_socket(); if (!lws_sockfd_valid(sockfd)) { #endif - lwsl_err("ERROR opening socket\n"); return 1; } @@ -67,7 +65,7 @@ int lws_context_init_server(struct lws_context_creation_info *info, * allow us to restart even if old sockets in TIME_WAIT */ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, - (const void *)&opt, sizeof(opt)) < 0) { + (const void *)&opt, sizeof(opt)) < 0) { compatible_close(sockfd); return 1; } @@ -121,7 +119,7 @@ int lws_context_init_server(struct lws_context_creation_info *info, context->listen_port = info->port; - wsi = lws_zalloc(sizeof(struct libwebsocket)); + wsi = lws_zalloc(sizeof(struct lws)); if (wsi == NULL) { lwsl_err("Out of mem\n"); compatible_close(sockfd); @@ -151,9 +149,9 @@ int lws_context_init_server(struct lws_context_creation_info *info, } int -_libwebsocket_rx_flow_control(struct libwebsocket *wsi) +_lws_rx_flow_control(struct lws *wsi) { - struct libwebsocket_context *context = wsi->protocol->owning_server; + struct lws_context *context = wsi->protocol->owning_server; /* there is no pending change */ if (!(wsi->rxflow_change_to & LWS_RXFLOW_PENDING_CHANGE)) @@ -162,7 +160,7 @@ _libwebsocket_rx_flow_control(struct libwebsocket *wsi) /* stuff is still buffered, not ready to really accept new input */ if (wsi->rxflow_buffer) { /* get ourselves called back to deal with stashed buffer */ - libwebsocket_callback_on_writable(context, wsi); + lws_callback_on_writable(context, wsi); return 0; } @@ -187,18 +185,18 @@ _libwebsocket_rx_flow_control(struct libwebsocket *wsi) return 0; } -int lws_http_action(struct libwebsocket_context *context, - struct libwebsocket *wsi) +int lws_http_action(struct lws_context *context, struct lws *wsi) { - char *uri_ptr = NULL; - int uri_len = 0; - enum http_version request_version; enum http_connection_type connection_type; - int http_version_len; + enum http_version request_version; char content_length_str[32]; + unsigned int n, count = 0; char http_version_str[10]; char http_conn_str[20]; - unsigned int n, count = 0; + int http_version_len; + char *uri_ptr = NULL; + int uri_len = 0; + static const unsigned char methods[] = { WSI_TOKEN_GET_URI, WSI_TOKEN_POST_URI, @@ -234,7 +232,7 @@ int lws_http_action(struct libwebsocket_context *context, goto bail_nuke_ah; } - if (libwebsocket_ensure_user_space(wsi)) + if (lws_ensure_user_space(wsi)) goto bail_nuke_ah; for (n = 0; n < ARRAY_SIZE(methods); n++) @@ -293,23 +291,19 @@ int lws_http_action(struct libwebsocket_context *context, } wsi->u.http.connection_type = connection_type; - n = 0; - if (wsi->protocol->callback) - n = wsi->protocol->callback(context, wsi, - LWS_CALLBACK_FILTER_HTTP_CONNECTION, - wsi->user_space, uri_ptr, uri_len); + n = wsi->protocol->callback(context, wsi, + LWS_CALLBACK_FILTER_HTTP_CONNECTION, + wsi->user_space, uri_ptr, uri_len); if (!n) { /* * if there is content supposed to be coming, * put a timeout on it having arrived */ - libwebsocket_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT, - AWAITING_TIMEOUT); + lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT, + AWAITING_TIMEOUT); - if (wsi->protocol->callback) - n = wsi->protocol->callback(context, wsi, - LWS_CALLBACK_HTTP, + n = wsi->protocol->callback(context, wsi, LWS_CALLBACK_HTTP, wsi->user_space, uri_ptr, uri_len); } @@ -325,7 +319,7 @@ int lws_http_action(struct libwebsocket_context *context, * HTTP keep-alive. No keep-alive header allocation for * ISSUING_FILE, as this uses HTTP/1.0. * - * In any case, return 0 and let libwebsocket_read decide how to + * In any case, return 0 and let lws_read decide how to * proceed based on state */ if (wsi->state != WSI_STATE_HTTP_ISSUING_FILE) @@ -343,31 +337,30 @@ bail_nuke_ah: } -int lws_handshake_server(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char **buf, size_t len) +int lws_handshake_server(struct lws_context *context, struct lws *wsi, + unsigned char **buf, size_t len) { struct allocated_headers *ah; - int protocol_len; + int protocol_len, n, hit; char protocol_list[128]; char protocol_name[32]; char *p; - int n, hit; /* LWS_CONNMODE_WS_SERVING */ while (len--) { - if (libwebsocket_parse(context, wsi, *(*buf)++)) { - lwsl_info("libwebsocket_parse failed\n"); + if (lws_parse(context, wsi, *(*buf)++)) { + lwsl_info("lws_parse failed\n"); goto bail_nuke_ah; } if (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE) continue; - lwsl_parser("libwebsocket_parse sees parsing complete\n"); + lwsl_parser("lws_parse sees parsing complete\n"); wsi->mode = LWS_CONNMODE_PRE_WS_SERVING_ACCEPT; - libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); + lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); /* is this websocket protocol or normal http 1.0? */ @@ -389,7 +382,7 @@ int lws_handshake_server(struct libwebsocket_context *context, } if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE), - "websocket")) + "websocket")) goto upgrade_ws; #ifdef LWS_USE_HTTP2 if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE), @@ -410,7 +403,8 @@ upgrade_h2c: p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP2_SETTINGS); /* convert the peer's HTTP-Settings */ - n = lws_b64_decode_string(p, protocol_list, sizeof(protocol_list)); + n = lws_b64_decode_string(p, protocol_list, + sizeof(protocol_list)); if (n < 0) { lwsl_parser("HTTP2_SETTINGS too long\n"); return 1; @@ -430,7 +424,8 @@ upgrade_h2c: /* HTTP2 union */ - lws_http2_interpret_settings_payload(&wsi->u.http2.peer_settings, (unsigned char *)protocol_list, n); + lws_http2_interpret_settings_payload(&wsi->u.http2.peer_settings, + (unsigned char *)protocol_list, n); strcpy(protocol_list, "HTTP/1.1 101 Switching Protocols\x0d\x0a" @@ -450,7 +445,7 @@ upgrade_h2c: upgrade_ws: if (!wsi->protocol) - lwsl_err("NULL protocol at libwebsocket_read\n"); + lwsl_err("NULL protocol at lws_read\n"); /* * It's websocket @@ -520,7 +515,7 @@ upgrade_ws: } /* allocate wsi->user storage */ - if (libwebsocket_ensure_user_space(wsi)) + if (lws_ensure_user_space(wsi)) goto bail_nuke_ah; /* @@ -579,7 +574,8 @@ upgrade_ws: } lwsl_info("Allocating RX buffer %d\n", n); #if LWS_POSIX - if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF, (const char *)&n, sizeof n)) { + if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF, + (const char *)&n, sizeof n)) { lwsl_warn("Failed to set SNDBUF to %d", n); return 1; } @@ -596,12 +592,12 @@ bail_nuke_ah: return 1; } -struct libwebsocket * -libwebsocket_create_new_server_wsi(struct libwebsocket_context *context) +struct lws * +lws_create_new_server_wsi(struct lws_context *context) { - struct libwebsocket *new_wsi; + struct lws *new_wsi; - new_wsi = lws_zalloc(sizeof(struct libwebsocket)); + new_wsi = lws_zalloc(sizeof(struct lws)); if (new_wsi == NULL) { lwsl_err("Out of memory for new connection\n"); return NULL; @@ -656,7 +652,7 @@ libwebsocket_create_new_server_wsi(struct libwebsocket_context *context) */ LWS_VISIBLE -int lws_http_transaction_completed(struct libwebsocket *wsi) +int lws_http_transaction_completed(struct lws *wsi) { /* if we can't go back to accept new headers, drop the connection */ if (wsi->u.http.connection_type != HTTP_CONNECTION_KEEP_ALIVE) { @@ -670,7 +666,7 @@ int lws_http_transaction_completed(struct libwebsocket *wsi) wsi->u.http.content_length = 0; /* He asked for it to stay alive indefinitely */ - libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); + lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); if (lws_allocate_header_table(wsi)) return 1; @@ -684,17 +680,16 @@ int lws_http_transaction_completed(struct libwebsocket *wsi) } LWS_VISIBLE -int lws_server_socket_service(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd) +int lws_server_socket_service(struct lws_context *context, + struct lws *wsi, struct lws_pollfd *pollfd) { - struct libwebsocket *new_wsi = NULL; lws_sockfd_type accept_fd = LWS_SOCK_INVALID; #if LWS_POSIX - socklen_t clilen; struct sockaddr_in cli_addr; + socklen_t clilen; #endif - int n; - int len; + struct lws *new_wsi = NULL; + int n, len; switch (wsi->mode) { @@ -709,10 +704,9 @@ int lws_server_socket_service(struct libwebsocket_context *context, if (wsi->truncated_send_len) { if (pollfd->revents & LWS_POLLOUT) if (lws_issue_raw(wsi, wsi->truncated_send_malloc + - wsi->truncated_send_offset, - wsi->truncated_send_len) < 0) { - lwsl_info("closing from socket service\n"); - return -1; + wsi->truncated_send_offset, + wsi->truncated_send_len) < 0) { + goto fail; } /* * we can't afford to allow input processing send @@ -726,8 +720,8 @@ int lws_server_socket_service(struct libwebsocket_context *context, if (pollfd->revents & LWS_POLLIN) { len = lws_ssl_capable_read(context, wsi, - context->service_buffer, - sizeof(context->service_buffer)); + context->service_buffer, + sizeof(context->service_buffer)); lwsl_debug("%s: read %d\r\n", __func__, len); switch (len) { case 0: @@ -737,10 +731,7 @@ int lws_server_socket_service(struct libwebsocket_context *context, lws_free_header_table(wsi); /* fallthru */ case LWS_SSL_CAPABLE_ERROR: - libwebsocket_close_and_free_session( - context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - return 0; + goto fail; case LWS_SSL_CAPABLE_MORE_SERVICE: goto try_pollout; } @@ -748,14 +739,17 @@ int lws_server_socket_service(struct libwebsocket_context *context, /* just ignore incoming if waiting for close */ if (wsi->state != WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE) { - /* hm this may want to send (via HTTP callback for example) */ - n = libwebsocket_read(context, wsi, - context->service_buffer, len); - if (n < 0) - /* we closed wsi */ - return 0; + /* + * hm this may want to send + * (via HTTP callback for example) + */ + n = lws_read(context, wsi, + context->service_buffer, len); + if (n < 0) /* we closed wsi */ + return 1; - /* hum he may have used up the writability above */ + /* hum he may have used up the + * writability above */ break; } } @@ -786,7 +780,7 @@ try_pollout: } /* >0 == completion, <0 == error */ - n = libwebsockets_serve_http_file_fragment(context, wsi); + n = lws_serve_http_file_fragment(context, wsi); if (n < 0 || (n > 0 && lws_http_transaction_completed(wsi))) goto fail; break; @@ -804,12 +798,13 @@ try_pollout: clilen = sizeof(cli_addr); lws_latency_pre(context, wsi); accept_fd = accept(pollfd->fd, (struct sockaddr *)&cli_addr, - &clilen); + &clilen); lws_latency(context, wsi, "unencrypted accept LWS_CONNMODE_SERVER_LISTENER", accept_fd, accept_fd >= 0); if (accept_fd < 0) { - if (LWS_ERRNO == LWS_EAGAIN || LWS_ERRNO == LWS_EWOULDBLOCK) { + if (LWS_ERRNO == LWS_EAGAIN || + LWS_ERRNO == LWS_EWOULDBLOCK) { lwsl_debug("accept asks to try again\n"); break; } @@ -836,7 +831,7 @@ try_pollout: break; } - new_wsi = libwebsocket_create_new_server_wsi(context); + new_wsi = lws_create_new_server_wsi(context); if (new_wsi == NULL) { compatible_close(accept_fd); break; @@ -845,9 +840,8 @@ try_pollout: new_wsi->sock = accept_fd; /* the transport is accepted... give him time to negotiate */ - libwebsocket_set_timeout(new_wsi, - PENDING_TIMEOUT_ESTABLISH_WITH_SERVER, - AWAITING_TIMEOUT); + lws_set_timeout(new_wsi, PENDING_TIMEOUT_ESTABLISH_WITH_SERVER, + AWAITING_TIMEOUT); #if LWS_POSIX == 0 mbed3_tcp_stream_accept(accept_fd, new_wsi); @@ -858,9 +852,9 @@ try_pollout: * set properties of the newly created wsi. There's no protocol * selected yet so we issue this to protocols[0] */ - (context->protocols[0].callback)(context, new_wsi, - LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED, NULL, NULL, 0); + LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED, + NULL, NULL, 0); lws_libev_accept(context, new_wsi, accept_fd); @@ -878,20 +872,18 @@ try_pollout: break; } - if (lws_server_socket_service_ssl(context, &wsi, new_wsi, - accept_fd, pollfd)) - goto fail; - - return 0; + if (!lws_server_socket_service_ssl(context, &wsi, new_wsi, accept_fd, + pollfd)) + return 0; fail: - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); + lws_close_and_free_session(context, wsi, LWS_CLOSE_STATUS_NOSTATUS); + return 1; } /** - * libwebsockets_serve_http_file() - Send a file back to the client using http + * lws_serve_http_file() - Send a file back to the client using http * @context: libwebsockets context * @wsi: Websocket instance (available from user callback) * @file: The file to issue over http @@ -909,34 +901,41 @@ fail: * the wsi should be left alone. */ -LWS_VISIBLE int libwebsockets_serve_http_file( - struct libwebsocket_context *context, - struct libwebsocket *wsi, const char *file, - const char *content_type, const char *other_headers, - int other_headers_len) +LWS_VISIBLE int lws_serve_http_file(struct lws_context *context, + struct lws *wsi, const char *file, + const char *content_type, + const char *other_headers, + int other_headers_len) { - unsigned char *response = context->service_buffer + LWS_SEND_BUFFER_PRE_PADDING; + unsigned char *response = context->service_buffer + + LWS_SEND_BUFFER_PRE_PADDING; unsigned char *p = response; unsigned char *end = p + sizeof(context->service_buffer) - - LWS_SEND_BUFFER_PRE_PADDING; + LWS_SEND_BUFFER_PRE_PADDING; int ret = 0; wsi->u.http.fd = context->file_callbacks.pfn_open(file, &wsi->u.http.filelen); if (wsi->u.http.fd == LWS_INVALID_FILE) { lwsl_err("Unable to open '%s'\n", file); - libwebsockets_return_http_status(context, wsi, - HTTP_STATUS_NOT_FOUND, NULL); + lws_return_http_status(context, wsi, HTTP_STATUS_NOT_FOUND, + NULL); return -1; } if (lws_add_http_header_status(context, wsi, 200, &p, end)) return -1; - if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_SERVER, (unsigned char *)"libwebsockets", 13, &p, end)) + if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_SERVER, + (unsigned char *)"libwebsockets", 13, + &p, end)) return -1; - if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, (unsigned char *)content_type, strlen(content_type), &p, end)) + if (lws_add_http_header_by_token(context, wsi, + WSI_TOKEN_HTTP_CONTENT_TYPE, + (unsigned char *)content_type, + strlen(content_type), &p, end)) return -1; - if (lws_add_http_header_content_length(context, wsi, wsi->u.http.filelen, &p, end)) + if (lws_add_http_header_content_length(context, wsi, + wsi->u.http.filelen, &p, end)) return -1; if (other_headers) { @@ -949,7 +948,7 @@ LWS_VISIBLE int libwebsockets_serve_http_file( if (lws_finalize_http_header(context, wsi, &p, end)) return -1; - ret = libwebsocket_write(wsi, response, + ret = lws_write(wsi, response, p - response, LWS_WRITE_HTTP_HEADERS); if (ret != (p - response)) { lwsl_err("_write returned %d from %d\n", ret, (p - response)); @@ -959,12 +958,12 @@ LWS_VISIBLE int libwebsockets_serve_http_file( wsi->u.http.filepos = 0; wsi->state = WSI_STATE_HTTP_ISSUING_FILE; - return libwebsockets_serve_http_file_fragment(context, wsi); + return lws_serve_http_file_fragment(context, wsi); } -int libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi, - unsigned char *buf, size_t len) +int lws_interpret_incoming_packet(struct lws *wsi, unsigned char *buf, + size_t len) { size_t n = 0; int m; @@ -991,7 +990,7 @@ int libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi, wsi->rxflow_pos++; /* process the byte */ - m = libwebsocket_rx_sm(wsi, buf[n++]); + m = lws_rx_sm(wsi, buf[n++]); if (m < 0) return -1; } @@ -1000,8 +999,8 @@ int libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi, } LWS_VISIBLE void -lws_server_get_canonical_hostname(struct libwebsocket_context *context, - struct lws_context_creation_info *info) +lws_server_get_canonical_hostname(struct lws_context *context, + struct lws_context_creation_info *info) { if (info->options & LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME) return; diff --git a/lib/service.c b/lib/service.c index 1b5dcf423..7c4ad54fe 100644 --- a/lib/service.c +++ b/lib/service.c @@ -22,8 +22,7 @@ #include "private-libwebsockets.h" static int -lws_calllback_as_writeable(struct libwebsocket_context *context, - struct libwebsocket *wsi) +lws_calllback_as_writeable(struct lws_context *context, struct lws *wsi) { int n; @@ -40,22 +39,20 @@ lws_calllback_as_writeable(struct libwebsocket_context *context, } lwsl_info("%s: %p (user=%p)\n", __func__, wsi, wsi->user_space); return user_callback_handle_rxflow(wsi->protocol->callback, context, - wsi, (enum libwebsocket_callback_reasons) n, - wsi->user_space, NULL, 0); + wsi, (enum lws_callback_reasons) n, + wsi->user_space, NULL, 0); } int -lws_handle_POLLOUT_event(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd) +lws_handle_POLLOUT_event(struct lws_context *context, struct lws *wsi, + struct lws_pollfd *pollfd) { - int n; + int write_type = LWS_WRITE_PONG; struct lws_tokens eff_buf; #ifdef LWS_USE_HTTP2 - struct libwebsocket *wsi2; + struct lws *wsi2; #endif - int ret; - int m; - int write_type = LWS_WRITE_PONG; + int ret, m, n; /* pending truncated sends have uber priority */ @@ -86,7 +83,7 @@ lws_handle_POLLOUT_event(struct libwebsocket_context *context, break; } wsi->pps = LWS_PPS_NONE; - libwebsocket_rx_flow_control(wsi, 1); + lws_rx_flow_control(wsi, 1); return 0; /* leave POLLOUT active */ } @@ -101,11 +98,9 @@ lws_handle_POLLOUT_event(struct libwebsocket_context *context, if (wsi->u.ws.payload_is_close) write_type = LWS_WRITE_CLOSE; - n = libwebsocket_write(wsi, - &wsi->u.ws.ping_payload_buf[ + n = lws_write(wsi, &wsi->u.ws.ping_payload_buf[ LWS_SEND_BUFFER_PRE_PADDING], - wsi->u.ws.ping_payload_len, - write_type); + wsi->u.ws.ping_payload_len, write_type); if (n < 0) return -1; @@ -263,7 +258,7 @@ user_service: wsi2->u.http2.requested_POLLOUT = 0; if (lws_calllback_as_writeable(context, wsi2)) { lwsl_debug("Closing POLLOUT child\n"); - libwebsocket_close_and_free_session(context, wsi2, + lws_close_and_free_session(context, wsi2, LWS_CLOSE_STATUS_NOSTATUS); } wsi2 = wsi; @@ -280,14 +275,15 @@ notify: int -libwebsocket_service_timeout_check(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned int sec) +lws_service_timeout_check(struct lws_context *context, + struct lws *wsi, unsigned int sec) { /* * if extensions want in on it (eg, we are a mux parent) * give them a chance to service child timeouts */ - if (lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_1HZ, NULL, sec) < 0) + if (lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_1HZ, + NULL, sec) < 0) return 0; if (!wsi->pending_timeout) @@ -298,7 +294,8 @@ libwebsocket_service_timeout_check(struct libwebsocket_context *context, * connection */ if ((time_t)sec > wsi->pending_timeout_limit) { - lwsl_info("wsi %p: TIMEDOUT WAITING on %d\n", (void *)wsi, wsi->pending_timeout); + lwsl_info("wsi %p: TIMEDOUT WAITING on %d\n", + (void *)wsi, wsi->pending_timeout); /* * Since he failed a timeout, he already had a chance to do * something and was unable to... that includes situations like @@ -307,15 +304,15 @@ libwebsocket_service_timeout_check(struct libwebsocket_context *context, * cleanup like flush partials. */ wsi->socket_is_permanently_unusable = 1; - libwebsocket_close_and_free_session(context, - wsi, LWS_CLOSE_STATUS_NOSTATUS); + lws_close_and_free_session(context, wsi, + LWS_CLOSE_STATUS_NOSTATUS); return 1; } return 0; } -int lws_rxflow_cache(struct libwebsocket *wsi, unsigned char *buf, int n, int len) +int lws_rxflow_cache(struct lws *wsi, unsigned char *buf, int n, int len) { /* his RX is flowcontrolled, don't send remaining now */ if (wsi->rxflow_buffer) { @@ -335,20 +332,20 @@ int lws_rxflow_cache(struct libwebsocket *wsi, unsigned char *buf, int n, int le } /** - * libwebsocket_service_fd() - Service polled socket with something waiting + * lws_service_fd() - Service polled socket with something waiting * @context: Websocket context * @pollfd: The pollfd entry describing the socket fd and which events * happened. * * This function takes a pollfd that has POLLIN or POLLOUT activity and * services it according to the state of the associated - * struct libwebsocket. + * struct lws. * * The one call deals with all "service" that might happen on a socket * including listen accepts, http files as well as websocket protocol. * * If a pollfd says it has something, you can just pass it to - * libwebsocket_serice_fd() whether it is a socket handled by lws or not. + * lws_service_fd() whether it is a socket handled by lws or not. * If it sees it is a lws socket, the traffic will be handled and * pollfd->revents will be zeroed now. * @@ -358,26 +355,26 @@ int lws_rxflow_cache(struct libwebsocket *wsi, unsigned char *buf, int n, int le */ LWS_VISIBLE int -libwebsocket_service_fd(struct libwebsocket_context *context, - struct libwebsocket_pollfd *pollfd) +lws_service_fd(struct lws_context *context, struct lws_pollfd *pollfd) { - struct libwebsocket *wsi; - int n, m; - lws_sockfd_type mfd; #if LWS_POSIX int listen_socket_fds_index = 0; #endif - time_t now; - int timed_out = 0; lws_sockfd_type our_fd = 0; - char draining_flow = 0; - int more; struct lws_tokens eff_buf; unsigned int pending = 0; + char draining_flow = 0; + lws_sockfd_type mfd; + int timed_out = 0; + struct lws *wsi; + time_t now; + int n, m; + int more; #if LWS_POSIX if (context->listen_service_fd) - listen_socket_fds_index = wsi_from_fd(context,context->listen_service_fd)->position_in_fds_table; + listen_socket_fds_index = wsi_from_fd(context, + context->listen_service_fd)->position_in_fds_table; #endif /* * you can call us with pollfd = NULL to just allow the once-per-second @@ -404,13 +401,13 @@ libwebsocket_service_fd(struct libwebsocket_context *context, if (!wsi) continue; - if (libwebsocket_service_timeout_check(context, wsi, now)) + if (lws_service_timeout_check(context, wsi, + (unsigned int)now)) /* he did time out... */ - if (mfd == our_fd) { + if (mfd == our_fd) /* it was the guy we came to service! */ timed_out = 1; /* he's gone, no need to mark as handled */ - } } } @@ -419,12 +416,12 @@ libwebsocket_service_fd(struct libwebsocket_context *context, return 0; /* just here for timeout management? */ - if (pollfd == NULL) + if (!pollfd) return 0; /* no, here to service a socket descriptor */ wsi = wsi_from_fd(context, pollfd->fd); - if (wsi == NULL) + if (!wsi) /* not lws connection ... leave revents alone and return */ return 0; @@ -458,9 +455,10 @@ libwebsocket_service_fd(struct libwebsocket_context *context, * even with extpoll, we prepared this * internal fds for listen */ - n = lws_poll_listen_fd(&context->fds[listen_socket_fds_index]); + n = lws_poll_listen_fd( + &context->fds[listen_socket_fds_index]); if (n > 0) { /* there's a conn waiting for us */ - libwebsocket_service_fd(context, + lws_service_fd(context, &context-> fds[listen_socket_fds_index]); context->listen_service_extraseen++; @@ -495,8 +493,11 @@ libwebsocket_service_fd(struct libwebsocket_context *context, case LWS_CONNMODE_SERVER_LISTENER: case LWS_CONNMODE_SSL_ACK_PENDING: n = lws_server_socket_service(context, wsi, pollfd); - if (n < 0) - goto close_and_handled; + if (n) /* closed by above */ + return 1; + pending = lws_ssl_pending(wsi); + if (pending) + goto handle_pending; goto handled; case LWS_CONNMODE_WS_SERVING: @@ -514,7 +515,7 @@ libwebsocket_service_fd(struct libwebsocket_context *context, lws_handle_POLLOUT_event(context, wsi, pollfd)) { if (wsi->state == WSI_STATE_RETURNED_CLOSE_ALREADY) wsi->state = WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE; - lwsl_info("libwebsocket_service_fd: closing\n"); + lwsl_info("lws_service_fd: closing\n"); goto close_and_handled; } @@ -536,8 +537,9 @@ libwebsocket_service_fd(struct libwebsocket_context *context, read: eff_buf.token_len = lws_ssl_capable_read(context, wsi, - context->service_buffer, - pending?pending:sizeof(context->service_buffer)); + context->service_buffer, + pending ? pending : + sizeof(context->service_buffer)); switch (eff_buf.token_len) { case 0: lwsl_info("service_fd: closing due to 0 length read\n"); @@ -567,7 +569,6 @@ read: drain: do { - more = 0; m = lws_ext_callback_for_each_active(wsi, @@ -580,7 +581,7 @@ drain: /* service incoming data */ if (eff_buf.token_len) { - n = libwebsocket_read(context, wsi, + n = lws_read(context, wsi, (unsigned char *)eff_buf.token, eff_buf.token_len); if (n < 0) { @@ -596,8 +597,9 @@ drain: pending = lws_ssl_pending(wsi); if (pending) { - pending = pending > sizeof(context->service_buffer)? - sizeof(context->service_buffer):pending; +handle_pending: + pending = pending > sizeof(context->service_buffer) ? + sizeof(context->service_buffer) : pending; goto read; } @@ -609,7 +611,8 @@ drain: #ifdef LWS_NO_SERVER n = #endif - _libwebsocket_rx_flow_control(wsi); /* n ignored, needed for NO_SERVER case */ + _lws_rx_flow_control(wsi); + /* n ignored, needed for NO_SERVER case */ } break; @@ -628,9 +631,12 @@ drain: close_and_handled: lwsl_debug("Close and handled\n"); - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - // pollfd points to something else after the close + lws_close_and_free_session(context, wsi, LWS_CLOSE_STATUS_NOSTATUS); + /* + * pollfd may point to something else after the close + * due to pollfd swapping scheme on delete on some platforms + * we can't clear revents now because it'd be the wrong guy's revents + */ return 1; handled: @@ -639,7 +645,7 @@ handled: } /** - * libwebsocket_service() - Service any pending websocket activity + * lws_service() - Service any pending websocket activity * @context: Websocket context * @timeout_ms: Timeout for poll; 0 means return immediately if nothing needed * service otherwise block and service immediately, returning @@ -671,7 +677,7 @@ handled: */ LWS_VISIBLE int -libwebsocket_service(struct libwebsocket_context *context, int timeout_ms) +lws_service(struct lws_context *context, int timeout_ms) { return lws_plat_service(context, timeout_ms); } diff --git a/lib/sha-1.c b/lib/sha-1.c index 019f92a11..1c5f69acc 100644 --- a/lib/sha-1.c +++ b/lib/sha-1.c @@ -212,14 +212,14 @@ sha1_pad(struct sha1_ctxt *ctxt) padlen = 64 - padstart; if (padlen < 8) { bzero(&ctxt->m.b8[padstart], padlen); - COUNT += padlen; + COUNT += (unsigned char)padlen; COUNT %= 64; sha1_step(ctxt); padstart = COUNT % 64; /* should be 0 */ padlen = 64 - padstart; /* should be 64 */ } bzero(&ctxt->m.b8[padstart], padlen - 8); - COUNT += (padlen - 8); + COUNT += ((unsigned char)padlen - 8); COUNT %= 64; #if BYTE_ORDER == BIG_ENDIAN PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]); @@ -250,7 +250,7 @@ sha1_loop(struct sha1_ctxt *ctxt, const unsigned char *input, size_t len) copysiz = (gaplen < len - off) ? gaplen : len - off; memcpy(&ctxt->m.b8[gapstart], &input[off], copysiz); - COUNT += copysiz; + COUNT += (unsigned char)copysiz; COUNT %= 64; ctxt->c.b64[0] += copysiz * 8; if (COUNT % 64 == 0) @@ -287,7 +287,7 @@ sha1_result(struct sha1_ctxt *ctxt, void *digest0) */ LWS_VISIBLE unsigned char * -libwebsockets_SHA1(const unsigned char *d, size_t n, unsigned char *md) +lws_SHA1(const unsigned char *d, size_t n, unsigned char *md) { struct sha1_ctxt ctx; diff --git a/lib/ssl-http2.c b/lib/ssl-http2.c index caa028cab..b65e8a32d 100644 --- a/lib/ssl-http2.c +++ b/lib/ssl-http2.c @@ -59,7 +59,8 @@ struct alpn_ctx { unsigned short len; }; -static int npn_cb(SSL *s, const unsigned char **data, unsigned int *len, void *arg) +static int +npn_cb(SSL *s, const unsigned char **data, unsigned int *len, void *arg) { struct alpn_ctx *alpn_ctx = arg; @@ -70,15 +71,15 @@ static int npn_cb(SSL *s, const unsigned char **data, unsigned int *len, void *a return SSL_TLSEXT_ERR_OK; } -static int alpn_cb(SSL *s, const unsigned char **out, - unsigned char *outlen, const unsigned char *in, - unsigned int inlen, void *arg) +static int +alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, void *arg) { struct alpn_ctx *alpn_ctx = arg; - if (SSL_select_next_proto((unsigned char **)out, outlen, - alpn_ctx->data, alpn_ctx->len, in, inlen) != - OPENSSL_NPN_NEGOTIATED) + if (SSL_select_next_proto((unsigned char **)out, outlen, alpn_ctx->data, + alpn_ctx->len, in, inlen) != + OPENSSL_NPN_NEGOTIATED) return SSL_TLSEXT_ERR_NOACK; return SSL_TLSEXT_ERR_OK; @@ -86,13 +87,11 @@ static int alpn_cb(SSL *s, const unsigned char **out, #endif LWS_VISIBLE void -lws_context_init_http2_ssl(struct libwebsocket_context *context) +lws_context_init_http2_ssl(struct lws_context *context) { #if OPENSSL_VERSION_NUMBER >= 0x10002000L - static struct alpn_ctx protos = { (unsigned char *) - "\x05h2-14" - "\x08http/1.1", - 6 + 9 }; + static struct alpn_ctx protos = { (unsigned char *)"\x05h2-14" + "\x08http/1.1", 6 + 9 }; SSL_CTX_set_next_protos_advertised_cb(context->ssl_ctx, npn_cb, &protos); @@ -106,13 +105,13 @@ lws_context_init_http2_ssl(struct libwebsocket_context *context) #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L } -void lws_http2_configure_if_upgraded(struct libwebsocket *wsi) +void lws_http2_configure_if_upgraded(struct lws *wsi) { #if OPENSSL_VERSION_NUMBER >= 0x10002000L struct allocated_headers *ah; + const char *method = "alpn"; const unsigned char *name; unsigned len; - const char *method = "alpn"; SSL_get0_alpn_selected(wsi->ssl, &name, &len); @@ -151,4 +150,4 @@ void lws_http2_configure_if_upgraded(struct libwebsocket *wsi) } #endif -#endif \ No newline at end of file +#endif diff --git a/lib/ssl.c b/lib/ssl.c index 04c96cf05..2cb5d86fe 100644 --- a/lib/ssl.c +++ b/lib/ssl.c @@ -26,9 +26,11 @@ int openssl_websocket_private_data_index; -static int lws_context_init_ssl_pem_passwd_cb(char * buf, int size, int rwflag, void *userdata) +static int lws_context_init_ssl_pem_passwd_cb(char * buf, int size, + int rwflag, void *userdata) { - struct lws_context_creation_info * info = (struct lws_context_creation_info *)userdata; + struct lws_context_creation_info * info = + (struct lws_context_creation_info *)userdata; strncpy(buf, info->ssl_private_key_password, size); buf[size - 1] = '\0'; @@ -57,7 +59,7 @@ OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) { SSL *ssl; int n; - struct libwebsocket_context *context; + struct lws_context *context; ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); @@ -78,7 +80,7 @@ OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) LWS_VISIBLE int lws_context_init_server_ssl(struct lws_context_creation_info *info, - struct libwebsocket_context *context) + struct lws_context *context) { SSL_METHOD *method; int error; @@ -246,7 +248,7 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info, #endif LWS_VISIBLE void -lws_ssl_destroy(struct libwebsocket_context *context) +lws_ssl_destroy(struct lws_context *context) { if (context->ssl_ctx) SSL_CTX_free(context->ssl_ctx); @@ -264,7 +266,7 @@ lws_ssl_destroy(struct libwebsocket_context *context) } LWS_VISIBLE void -libwebsockets_decode_ssl_error(void) +lws_decode_ssl_error(void) { char buf[256]; u_long err; @@ -278,7 +280,7 @@ libwebsockets_decode_ssl_error(void) #ifndef LWS_NO_CLIENT int lws_context_init_client_ssl(struct lws_context_creation_info *info, - struct libwebsocket_context *context) + struct lws_context *context) { int error; int n; @@ -406,8 +408,8 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info, #endif LWS_VISIBLE void -lws_ssl_remove_wsi_from_buffered_list(struct libwebsocket_context *context, - struct libwebsocket *wsi) +lws_ssl_remove_wsi_from_buffered_list(struct lws_context *context, + struct lws *wsi) { if (!wsi->pending_read_list_prev && !wsi->pending_read_list_next && @@ -432,8 +434,8 @@ lws_ssl_remove_wsi_from_buffered_list(struct libwebsocket_context *context, } LWS_VISIBLE int -lws_ssl_capable_read(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char *buf, int len) +lws_ssl_capable_read(struct lws_context *context, + struct lws *wsi, unsigned char *buf, int len) { int n; @@ -441,7 +443,11 @@ lws_ssl_capable_read(struct libwebsocket_context *context, return lws_ssl_capable_read_no_ssl(context, wsi, buf, len); n = SSL_read(wsi->ssl, buf, len); - if (n >= 0) { + /* manpage: returning 0 means connection shut down */ + if (!n) + return LWS_SSL_CAPABLE_ERROR; + + if (n > 0) { /* * if it was our buffer that limited what we read, * check if SSL has additional data pending inside SSL buffers. @@ -473,7 +479,7 @@ lwsl_err("%s: LWS_SSL_CAPABLE_ERROR\n", __func__); } LWS_VISIBLE int -lws_ssl_pending(struct libwebsocket *wsi) +lws_ssl_pending(struct lws *wsi) { if (!wsi->ssl) return 0; @@ -482,7 +488,7 @@ lws_ssl_pending(struct libwebsocket *wsi) } LWS_VISIBLE int -lws_ssl_capable_write(struct libwebsocket *wsi, unsigned char *buf, int len) +lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, int len) { int n; @@ -490,7 +496,7 @@ lws_ssl_capable_write(struct libwebsocket *wsi, unsigned char *buf, int len) return lws_ssl_capable_write_no_ssl(wsi, buf, len); n = SSL_write(wsi->ssl, buf, len); - if (n >= 0) + if (n > 0) return n; n = SSL_get_error(wsi->ssl, n); @@ -504,7 +510,7 @@ lwsl_err("%s: LWS_SSL_CAPABLE_ERROR\n", __func__); } LWS_VISIBLE int -lws_ssl_close(struct libwebsocket *wsi) +lws_ssl_close(struct lws *wsi) { int n; @@ -515,17 +521,20 @@ lws_ssl_close(struct libwebsocket *wsi) SSL_shutdown(wsi->ssl); compatible_close(n); SSL_free(wsi->ssl); + wsi->ssl = NULL; return 1; /* handled */ } +/* leave all wsi close processing to the caller */ + LWS_VISIBLE int -lws_server_socket_service_ssl(struct libwebsocket_context *context, - struct libwebsocket **pwsi, struct libwebsocket *new_wsi, - int accept_fd, struct libwebsocket_pollfd *pollfd) +lws_server_socket_service_ssl(struct lws_context *context, struct lws **pwsi, + struct lws *new_wsi, lws_sockfd_type accept_fd, + struct lws_pollfd *pollfd) { + struct lws *wsi = *pwsi; int n, m; - struct libwebsocket *wsi = *pwsi; #ifndef USE_WOLFSSL BIO *bio; #endif @@ -544,10 +553,8 @@ lws_server_socket_service_ssl(struct libwebsocket_context *context, new_wsi->ssl = SSL_new(context->ssl_ctx); if (new_wsi->ssl == NULL) { lwsl_err("SSL_new failed: %s\n", - ERR_error_string(SSL_get_error(new_wsi->ssl, 0), NULL)); - libwebsockets_decode_ssl_error(); - - // TODO: Shouldn't the caller handle this? + ERR_error_string(SSL_get_error(new_wsi->ssl, 0), NULL)); + lws_decode_ssl_error(); compatible_close(accept_fd); goto fail; } @@ -589,7 +596,7 @@ lws_server_socket_service_ssl(struct libwebsocket_context *context, if (insert_wsi_socket_into_fds(context, wsi)) goto fail; - libwebsocket_set_timeout(wsi, PENDING_TIMEOUT_SSL_ACCEPT, + lws_set_timeout(wsi, PENDING_TIMEOUT_SSL_ACCEPT, AWAITING_TIMEOUT); lwsl_info("inserted SSL accept into fds, trying SSL_accept\n"); @@ -663,7 +670,7 @@ lws_server_socket_service_ssl(struct libwebsocket_context *context, m = SSL_get_error(wsi->ssl, n); lwsl_debug("SSL_accept failed %d / %s\n", - m, ERR_error_string(m, NULL)); + m, ERR_error_string(m, NULL)); go_again: if (m == SSL_ERROR_WANT_READ) { if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) @@ -682,14 +689,13 @@ go_again: break; } lwsl_debug("SSL_accept failed skt %u: %s\n", - pollfd->fd, ERR_error_string(m, NULL)); + pollfd->fd, ERR_error_string(m, NULL)); goto fail; accepted: /* OK, we are accepted... give him some time to negotiate */ - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_ESTABLISH_WITH_SERVER, - AWAITING_TIMEOUT); + lws_set_timeout(wsi, PENDING_TIMEOUT_ESTABLISH_WITH_SERVER, + AWAITING_TIMEOUT); wsi->mode = LWS_CONNMODE_HTTP_SERVING; @@ -706,7 +712,7 @@ fail: } LWS_VISIBLE void -lws_ssl_context_destroy(struct libwebsocket_context *context) +lws_ssl_context_destroy(struct lws_context *context) { if (context->ssl_ctx) SSL_CTX_free(context->ssl_ctx); diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html index 7a150456c..0abef3832 100644 --- a/libwebsockets-api-doc.html +++ b/libwebsockets-api-doc.html @@ -1,392 +1,10 @@ -

lws_frame_is_binary -

+

lws_write - Apply protocol then write data to client

int -lws_frame_is_binary -(struct libwebsocket * wsi) -

Arguments

-
-
wsi -
the connection we are inquiring about -
-

Description

-
-This is intended to be called from the LWS_CALLBACK_RECEIVE callback if -it's interested to see if the frame it's dealing with was sent in binary -mode. -
-
-

libwebsockets_remaining_packet_payload - Bytes to come before "overall" rx packet is complete

-size_t -libwebsockets_remaining_packet_payload -(struct libwebsocket * wsi) -

Arguments

-
-
wsi -
Websocket instance (available from user callback) -
-

Description

-
-This function is intended to be called from the callback if the -user code is interested in "complete packets" from the client. -libwebsockets just passes through payload as it comes and issues a buffer -additionally when it hits a built-in limit. The LWS_CALLBACK_RECEIVE -callback handler can use this API to find out if the buffer it has just -been given is the last piece of a "complete packet" from the client -- -when that is the case libwebsockets_remaining_packet_payload will return -0. -

-Many protocols won't care becuse their packets are always small. -

-
-

lws_get_library_version -

-const char * -lws_get_library_version -( void) -

Arguments

-
-
void -
no arguments -
-

Description

-
-

-returns a const char * to a string like "1.1 178d78c" -representing the library version followed by the git head hash it -was built from -

-
-

libwebsockets_get_peer_addresses - Get client address information

-void -libwebsockets_get_peer_addresses -(struct libwebsocket_context * context, -struct libwebsocket * wsi, -int fd, -char * name, -int name_len, -char * rip, -int rip_len) -

Arguments

-
-
context -
Libwebsockets context -
wsi -
Local struct libwebsocket associated with -
fd -
Connection socket descriptor -
name -
Buffer to take client address name -
name_len -
Length of client address name buffer -
rip -
Buffer to take client address IP qotted quad -
rip_len -
Length of client address IP buffer -
-

Description

-
-This function fills in name and rip with the name and IP of -the client connected with socket descriptor fd. Names may be -truncated if there is not enough room. If either cannot be -determined, they will be returned as valid zero-length strings. -
-
-

libwebsocket_service_fd - Service polled socket with something waiting

-int -libwebsocket_service_fd -(struct libwebsocket_context * context, -struct pollfd * pollfd) -

Arguments

-
-
context -
Websocket context -
pollfd -
The pollfd entry describing the socket fd and which events -happened. -
-

Description

-
-This function takes a pollfd that has POLLIN or POLLOUT activity and -services it according to the state of the associated -struct libwebsocket. -

-The one call deals with all "service" that might happen on a socket -including listen accepts, http files as well as websocket protocol. -

-If a pollfd says it has something, you can just pass it to -libwebsocket_serice_fd whether it is a socket handled by lws or not. -If it sees it is a lws socket, the traffic will be handled and -pollfd->revents will be zeroed now. -

-If the socket is foreign to lws, it leaves revents alone. So you can -see if you should service yourself by checking the pollfd revents -after letting lws try to service it. -

-
-

libwebsocket_context_destroy - Destroy the websocket context

-void -libwebsocket_context_destroy -(struct libwebsocket_context * context) -

Arguments

-
-
context -
Websocket context -
-

Description

-
-This function closes any active connections and then frees the -context. After calling this, any further use of the context is -undefined. -
-
-

libwebsocket_context_user - get the user data associated with the context

-LWS_EXTERN void * -libwebsocket_context_user -(struct libwebsocket_context * context) -

Arguments

-
-
context -
Websocket context -
-

Description

-
-This returns the optional user allocation that can be attached to -the context the sockets live in at context_create time. It's a way -to let all sockets serviced in the same context share data without -using globals statics in the user code. -
-
-

libwebsocket_service - Service any pending websocket activity

-int -libwebsocket_service -(struct libwebsocket_context * context, -int timeout_ms) -

Arguments

-
-
context -
Websocket context -
timeout_ms -
Timeout for poll; 0 means return immediately if nothing needed -service otherwise block and service immediately, returning -after the timeout if nothing needed service. -
-

Description

-
-This function deals with any pending websocket traffic, for three -kinds of event. It handles these events on both server and client -types of connection the same. -

-1) Accept new connections to our context's server -

-2) Call the receive callback for incoming frame data received by -server or client connections. -

-You need to call this service function periodically to all the above -functions to happen; if your application is single-threaded you can -just call it in your main event loop. -

-Alternatively you can fork a new process that asynchronously handles -calling this service in a loop. In that case you are happy if this -call blocks your thread until it needs to take care of something and -would call it with a large nonzero timeout. Your loop then takes no -CPU while there is nothing happening. -

-If you are calling it in a single-threaded app, you don't want it to -wait around blocking other things in your loop from happening, so you -would call it with a timeout_ms of 0, so it returns immediately if -nothing is pending, or as soon as it services whatever was pending. -

-
-

libwebsocket_callback_on_writable - Request a callback when this socket becomes able to be written to without blocking

-int -libwebsocket_callback_on_writable -(struct libwebsocket_context * context, -struct libwebsocket * wsi) -

Arguments

-
-
context -
libwebsockets context -
wsi -
Websocket connection instance to get callback for -
-
-

libwebsocket_callback_on_writable_all_protocol - Request a callback for all connections using the given protocol when it becomes possible to write to each socket without blocking in turn.

-int -libwebsocket_callback_on_writable_all_protocol -(const struct libwebsocket_protocols * protocol) -

Arguments

-
-
protocol -
Protocol whose connections will get callbacks -
-
-

libwebsocket_set_timeout - marks the wsi as subject to a timeout

-void -libwebsocket_set_timeout -(struct libwebsocket * wsi, -enum pending_timeout reason, -int secs) -

Arguments

-
-
wsi -
Websocket connection instance -
reason -
timeout reason -
secs -
how many seconds -
-

Description

-
-

-You will not need this unless you are doing something special -

-
-

libwebsocket_get_socket_fd - returns the socket file descriptor

-int -libwebsocket_get_socket_fd -(struct libwebsocket * wsi) -

Arguments

-
-
wsi -
Websocket connection instance -
-

Description

-
-

-You will not need this unless you are doing something special -

-
-

libwebsocket_rx_flow_control - Enable and disable socket servicing for receieved packets.

-int -libwebsocket_rx_flow_control -(struct libwebsocket * wsi, -int enable) -

Arguments

-
-
wsi -
Websocket connection instance to get callback for -
enable -
0 = disable read servicing for this connection, 1 = enable -
-

Description

-
-

-If the output side of a server process becomes choked, this allows flow -control for the input side. -

-
-

libwebsocket_rx_flow_allow_all_protocol - Allow all connections with this protocol to receive

-void -libwebsocket_rx_flow_allow_all_protocol -(const struct libwebsocket_protocols * protocol) -

Arguments

-
-
protocol -
all connections using this protocol will be allowed to receive -
-

Description

-
-

-When the user server code realizes it can accept more input, it can -call this to have the RX flow restriction removed from all connections using -the given protocol. -

-
-

libwebsocket_canonical_hostname - returns this host's hostname

-const char * -libwebsocket_canonical_hostname -(struct libwebsocket_context * context) -

Arguments

-
-
context -
Websocket context -
-

Description

-
-

-This is typically used by client code to fill in the host parameter -when making a client connection. You can only call it after the context -has been created. -

-
-

libwebsocket_create_context - Create the websocket handler

-struct libwebsocket_context * -libwebsocket_create_context -(struct lws_context_creation_info * info) -

Arguments

-
-
info -
pointer to struct with parameters -
-

Description

-
-This function creates the listening socket (if serving) and takes care -of all initialization in one step. -

-After initialization, it returns a struct libwebsocket_context * that -represents this server. After calling, user code needs to take care -of calling libwebsocket_service with the context pointer to get the -server's sockets serviced. This can be done in the same process context -or a forked process, or another thread, -

-The protocol callback functions are called for a handful of events -including http requests coming in, websocket connections becoming -established, and data arriving; it's also called periodically to allow -async transmission. -

-HTTP requests are sent always to the FIRST protocol in protocol, since -at that time websocket protocol has not been negotiated. Other -protocols after the first one never see any HTTP callack activity. -

-The server created is a simple http server by default; part of the -websocket standard is upgrading this http connection to a websocket one. -

-This allows the same server to provide files like scripts and favicon / -images or whatever over http and dynamic data over websockets all in -one place; they're all handled in the user callback. -

-
-

libwebsockets_get_protocol - Returns a protocol pointer from a websocket connection.

-const struct libwebsocket_protocols * -libwebsockets_get_protocol -(struct libwebsocket * wsi) -

Arguments

-
-
wsi -
pointer to struct websocket you want to know the protocol of -
-

Description

-
-

-Some apis can act on all live connections of a given protocol, -this is how you can get a pointer to the active protocol if needed. -

-
-

lws_set_log_level - Set the logging bitfield

-void -lws_set_log_level -(int level, -void (*log_emit_function) (int level, const char *line)) -

Arguments

-
-
level -
OR together the LLL_ debug contexts you want output from -
log_emit_function -
NULL to leave it as it is, or a user-supplied -function to perform log string emission instead of -the default stderr one. -
-

Description

-
-log level defaults to "err", "warn" and "notice" contexts enabled and -emission on stderr. -
-
-

libwebsocket_write - Apply protocol then write data to client

-int -libwebsocket_write -(struct libwebsocket * wsi, +lws_write +(struct lws * wsi, unsigned char * buf, size_t len, -enum libwebsocket_write_protocol protocol) +enum lws_write_protocol protocol)

Arguments

wsi @@ -423,13 +41,31 @@ can be less than the requested number of bytes due to OS memory pressure at any given time.
-

libwebsockets_serve_http_file - Send a file back to the client using http

+

lws_http_transaction_completed - wait for new http transaction or close

int -libwebsockets_serve_http_file -(struct libwebsocket_context * context, -struct libwebsocket * wsi, +lws_http_transaction_completed +(struct lws * wsi) +

Arguments

+
+
wsi +
websocket connection +
+

Description

+
+Returns 1 if the HTTP connection must close now +Returns 0 and resets connection to wait for new HTTP header / +transaction if possible +
+
+

lws_serve_http_file - Send a file back to the client using http

+int +lws_serve_http_file +(struct lws_context * context, +struct lws * wsi, const char * file, -const char * content_type) +const char * content_type, +const char * other_headers, +int other_headers_len)

Arguments

context @@ -440,6 +76,8 @@ pressure at any given time.
The file to issue over http
content_type
The http content type, eg, text/html +
other_headers +
NULL or pointer to \0-terminated other header string

Description

@@ -448,15 +86,40 @@ to http requests from the client. It allows the callback to issue local files down the http link in a single step.

Returning <0 indicates error and the wsi should be closed. Returning ->0 indicates the file was completely sent and the wsi should be closed. +>0 indicates the file was completely sent and +lws_http_transaction_completed called on the wsi (and close if != 0) ==0 indicates the file transfer is started and needs more service later, the wsi should be left alone.


-

libwebsocket_client_connect - Connect to another websocket server

-struct libwebsocket * -libwebsocket_client_connect -(struct libwebsocket_context * context, +

lws_return_http_status - Return simple http status

+int +lws_return_http_status +(struct lws_context * context, +struct lws * wsi, +unsigned int code, +const char * html_body) +

Arguments

+
+
context +
libwebsockets context +
wsi +
Websocket instance (available from user callback) +
code +
Status index, eg, 404 +
html_body +
User-readable HTML description < 1KB, or NULL +
+

Description

+
+Helper to report HTTP errors back to the client cleanly and +consistently +
+
+

lws_client_connect - Connect to another websocket server

+struct lws * +lws_client_connect +(struct lws_context * context, const char * address, int port, int ssl_connection, @@ -485,7 +148,8 @@ signed certs
protocol
Comma-separated list of protocols being asked for from the server, or just one. The server will pick the one it -likes best. +likes best. If you don't want to specify a protocol, which is +legal, use NULL here.
ietf_version_or_minus_one
-1 to ask to connect using the default, latest protocol supported, or the specific protocol ordinal @@ -495,10 +159,10 @@ protocol supported, or the specific protocol ordinal This function creates a connection to a remote server
-

libwebsocket_client_connect_extended - Connect to another websocket server

-struct libwebsocket * -libwebsocket_client_connect_extended -(struct libwebsocket_context * context, +

lws_client_connect_extended - Connect to another websocket server

+struct lws * +lws_client_connect_extended +(struct lws_context * context, const char * address, int port, int ssl_connection, @@ -540,12 +204,522 @@ protocol supported, or the specific protocol ordinal This function creates a connection to a remote server
+

lws_service_fd - Service polled socket with something waiting

+int +lws_service_fd +(struct lws_context * context, +struct lws_pollfd * pollfd) +

Arguments

+
+
context +
Websocket context +
pollfd +
The pollfd entry describing the socket fd and which events +happened. +
+

Description

+
+This function takes a pollfd that has POLLIN or POLLOUT activity and +services it according to the state of the associated +struct lws. +

+The one call deals with all "service" that might happen on a socket +including listen accepts, http files as well as websocket protocol. +

+If a pollfd says it has something, you can just pass it to +lws_service_fd whether it is a socket handled by lws or not. +If it sees it is a lws socket, the traffic will be handled and +pollfd->revents will be zeroed now. +

+If the socket is foreign to lws, it leaves revents alone. So you can +see if you should service yourself by checking the pollfd revents +after letting lws try to service it. +

+
+

lws_service - Service any pending websocket activity

+int +lws_service +(struct lws_context * context, +int timeout_ms) +

Arguments

+
+
context +
Websocket context +
timeout_ms +
Timeout for poll; 0 means return immediately if nothing needed +service otherwise block and service immediately, returning +after the timeout if nothing needed service. +
+

Description

+
+This function deals with any pending websocket traffic, for three +kinds of event. It handles these events on both server and client +types of connection the same. +

+1) Accept new connections to our context's server +

+2) Call the receive callback for incoming frame data received by +server or client connections. +

+You need to call this service function periodically to all the above +functions to happen; if your application is single-threaded you can +just call it in your main event loop. +

+Alternatively you can fork a new process that asynchronously handles +calling this service in a loop. In that case you are happy if this +call blocks your thread until it needs to take care of something and +would call it with a large nonzero timeout. Your loop then takes no +CPU while there is nothing happening. +

+If you are calling it in a single-threaded app, you don't want it to +wait around blocking other things in your loop from happening, so you +would call it with a timeout_ms of 0, so it returns immediately if +nothing is pending, or as soon as it services whatever was pending. +

+
+

lws_frame_is_binary -

+int +lws_frame_is_binary +(struct lws * wsi) +

Arguments

+
+
wsi +
the connection we are inquiring about +
+

Description

+
+This is intended to be called from the LWS_CALLBACK_RECEIVE callback if +it's interested to see if the frame it's dealing with was sent in binary +mode. +
+
+

lws_remaining_packet_payload - Bytes to come before "overall" rx packet is complete

+size_t +lws_remaining_packet_payload +(struct lws * wsi) +

Arguments

+
+
wsi +
Websocket instance (available from user callback) +
+

Description

+
+This function is intended to be called from the callback if the +user code is interested in "complete packets" from the client. +libwebsockets just passes through payload as it comes and issues a buffer +additionally when it hits a built-in limit. The LWS_CALLBACK_RECEIVE +callback handler can use this API to find out if the buffer it has just +been given is the last piece of a "complete packet" from the client -- +when that is the case lws_remaining_packet_payload will return +0. +

+Many protocols won't care becuse their packets are always small. +

+
+

lws_get_peer_addresses - Get client address information

+void +lws_get_peer_addresses +(struct lws_context * context, +struct lws * wsi, +lws_sockfd_type fd, +char * name, +int name_len, +char * rip, +int rip_len) +

Arguments

+
+
context +
Libwebsockets context +
wsi +
Local struct lws associated with +
fd +
Connection socket descriptor +
name +
Buffer to take client address name +
name_len +
Length of client address name buffer +
rip +
Buffer to take client address IP dotted quad +
rip_len +
Length of client address IP buffer +
+

Description

+
+This function fills in name and rip with the name and IP of +the client connected with socket descriptor fd. Names may be +truncated if there is not enough room. If either cannot be +determined, they will be returned as valid zero-length strings. +
+
+

lws_context_user - get the user data associated with the context

+LWS_EXTERN void * +lws_context_user +(struct lws_context * context) +

Arguments

+
+
context +
Websocket context +
+

Description

+
+This returns the optional user allocation that can be attached to +the context the sockets live in at context_create time. It's a way +to let all sockets serviced in the same context share data without +using globals statics in the user code. +
+
+

lws_callback_all_protocol - Callback all connections using the given protocol with the given reason

+int +lws_callback_all_protocol +(const struct lws_protocols * protocol, +int reason) +

Arguments

+
+
protocol +
Protocol whose connections will get callbacks +
reason +
Callback reason index +
+
+

lws_set_timeout - marks the wsi as subject to a timeout

+void +lws_set_timeout +(struct lws * wsi, +enum pending_timeout reason, +int secs) +

Arguments

+
+
wsi +
Websocket connection instance +
reason +
timeout reason +
secs +
how many seconds +
+

Description

+
+

+You will not need this unless you are doing something special +

+
+

lws_get_socket_fd - returns the socket file descriptor

+int +lws_get_socket_fd +(struct lws * wsi) +

Arguments

+
+
wsi +
Websocket connection instance +
+

Description

+
+

+You will not need this unless you are doing something special +

+
+

lws_rx_flow_control - Enable and disable socket servicing for received packets.

+int +lws_rx_flow_control +(struct lws * wsi, +int enable) +

Arguments

+
+
wsi +
Websocket connection instance to get callback for +
enable +
0 = disable read servicing for this connection, 1 = enable +
+

Description

+
+

+If the output side of a server process becomes choked, this allows flow +control for the input side. +

+
+

lws_rx_flow_allow_all_protocol - Allow all connections with this protocol to receive

+void +lws_rx_flow_allow_all_protocol +(const struct lws_protocols * protocol) +

Arguments

+
+
protocol +
all connections using this protocol will be allowed to receive +
+

Description

+
+

+When the user server code realizes it can accept more input, it can +call this to have the RX flow restriction removed from all connections using +the given protocol. +

+
+

lws_canonical_hostname - returns this host's hostname

+const char * +lws_canonical_hostname +(struct lws_context * context) +

Arguments

+
+
context +
Websocket context +
+

Description

+
+

+This is typically used by client code to fill in the host parameter +when making a client connection. You can only call it after the context +has been created. +

+
+

lws_set_proxy - Setups proxy to lws_context.

+int +lws_set_proxy +(struct lws_context * context, +const char * proxy) +

Arguments

+
+
context +
pointer to struct lws_context you want set proxy to +
proxy +
pointer to c string containing proxy in format address:port +
+

Description

+
+Returns 0 if proxy string was parsed and proxy was setup. +Returns -1 if proxy is NULL or has incorrect format. +

+This is only required if your OS does not provide the http_proxy +environment variable (eg, OSX) +

+IMPORTANT! You should call this function right after creation of the +lws_context and before call to connect. If you call this +function after connect behavior is undefined. +This function will override proxy settings made on lws_context +creation with genenv call. +

+
+

lws_get_protocol - Returns a protocol pointer from a websocket connection.

+const struct lws_protocols * +lws_get_protocol +(struct lws * wsi) +

Arguments

+
+
wsi +
pointer to struct websocket you want to know the protocol of +
+

Description

+
+

+Some apis can act on all live connections of a given protocol, +this is how you can get a pointer to the active protocol if needed. +

+
+

lws_set_log_level - Set the logging bitfield

+void +lws_set_log_level +(int level, +void (*log_emit_function) (int level, const char *line)) +

Arguments

+
+
level +
OR together the LLL_ debug contexts you want output from +
log_emit_function +
NULL to leave it as it is, or a user-supplied +function to perform log string emission instead of +the default stderr one. +
+

Description

+
+log level defaults to "err", "warn" and "notice" contexts enabled and +emission on stderr. +
+
+

lws_is_ssl - Find out if connection is using SSL

+int +lws_is_ssl +(struct lws * wsi) +

Arguments

+
+
wsi +
websocket connection to check +
+

Description

+
+Returns 0 if the connection is not using SSL, 1 if using SSL and +using verified cert, and 2 if using SSL but the cert was not +checked (appears for client wsi told to skip check on connection) +
+
+

lws_partial_buffered - find out if lws buffered the last write

+int +lws_partial_buffered +(struct lws * wsi) +

Arguments

+
+
wsi +
websocket connection to check +
+

Description

+
+Returns 1 if you cannot use lws_write because the last +write on this connection is still buffered, and can't be cleared without +returning to the service loop and waiting for the connection to be +writeable again. +

+If you will try to do >1 lws_write call inside a single +WRITEABLE callback, you must check this after every write and bail if +set, ask for a new writeable callback and continue writing from there. +

+This is never set at the start of a writeable callback, but any write +may set it. +

+
+

lws_get_library_version -

+const char * +lws_get_library_version +( void) +

Arguments

+
+
void +
no arguments +
+

Description

+
+

+returns a const char * to a string like "1.1 178d78c" +representing the library version followed by the git head hash it +was built from +

+
+

lws_create_context - Create the websocket handler

+struct lws_context * +lws_create_context +(struct lws_context_creation_info * info) +

Arguments

+
+
info +
pointer to struct with parameters +
+

Description

+
+This function creates the listening socket (if serving) and takes care +of all initialization in one step. +

+After initialization, it returns a struct lws_context * that +represents this server. After calling, user code needs to take care +of calling lws_service with the context pointer to get the +server's sockets serviced. This must be done in the same process +context as the initialization call. +

+The protocol callback functions are called for a handful of events +including http requests coming in, websocket connections becoming +established, and data arriving; it's also called periodically to allow +async transmission. +

+HTTP requests are sent always to the FIRST protocol in protocol, since +at that time websocket protocol has not been negotiated. Other +protocols after the first one never see any HTTP callack activity. +

+The server created is a simple http server by default; part of the +websocket standard is upgrading this http connection to a websocket one. +

+This allows the same server to provide files like scripts and favicon / +images or whatever over http and dynamic data over websockets all in +one place; they're all handled in the user callback. +

+
+

lws_context_destroy - Destroy the websocket context

+void +lws_context_destroy +(struct lws_context * context) +

Arguments

+
+
context +
Websocket context +
+

Description

+
+This function closes any active connections and then frees the +context. After calling this, any further use of the context is +undefined. +
+
+

lws_callback_on_writable - Request a callback when this socket becomes able to be written to without blocking

+int +lws_callback_on_writable +(struct lws_context * context, +struct lws * wsi) +

Arguments

+
+
context +
libwebsockets context +
wsi +
Websocket connection instance to get callback for +
+
+

lws_callback_on_writable_all_protocol - Request a callback for all connections using the given protocol when it becomes possible to write to each socket without blocking in turn.

+int +lws_callback_on_writable_all_protocol +(const struct lws_protocols * protocol) +

Arguments

+
+
protocol +
Protocol whose connections will get callbacks +
+
+

lws_cancel_service - Cancel servicing of pending websocket activity

+void +lws_cancel_service +(struct lws_context * context) +

Arguments

+
+
context +
Websocket context +
+

Description

+
+This function let a call to lws_service waiting for a timeout +immediately return. +
+
+

lws_cancel_service - Cancel servicing of pending websocket activity

+void +lws_cancel_service +(struct lws_context * context) +

Arguments

+
+
context +
Websocket context +
+

Description

+
+This function let a call to lws_service waiting for a timeout +immediately return. +
+
+

lws_cancel_service - Cancel servicing of pending websocket activity

+void +lws_cancel_service +(struct lws_context * context) +

Arguments

+
+
context +
Websocket context +
+

Description

+
+This function let a call to lws_service waiting for a timeout +immediately return. +

+There is no poll in MBED3, he will fire callbacks when he feels like +it. +

+

callback - User server actions

LWS_EXTERN int callback -(struct libwebsocket_context * context, -struct libwebsocket * wsi, -enum libwebsocket_callback_reasons reason, +(struct lws_context * context, +struct lws * wsi, +enum lws_callback_reasons reason, void * user, void * in, size_t len) @@ -571,7 +745,7 @@ protocol detail is hidden and handled by the library.

For each connection / session there is user data allocated that is pointed to by "user". You set the size of this user data area when -the library is initialized with libwebsocket_create_server. +the library is initialized with lws_create_server.

You get an opportunity to initialize user data when called back with LWS_CALLBACK_ESTABLISHED reason. @@ -584,7 +758,9 @@ an incoming client

LWS_CALLBACK_CLIENT_CONNECTION_ERROR

the request client connection has -been unable to complete a handshake with the remote server +been unable to complete a handshake with the remote server. If +in is non-NULL, you can find an error string of length len where +it points to.

LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH

@@ -605,6 +781,10 @@ a handshake with the remote server
when the websocket session ends
+

LWS_CALLBACK_CLOSED_HTTP

+
+when a HTTP (non-websocket) session ends +

LWS_CALLBACK_RECEIVE

data has appeared for this server endpoint from a @@ -631,7 +811,7 @@ one. This is a chance to serve http content, for example, to send a script to the client which will then open the websockets connection. in points to the URI path requested and -libwebsockets_serve_http_file makes it very +lws_serve_http_file makes it very simple to send back a file to the client. Normally after sending the file you are done with the http connection, since the rest of the @@ -642,6 +822,16 @@ That's important because it uses a slot in the total number of client connections allowed set by MAX_CLIENTS.
+

LWS_CALLBACK_HTTP_BODY

+
+the next len bytes data from the http +request body HTTP connection is now available in in. +
+

LWS_CALLBACK_HTTP_BODY_COMPLETION

+
+the expected amount of http request +body has been delivered +

LWS_CALLBACK_HTTP_WRITEABLE

you can write more down the http protocol @@ -655,7 +845,7 @@ http link has completed.

LWS_CALLBACK_SERVER_WRITEABLE

If you call -libwebsocket_callback_on_writable on a connection, you will +lws_callback_on_writable on a connection, you will get one of these callbacks coming when the connection socket is able to accept another write packet without blocking. If it already was able to take another packet without blocking, @@ -669,22 +859,50 @@ called when a client connects to the server at network level; the connection is accepted but then passed to this callback to decide whether to hang up immediately or not, based on the client IP. in contains the connection -socket's descriptor. Return non-zero to terminate -the connection before sending or receiving anything. -Because this happens immediately after the network connection -from the client, there's no websocket protocol selected yet so -this callback is issued only to protocol 0. +socket's descriptor. Since the client connection information is +not available yet, wsi still pointing to the main server socket. +Return non-zero to terminate the connection before sending or +receiving anything. Because this happens immediately after the +network connection from the client, there's no websocket protocol +selected yet so this callback is issued only to protocol 0. +
+

LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED

+
+A new client just had +been connected, accepted, and instantiated into the pool. This +callback allows setting any relevant property to it. Because this +happens immediately after the instantiation of a new client, +there's no websocket protocol selected yet so this callback is +issued only to protocol 0. Only wsi is defined, pointing to the +new client, and the return value is ignored. +
+

LWS_CALLBACK_FILTER_HTTP_CONNECTION

+
+called when the request has +been received and parsed from the client, but the response is +not sent yet. Return non-zero to disallow the connection. +user is a pointer to the connection user space allocation, +in is the URI, eg, "/" +In your handler you can use the public APIs +lws_hdr_total_length / lws_hdr_copy to access all of the +headers using the header enums lws_token_indexes from +libwebsockets.h to check for and read the supported header +presence and content before deciding to allow the http +connection to proceed or to kill the connection.

LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION

called when the handshake has been received and parsed from the client, but the response is not sent yet. Return non-zero to disallow the connection. -user is a pointer to an array of struct lws_tokens, you can -use the header enums lws_token_indexes from libwebsockets.h -to check for and read the supported header presence and -content before deciding to allow the handshake to proceed or -to kill the connection. +user is a pointer to the connection user space allocation, +in is the requested protocol name +In your handler you can use the public APIs +lws_hdr_total_length / lws_hdr_copy to access all of the +headers using the header enums lws_token_indexes from +libwebsockets.h to check for and read the supported header +presence and content before deciding to allow the handshake +to proceed or to kill the connection.

LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS

@@ -703,6 +921,17 @@ to load extra certifcates into the server which allow it to verify the validity of certificates returned by clients. user is the server's OpenSSL SSL_CTX*
+

LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY

+
+if configured for +including OpenSSL support but no private key file has been specified +(ssl_private_key_filepath is NULL), this callback is called to +allow the user to set the private key directly via libopenssl +and perform further operations if required; this might be useful +in situations where the private key is not directly accessible by +the OS, for example if it is stored on a smartcard +user is the server's OpenSSL SSL_CTX* +

LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION

if the @@ -788,10 +1017,21 @@ One-time call per protocol indicating this protocol won't get used at all after this callback, the context is getting destroyed. Take the opportunity to deallocate everything that was allocated by the protocol. +
+

LWS_CALLBACK_WSI_CREATE

+
+outermost (earliest) wsi create notification +
+

LWS_CALLBACK_WSI_DESTROY

+
+outermost (latest) wsi destroy notification

-The next four reasons are optional and only need taking care of if you +The next five reasons are optional and only need taking care of if you will be integrating libwebsockets sockets into an external polling array. +

+For these calls, in points to a struct lws_pollargs that +contains fd, events and prev_events members

LWS_CALLBACK_ADD_POLL_FD

@@ -802,46 +1042,58 @@ polling array with the other server. This and the other POLL_FD related callbacks let you put your specialized poll array interface code in the callback for protocol 0, the first protocol you support, usually the HTTP protocol in the -serving case. This callback happens when a socket needs to be +serving case. +This callback happens when a socket needs to be

added to the polling loop

-in contains the fd, and -len is the events bitmap (like, POLLIN). If you are using the -internal polling loop (the "service" callback), you can just -ignore these callbacks. +in points to a struct +lws_pollargs; the fd member of the struct is the file +descriptor, and events contains the active events. +

+If you are using the internal polling loop (the "service" +callback), you can just ignore these callbacks.

LWS_CALLBACK_DEL_POLL_FD

This callback happens when a socket descriptor needs to be removed from an external polling array. in is -the socket desricptor. If you are using the internal polling +again the struct lws_pollargs containing the fd member +to be removed. If you are using the internal polling loop, you can just ignore it.
-

LWS_CALLBACK_SET_MODE_POLL_FD

+

LWS_CALLBACK_CHANGE_MODE_POLL_FD

-This callback happens when libwebsockets -wants to modify the events for the socket descriptor in in. -The handler should OR len on to the events member of the pollfd -struct for this socket descriptor. If you are using the -internal polling loop, you can just ignore it. +This callback happens when +libwebsockets wants to modify the events for a connectiion. +in is the struct lws_pollargs with the fd to change. +The new event mask is in events member and the old mask is in +the prev_events member. +If you are using the internal polling loop, you can just ignore +it.
-

LWS_CALLBACK_CLEAR_MODE_POLL_FD

+

LWS_CALLBACK_UNLOCK_POLL

-This callback occurs when libwebsockets -wants to modify the events for the socket descriptor in in. -The handler should AND ~len on to the events member of the -pollfd struct for this socket descriptor. If you are using the -internal polling loop, you can just ignore it. +These allow the external poll changes driven +by libwebsockets to participate in an external thread locking +scheme around the changes, so the whole thing is threadsafe. +These are called around three activities in the library, +- inserting a new wsi in the wsi / fd table (len=1) +- deleting a wsi from the wsi / fd table (len=1) +- changing a wsi's POLLIN/OUT state (len=0) +Locking and unlocking external synchronization objects when +len == 1 allows external threads to be synchronized against +wsi lifecycle changes if it acquires the same lock for the +duration of wsi dereference from the other thread context.

extension_callback - Hooks to allow extensions to operate

LWS_EXTERN int extension_callback -(struct libwebsocket_context * context, -struct libwebsocket_extension * ext, -struct libwebsocket * wsi, -enum libwebsocket_extension_callback_reasons reason, +(struct lws_context * context, +struct lws_extension * ext, +struct lws * wsi, +enum lws_extension_callback_reasons reason, void * user, void * in, size_t len) @@ -923,20 +1175,22 @@ buffer safely, it should copy the data into its own buffer and set the lws_tokens token pointer to it.

-

struct libwebsocket_protocols - List of protocols and handlers server supports.

-struct libwebsocket_protocols {
+

struct lws_protocols - List of protocols and handlers server supports.

+struct lws_protocols {
    const char * name;
    callback_function * callback;
    size_t per_session_data_size;
    size_t rx_buffer_size;
-    struct libwebsocket_context * owning_server;
+    unsigned int id;
+    void * user;
+    struct lws_context * owning_server;
    int protocol_index;
};

Members

name
Protocol name that must match the one given in the client -Javascript new WebSocket(url, 'protocol') name +Javascript new WebSocket(url, 'protocol') name.
callback
The service callback used for this protocol. It allows the service action for an entire protocol to be encapsulated in @@ -952,9 +1206,21 @@ should set this to the size of the biggest legal frame that you support. If the frame size is exceeded, there is no error, but the buffer will spill to the user callback when full, which you can detect by using -libwebsockets_remaining_packet_payload. Notice that you +lws_remaining_packet_payload. Notice that you just talk about frame size here, the LWS_SEND_BUFFER_PRE_PADDING and post-padding are automatically also allocated on top. +
id +
ignored by lws, but useful to contain user information bound +to the selected protocol. For example if this protocol was +called "myprotocol-v2", you might set id to 2, and the user +code that acts differently according to the version can do so by +switch (wsi->protocol->id), user code might use some bits as +capability flags based on selected protocol version, etc. +
user +
User provided context data at the protocol level. +Accessible via lws_get_protocol(wsi)->user +This should not be confused with wsi->user, it is not the same. +The library completely ignores any value in here.
owning_server
the server init call fills in this opaque pointer when registering this protocol with the server. @@ -964,12 +1230,19 @@ registering this protocol with the server.

Description

This structure represents one protocol supported by the server. An -array of these structures is passed to libwebsocket_create_server +array of these structures is passed to lws_create_server allows as many protocols as you like to be handled by one server. +

+The first protocol given has its callback used for user callbacks when +there is no agreed protocol name, that's true during HTTP part of the +

+

connection and true if the client did not send a Protocol

+
+header.

-

struct libwebsocket_extension - An extension we know how to cope with

-struct libwebsocket_extension {
+

struct lws_extension - An extension we know how to cope with

+struct lws_extension {
    const char * name;
    extension_callback_function * callback;
    size_t per_session_data_size;
@@ -995,12 +1268,15 @@ all sessions, etc, if it wants struct lws_context_creation_info {
    int port;
    const char * iface;
-    struct libwebsocket_protocols * protocols;
-    struct libwebsocket_extension * extensions;
+    struct lws_protocols * protocols;
+    struct lws_extension * extensions;
+    struct lws_token_limits * token_limits;
    const char * ssl_cert_filepath;
    const char * ssl_private_key_filepath;
    const char * ssl_ca_filepath;
    const char * ssl_cipher_list;
+    const char * http_proxy_address;
+    unsigned int http_proxy_port;
    int gid;
    int uid;
    unsigned int options;
@@ -1008,13 +1284,19 @@ all sessions, etc, if it wants     int ka_time;
    int ka_probes;
    int ka_interval;
+#ifdef LWS_OPENSSL_SUPPORT
+    void * provided_client_ssl_ctx;
+#else
+    void * provided_client_ssl_ctx;
+#endif
};

Members

port -
Port to listen on... you can use 0 to suppress listening on -any port, that's what you want if you are not running a -websocket server at all but just using it as a client +
Port to listen on... you can use CONTEXT_PORT_NO_LISTEN to +suppress listening on any port, that's what you want if you are +not running a websocket server at all but just using it as a +client
iface
NULL to bind the listen socket to all interfaces, or the interface name, eg, "eth2" @@ -1024,22 +1306,33 @@ specific callback for each one. The list is ended with an 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 +
NULL or array of lws_extension structs listing the extensions this context supports. If you configured with --without-extensions, you should give NULL here. +
token_limits +
NULL or struct lws_token_limits pointer which is initialized +with a token length limit for each possible WSI_TOKEN_***
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
ssl_private_key_filepath -
filepath to private key if wanting SSL mode, -else ignored +
filepath to private key if wanting SSL mode; +if this is set to NULL but sll_cert_filepath is set, the +OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY callback is called to allow +setting of the private key directly via openSSL library calls
ssl_ca_filepath
CA certificate filepath or NULL
ssl_cipher_list
List of valid ciphers to use (eg, "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" or you can leave it as NULL to get "DEFAULT" +
http_proxy_address +
If non-NULL, attempts to proxy via the given address. +If proxy auth is required, use format +"username:passwordserver:port" +
http_proxy_port +
If http_proxy_address was non-NULL, uses this port at the address
gid
group id to change to after setting listen socket, or -1.
uid @@ -1048,7 +1341,7 @@ or you can leave it as NULL to get "DEFAULT"
0, or LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK
user
optional user pointer that can be recovered via the context -pointer using libwebsocket_context_user +pointer using lws_context_user
ka_time
0 for no keepalive, otherwise apply this keepalive timeout to all libwebsocket sockets, client or server @@ -1059,5 +1352,15 @@ and killing the connection
ka_interval
if ka_time was nonzero, how long to wait before each ka_probes attempt +
provided_client_ssl_ctx +
If non-null, swap out libwebsockets ssl +implementation for the one provided by provided_ssl_ctx. +Libwebsockets no longer is responsible for freeing the context +if this option is selected. +
provided_client_ssl_ctx +
If non-null, swap out libwebsockets ssl +implementation for the one provided by provided_ssl_ctx. +Libwebsockets no longer is responsible for freeing the context +if this option is selected.

diff --git a/lws_config.h.in b/lws_config.h.in index 4c3c3b981..13622fbc0 100644 --- a/lws_config.h.in +++ b/lws_config.h.in @@ -62,4 +62,7 @@ /* use SHA1() not internal libwebsockets_SHA1 */ #cmakedefine LWS_SHA1_USE_OPENSSL_NAME +/* whether to provide pre v1.6 compatibility wrappers */ +#cmakedefine LWS_WITH_OLD_API_WRAPPERS + ${LWS_SIZEOFPTR_CODE} diff --git a/module.json b/module.json index f2c565edd..221e2994a 100644 --- a/module.json +++ b/module.json @@ -15,6 +15,7 @@ "extraIncludes": [ "build/frdm-k64f-gcc/generated/include" ], "dependencies": { "mbed-drivers": "^0.11.1", + "sal-stack-lwip": "^1.0.4", "sockets": "^1.0.0" } } diff --git a/test-server/attack.sh b/test-server/attack.sh index 16ed1b57f..3413b44e8 100755 --- a/test-server/attack.sh +++ b/test-server/attack.sh @@ -6,6 +6,9 @@ SERVER=127.0.0.1 PORT=7681 LOG=/tmp/lwslog +A=`which libwebsockets-test-server` +INSTALLED=`dirname $A` + CPID= LEN=0 @@ -18,7 +21,7 @@ function check { dd if=$LOG bs=1 skip=$LEN 2>/dev/null if [ "$1" = "default" ] ; then - diff /tmp/lwscap /usr/share/libwebsockets-test-server/test.html > /dev/null + diff /tmp/lwscap $INSTALLED/../share/libwebsockets-test-server/test.html > /dev/null if [ $? -ne 0 ] ; then echo "FAIL: got something other than test.html back" exit 1 @@ -26,7 +29,7 @@ function check { fi if [ "$1" = "forbidden" ] ; then - if [ -z "`grep '

403 Forbidden

' /tmp/lwscap`" ] ; then + if [ -z "`grep '

403

' /tmp/lwscap`" ] ; then echo "FAIL: should have told forbidden (test server has no dirs)" exit 1 fi diff --git a/test-server/test-client.c b/test-server/test-client.c index 5d3b68041..59e6f4f54 100644 --- a/test-server/test-client.c +++ b/test-server/test-client.c @@ -27,20 +27,19 @@ #ifdef _WIN32 #define random rand +#include "gettimeofday.h" #else +#include +#include #include #endif #include "../lib/libwebsockets.h" +static int deny_deflate, deny_mux, longlived, mirror_lifetime; +static struct lws *wsi_dumb, *wsi_mirror; +static volatile int force_exit; static unsigned int opts; -static int was_closed; -static int deny_deflate; -static int deny_mux; -static struct libwebsocket *wsi_mirror; -static int mirror_lifetime = 0; -static volatile int force_exit = 0; -static int longlived = 0; /* * This demo shows how to connect multiple websockets simultaneously to a @@ -65,51 +64,61 @@ enum demo_protocols { }; -/* dumb_increment protocol */ +/* + * dumb_increment protocol + * + * since this also happens to be protocols[0], some callbacks that are not + * bound to a specific protocol also turn up here. + */ static int -callback_dumb_increment(struct libwebsocket_context *this, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, - void *user, void *in, size_t len) +callback_dumb_increment(struct lws_context *this, + struct lws *wsi, + enum lws_callback_reasons reason, + void *user, void *in, size_t len) { switch (reason) { case LWS_CALLBACK_CLIENT_ESTABLISHED: - fprintf(stderr, "callback_dumb_increment: LWS_CALLBACK_CLIENT_ESTABLISHED\n"); - break; - - case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: - fprintf(stderr, "LWS_CALLBACK_CLIENT_CONNECTION_ERROR\n"); - was_closed = 1; + lwsl_info("dumb: LWS_CALLBACK_CLIENT_ESTABLISHED\n"); break; case LWS_CALLBACK_CLOSED: - fprintf(stderr, "LWS_CALLBACK_CLOSED\n"); - was_closed = 1; + lwsl_notice("dumb: LWS_CALLBACK_CLOSED\n"); + wsi_dumb = NULL; break; case LWS_CALLBACK_CLIENT_RECEIVE: ((char *)in)[len] = '\0'; - fprintf(stderr, "rx %d '%s'\n", (int)len, (char *)in); + lwsl_info("rx %d '%s'\n", (int)len, (char *)in); break; /* because we are protocols[0] ... */ + case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: + if (wsi == wsi_dumb) { + lwsl_err("dumb: LWS_CALLBACK_CLIENT_CONNECTION_ERROR\n"); + wsi_dumb = NULL; + } + if (wsi == wsi_mirror) { + lwsl_err("mirror: LWS_CALLBACK_CLIENT_CONNECTION_ERROR\n"); + wsi_mirror = NULL; + } + break; + case LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED: if ((strcmp(in, "deflate-stream") == 0) && deny_deflate) { - fprintf(stderr, "denied deflate-stream extension\n"); + lwsl_notice("denied deflate-stream extension\n"); return 1; } if ((strcmp(in, "deflate-frame") == 0) && deny_deflate) { - fprintf(stderr, "denied deflate-frame extension\n"); + lwsl_notice("denied deflate-frame extension\n"); return 1; } if ((strcmp(in, "x-google-mux") == 0) && deny_mux) { - fprintf(stderr, "denied x-google-mux extension\n"); + lwsl_notice("denied x-google-mux extension\n"); return 1; } - break; default: @@ -124,60 +133,51 @@ callback_dumb_increment(struct libwebsocket_context *this, static int -callback_lws_mirror(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, - void *user, void *in, size_t len) +callback_lws_mirror(struct lws_context *context, + struct lws *wsi, + enum lws_callback_reasons reason, + void *user, void *in, size_t len) { unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 4096 + - LWS_SEND_BUFFER_POST_PADDING]; + LWS_SEND_BUFFER_POST_PADDING]; + unsigned int rands[4]; int l = 0; int n; - unsigned int rands[4]; switch (reason) { - case LWS_CALLBACK_CLIENT_ESTABLISHED: - fprintf(stderr, "callback_lws_mirror: LWS_CALLBACK_CLIENT_ESTABLISHED\n"); + lwsl_notice("mirror: LWS_CALLBACK_CLIENT_ESTABLISHED\n"); - libwebsockets_get_random(context, rands, sizeof(rands[0])); - mirror_lifetime = 10 + (rands[0] & 1023); + lws_get_random(context, rands, sizeof(rands[0])); + mirror_lifetime = 16384 + (rands[0] & 65535); /* useful to test single connection stability */ if (longlived) - mirror_lifetime += 50000; + mirror_lifetime += 500000; - fprintf(stderr, "opened mirror connection with " - "%d lifetime\n", mirror_lifetime); + lwsl_info("opened mirror connection with " + "%d lifetime\n", mirror_lifetime); /* * mirror_lifetime is decremented each send, when it reaches * zero the connection is closed in the send callback. * When the close callback comes, wsi_mirror is set to NULL * so a new connection will be opened - */ - - /* + * * start the ball rolling, * LWS_CALLBACK_CLIENT_WRITEABLE will come next service */ - - libwebsocket_callback_on_writable(context, wsi); + lws_callback_on_writable(context, wsi); break; case LWS_CALLBACK_CLOSED: - fprintf(stderr, "mirror: LWS_CALLBACK_CLOSED mirror_lifetime=%d\n", mirror_lifetime); + lwsl_notice("mirror: LWS_CALLBACK_CLOSED mirror_lifetime=%d\n", mirror_lifetime); wsi_mirror = NULL; break; - case LWS_CALLBACK_CLIENT_RECEIVE: -/* fprintf(stderr, "rx %d '%s'\n", (int)len, (char *)in); */ - break; - case LWS_CALLBACK_CLIENT_WRITEABLE: - for (n = 0; n < 1; n++) { - libwebsockets_get_random(context, rands, sizeof(rands)); + lws_get_random(context, rands, sizeof(rands)); l += sprintf((char *)&buf[LWS_SEND_BUFFER_PRE_PADDING + l], "c #%06X %d %d %d;", (int)rands[0] & 0xffffff, @@ -186,9 +186,8 @@ callback_lws_mirror(struct libwebsocket_context *context, (int)rands[3] % 24); } - n = libwebsocket_write(wsi, - &buf[LWS_SEND_BUFFER_PRE_PADDING], l, opts | LWS_WRITE_TEXT); - + n = lws_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], l, + opts | LWS_WRITE_TEXT); if (n < 0) return -1; if (n < l) { @@ -198,11 +197,11 @@ callback_lws_mirror(struct libwebsocket_context *context, mirror_lifetime--; if (!mirror_lifetime) { - fprintf(stderr, "closing mirror session\n"); + lwsl_info("closing mirror session\n"); return -1; - } else - /* get notified as soon as we can write again */ - libwebsocket_callback_on_writable(context, wsi); + } + /* get notified as soon as we can write again */ + lws_callback_on_writable(context, wsi); break; default: @@ -215,7 +214,7 @@ callback_lws_mirror(struct libwebsocket_context *context, /* list of supported protocols and callbacks */ -static struct libwebsocket_protocols protocols[] = { +static struct lws_protocols protocols[] = { { "dumb-increment-protocol,fake-nonexistant-protocol", callback_dumb_increment, @@ -248,24 +247,33 @@ static struct option options[] = { { NULL, 0, 0, 0 } }; +static int ratelimit_connects(unsigned int *last, int secs) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + if (tv.tv_sec - (*last) < secs) + return 0; + + *last = tv.tv_sec; + + return 1; +} int main(int argc, char **argv) { - int n = 0; - int ret = 0; - int port = 7681; - int use_ssl = 0; - struct libwebsocket_context *context; - const char *address; - struct libwebsocket *wsi_dumb; - int ietf_version = -1; /* latest */ + int n = 0, ret = 0, port = 7681, use_ssl = 0; + unsigned int rl_dumb = 0, rl_mirror = 0; struct lws_context_creation_info info; + struct lws_context *context; + int ietf_version = -1; /* latest */ + const char *address; memset(&info, 0, sizeof info); fprintf(stderr, "libwebsockets test client\n" "(C) Copyright 2010-2015 Andy Green " - "licensed under LGPL2.1\n"); + "licensed under LGPL2.1\n"); if (argc < 2) goto usage; @@ -319,67 +327,51 @@ int main(int argc, char **argv) info.port = CONTEXT_PORT_NO_LISTEN; info.protocols = protocols; #ifndef LWS_NO_EXTENSIONS - info.extensions = libwebsocket_get_internal_extensions(); + info.extensions = lws_get_internal_extensions(); #endif info.gid = -1; info.uid = -1; - context = libwebsocket_create_context(&info); + context = lws_create_context(&info); if (context == NULL) { fprintf(stderr, "Creating libwebsocket context failed\n"); return 1; } - /* create a client websocket using dumb increment protocol */ - - wsi_dumb = libwebsocket_client_connect(context, address, port, use_ssl, - "/", argv[optind], argv[optind], - protocols[PROTOCOL_DUMB_INCREMENT].name, ietf_version); - - if (wsi_dumb == NULL) { - fprintf(stderr, "libwebsocket connect failed\n"); - ret = 1; - goto bail; - } - - fprintf(stderr, "Waiting for connect...\n"); - /* * sit there servicing the websocket context to handle incoming * packets, and drawing random circles on the mirror protocol websocket + * * nothing happens until the client websocket connection is - * asynchronously established + * asynchronously established... calling lws_client_connect() only + * instantiates the connection logically, lws_service() progresses it + * asynchronously. */ - n = 0; - while (n >= 0 && !was_closed && !force_exit) { - n = libwebsocket_service(context, 10); + while (!force_exit) { - if (n < 0) - continue; - - if (wsi_mirror) - continue; - - /* create a client websocket using mirror protocol */ - - wsi_mirror = libwebsocket_client_connect(context, - address, port, use_ssl, "/", - argv[optind], argv[optind], - protocols[PROTOCOL_LWS_MIRROR].name, ietf_version); - - if (wsi_mirror == NULL) { - fprintf(stderr, "libwebsocket " - "mirror connect failed\n"); - ret = 1; - goto bail; + if (!wsi_dumb && ratelimit_connects(&rl_dumb, 2)) { + lwsl_notice("dumb: connecting\n"); + wsi_dumb = lws_client_connect(context, address, port, + use_ssl, "/", argv[optind], argv[optind], + protocols[PROTOCOL_DUMB_INCREMENT].name, + ietf_version); } + + if (!wsi_mirror && ratelimit_connects(&rl_mirror, 2)) { + lwsl_notice("mirror: connecting\n"); + wsi_mirror = lws_client_connect(context, + address, port, use_ssl, "/", + argv[optind], argv[optind], + protocols[PROTOCOL_LWS_MIRROR].name, + ietf_version); + } + + lws_service(context, 500); } -bail: - fprintf(stderr, "Exiting\n"); - - libwebsocket_context_destroy(context); + lwsl_err("Exiting\n"); + lws_context_destroy(context); return ret; diff --git a/test-server/test-echo.c b/test-server/test-echo.c index f74a5c46b..ccdc3c515 100644 --- a/test-server/test-echo.c +++ b/test-server/test-echo.c @@ -53,9 +53,9 @@ struct per_session_data__echo { }; static int -callback_echo(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, +callback_echo(struct lws_context *context, + struct lws *wsi, + enum lws_callback_reasons reason, void *user, void *in, size_t len) { struct per_session_data__echo *pss = (struct per_session_data__echo *)user; @@ -68,7 +68,7 @@ callback_echo(struct libwebsocket_context *context, case LWS_CALLBACK_SERVER_WRITEABLE: do_tx: - n = libwebsocket_write(wsi, &pss->buf[LWS_SEND_BUFFER_PRE_PADDING], pss->len, LWS_WRITE_TEXT); + n = lws_write(wsi, &pss->buf[LWS_SEND_BUFFER_PRE_PADDING], pss->len, LWS_WRITE_TEXT); if (n < 0) { lwsl_err("ERROR %d writing to socket, hanging up\n", n); return 1; @@ -87,7 +87,7 @@ do_rx: } memcpy(&pss->buf[LWS_SEND_BUFFER_PRE_PADDING], in, len); pss->len = (unsigned int)len; - libwebsocket_callback_on_writable(context, wsi); + lws_callback_on_writable(context, wsi); break; #endif @@ -122,7 +122,7 @@ do_rx: /* we will send our packet... */ pss->len = sprintf((char *)&pss->buf[LWS_SEND_BUFFER_PRE_PADDING], "hello from libwebsockets-test-echo client pid %d index %d\n", getpid(), pss->index++); lwsl_notice("Client TX: %s", &pss->buf[LWS_SEND_BUFFER_PRE_PADDING]); - n = libwebsocket_write(wsi, &pss->buf[LWS_SEND_BUFFER_PRE_PADDING], pss->len, LWS_WRITE_TEXT); + n = lws_write(wsi, &pss->buf[LWS_SEND_BUFFER_PRE_PADDING], pss->len, LWS_WRITE_TEXT); if (n < 0) { lwsl_err("ERROR %d writing to socket, hanging up\n", n); return -1; @@ -145,7 +145,7 @@ do_rx: -static struct libwebsocket_protocols protocols[] = { +static struct lws_protocols protocols[] = { /* first protocol must always be HTTP handler */ { @@ -189,7 +189,7 @@ int main(int argc, char **argv) int n = 0; int port = 7681; int use_ssl = 0; - struct libwebsocket_context *context; + struct lws_context *context; int opts = 0; char interface_name[128] = ""; const char *_interface = NULL; @@ -207,7 +207,7 @@ int main(int argc, char **argv) char address[256], ads_port[256 + 30]; int rate_us = 250000; unsigned long long oldus; - struct libwebsocket *wsi; + struct lws *wsi; int disallow_selfsigned = 0; struct timeval tv; #endif @@ -364,7 +364,7 @@ int main(int argc, char **argv) info.iface = _interface; info.protocols = protocols; #ifndef LWS_NO_EXTENSIONS - info.extensions = libwebsocket_get_internal_extensions(); + info.extensions = lws_get_internal_extensions(); #endif if (use_ssl && !client) { info.ssl_cert_filepath = ssl_cert; @@ -378,7 +378,7 @@ int main(int argc, char **argv) info.uid = -1; info.options = opts; - context = libwebsocket_create_context(&info); + context = lws_create_context(&info); if (context == NULL) { lwsl_err("libwebsocket init failed\n"); return -1; @@ -403,7 +403,7 @@ int main(int argc, char **argv) address[sizeof(address) - 1] = '\0'; sprintf(ads_port, "%s:%u", address, port & 65535); - wsi = libwebsocket_client_connect(context, address, + wsi = lws_client_connect(context, address, port, use_ssl, uri, ads_port, ads_port, NULL, -1); if (!wsi) { @@ -416,17 +416,17 @@ int main(int argc, char **argv) gettimeofday(&tv, NULL); if (((((unsigned long long)tv.tv_sec * 1000000) + tv.tv_usec) - oldus) > rate_us) { - libwebsocket_callback_on_writable_all_protocol(&protocols[0]); + lws_callback_on_writable_all_protocol(&protocols[0]); oldus = ((unsigned long long)tv.tv_sec * 1000000) + tv.tv_usec; } } #endif - n = libwebsocket_service(context, 10); + n = lws_service(context, 10); } #ifndef LWS_NO_CLIENT bail: #endif - libwebsocket_context_destroy(context); + lws_context_destroy(context); lwsl_notice("libwebsockets-test-echo exited cleanly\n"); #ifndef _WIN32 diff --git a/test-server/test-fraggle.c b/test-server/test-fraggle.c index 5faad2572..3f8c3449f 100644 --- a/test-server/test-fraggle.c +++ b/test-server/test-fraggle.c @@ -53,9 +53,9 @@ struct per_session_data__fraggle { }; static int -callback_fraggle(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, +callback_fraggle(struct lws_context *context, + struct lws *wsi, + enum lws_callback_reasons reason, void *user, void *in, size_t len) { int n; @@ -76,7 +76,7 @@ callback_fraggle(struct libwebsocket_context *context, fprintf(stderr, "server sees client connect\n"); psf->state = FRAGSTATE_START_MESSAGE; /* start the ball rolling */ - libwebsocket_callback_on_writable(context, wsi); + lws_callback_on_writable(context, wsi); break; case LWS_CALLBACK_CLIENT_ESTABLISHED: @@ -106,7 +106,7 @@ callback_fraggle(struct libwebsocket_context *context, psf->total_message += len; psf->packets_left++; - if (libwebsocket_is_final_fragment(wsi)) + if (lws_is_final_fragment(wsi)) psf->state = FRAGSTATE_POST_PAYLOAD_SUM; break; @@ -136,7 +136,7 @@ callback_fraggle(struct libwebsocket_context *context, switch (psf->state) { case FRAGSTATE_START_MESSAGE: - libwebsockets_get_random(context, &ran, sizeof(ran)); + lws_get_random(context, &ran, sizeof(ran)); psf->packets_left = (ran % 1024) + 1; fprintf(stderr, "Spamming %d random fragments\n", psf->packets_left); @@ -155,11 +155,11 @@ callback_fraggle(struct libwebsocket_context *context, * code for rx spill because the rx buffer is full */ - libwebsockets_get_random(context, &ran, sizeof(ran)); + lws_get_random(context, &ran, sizeof(ran)); chunk = (ran % 8000) + 1; psf->total_message += chunk; - libwebsockets_get_random(context, bp, chunk); + lws_get_random(context, bp, chunk); for (n = 0; n < chunk; n++) psf->sum += bp[n]; @@ -169,7 +169,7 @@ callback_fraggle(struct libwebsocket_context *context, else psf->state = FRAGSTATE_POST_PAYLOAD_SUM; - n = libwebsocket_write(wsi, bp, chunk, write_mode); + n = lws_write(wsi, bp, chunk, write_mode); if (n < 0) return -1; if (n < chunk) { @@ -177,7 +177,7 @@ callback_fraggle(struct libwebsocket_context *context, return -1; } - libwebsocket_callback_on_writable(context, wsi); + lws_callback_on_writable(context, wsi); break; case FRAGSTATE_POST_PAYLOAD_SUM: @@ -191,7 +191,7 @@ callback_fraggle(struct libwebsocket_context *context, bp[2] = psf->sum >> 8; bp[3] = psf->sum; - n = libwebsocket_write(wsi, (unsigned char *)bp, + n = lws_write(wsi, (unsigned char *)bp, 4, LWS_WRITE_BINARY); if (n < 0) return -1; @@ -202,7 +202,7 @@ callback_fraggle(struct libwebsocket_context *context, psf->state = FRAGSTATE_START_MESSAGE; - libwebsocket_callback_on_writable(context, wsi); + lws_callback_on_writable(context, wsi); break; } break; @@ -232,7 +232,7 @@ callback_fraggle(struct libwebsocket_context *context, /* list of supported protocols and callbacks */ -static struct libwebsocket_protocols protocols[] = { +static struct lws_protocols protocols[] = { { "fraggle-protocol", callback_fraggle, @@ -258,11 +258,11 @@ int main(int argc, char **argv) int n = 0; int port = 7681; int use_ssl = 0; - struct libwebsocket_context *context; + struct lws_context *context; int opts = 0; char interface_name[128] = ""; const char *iface = NULL; - struct libwebsocket *wsi; + struct lws *wsi; const char *address; int server_port = port; struct lws_context_creation_info info; @@ -318,7 +318,7 @@ int main(int argc, char **argv) info.iface = iface; info.protocols = protocols; #ifndef LWS_NO_EXTENSIONS - info.extensions = libwebsocket_get_internal_extensions(); + info.extensions = lws_get_internal_extensions(); #endif if (use_ssl) { info.ssl_cert_filepath = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem"; @@ -328,7 +328,7 @@ int main(int argc, char **argv) info.uid = -1; info.options = opts; - context = libwebsocket_create_context(&info); + context = lws_create_context(&info); if (context == NULL) { fprintf(stderr, "libwebsocket init failed\n"); return -1; @@ -337,7 +337,7 @@ int main(int argc, char **argv) if (client) { address = argv[optind]; fprintf(stderr, "Connecting to %s:%u\n", address, port); - wsi = libwebsocket_client_connect(context, address, + wsi = lws_client_connect(context, address, port, use_ssl, "/", address, "origin", protocols[PROTOCOL_FRAGGLE].name, -1); @@ -349,12 +349,12 @@ int main(int argc, char **argv) n = 0; while (!n && !terminate) - n = libwebsocket_service(context, 50); + n = lws_service(context, 50); fprintf(stderr, "Terminating...\n"); bail: - libwebsocket_context_destroy(context); + lws_context_destroy(context); return 0; } diff --git a/test-server/test-ping.c b/test-server/test-ping.c index d5b7c8e36..dd07e9fe1 100644 --- a/test-server/test-ping.c +++ b/test-server/test-ping.c @@ -48,7 +48,7 @@ #define MAX_PING_CLIENTS 256 #define PING_RINGBUFFER_SIZE 256 -static struct libwebsocket *ping_wsi[MAX_PING_CLIENTS]; +static struct lws *ping_wsi[MAX_PING_CLIENTS]; static unsigned int interval_us = 1000000; static unsigned int size = 64; static int flood; @@ -100,9 +100,9 @@ enum demo_protocols { static int -callback_lws_mirror(struct libwebsocket_context * this, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, +callback_lws_mirror(struct lws_context * this, + struct lws *wsi, + enum lws_callback_reasons reason, void *user, void *in, size_t len) { struct timeval tv; @@ -144,7 +144,7 @@ callback_lws_mirror(struct libwebsocket_context * this, * LWS_CALLBACK_CLIENT_WRITEABLE will come next service */ - libwebsocket_callback_on_writable(this, wsi); + lws_callback_on_writable(this, wsi); break; case LWS_CALLBACK_CLIENT_RECEIVE: @@ -256,11 +256,11 @@ callback_lws_mirror(struct libwebsocket_context * this, global_tx_count++; if (use_mirror) - n = libwebsocket_write(wsi, + n = lws_write(wsi, &pingbuf[LWS_SEND_BUFFER_PRE_PADDING], size, write_options | LWS_WRITE_BINARY); else - n = libwebsocket_write(wsi, + n = lws_write(wsi, &pingbuf[LWS_SEND_BUFFER_PRE_PADDING], size, write_options | LWS_WRITE_PING); @@ -286,7 +286,7 @@ callback_lws_mirror(struct libwebsocket_context * this, /* list of supported protocols and callbacks */ -static struct libwebsocket_protocols protocols[] = { +static struct lws_protocols protocols[] = { { "lws-mirror-protocol", @@ -330,7 +330,7 @@ int main(int argc, char **argv) int n = 0; int port = 7681; int use_ssl = 0; - struct libwebsocket_context *context; + struct lws_context *context; char protocol_name[256]; char ip[30]; #ifndef _WIN32 @@ -426,12 +426,12 @@ int main(int argc, char **argv) info.port = CONTEXT_PORT_NO_LISTEN; info.protocols = protocols; #ifndef LWS_NO_EXTENSIONS - info.extensions = libwebsocket_get_internal_extensions(); + info.extensions = lws_get_internal_extensions(); #endif info.gid = -1; info.uid = -1; - context = libwebsocket_create_context(&info); + context = lws_create_context(&info); if (context == NULL) { fprintf(stderr, "Creating libwebsocket context failed\n"); return 1; @@ -440,7 +440,7 @@ int main(int argc, char **argv) /* create client websockets using dumb increment protocol */ for (n = 0; n < clients; n++) { - ping_wsi[n] = libwebsocket_client_connect(context, address, + ping_wsi[n] = lws_client_connect(context, address, port, use_ssl, "/", address, "origin", protocols[PROTOCOL_LWS_MIRROR].name, ietf_version); @@ -451,8 +451,8 @@ int main(int argc, char **argv) } } - libwebsockets_get_peer_addresses(context, ping_wsi[0], - libwebsocket_get_socket_fd(ping_wsi[0]), + lws_get_peer_addresses(context, ping_wsi[0], + lws_get_socket_fd(ping_wsi[0]), peer_name, sizeof peer_name, ip, sizeof ip); fprintf(stderr, "Websocket PING %s (%s) %d bytes of data.\n", @@ -487,7 +487,7 @@ int main(int argc, char **argv) if (!interrupted_time) { if ((l - oldus) > interval_us) { for (n = 0; n < clients; n++) - libwebsocket_callback_on_writable( + lws_callback_on_writable( context, ping_wsi[n]); oldus = l; } @@ -501,9 +501,9 @@ int main(int argc, char **argv) } if (!interval_us) - n = libwebsocket_service(context, 0); + n = lws_service(context, 0); else - n = libwebsocket_service(context, 1); + n = lws_service(context, 1); } /* stats */ @@ -523,7 +523,7 @@ int main(int argc, char **argv) ((double)global_rx_count * (double)size) / ((double)(l - started) / 1000000.0) / 1024.0); - libwebsocket_context_destroy(context); + lws_context_destroy(context); return 0; diff --git a/test-server/test-server-dumb-increment.c b/test-server/test-server-dumb-increment.c index 81af06dcb..b8cba7a1e 100644 --- a/test-server/test-server-dumb-increment.c +++ b/test-server/test-server-dumb-increment.c @@ -23,9 +23,9 @@ /* dumb_increment protocol */ int -callback_dumb_increment(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, +callback_dumb_increment(struct lws_context *context, + struct lws *wsi, + enum lws_callback_reasons reason, void *user, void *in, size_t len) { unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 + @@ -43,7 +43,7 @@ callback_dumb_increment(struct libwebsocket_context *context, case LWS_CALLBACK_SERVER_WRITEABLE: n = sprintf((char *)p, "%d", pss->number++); - m = libwebsocket_write(wsi, p, n, LWS_WRITE_TEXT); + m = lws_write(wsi, p, n, LWS_WRITE_TEXT); if (m < n) { lwsl_err("ERROR %d writing to di socket\n", n); return -1; diff --git a/test-server/test-server-http.c b/test-server/test-server-http.c index dacd8e8db..7456d01af 100644 --- a/test-server/test-server-http.c +++ b/test-server/test-server-http.c @@ -60,7 +60,7 @@ struct serveable { * content */ void -dump_handshake_info(struct libwebsocket *wsi) +dump_handshake_info(struct lws *wsi) { int n = 0; char buf[256]; @@ -110,10 +110,9 @@ const char * get_mimetype(const char *file) * here on the first protocol server. */ -int callback_http(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, - void *in, size_t len) +int callback_http(struct lws_context *context, struct lws *wsi, + enum lws_callback_reasons reason, void *user, + void *in, size_t len) { struct per_session_data__http *pss = (struct per_session_data__http *)user; @@ -130,7 +129,7 @@ int callback_http(struct libwebsocket_context *context, int n, m; #ifdef EXTERNAL_POLL - struct libwebsocket_pollargs *pa = (struct libwebsocket_pollargs *)in; + struct lws_pollargs *pa = (struct lws_pollargs *)in; #endif switch (reason) { @@ -139,14 +138,14 @@ int callback_http(struct libwebsocket_context *context, dump_handshake_info(wsi); if (len < 1) { - libwebsockets_return_http_status(context, wsi, + lws_return_http_status(context, wsi, HTTP_STATUS_BAD_REQUEST, NULL); goto try_to_reuse; } /* this example server has no concept of directories */ if (strchr((const char *)in + 1, '/')) { - libwebsockets_return_http_status(context, wsi, + lws_return_http_status(context, wsi, HTTP_STATUS_FORBIDDEN, NULL); goto try_to_reuse; } @@ -217,7 +216,7 @@ int callback_http(struct libwebsocket_context *context, * this is mandated by changes in HTTP2 */ - n = libwebsocket_write(wsi, + n = lws_write(wsi, buffer + LWS_SEND_BUFFER_PRE_PADDING, p - (buffer + LWS_SEND_BUFFER_PRE_PADDING), LWS_WRITE_HTTP_HEADERS); @@ -229,7 +228,7 @@ int callback_http(struct libwebsocket_context *context, /* * book us a LWS_CALLBACK_HTTP_WRITEABLE callback */ - libwebsocket_callback_on_writable(context, wsi); + lws_callback_on_writable(context, wsi); break; } @@ -247,7 +246,7 @@ int callback_http(struct libwebsocket_context *context, mimetype = get_mimetype(buf); if (!mimetype) { lwsl_err("Unknown mimetype for %s\n", buf); - libwebsockets_return_http_status(context, wsi, + lws_return_http_status(context, wsi, HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE, NULL); return -1; } @@ -275,7 +274,7 @@ int callback_http(struct libwebsocket_context *context, other_headers = leaf_path; } - n = libwebsockets_serve_http_file(context, wsi, buf, + n = lws_serve_http_file(context, wsi, buf, mimetype, other_headers, n); if (n < 0 || ((n > 0) && lws_http_transaction_completed(wsi))) return -1; /* error or can't reuse connection: close the socket */ @@ -302,7 +301,7 @@ int callback_http(struct libwebsocket_context *context, case LWS_CALLBACK_HTTP_BODY_COMPLETION: lwsl_notice("LWS_CALLBACK_HTTP_BODY_COMPLETION\n"); /* the whole of the sent body arrived, close or reuse the connection */ - libwebsockets_return_http_status(context, wsi, + lws_return_http_status(context, wsi, HTTP_STATUS_OK, NULL); goto try_to_reuse; @@ -330,7 +329,7 @@ int callback_http(struct libwebsocket_context *context, n = m; n = read(pss->fd, buffer + LWS_SEND_BUFFER_PRE_PADDING, - n); + n); /* problem reading, close conn */ if (n < 0) goto bail; @@ -344,9 +343,8 @@ int callback_http(struct libwebsocket_context *context, * is handled by the library itself if you sent a * content-length header */ - m = libwebsocket_write(wsi, - buffer + LWS_SEND_BUFFER_PRE_PADDING, - n, LWS_WRITE_HTTP); + m = lws_write(wsi, buffer + LWS_SEND_BUFFER_PRE_PADDING, + n, LWS_WRITE_HTTP); if (m < 0) /* write failed, close conn */ goto bail; @@ -360,22 +358,23 @@ int callback_http(struct libwebsocket_context *context, goto bail; if (m) /* while still active, extend timeout */ - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_HTTP_CONTENT, 5); + lws_set_timeout(wsi, + PENDING_TIMEOUT_HTTP_CONTENT, 5); - /* if we have indigestion, let him clear it before eating more */ + /* if we have indigestion, let him clear it + * before eating more */ if (lws_partial_buffered(wsi)) break; } while (!lws_send_pipe_choked(wsi)); later: - libwebsocket_callback_on_writable(context, wsi); + lws_callback_on_writable(context, wsi); break; flush_bail: /* true if still partial pending */ if (lws_partial_buffered(wsi)) { - libwebsocket_callback_on_writable(context, wsi); + lws_callback_on_writable(context, wsi); break; } close(pss->fd); @@ -397,7 +396,6 @@ bail: /* if we returned non-zero from here, we kill the connection */ break; -#ifdef EXTERNAL_POLL /* * callbacks for managing the external poll() array appear in * protocol 0 callback @@ -407,16 +405,21 @@ bail: /* * lock mutex to protect pollfd state * called before any other POLL related callback + * if protecting wsi lifecycle change, len == 1 */ + test_server_lock(len); break; case LWS_CALLBACK_UNLOCK_POLL: /* * unlock mutex to protect pollfd state when * called after any other POLL related callback + * if protecting wsi lifecycle change, len == 1 */ + test_server_unlock(len); break; +#ifdef EXTERNAL_POLL case LWS_CALLBACK_ADD_POLL_FD: if (count_pollfds >= max_poll_elements) { @@ -446,7 +449,7 @@ bail: case LWS_CALLBACK_GET_THREAD_ID: /* - * if you will call "libwebsocket_callback_on_writable" + * if you will call "lws_callback_on_writable" * from a different thread, return the caller thread ID * here so lws can use this information to work out if it * should signal the poll() loop to exit and restart early diff --git a/test-server/test-server-mirror.c b/test-server/test-server-mirror.c index ced499d4b..bfc613330 100644 --- a/test-server/test-server-mirror.c +++ b/test-server/test-server-mirror.c @@ -33,9 +33,9 @@ static struct a_message ringbuffer[MAX_MESSAGE_QUEUE]; static int ringbuffer_head; int -callback_lws_mirror(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, +callback_lws_mirror(struct lws_context *context, + struct lws *wsi, + enum lws_callback_reasons reason, void *user, void *in, size_t len) { struct per_session_data__lws_mirror *pss = @@ -62,7 +62,7 @@ callback_lws_mirror(struct libwebsocket_context *context, break; while (pss->ringbuffer_tail != ringbuffer_head) { - n = libwebsocket_write(wsi, (unsigned char *) + n = lws_write(wsi, (unsigned char *) ringbuffer[pss->ringbuffer_tail].payload + LWS_SEND_BUFFER_PRE_PADDING, ringbuffer[pss->ringbuffer_tail].len, @@ -82,11 +82,11 @@ callback_lws_mirror(struct libwebsocket_context *context, if (((ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 15)) - libwebsocket_rx_flow_allow_all_protocol( - libwebsockets_get_protocol(wsi)); + lws_rx_flow_allow_all_protocol( + lws_get_protocol(wsi)); if (lws_partial_buffered(wsi) || lws_send_pipe_choked(wsi)) { - libwebsocket_callback_on_writable(context, wsi); + lws_callback_on_writable(context, wsi); break; } /* @@ -128,11 +128,11 @@ callback_lws_mirror(struct libwebsocket_context *context, choke: lwsl_debug("LWS_CALLBACK_RECEIVE: throttling %p\n", wsi); - libwebsocket_rx_flow_control(wsi, 0); + lws_rx_flow_control(wsi, 0); done: - libwebsocket_callback_on_writable_all_protocol( - libwebsockets_get_protocol(wsi)); + lws_callback_on_writable_all_protocol( + lws_get_protocol(wsi)); break; /* diff --git a/test-server/test-server-pthreads.c b/test-server/test-server-pthreads.c new file mode 100644 index 000000000..3d3c3d663 --- /dev/null +++ b/test-server/test-server-pthreads.c @@ -0,0 +1,342 @@ +/* + * libwebsockets-test-server - libwebsockets test implementation + * + * Copyright (C) 2010-2015 Andy Green + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation: + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "test-server.h" +#include + +int close_testing; +int max_poll_elements; + +#ifdef EXTERNAL_POLL +struct lws_pollfd *pollfds; +int *fd_lookup; +int count_pollfds; +#endif +volatile int force_exit = 0; +struct lws_context *context; + +/* + * This mutex lock protects code that changes or relies on wsi list outside of + * the service thread. The service thread will acquire it when changing the + * wsi list and other threads should acquire it while dereferencing wsis or + * calling apis like lws_callback_on_writable_all_protocol() which + * use the wsi list and wsis from a different thread context. + */ +pthread_mutex_t lock_established_conns; + +/* http server gets files from this path */ +#define LOCAL_RESOURCE_PATH INSTALL_DATADIR"/libwebsockets-test-server" +char *resource_path = LOCAL_RESOURCE_PATH; + +/* + * multithreaded version - protect wsi lifecycle changes in the library + * these are called from protocol 0 callbacks + */ + +void test_server_lock(int care) +{ + if (care) + pthread_mutex_lock(&lock_established_conns); +} +void test_server_unlock(int care) +{ + if (care) + pthread_mutex_unlock(&lock_established_conns); +} + +/* + * This demo server shows how to use libwebsockets for one or more + * websocket protocols in the same server + * + * It defines the following websocket protocols: + * + * dumb-increment-protocol: once the socket is opened, an incrementing + * ascii string is sent down it every 50ms. + * If you send "reset\n" on the websocket, then + * the incrementing number is reset to 0. + * + * lws-mirror-protocol: copies any received packet to every connection also + * using this protocol, including the sender + */ + +enum demo_protocols { + /* always first */ + PROTOCOL_HTTP = 0, + + PROTOCOL_DUMB_INCREMENT, + PROTOCOL_LWS_MIRROR, + + /* always last */ + DEMO_PROTOCOL_COUNT +}; + +/* list of supported protocols and callbacks */ + +static struct lws_protocols protocols[] = { + /* first protocol must always be HTTP handler */ + + { + "http-only", /* name */ + callback_http, /* callback */ + sizeof (struct per_session_data__http), /* per_session_data_size */ + 0, /* max frame size / rx buffer */ + }, + { + "dumb-increment-protocol", + callback_dumb_increment, + sizeof(struct per_session_data__dumb_increment), + 10, + }, + { + "lws-mirror-protocol", + callback_lws_mirror, + sizeof(struct per_session_data__lws_mirror), + 128, + }, + { NULL, NULL, 0, 0 } /* terminator */ +}; + +void *thread_dumb_increment(void *threadid) +{ + while (!force_exit) { + /* + * this lock means wsi in the active list cannot + * disappear underneath us, because the code to add and remove + * them is protected by the same lock + */ + pthread_mutex_lock(&lock_established_conns); + lws_callback_on_writable_all_protocol( + &protocols[PROTOCOL_DUMB_INCREMENT]); + pthread_mutex_unlock(&lock_established_conns); + usleep(100000); + } + + pthread_exit(NULL); +} + +void sighandler(int sig) +{ + force_exit = 1; + lws_cancel_service(context); +} + +static struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "debug", required_argument, NULL, 'd' }, + { "port", required_argument, NULL, 'p' }, + { "ssl", no_argument, NULL, 's' }, + { "allow-non-ssl", no_argument, NULL, 'a' }, + { "interface", required_argument, NULL, 'i' }, + { "closetest", no_argument, NULL, 'c' }, + { "libev", no_argument, NULL, 'e' }, +#ifndef LWS_NO_DAEMONIZE + { "daemonize", no_argument, NULL, 'D' }, +#endif + { "resource_path", required_argument, NULL, 'r' }, + { NULL, 0, 0, 0 } +}; + +int main(int argc, char **argv) +{ + struct lws_context_creation_info info; + char interface_name[128] = ""; + const char *iface = NULL; + pthread_t pthread_dumb; + char cert_path[1024]; + char key_path[1024]; + int debug_level = 7; + int use_ssl = 0; + void *retval; + int opts = 0; + int n = 0; +#ifndef _WIN32 + int syslog_options = LOG_PID | LOG_PERROR; +#endif +#ifndef LWS_NO_DAEMONIZE + int daemonize = 0; +#endif + + /* + * take care to zero down the info struct, he contains random garbaage + * from the stack otherwise + */ + memset(&info, 0, sizeof info); + info.port = 7681; + + pthread_mutex_init(&lock_established_conns, NULL); + + while (n >= 0) { + n = getopt_long(argc, argv, "eci:hsap:d:Dr:", options, NULL); + if (n < 0) + continue; + switch (n) { + case 'e': + opts |= LWS_SERVER_OPTION_LIBEV; + break; +#ifndef LWS_NO_DAEMONIZE + case 'D': + daemonize = 1; + #ifndef _WIN32 + syslog_options &= ~LOG_PERROR; + #endif + break; +#endif + case 'd': + debug_level = atoi(optarg); + break; + case 's': + use_ssl = 1; + break; + case 'a': + opts |= LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT; + break; + case 'p': + info.port = atoi(optarg); + break; + case 'i': + strncpy(interface_name, optarg, sizeof interface_name); + interface_name[(sizeof interface_name) - 1] = '\0'; + iface = interface_name; + break; + case 'c': + close_testing = 1; + fprintf(stderr, " Close testing mode -- closes on " + "client after 50 dumb increments" + "and suppresses lws_mirror spam\n"); + break; + case 'r': + resource_path = optarg; + printf("Setting resource path to \"%s\"\n", resource_path); + break; + case 'h': + fprintf(stderr, "Usage: test-server " + "[--port=

] [--ssl] " + "[-d ] " + "[--resource_path ]\n"); + exit(1); + } + } + +#if !defined(LWS_NO_DAEMONIZE) && !defined(WIN32) + /* + * normally lock path would be /var/lock/lwsts or similar, to + * simplify getting started without having to take care about + * permissions or running as root, set to /tmp/.lwsts-lock + */ + if (daemonize && lws_daemonize("/tmp/.lwsts-lock")) { + fprintf(stderr, "Failed to daemonize\n"); + return 1; + } +#endif + + signal(SIGINT, sighandler); + +#ifndef _WIN32 + /* we will only try to log things according to our debug_level */ + setlogmask(LOG_UPTO (LOG_DEBUG)); + openlog("lwsts", syslog_options, LOG_DAEMON); +#endif + + /* tell the library what debug level to emit and to send it to syslog */ + lws_set_log_level(debug_level, lwsl_emit_syslog); + + lwsl_notice("libwebsockets test server - " + "(C) Copyright 2010-2015 Andy Green - " + "licensed under LGPL2.1\n"); + + printf("Using resource path \"%s\"\n", resource_path); +#ifdef EXTERNAL_POLL + max_poll_elements = getdtablesize(); + pollfds = malloc(max_poll_elements * sizeof (struct lws_pollfd)); + fd_lookup = malloc(max_poll_elements * sizeof (int)); + if (pollfds == NULL || fd_lookup == NULL) { + lwsl_err("Out of memory pollfds=%d\n", max_poll_elements); + return -1; + } +#endif + + info.iface = iface; + info.protocols = protocols; +#ifndef LWS_NO_EXTENSIONS + info.extensions = lws_get_internal_extensions(); +#endif + + info.ssl_cert_filepath = NULL; + info.ssl_private_key_filepath = NULL; + + if (use_ssl) { + if (strlen(resource_path) > sizeof(cert_path) - 32) { + lwsl_err("resource path too long\n"); + return -1; + } + sprintf(cert_path, "%s/libwebsockets-test-server.pem", + resource_path); + if (strlen(resource_path) > sizeof(key_path) - 32) { + lwsl_err("resource path too long\n"); + return -1; + } + sprintf(key_path, "%s/libwebsockets-test-server.key.pem", + resource_path); + + info.ssl_cert_filepath = cert_path; + info.ssl_private_key_filepath = key_path; + } + info.gid = -1; + info.uid = -1; + info.options = opts; + + context = lws_create_context(&info); + if (context == NULL) { + lwsl_err("libwebsocket init failed\n"); + return -1; + } + + /* start the dumb increment thread */ + + n = pthread_create(&pthread_dumb, NULL, thread_dumb_increment, 0); + if (n) { + lwsl_err("Unable to create dumb thread\n"); + goto done; + } + + /* this is our service thread */ + + n = 0; + while (n >= 0 && !force_exit) { + n = lws_service(context, 50); + } + + /* wait for pthread_dumb to exit */ + pthread_join(pthread_dumb, &retval); + +done: + lws_context_destroy(context); + pthread_mutex_destroy(&lock_established_conns); + + + lwsl_notice("libwebsockets-test-server exited cleanly\n"); + +#ifndef _WIN32 + closelog(); +#endif + + return 0; +} diff --git a/test-server/test-server.c b/test-server/test-server.c index c53037e9c..3b9b7c850 100644 --- a/test-server/test-server.c +++ b/test-server/test-server.c @@ -25,17 +25,26 @@ int close_testing; int max_poll_elements; #ifdef EXTERNAL_POLL -struct libwebsocket_pollfd *pollfds; +struct lws_pollfd *pollfds; int *fd_lookup; int count_pollfds; #endif volatile int force_exit = 0; -struct libwebsocket_context *context; +struct lws_context *context; /* http server gets files from this path */ #define LOCAL_RESOURCE_PATH INSTALL_DATADIR"/libwebsockets-test-server" char *resource_path = LOCAL_RESOURCE_PATH; +/* singlethreaded version --> no locks */ + +void test_server_lock(int care) +{ +} +void test_server_unlock(int care) +{ +} + /* * This demo server shows how to use libwebsockets for one or more * websocket protocols in the same server @@ -64,7 +73,7 @@ enum demo_protocols { /* list of supported protocols and callbacks */ -static struct libwebsocket_protocols protocols[] = { +static struct lws_protocols protocols[] = { /* first protocol must always be HTTP handler */ { @@ -91,7 +100,7 @@ static struct libwebsocket_protocols protocols[] = { void sighandler(int sig) { force_exit = 1; - libwebsocket_cancel_service(context); + lws_cancel_service(context); } static struct option options[] = { @@ -126,7 +135,7 @@ int main(int argc, char **argv) int syslog_options = LOG_PID | LOG_PERROR; #endif #ifndef LWS_NO_DAEMONIZE -// int daemonize = 0; + int daemonize = 0; #endif /* @@ -218,7 +227,7 @@ int main(int argc, char **argv) printf("Using resource path \"%s\"\n", resource_path); #ifdef EXTERNAL_POLL max_poll_elements = getdtablesize(); - pollfds = malloc(max_poll_elements * sizeof (struct libwebsocket_pollfd)); + pollfds = malloc(max_poll_elements * sizeof (struct lws_pollfd)); fd_lookup = malloc(max_poll_elements * sizeof (int)); if (pollfds == NULL || fd_lookup == NULL) { lwsl_err("Out of memory pollfds=%d\n", max_poll_elements); @@ -229,7 +238,7 @@ int main(int argc, char **argv) info.iface = iface; info.protocols = protocols; #ifndef LWS_NO_EXTENSIONS - info.extensions = libwebsocket_get_internal_extensions(); + info.extensions = lws_get_internal_extensions(); #endif info.ssl_cert_filepath = NULL; @@ -256,7 +265,7 @@ int main(int argc, char **argv) info.uid = -1; info.options = opts; - context = libwebsocket_create_context(&info); + context = lws_create_context(&info); if (context == NULL) { lwsl_err("libwebsocket init failed\n"); return -1; @@ -276,7 +285,7 @@ int main(int argc, char **argv) ms = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); if ((ms - oldms) > 50) { - libwebsocket_callback_on_writable_all_protocol( + lws_callback_on_writable_all_protocol( &protocols[PROTOCOL_DUMB_INCREMENT]); oldms = ms; } @@ -301,7 +310,7 @@ int main(int argc, char **argv) * match anything under libwebsockets * control */ - if (libwebsocket_service_fd(context, + if (lws_service_fd(context, &pollfds[n]) < 0) goto done; #else @@ -314,7 +323,7 @@ int main(int argc, char **argv) * the number of ms in the second argument. */ - n = libwebsocket_service(context, 50); + n = lws_service(context, 50); #endif } @@ -322,7 +331,7 @@ int main(int argc, char **argv) done: #endif - libwebsocket_context_destroy(context); + lws_context_destroy(context); lwsl_notice("libwebsockets-test-server exited cleanly\n"); diff --git a/test-server/test-server.h b/test-server/test-server.h index 73805eb8e..3ebf6f790 100644 --- a/test-server/test-server.h +++ b/test-server/test-server.h @@ -27,14 +27,17 @@ extern int close_testing; extern int max_poll_elements; #ifdef EXTERNAL_POLL -extern struct libwebsocket_pollfd *pollfds; +extern struct lws_pollfd *pollfds; extern int *fd_lookup; extern int count_pollfds; #endif extern volatile int force_exit; -extern struct libwebsocket_context *context; +extern struct lws_context *context; extern char *resource_path; +extern void test_server_lock(int care); +extern void test_server_unlock(int care); + #ifndef __func__ #define __func__ __FUNCTION__ #endif @@ -56,22 +59,22 @@ struct per_session_data__dumb_increment { }; struct per_session_data__lws_mirror { - struct libwebsocket *wsi; + struct lws *wsi; int ringbuffer_tail; }; -extern int callback_http(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, +extern int callback_http(struct lws_context *context, + struct lws *wsi, + enum lws_callback_reasons reason, void *user, void *in, size_t len); -extern int callback_lws_mirror(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, +extern int callback_lws_mirror(struct lws_context *context, + struct lws *wsi, + enum lws_callback_reasons reason, void *user, void *in, size_t len); -extern int callback_dumb_increment(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, +extern int callback_dumb_increment(struct lws_context *context, + struct lws *wsi, + enum lws_callback_reasons reason, void *user, void *in, size_t len); extern void -dump_handshake_info(struct libwebsocket *wsi); \ No newline at end of file +dump_handshake_info(struct lws *wsi);