From 02f880d9b63e71646b6b88e3402ececc405f50fe Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 13 Jul 2016 08:14:57 +0800 Subject: [PATCH] doxygen use sections --- README.build.md | 107 ++++++-------- README.coding.md | 121 +++++++++------- README.generic-sessions.md | 36 ++--- README.lwsws.md | 53 +++---- README.test-apps.md | 56 +++----- doc/html/md_README.build.html | 64 +++++---- doc/html/md_README.coding.html | 84 +++++++---- doc/html/md_README.generic-sessions.html | 32 +++-- doc/html/md_README.generic-table.html | 171 +++++++++++++++++++++++ doc/html/md_README.lwsws.html | 50 ++++--- doc/html/md_README.test-apps.html | 51 ++++--- doc/html/navtreedata.js | 99 ++++++++++++- doc/html/navtreeindex0.js | 58 ++++---- doc/html/navtreeindex1.js | 68 ++++----- doc/html/navtreeindex2.js | 68 ++++----- doc/html/navtreeindex3.js | 132 ++++++++++------- doc/html/navtreeindex4.js | 53 +++++++ doc/latex/md_README.build.tex | 109 +++------------ doc/latex/md_README.coding.tex | 116 ++++++--------- doc/latex/md_README.generic-sessions.tex | 47 ++----- doc/latex/md_README.lwsws.tex | 70 +++------- doc/latex/md_README.test-apps.tex | 85 +++-------- 22 files changed, 970 insertions(+), 760 deletions(-) create mode 100644 doc/html/md_README.generic-table.html create mode 100644 doc/html/navtreeindex4.js diff --git a/README.build.md b/README.build.md index 4055ecf1..18dea7a2 100644 --- a/README.build.md +++ b/README.build.md @@ -2,8 +2,7 @@ Notes about building lws ======================== -Introduction to CMake ---------------------- +@section cm Introduction to CMake CMake is a multi-platform build tool that can generate build files for many different target platforms. See more info at http://www.cmake.org @@ -22,8 +21,8 @@ with SSL support (both OpenSSL/wolfSSL): - OSX - NetBSD -Building the library and test apps ----------------------------------- + +@section build1 Building the library and test apps The project settings used by CMake to generate the platform specific build files is called [CMakeLists.txt](CMakeLists.txt). CMake then uses one of its "Generators" to @@ -33,8 +32,8 @@ the available generators for your platform, simply run the "cmake" command. Note that by default OpenSSL will be linked, if you don't want SSL support see below on how to toggle compile options. -Building on Unix: ------------------ + +@section bu Building on Unix: 1. Install CMake 2.8 or greater: http://cmake.org/cmake/resources/software.html (Most Unix distributions comes with a packaged version also) @@ -101,15 +100,15 @@ compiled in, use $ cmake .. -DCMAKE_BUILD_TYPE=DEBUG ``` -Quirk of cmake --------------- +@section cmq Quirk of cmake When changing cmake options, for some reason the only way to get it to see the changes sometimes is delete the contents of your build directory and do the cmake from scratch. -Building on Windows (Visual Studio) ------------------------------------ + +@section cmw Building on Windows (Visual Studio) + 1. Install CMake 2.6 or greater: http://cmake.org/cmake/resources/software.html 2. Install OpenSSL binaries. http://www.openssl.org/related/binaries.html @@ -147,8 +146,8 @@ Building on Windows (Visual Studio) 6. If you're using libuv, you must make sure to compile libuv with the same multithread-dll / Mtd attributes as libwebsockets itself -Building on Windows (MinGW) ---------------------------- +@section cmwmgw Building on Windows (MinGW) + 1. Install MinGW: http://sourceforge.net/projects/mingw/files (**NOTE**: Preferably in the default location C:\MinGW) @@ -210,26 +209,8 @@ Building on Windows (MinGW) $ make install ``` -Setting compile options ------------------------ +@section mbed3 Building on mbed3 -To set compile time flags you can either use one of the CMake gui applications -or do it via command line. - -Command line ------------- -To list avaialable options (ommit the H if you don't want the help text): - - cmake -LH .. - -Then to set an option and build (for example turn off SSL support): - - cmake -DLWS_WITH_SSL=0 .. -or - cmake -DLWS_WITH_SSL:BOOL=OFF .. - -Building on mbed3 ------------------ MBED3 is a non-posix embedded OS targeted on Cortex M class chips. https://www.mbed.com/ @@ -270,21 +251,39 @@ and cd into it 8) yotta build +@section cmco Setting compile options + + +To set compile time flags you can either use one of the CMake gui applications +or do it via command line. + +@subsection cmcocl Command line + +To list avaialable options (omit the H if you don't want the help text): + + cmake -LH .. + +Then to set an option and build (for example turn off SSL support): + + cmake -DLWS_WITH_SSL=0 .. +or + cmake -DLWS_WITH_SSL:BOOL=OFF .. + +@subsection cmcoug Unix GUI -Unix GUI --------- If you have a curses-enabled build you simply type: (not all packages include this, my debian install does not for example). ccmake -Windows GUI ------------ +@subsection cmcowg Windows GUI + On windows CMake comes with a gui application: Start -> Programs -> CMake -> CMake (cmake-gui) -wolfSSL/CyaSSL replacement for OpenSSL --------------------------------------- + +@section wolf wolfSSL/CyaSSL replacement for OpenSSL + wolfSSL/CyaSSL is a lightweight SSL library targeted at embedded systems: https://www.wolfssl.com/wolfSSL/Products-wolfssl.html @@ -294,8 +293,8 @@ much link to it instead of OpenSSL, giving a much smaller footprint. **NOTE**: wolfssl needs to be compiled using the `--enable-opensslextra` flag for this to work. -Compiling libwebsockets with wolfSSL ------------------------------------- +@section wolf1 Compiling libwebsockets with wolfSSL + ``` cmake .. -DLWS_USE_WOLFSSL=1 \ -DLWS_WOLFSSL_INCLUDE_DIRS=/path/to/wolfssl \ @@ -304,8 +303,8 @@ Compiling libwebsockets with wolfSSL **NOTE**: On windows use the .lib file extension for `LWS_WOLFSSL_LIBRARIES` instead. -Compiling libwebsockets with CyaSSL ------------------------------------ +@section cya Compiling libwebsockets with CyaSSL + ``` cmake .. -DLWS_USE_CYASSL=1 \ -DLWS_CYASSL_INCLUDE_DIRS=/path/to/cyassl \ @@ -314,22 +313,8 @@ Compiling libwebsockets with CyaSSL **NOTE**: On windows use the .lib file extension for `LWS_CYASSL_LIBRARIES` instead. -Compiling libwebsockets with PolarSSL -------------------------------------- -Caution... at some point PolarSSL became MbedTLS. But it did not happen all at once. -The name changed first then at mbedTLS 2.0 the apis changed. So eg in Fedora 22, -there is an "mbedtls" package which is actually using polarssl for the include dir -and polarssl apis... this should be treated as polarssl then. - -Example config for this case is -``` -cmake .. -DLWS_USE_POLARSSL=1 -DLWS_POLARSSL_LIBRARIES=/usr/lib64/libmbedtls.so \ - -DLWS_POLARSSL_INCLUDE_DIRS=/usr/include/polarssl/ -``` - -Building plugins outside of lws itself --------------------------------------- +@section extplugins Building plugins outside of lws itself The directory ./plugin-standalone/ shows how easy it is to create plugins outside of lws itself. First build lws itself with -DLWS_WITH_PLUGINS, @@ -361,8 +346,7 @@ additionally, discovered plugins are not enabled automatically for security reasons. You do this using info->pvo or for lwsws, in the JSON config. -Reproducing HTTP2.0 tests -------------------------- +@section http2rp Reproducing HTTP2.0 tests You must have built and be running lws against a version of openssl that has ALPN / NPN. Most distros still have older versions. You'll know it's right by @@ -383,8 +367,8 @@ For SSL / ALPN HTTP2.0 upgrade $ nghttp -nvas https://localhost:7681/test.html ``` -Cross compiling ---------------- +@section cross Cross compiling + To enable cross-compiling **libwebsockets** using CMake you need to create a "Toolchain file" that you supply to CMake when generating your build files. CMake will then use the cross compilers and build paths specified in this file @@ -408,8 +392,7 @@ need to provide the cross libraries otherwise. Additional information on cross compilation with CMake: http://www.vtk.org/Wiki/CMake_Cross_Compiling -Memory efficiency ------------------ +@section mem Memory efficiency Embedded server-only configuration without extensions (ie, no compression on websocket connections), but with full v13 websocket features and http diff --git a/README.coding.md b/README.coding.md index 5b438397..7a85e338 100644 --- a/README.coding.md +++ b/README.coding.md @@ -1,8 +1,7 @@ Notes about coding with lws =========================== -Daemonization -------------- +@section dae Daemonization There's a helper api `lws_daemonize` built by default that does everything you need to daemonize well, including creating a lock file. If you're making @@ -14,8 +13,7 @@ daemon is headless, so you'll need to sort out alternative logging, by, eg, syslog. -Maximum number of connections ------------------------------ +@section conns Maximum number of connections The maximum number of connections the library can deal with is decided when it starts by querying the OS to find out how many file descriptors it is @@ -28,8 +26,9 @@ similar to change the avaiable number of file descriptors, and when restarted **libwebsockets** will adapt accordingly. -Libwebsockets is singlethreaded -------------------------------- +@section evtloop Libwebsockets is singlethreaded + +Libwebsockets works in a serialized event loop, in a single thread. Directly performing websocket actions from other threads is not allowed. Aside from the internal data being inconsistent in `forked()` processes, @@ -67,8 +66,7 @@ SSL_library_init() is called from the context create api and it also is not reentrant. So at least create the contexts sequentially. -Only send data when socket writeable ------------------------------------- +@section writeable Only send data when socket writeable You should only send data on a websocket connection from the user callback `LWS_CALLBACK_SERVER_WRITEABLE` (or `LWS_CALLBACK_CLIENT_WRITEABLE` for @@ -90,8 +88,7 @@ in the ...WRITEABLE callback. See the test server code for an example of how to do this. -Do not rely on only your own WRITEABLE requests appearing ---------------------------------------------------------- +@section otherwr Do not rely on only your own WRITEABLE requests appearing Libwebsockets may generate additional `LWS_CALLBACK_CLIENT_WRITEABLE` events if it met network conditions where it had to buffer your send data internally. @@ -104,8 +101,7 @@ It's quite possible you get an 'extra' writeable callback at any time and just need to `return 0` and wait for the expected callback later. -Closing connections from the user side --------------------------------------- +@section closing 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. @@ -122,11 +118,10 @@ take care of closing the connection automatically. If you have a silently dead connection, it's possible to enter a state where the send pipe on the connection is choked but no ack will ever come, so the dead connection will never become writeable. To cover that, you can use TCP -keepalives (see later in this document) +keepalives (see later in this document) or pings. -Fragmented messages -------------------- +@section frags Fragmented messages To support fragmented messages you need to check for the final frame of a message with `lws_is_final_fragment`. This @@ -158,8 +153,7 @@ The test app libwebsockets-test-fraggle sources also show how to deal with fragmented messages. -Debug Logging -------------- +@section debuglog Debug Logging Also using `lws_set_log_level` api you may provide a custom callback to actually emit the log string. By default, this points to an internal emit function @@ -180,9 +174,17 @@ The logging apis are made available for user code. The difference between notice and info is that notice will be logged by default whereas info is ignored by default. +If you are not building with _DEBUG defined, ie, without this -External Polling Loop support ------------------------------ +``` + $ cmake .. -DCMAKE_BUILD_TYPE=DEBUG +``` + +then log levels below notice do not actually get compiled in. + + + +@section extpoll External Polling Loop support **libwebsockets** maintains an internal `poll()` array for all of its sockets, but you can instead integrate the sockets into an @@ -215,8 +217,7 @@ reflecting the real event: losing windows compatibility -Using with in c++ apps ----------------------- +@section cpp Using with in c++ apps The library is ready for use by C++ apps. You can get started quickly by copying the test server @@ -236,18 +237,21 @@ you remove the references to it in your app you don't need to define it on the g++ line either. -Availability of header information ----------------------------------- +@section headerinfo Availability of header information -From v1.2 of the library onwards, the HTTP header content is `free()`d as soon -as the websocket connection is established. For websocket servers, you can -copy interesting headers by handling `LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION` -callback, for clients there's a new callback just for this purpose -`LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH`. +HTTP Header information is managed by a pool of "ah" structs. These are a +limited resource so there is pressure to free the headers and return the ah to +the pool for reuse. + +For that reason header information on HTTP connections that get upgraded to +websockets is lost after the ESTABLISHED callback. Anything important that +isn't processed by user code before then should be copied out for later. + +For HTTP connections that don't upgrade, header info remains available the +whole time. -TCP Keepalive -------------- +@section ka TCP Keepalive It is possible for a connection which is not being used to send to die silently somewhere between the peer and the side not sending. In this case @@ -272,8 +276,8 @@ like Linux does. On those systems you can enable keepalive by a nonzero value in `ka_time`, but the systemwide kernel settings for the time / probes/ interval are used, regardless of what nonzero value is in `ka_time`. -Optimizing SSL connections --------------------------- + +@section sslopt Optimizing SSL connections There's a member `ssl_cipher_list` in the `lws_context_creation_info` struct which allows the user code to restrict the possible cipher selection at @@ -289,8 +293,7 @@ if left `NULL`, then the "DEFAULT" set of ciphers are all possible to select. You can also set it to `"ALL"` to allow everything (including insecure ciphers). -Async nature of client connections ----------------------------------- +@section clientasync Async nature of client connections When you call `lws_client_connect_info(..)` and get a `wsi` back, it does not mean your connection is active. It just means it started trying to connect. @@ -308,8 +311,19 @@ 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. -Lws platform-independent file access apis ------------------------------------------ +Notice that the client connection api tries to progress the connection +somewhat before returning. That means it's possible to get callbacks like +CONNECTION_ERROR on the new connection before your user code had a chance to +get the wsi returned to identify it (in fact if the connection did fail early, +NULL will be returned instead of the wsi anyway). + +To avoid that problem, you can fill in `pwsi` in the client connection info +struct to point to a struct lws that get filled in early by the client +connection api with the related wsi. You can then check for that in the +callback to confirm the identity of the failing client connection. + + +@section fileapi Lws platform-independent file access apis lws now exposes his internal platform file abstraction in a way that can be both used by user code to make it platform-agnostic, and be overridden or @@ -352,8 +366,7 @@ file handling apis The user code can also override or subclass the file operations, to either wrap or replace them. An example is shown in test server. -ECDH Support ------------- +@section ecdh ECDH Support ECDH Certs are now supported. Enable the CMake option @@ -365,8 +378,7 @@ ECDH Certs are now supported. Enable the CMake option to build in support and select it at runtime. -SMP / Multithreaded service ---------------------------- +@section smp SMP / Multithreaded service SMP support is integrated into LWS without any internal threading. It's very simple to use, libwebsockets-test-server-pthread shows how to do it, @@ -414,8 +426,7 @@ There is no knowledge or dependency in lws itself about pthreads. How the locking is implemented is entirely up to the user code. -Libev / Libuv support ---------------------- +@section libevuv Libev / Libuv support You can select either or both @@ -431,8 +442,7 @@ context init options flags to indicate it will use either of the event libraries. -Extension option control from user code ---------------------------------------- +@section extopts Extension option control from user code User code may set per-connection extension options now, using a new api `lws_set_extension_option()`. @@ -452,8 +462,8 @@ The extension may decide to alter or disallow the change, in the example above permessage-deflate restricts the size of his rx output buffer also considering the protocol's rx_buf_size member. -Client connections as HTTP[S] rather than WS[S] ------------------------------------------------ + +@section httpsclient Client connections as HTTP[S] rather than WS[S] You may open a generic http client connection using the same struct lws_client_connect_info used to create client ws[s] @@ -497,8 +507,14 @@ data, eg break; ``` -Using lws v2 vhosts -------------------- +Notice that if you will use SSL client connections on a vhost, you must +prepare the client SSL context for the vhost after creating the vhost, since +this is not normally done if the vhost was set up to listen / serve. Call +the api lws_init_vhost_client_ssl() to also allow client SSL on the vhost. + + + +@section vhosts Using lws vhosts If you set LWS_SERVER_OPTION_EXPLICIT_VHOSTS options flag when you create your context, it won't create a default vhost using the info struct @@ -534,8 +550,7 @@ There are some new members but mainly it's stuff you used to set at context creation time. -How lws matches hostname or SNI to a vhost ------------------------------------------- +@section sni How lws matches hostname or SNI to a vhost LWS first strips any trailing :port number. @@ -553,8 +568,7 @@ certificate allows wildcards and error out if not. -Using lws v2 mounts on a vhost ------------------------------- +@section mounts Using lws mounts on a vhost The last argument to lws_create_vhost() lets you associate a linked list of lws_http_mount structures with that vhost's URL 'namespace', in @@ -615,8 +629,7 @@ origin URL. associated with the named protocol (which may be a plugin). -Operation of LWSMPRO_CALLBACK mounts ------------------------------------- +@section mountcallback Operation of LWSMPRO_CALLBACK mounts The feature provided by CALLBACK type mounts is binding a part of the URL namespace to a named protocol callback handler. diff --git a/README.generic-sessions.md b/README.generic-sessions.md index 7f2acc11..376342a0 100644 --- a/README.generic-sessions.md +++ b/README.generic-sessions.md @@ -1,16 +1,14 @@ Notes about generic-sessions Plugin =================================== -Enabling for build ------------------- +@section gseb Enabling lwsgs for build Enable at CMake with -DLWS_WITH_GENERIC_SESSIONS=1 This also needs sqlite3 (libsqlite3-dev or similar package) -Introduction ------------- +@section gsi lwsgs Introduction The generic-sessions protocol plugin provides cookie-based login authentication for lws web and ws connections. @@ -51,8 +49,7 @@ authenticated as. Everything underneath is managed in generic-sessions. - No code (just config) required for, eg, private URL namespace that requires login to access. -Integration to HTML -------------------- +@section gsin Lwsgs Integration to HTML Only three steps are needed to integrate lwsgs in your HTML. @@ -92,8 +89,8 @@ That's it. An example is below ``` -Overall Flow ------------- + +@section gsof Lwsgs Overall Flow@ When the protocol is initialized, it gets per-vhost information from the config, such as where the sqlite3 databases are to be stored. The admin username and sha-1 of the @@ -112,10 +109,9 @@ After a successful login, the sqlite record at the server for the current sessio -Configuration -------------- +@section gsconf Lwsgs Configuration -"auth-mask" defines the autorization sector bits that must be enabled on the session to gain access. +"auth-mask" defines the authorization sector bits that must be enabled on the session to gain access. "auth-mask" 0 is the default. @@ -227,8 +223,7 @@ Notice the real application uses his own sqlite db, no details about how generic-sessions works or how it stores data are available to it. -Password Confounder -------------------- +@section gspwc Lwsgs Password Confounder You can also define a per-vhost confounder shown in the example above, used when aggregating the password with the salt when it is hashed. Any attacker @@ -236,8 +231,7 @@ will also need to get the confounder along with the database, which you can make harder by making the config dir only eneterable / readable by root. -Preparing the db directory --------------------------- +@section gsprep Lwsgs Preparing the db directory You will have to prepare the db directory so it's suitable for the lwsws user to use, that usually means apache, eg @@ -248,8 +242,7 @@ that usually means apache, eg # chmod 770 /var/www/sessions ``` -Email configuration -------------------- +@section gsrmail Lwsgs Email configuration lwsgs will can send emails by talking to an SMTP server on localhost:25. That will usually be sendmail or postfix, you should confirm that works first by @@ -258,14 +251,16 @@ itself using the `mail` application to send on it. lwsgs has been tested on stock Fedora sendmail and postfix. -Integration with another protocol ---------------------------------- +@section gsap Lwsgs Integration with another protocol lwsgs is designed to provide sessions and accounts in a standalone and generic way. But it's not useful by itself, there will always be the actual application who wants to make use of generic-sessions features. +We provide the "messageboard" plugin as an example of how to integrate with +your actual application protocol. + The basic approach is the 'real' protocol handler (usually a plugin itself) subclasses the generic-sessions plugin and calls through to it by default. @@ -340,8 +335,7 @@ secondary allocations. ``` -Getting session-specific information from another protocol ----------------------------------------------------------- +#section gsapsib Getting session-specific information from another protocol At least at the time when someone tries to upgrade an http(s) connection to ws(s) with your real protocol, it is necessary to confirm the cookie the http(s) diff --git a/README.lwsws.md b/README.lwsws.md index a8722b0a..d9f6f073 100644 --- a/README.lwsws.md +++ b/README.lwsws.md @@ -1,26 +1,29 @@ Notes about lwsws ================= -Libwebsockets Web Server ------------------------- +@section lwsws Libwebsockets Web Server lwsws is an implementation of a very lightweight, ws-capable generic web server, which uses libwebsockets to implement everything underneath. -Build ------ +If you are basically implementing a standalone server with lws, you can avoid +reinventing the wheel and use a debugged server including lws. + + +@section lwswsb Build Just enable -DLWS_WITH_LWSWS=1 at cmake-time. It enables libuv and plugin support automatically. -Configuration -------------- +@section lwswsc Lwsws Configuration -lwsws uses JSON config files, they're pure JSON but # may be used to turn the rest of the line into a comment. +lwsws uses JSON config files, they're pure JSON except: -There's also a single substitution, if a string contains "_lws_ddir_", then that is + - '#' may be used to turn the rest of the line into a comment. + + - There's also a single substitution, if a string contains "_lws_ddir_", then that is replaced with the LWS install data directory path, eg, "/usr/share" or whatever was set when LWS was built + installed. That lets you refer to installed paths without having to change the config if your install path was different. @@ -71,8 +74,8 @@ on port 7681, non-SSL is provided. To set it up # cp ./lwsws/etc-lwsws-conf.d-localhost-EXAMPLE /etc/lwsws/conf.d/test-server # sudo lwsws ``` -Vhosts ------- + +@section lwswsv Lwsws Vhosts One server can run many vhosts, where SSL is in use SNI is used to match the connection to a vhost and its vhost-specific SSL keys during SSL @@ -132,8 +135,7 @@ Listing multiple vhosts looks something like this That sets up three vhosts all called "localhost" on ports 443 and 7681 with SSL, and port 80 without SSL but with a forced redirect to https://localhost -Vhost name and port -------------------- +@section lwswsvn Lwsws Vhost name and port sharing The vhost name field is used to match on incoming SNI or Host: header, so it must always be the host name used to reach the vhost externally. @@ -147,8 +149,7 @@ negotiation time (via SNI) or if no SSL, then after the Host: header from the client has been parsed. -Protocols ---------- +@section lwswspr Lwsws Protocols Vhosts by default have available the union of any initial protocols from context creation time, and any protocols exposed by plugins. @@ -178,8 +179,7 @@ by the client, you can use "default": "1" ``` -Other vhost options -------------------- +@section lwswsovo Lwsws Other vhost options - If the three options `host-ssl-cert`, `host-ssl-ca` and `host-ssl-key` are given, then the vhost supports SSL. @@ -223,8 +223,7 @@ Other vhost options - "`ssl-option-clear'": "" Clears the SSL option flag value for the vhost. It may be used multiple times and OR's the flags together. -Mounts ------- +@section lwswsm Lwsws Mounts Where mounts are given in the vhost definition, then directory contents may be auto-served if it matches the mountpoint. @@ -261,8 +260,7 @@ Mount protocols are used to control what kind of translation happens -Other mount options -------------------- +@section lwswsomo Lwsws Other mount options 1) Some protocols may want "per-mount options" in name:value format. You can provide them using "pmo" @@ -329,8 +327,7 @@ options are given, the content is marked uncacheable. } ``` -Plugins -------- +@section lwswspl Lwsws Plugins Protcols and extensions may also be provided from "plugins", these are lightweight dynamic libraries. They are scanned for at init time, and @@ -357,8 +354,7 @@ To help that happen conveniently, there are some new apis dumb increment, mirror and status protocol plugins are provided as examples. -Additional plugin search paths ------------------------------- +@section lwswsplaplp Additional plugin search paths Packages that have their own lws plugins can install them in their own preferred dir and ask lwsws to scan there by using a config fragment @@ -371,8 +367,7 @@ like this, in its own conf.d/ file managed by the other package } ``` -lws-server-status plugin ------------------------- +@section lwswsssp lws-server-status plugin One provided protocol can be used to monitor the server status. @@ -397,8 +392,7 @@ You might choose to put it on its own vhost which has "interface": "lo", so it's externally visible. -Integration with Systemd ------------------------- +@section lwswssysd Lwsws Integration with Systemd lwsws needs a service file like this as `/usr/lib/systemd/system/lwsws.service` ``` @@ -417,8 +411,7 @@ lwsws needs a service file like this as `/usr/lib/systemd/system/lwsws.service` You can find this prepared in `./lwsws/usr-lib-systemd-system-lwsws.service` -Integration with logrotate --------------------------- +@section lwswslr Lwsws Integration with logrotate For correct operation with logrotate, `/etc/logrotate.d/lwsws` (if that's where we're putting the logs) should contain diff --git a/README.test-apps.md b/README.test-apps.md index 1437b31f..e9a3ae22 100644 --- a/README.test-apps.md +++ b/README.test-apps.md @@ -47,8 +47,7 @@ being done in protocol plugins only. Notes about lws test apps ========================= -Testing server with a browser ------------------------------ +@section tsb Testing server with a browser If you run [libwebsockets-test-server](test-server/test-server.c) and point your browser (eg, Chrome) to @@ -63,8 +62,7 @@ By default the test server logs to both stderr and syslog, you can control what is logged using `-d `, see later. -Running test server as a Daemon -------------------------------- +@section tsd Running test server as a Daemon You can use the -D option on the test server to have it fork into the background and return immediately. In this daemonized mode all stderr is @@ -85,8 +83,7 @@ If the lock is valid, the daemon will exit with a note on stderr that it was already running. -Using SSL on the server side ----------------------------- +@section sssl Using SSL on the server side To test it using SSL/WSS, just run the test server with ``` @@ -107,8 +104,7 @@ same. serving both the script html over http and websockets. -Testing websocket client support --------------------------------- +@section wscl Testing websocket client support If you run the test server as described above, you can also connect to it using the test client as well as a browser. @@ -134,8 +130,7 @@ otherwise it will strictly fail the connection if there is no CA cert to validate the server's certificate. -Choosing between test server variations ---------------------------------------- +@section choosingts Choosing between test server variations If you will be doing standalone serving with lws, ideally you should avoid making your own server at all, and use lwsws with your own protocol plugins. @@ -149,8 +144,7 @@ that's not possible then the other variations with their own protocol code should be considered. -Testing simple echo -------------------- +@section echo Testing simple echo You can test against `echo.websockets.org` as a sanity test like this (the client connects to port `80` by default): @@ -173,8 +167,7 @@ If you add the `--ssl` switch to both the client and server, you can also test with an encrypted link. -Testing SSL on the client side ------------------------------- +@section tassl Testing SSL on the client side To test SSL/WSS client action, just run the client test with ``` @@ -186,8 +179,7 @@ certificates used by the test server, this is indicated by the certificate that it doesn't have a trusted CA cert for. -Using the websocket ping utility --------------------------------- +@section taping Using the websocket ping utility libwebsockets-test-ping connects as a client to a remote websocket server and pings it like the @@ -233,8 +225,7 @@ another server, you can specify the protcol to handshake with by `--protocol=protocolname` -Fraggle test app ----------------- +@section ta fraggle Fraggle test app By default it runs in server mode ``` @@ -277,8 +268,7 @@ same checksum using websocket framing to see when the message has ended. It then accepts the server checksum message and compares that to its checksum. -proxy support -------------- +@section taproxy proxy support The http_proxy environment variable is respected by the client connection code for both `ws://` and `wss://`. It doesn't support @@ -290,16 +280,18 @@ You use it like this $ libwebsockets-test-client someserver.com ``` -debug logging -------------- +@section talog debug logging By default logging of severity "notice", "warn" or "err" is enabled to stderr. Again by default other logging is compiled in but disabled from printing. -If you want to eliminate the debug logging below notice in severity, use the -`--disable-debug` configure option to have it removed from the code by the -preprocesser. +By default debug logs below "notice" in severity are not compiled in. To get +them included, add this option in CMAKE + +``` + $ cmake .. -DCMAKE_BUILD_TYPE=DEBUG +``` If you want to see more detailed debug logs, you can control a bitfield to select which logs types may print using the `lws_set_log_level()` api, in the @@ -318,15 +310,13 @@ available are (OR together the numbers to select multiple) - 512 LATENCY -Websocket version supported ---------------------------- +@section ws13 Websocket version supported The final IETF standard is supported for both client and server, protocol version 13. -Latency Tracking ----------------- +@section latency Latency Tracking Since libwebsockets runs using `poll()` and a single threaded approach, any unexpected latency coming from system calls would be bad news. There's now @@ -349,8 +339,7 @@ that time, such as the browser, it may simply indicate the OS gave preferential treatment to the other app during that call. -Autobahn Test Suite -------------------- +@section autobahn Autobahn Test Suite Lws can be tested against the autobahn websocket fuzzer. @@ -377,13 +366,12 @@ file:///projects/libwebsockets/reports/clients/index.html to see the results -Autobahn Test Notes -------------------- +@section autobahnnotes Autobahn Test Notes 1) Autobahn tests the user code + lws implementation. So to get the same results, you need to follow test-echo.c in terms of user implmentation. -2) Some of the tests make no sense for Libwebsockets to support and we fail them. +2) Two of the tests make no sense for Libwebsockets to support and we fail them. - Tests 2.10 + 2.11: sends multiple pings on one connection. Lws policy is to only allow one active ping in flight on each connection, the rest are dropped. diff --git a/doc/html/md_README.build.html b/doc/html/md_README.build.html index b6b92c5b..f160b6d6 100644 --- a/doc/html/md_README.build.html +++ b/doc/html/md_README.build.html @@ -65,7 +65,8 @@ $(document).ready(function(){initNavTree('md_README.build.html','');});
Notes about building lws
-

Introduction to CMake

+

+Introduction to CMake

CMake is a multi-platform build tool that can generate build files for many different target platforms. See more info at http://www.cmake.org

CMake also allows/recommends you to do "out of source"-builds, that is, the build files are separated from your sources, so there is no need to create elaborate clean scripts to get a clean source tree, instead you simply remove your build directory.

Libwebsockets has been tested to build successfully on the following platforms with SSL support (both OpenSSL/wolfSSL):

@@ -76,19 +77,23 @@ $(document).ready(function(){initNavTree('md_README.build.html','');});
  • OSX
  • NetBSD
  • -

    Building the library and test apps

    +

    +Building the library and test apps

    The project settings used by CMake to generate the platform specific build files is called CMakeLists.txt. CMake then uses one of its "Generators" to output a Visual Studio project or Make file for instance. To see a list of the available generators for your platform, simply run the "cmake" command.

    Note that by default OpenSSL will be linked, if you don't want SSL support see below on how to toggle compile options.

    -

    Building on Unix:

    +

    +Building on Unix:

    1. Install CMake 2.8 or greater: http://cmake.org/cmake/resources/software.html (Most Unix distributions comes with a packaged version also)
    2. Install OpenSSL.
    3. Generate the build files (default is Make files):
      1 $ cd /path/to/src
      2 $ mkdir build
      3 $ cd build
      4 $ cmake ..
    4. Finally you can build using the generated Makefile:
      1 $ make && sudo make install
      NOTE: The build/directory can have any name and be located anywhere on your filesystem, and that the argument..` given to cmake is simply the source directory of libwebsockets containing the CMakeLists.txt project file. All examples in this file assumes you use ".."
    -

    NOTE2: A common option you may want to give is to set the install path, same as –prefix= with autotools. It defaults to /usr/local. You can do this by, eg

    1 $ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr .

    NOTE3: On machines that want libraries in lib64, you can also add the following to the cmake line

    1 -DLIB_SUFFIX=64

    NOTE4: If you are building against a non-distro OpenSSL (eg, in order to get access to ALPN support only in newer OpenSSL versions) the nice way to express that in one cmake command is eg,

    1 $ cmake .. -DOPENSSL_ROOT_DIR=/usr/local/ssl \
    2  -DCMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE=/usr/local/ssl \
    3  -DLWS_WITH_HTTP2=1

    When you run the test apps using non-distro SSL, you have to force them to use your libs, not the distro ones

    1 $ LD_LIBRARY_PATH=/usr/local/ssl/lib libwebsockets-test-server --ssl

    To get it to build on latest openssl (2016-04-10) it needed this approach

    1 cmake .. -DLWS_WITH_HTTP2=1 -DLWS_OPENSSL_INCLUDE_DIRS=/usr/local/include/openssl -DLWS_OPENSSL_LIBRARIES="/usr/local/lib64/libssl.so;/usr/local/lib64/libcrypto.so"

    NOTE5: To build with debug info and _DEBUG for lower priority debug messages compiled in, use

    1 $ cmake .. -DCMAKE_BUILD_TYPE=DEBUG

    Quirk of cmake

    +

    NOTE2: A common option you may want to give is to set the install path, same as –prefix= with autotools. It defaults to /usr/local. You can do this by, eg

    1 $ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr .

    NOTE3: On machines that want libraries in lib64, you can also add the following to the cmake line

    1 -DLIB_SUFFIX=64

    NOTE4: If you are building against a non-distro OpenSSL (eg, in order to get access to ALPN support only in newer OpenSSL versions) the nice way to express that in one cmake command is eg,

    1 $ cmake .. -DOPENSSL_ROOT_DIR=/usr/local/ssl \
    2  -DCMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE=/usr/local/ssl \
    3  -DLWS_WITH_HTTP2=1

    When you run the test apps using non-distro SSL, you have to force them to use your libs, not the distro ones

    1 $ LD_LIBRARY_PATH=/usr/local/ssl/lib libwebsockets-test-server --ssl

    To get it to build on latest openssl (2016-04-10) it needed this approach

    1 cmake .. -DLWS_WITH_HTTP2=1 -DLWS_OPENSSL_INCLUDE_DIRS=/usr/local/include/openssl -DLWS_OPENSSL_LIBRARIES="/usr/local/lib64/libssl.so;/usr/local/lib64/libcrypto.so"

    NOTE5: To build with debug info and _DEBUG for lower priority debug messages compiled in, use

    1 $ cmake .. -DCMAKE_BUILD_TYPE=DEBUG

    +Quirk of cmake

    When changing cmake options, for some reason the only way to get it to see the changes sometimes is delete the contents of your build directory and do the cmake from scratch.

    -

    Building on Windows (Visual Studio)

    +

    +Building on Windows (Visual Studio)

    1. Install CMake 2.6 or greater: http://cmake.org/cmake/resources/software.html
    2. Install OpenSSL binaries. http://www.openssl.org/related/binaries.html

      @@ -109,7 +114,8 @@ $(document).ready(function(){initNavTree('md_README.build.html','');});
    3. If you're using libuv, you must make sure to compile libuv with the same multithread-dll / Mtd attributes as libwebsockets itself
    -

    Building on Windows (MinGW)

    +

    +Building on Windows (MinGW)

    1. Install MinGW: http://sourceforge.net/projects/mingw/files

      (NOTE: Preferably in the default location C:)

      @@ -127,13 +133,8 @@ $(document).ready(function(){initNavTree('md_README.build.html','');});

      NOTE2: To generate build files allowing to create libwebsockets binaries with debug information set the CMAKE_BUILD_TYPE flag to DEBUG:

      1 $ cmake -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=C:/MinGW -DCMAKE_BUILD_TYPE=DEBUG ..
    2. Finally you can build using the generated Makefile and get the results deployed into your MinGW installation:
    -
    1 $ make
    2 $ make install

    Setting compile options

    -

    To set compile time flags you can either use one of the CMake gui applications or do it via command line.

    -

    Command line

    -

    To list avaialable options (ommit the H if you don't want the help text):

        cmake -LH ..
    -

    Then to set an option and build (for example turn off SSL support):

        cmake -DLWS_WITH_SSL=0 ..
    -

    or cmake -DLWS_WITH_SSL:BOOL=OFF ..

    -

    Building on mbed3

    +
    1 $ make
    2 $ make install

    +Building on mbed3

    MBED3 is a non-posix embedded OS targeted on Cortex M class chips.

    https://www.mbed.com/

    It's quite unlike any other Posixy platform since the OS is linked statically in with lws to form one binary.

    @@ -151,32 +152,47 @@ $(document).ready(function(){initNavTree('md_README.build.html','');});

    6) yotta target frdm-k64f-gcc

    7) yotta install

    8) yotta build

    -

    Unix GUI

    +

    +Setting compile options

    +

    To set compile time flags you can either use one of the CMake gui applications or do it via command line.

    +

    +Command line

    +

    To list avaialable options (omit the H if you don't want the help text):

        cmake -LH ..
    +

    Then to set an option and build (for example turn off SSL support):

        cmake -DLWS_WITH_SSL=0 ..
    +

    or cmake -DLWS_WITH_SSL:BOOL=OFF ..

    +

    +Unix GUI

    If you have a curses-enabled build you simply type: (not all packages include this, my debian install does not for example).

        ccmake
    -

    Windows GUI

    +

    +Windows GUI

    On windows CMake comes with a gui application: Start -> Programs -> CMake -> CMake (cmake-gui)

    -

    wolfSSL/CyaSSL replacement for OpenSSL

    +

    +wolfSSL/CyaSSL replacement for OpenSSL

    wolfSSL/CyaSSL is a lightweight SSL library targeted at embedded systems: https://www.wolfssl.com/wolfSSL/Products-wolfssl.html

    It contains a OpenSSL compatibility layer which makes it possible to pretty much link to it instead of OpenSSL, giving a much smaller footprint.

    NOTE: wolfssl needs to be compiled using the --enable-opensslextra flag for this to work.

    -

    Compiling libwebsockets with wolfSSL

    +

    +Compiling libwebsockets with wolfSSL

    1 cmake .. -DLWS_USE_WOLFSSL=1 \
    2  -DLWS_WOLFSSL_INCLUDE_DIRS=/path/to/wolfssl \
    3  -DLWS_WOLFSSL_LIBRARIES=/path/to/wolfssl/wolfssl.a ..

    NOTE: On windows use the .lib file extension for LWS_WOLFSSL_LIBRARIES instead.

    -

    Compiling libwebsockets with CyaSSL

    +

    +Compiling libwebsockets with CyaSSL

    1 cmake .. -DLWS_USE_CYASSL=1 \
    2  -DLWS_CYASSL_INCLUDE_DIRS=/path/to/cyassl \
    3  -DLWS_CYASSL_LIBRARIES=/path/to/wolfssl/cyassl.a ..

    NOTE: On windows use the .lib file extension for LWS_CYASSL_LIBRARIES instead.

    -

    Compiling libwebsockets with PolarSSL

    -

    Caution... at some point PolarSSL became MbedTLS. But it did not happen all at once. The name changed first then at mbedTLS 2.0 the apis changed. So eg in Fedora 22, there is an "mbedtls" package which is actually using polarssl for the include dir and polarssl apis... this should be treated as polarssl then.

    -

    Example config for this case is

    1 cmake .. -DLWS_USE_POLARSSL=1 -DLWS_POLARSSL_LIBRARIES=/usr/lib64/libmbedtls.so \
    2  -DLWS_POLARSSL_INCLUDE_DIRS=/usr/include/polarssl/

    Building plugins outside of lws itself

    +

    +Building plugins outside of lws itself

    The directory ./plugin-standalone/ shows how easy it is to create plugins outside of lws itself. First build lws itself with -DLWS_WITH_PLUGINS, then use the same flow to build the standalone plugin

    1 cd ./plugin-standalone
    2 mkdir build
    3 cd build
    4 cmake ..
    5 make && sudo make install

    if you changed the default plugin directory when you built lws, you must also give the same arguments to cmake here (eg, -DCMAKE_INSTALL_PREFIX:PATH=/usr/something/else... )

    Otherwise if you run lwsws or libwebsockets-test-server-v2.0, it will now find the additional plugin "libprotocol_example_standalone.so"

    1 lwsts[21257]: Plugins:
    2 lwsts[21257]: libprotocol_dumb_increment.so
    3 lwsts[21257]: libprotocol_example_standalone.so
    4 lwsts[21257]: libprotocol_lws_mirror.so
    5 lwsts[21257]: libprotocol_lws_server_status.so
    6 lwsts[21257]: libprotocol_lws_status.so

    If you have multiple vhosts, you must enable plugins at the vhost additionally, discovered plugins are not enabled automatically for security reasons. You do this using info->pvo or for lwsws, in the JSON config.

    -

    Reproducing HTTP2.0 tests

    +

    +Reproducing HTTP2.0 tests

    You must have built and be running lws against a version of openssl that has ALPN / NPN. Most distros still have older versions. You'll know it's right by seeing

    1 lwsts[4752]: Compiled with OpenSSL support
    2 lwsts[4752]: Using SSL mode
    3 lwsts[4752]: HTTP2 / ALPN enabled

    at lws startup.

    -

    For non-SSL HTTP2.0 upgrade

    1 $ nghttp -nvasu http://localhost:7681/test.htm

    For SSL / ALPN HTTP2.0 upgrade

    1 $ nghttp -nvas https://localhost:7681/test.html

    Cross compiling

    +

    For non-SSL HTTP2.0 upgrade

    1 $ nghttp -nvasu http://localhost:7681/test.htm

    For SSL / ALPN HTTP2.0 upgrade

    1 $ nghttp -nvas https://localhost:7681/test.html

    +Cross compiling

    To enable cross-compiling libwebsockets using CMake you need to create a "Toolchain file" that you supply to CMake when generating your build files. CMake will then use the cross compilers and build paths specified in this file to look for dependencies and such.

    Libwebsockets includes an example toolchain file cross-arm-linux-gnueabihf.cmake you can use as a starting point.

    The commandline to configure for cross with this would look like

    1 $ cmake .. -DCMAKE_INSTALL_PREFIX:PATH=/usr \
    2  -DCMAKE_TOOLCHAIN_FILE=../cross-arm-linux-gnueabihf.cmake \
    3  -DWITHOUT_EXTENSIONS=1 -DWITH_SSL=0

    The example shows how to build with no external cross lib dependencies, you need to provide the cross libraries otherwise.

    NOTE: start from an EMPTY build directory if you had a non-cross build in there before the settings will be cached and your changes ignored.

    Additional information on cross compilation with CMake: http://www.vtk.org/Wiki/CMake_Cross_Compiling

    -

    Memory efficiency

    +

    +Memory efficiency

    Embedded server-only configuration without extensions (ie, no compression on websocket connections), but with full v13 websocket features and http server, built on ARM Cortex-A9:

    Update at 8dac94d (2013-02-18)

    1 $ ./configure --without-client --without-extensions --disable-debug --without-daemonize
    2 
    3 Context Creation, 1024 fd limit[2]: 16720 (includes 12 bytes per fd)
    4 Per-connection [3]: 72 bytes, +1328 during headers
    5 
    6 .text .rodata .data .bss
    7 11512 2784 288 4

    This shows the impact of the major configuration with/without options at 13ba5bbc633ea962d46d using Ubuntu ARM on a PandaBoard ES.

    These are accounting for static allocations from the library elf, there are additional dynamic allocations via malloc. These are a bit old now but give the right idea for relative "expense" of features.

    diff --git a/doc/html/md_README.coding.html b/doc/html/md_README.coding.html index 570e6764..e387406c 100644 --- a/doc/html/md_README.coding.html +++ b/doc/html/md_README.coding.html @@ -65,13 +65,17 @@ $(document).ready(function(){initNavTree('md_README.coding.html','');});
    Notes about coding with lws
    -

    Daemonization

    +

    +Daemonization

    There's a helper api lws_daemonize built by default that does everything you need to daemonize well, including creating a lock file. If you're making what's basically a daemon, just call this early in your init to fork to a headless background process and exit the starting process.

    Notice stdout, stderr, stdin are all redirected to /dev/null to enforce your daemon is headless, so you'll need to sort out alternative logging, by, eg, syslog.

    -

    Maximum number of connections

    +

    +Maximum number of connections

    The maximum number of connections the library can deal with is decided when it starts by querying the OS to find out how many file descriptors it is allowed to open (1024 on Fedora for example). It then allocates arrays that allow up to that many connections, minus whatever other file descriptors are in use by the user code.

    If you want to restrict that allocation, or increase it, you can use ulimit or similar to change the avaiable number of file descriptors, and when restarted libwebsockets will adapt accordingly.

    -

    Libwebsockets is singlethreaded

    +

    +Libwebsockets is singlethreaded

    +

    Libwebsockets works in a serialized event loop, in a single thread.

    Directly performing websocket actions from other threads is not allowed. Aside from the internal data being inconsistent in forked() processes, the scope of a wsi (struct websocket) can end at any time during service with the socket closing and the wsi freed.

    Websocket write activities should only take place in the LWS_CALLBACK_SERVER_WRITEABLE callback as described below.

    [This network-programming necessity to link the issue of new data to the peer taking the previous data is not obvious to all users so let's repeat that in other words:

    @@ -83,7 +87,8 @@ $(document).ready(function(){initNavTree('md_README.coding.html','');});

    If you need to service other socket or file descriptors as well as the websocket ones, you can combine them together with the websocket ones in one poll loop, see "External Polling Loop support" below, and still do it all in one thread / process context.

    If you insist on trying to use it from multiple threads, take special care if you might simultaneously create more than one context from different threads.

    SSL_library_init() is called from the context create api and it also is not reentrant. So at least create the contexts sequentially.

    -

    Only send data when socket writeable

    +

    +Only send data when socket writeable

    You should only send data on a websocket connection from the user callback LWS_CALLBACK_SERVER_WRITEABLE (or LWS_CALLBACK_CLIENT_WRITEABLE for clients).

    If you want to send something, do not just send it but request a callback when the socket is writeable using

      @@ -92,19 +97,23 @@ $(document).ready(function(){initNavTree('md_README.coding.html','');});

    Usually you will get called back immediately next time around the service loop, but if your peer is slow or temporarily inactive the callback will be delayed accordingly. Generating what to write and sending it should be done in the ...WRITEABLE callback.

    See the test server code for an example of how to do this.

    -

    Do not rely on only your own WRITEABLE requests appearing

    +

    +Do not rely on only your own WRITEABLE requests appearing

    Libwebsockets may generate additional LWS_CALLBACK_CLIENT_WRITEABLE events if it met network conditions where it had to buffer your send data internally.

    So your code for LWS_CALLBACK_CLIENT_WRITEABLE needs to own the decision about what to send, it can't assume that just because the writeable callback came it really is time to send something.

    It's quite possible you get an 'extra' writeable callback at any time and just need to return 0 and wait for the expected callback later.

    -

    Closing connections from the user side

    +

    +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 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.

    If the socket knows the connection is dead, because the peer closed or there was an affirmitive network error like a FIN coming, then libwebsockets will take care of closing the connection automatically.

    -

    If you have a silently dead connection, it's possible to enter a state where the send pipe on the connection is choked but no ack will ever come, so the dead connection will never become writeable. To cover that, you can use TCP keepalives (see later in this document)

    -

    Fragmented messages

    +

    If you have a silently dead connection, it's possible to enter a state where the send pipe on the connection is choked but no ack will ever come, so the dead connection will never become writeable. To cover that, you can use TCP keepalives (see later in this document) or pings.

    +

    +Fragmented messages

    To support fragmented messages you need to check for the final 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:

    1 case LWS_CALLBACK_RECEIVE:
    2 {
    3  Client * const client = (Client *)user;
    4  const size_t remaining = lws_remaining_packet_payload(wsi);
    5 
    6  if (!remaining && lws_is_final_fragment(wsi)) {
    7  if (client->HasFragments()) {
    8  client->AppendMessageFragment(in, len, 0);
    9  in = (void *)client->GetMessage();
    10  len = client->GetMessageLength();
    11  }
    12 
    13  client->ProcessMessage((char *)in, len, wsi);
    14  client->ResetMessage();
    15  } else
    16  client->AppendMessageFragment(in, len, remaining);
    17 }
    18 break;

    The test app libwebsockets-test-fraggle sources also show how to deal with fragmented messages.

    -

    Debug Logging

    +

    +Debug Logging

    Also using lws_set_log_level api you may provide a custom callback to actually emit the log string. By default, this points to an internal emit function that sends to stderr. Setting it to NULL leaves it as it is instead.

    A helper function lwsl_emit_syslog() is exported from the library to simplify logging to syslog. You still need to use setlogmask, openlog and closelog in your user code.

    The logging apis are made available for user code.

    @@ -116,7 +125,10 @@ $(document).ready(function(){initNavTree('md_README.coding.html','');});
  • lwsl_debug(...)
  • The difference between notice and info is that notice will be logged by default whereas info is ignored by default.

    -

    External Polling Loop support

    +

    If you are not building with _DEBUG defined, ie, without this

    +
    1 $ cmake .. -DCMAKE_BUILD_TYPE=DEBUG

    then log levels below notice do not actually get compiled in.

    +

    +External Polling Loop support

    libwebsockets maintains an internal poll() array for all of its sockets, but you can instead integrate the sockets into an external polling array. That's needed if libwebsockets will cooperate with an existing poll array maintained by another server.

    Four callbacks LWS_CALLBACK_ADD_POLL_FD, LWS_CALLBACK_DEL_POLL_FD, LWS_CALLBACK_SET_MODE_POLL_FD and LWS_CALLBACK_CLEAR_MODE_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 lws_service_fd(), even if the socket or file does not belong to libwebsockets it is safe.

    @@ -127,41 +139,53 @@ $(document).ready(function(){initNavTree('md_README.coding.html','');});
  • check the built-in support for the event loop if possible (eg, ./lib/libuv.c) to see how it interfaces to lws
  • use LWS_POLLHUP / LWS_POLLIN / LWS_POLLOUT from libwebsockets.h to avoid losing windows compatibility
  • -

    Using with in c++ apps

    +

    +Using with in c++ apps

    The library is ready for use by C++ apps. You can get started quickly by copying the test server

    1 $ cp test-server/test-server.c test.cpp

    and building it in C++ like this

    1 $ g++ -DINSTALL_DATADIR=\"/usr/share\" -ocpptest test.cpp -lwebsockets

    INSTALL_DATADIR is only needed because the test server uses it as shipped, if you remove the references to it in your app you don't need to define it on the g++ line either.

    -

    Availability of header information

    -

    From v1.2 of the library onwards, the HTTP header content is free()d as soon as the websocket connection is established. For websocket servers, you can copy interesting headers by handling LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION callback, for clients there's a new callback just for this purpose LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH.

    -

    TCP Keepalive

    +

    +Availability of header information

    +

    HTTP Header information is managed by a pool of "ah" structs. These are a limited resource so there is pressure to free the headers and return the ah to the pool for reuse.

    +

    For that reason header information on HTTP connections that get upgraded to websockets is lost after the ESTABLISHED callback. Anything important that isn't processed by user code before then should be copied out for later.

    +

    For HTTP connections that don't upgrade, header info remains available the whole time.

    +

    +TCP Keepalive

    It is possible for a connection which is not being used to send to die silently somewhere between the peer and the side not sending. In this case by default TCP will just not report anything and you will never get any more incoming data or sign the link is dead until you try to send.

    To deal with getting a notification of that situation, you can choose to enable TCP keepalives on all libwebsockets sockets, when you create the context.

    To enable keepalive, set the ka_time member of the context creation parameter struct to a nonzero value (in seconds) at context creation time. You should also fill ka_probes and ka_interval in that case.

    With keepalive enabled, the TCP layer will send control packets that should stimulate a response from the peer without affecting link traffic. If the response is not coming, the socket will announce an error at poll() forcing a close.

    Note that BSDs don't support keepalive time / probes / interval per-socket like Linux does. On those systems you can enable keepalive by a nonzero value in ka_time, but the systemwide kernel settings for the time / probes/ interval are used, regardless of what nonzero value is in ka_time.

    -

    Optimizing SSL connections

    +

    +Optimizing SSL connections

    There's a member ssl_cipher_list in the lws_context_creation_info struct which allows the user code to restrict the possible cipher selection at context-creation time.

    You might want to look into that to stop the ssl peers selecting a cipher which is too computationally expensive. To use it, point it to a string like

        `"RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL"`
     

    if left NULL, then the "DEFAULT" set of ciphers are all possible to select.

    You can also set it to "ALL" to allow everything (including insecure ciphers).

    -

    Async nature of client connections

    +

    +Async nature of client connections

    When you call lws_client_connect_info(..) and get a wsi back, it does not mean your connection is active. It just means it started trying to connect.

    Your client connection is actually active only when you receive LWS_CALLBACK_CLIENT_ESTABLISHED for it.

    There's a 5 second timeout for the connection, and it may give up or die for other reasons, if any of that happens you'll get a LWS_CALLBACK_CLIENT_CONNECTION_ERROR callback on protocol 0 instead for the wsi.

    After attempting the connection and getting back a non-NULL wsi you should loop calling lws_service() until one of the above callbacks occurs.

    As usual, see test-client.c for example code.

    -

    Lws platform-independent file access apis

    +

    Notice that the client connection api tries to progress the connection somewhat before returning. That means it's possible to get callbacks like CONNECTION_ERROR on the new connection before your user code had a chance to get the wsi returned to identify it (in fact if the connection did fail early, NULL will be returned instead of the wsi anyway).

    +

    To avoid that problem, you can fill in pwsi in the client connection info struct to point to a struct lws that get filled in early by the client connection api with the related wsi. You can then check for that in the callback to confirm the identity of the failing client connection.

    +

    +Lws platform-independent file access apis

    lws now exposes his internal platform file abstraction in a way that can be both used by user code to make it platform-agnostic, and be overridden or subclassed by user code. This allows things like handling the URI "directory space" as a virtual filesystem that may or may not be backed by a regular filesystem. One example use is serving files from inside large compressed archive storage without having to unpack anything except the file being requested.

    The test server shows how to use it, basically the platform-specific part of lws prepares a file operations structure that lives in the lws context.

    The user code can get a pointer to the file operations struct

    1 LWS_VISIBLE LWS_EXTERN struct lws_plat_file_ops *
    2  `lws_get_fops`(struct lws_context *context);

    and then can use helpers to also leverage these platform-independent file handling apis

    1 static inline lws_filefd_type
    2 `lws_plat_file_open`(struct lws *wsi, const char *filename, unsigned long *filelen, int flags)
    3 
    4 static inline int
    5 `lws_plat_file_close`(struct lws *wsi, lws_filefd_type fd)
    6 
    7 static inline unsigned long
    8 `lws_plat_file_seek_cur`(struct lws *wsi, lws_filefd_type fd, long offset_from_cur_pos)
    9 
    10 static inline int
    11 `lws_plat_file_read`(struct lws *wsi, lws_filefd_type fd, unsigned long *amount, unsigned char *buf, unsigned long len)
    12 
    13 static inline int
    14 `lws_plat_file_write`(struct lws *wsi, lws_filefd_type fd, unsigned long *amount, unsigned char *buf, unsigned long len)

    The user code can also override or subclass the file operations, to either wrap or replace them. An example is shown in test server.

    -

    ECDH Support

    +

    +ECDH Support

    ECDH Certs are now supported. Enable the CMake option

        cmake .. -DLWS_SSL_SERVER_WITH_ECDH_CERT=1 
     

    and the info->options flag

        LWS_SERVER_OPTION_SSL_ECDH
     

    to build in support and select it at runtime.

    -

    SMP / Multithreaded service

    +

    +SMP / Multithreaded service

    SMP support is integrated into LWS without any internal threading. It's very simple to use, libwebsockets-test-server-pthread shows how to do it, use -j <n> argument there to control the number of service threads up to 32.

    Two new members are added to the info struct

        unsigned int count_threads;
         unsigned int fd_limit_per_thread;
    @@ -176,33 +200,40 @@ space" as a virtual filesystem that may or may not be backed by a regular filesy
     

    Because lws will limit the requested number of actual threads supported according to LWS_MAX_SMP, there is an api lws_get_count_threads(context) to discover how many threads were actually allowed when the context was created.

    It's required to implement locking in the user code in the same way that libwebsockets-test-server-pthread does it, for the FD locking callbacks.

    There is no knowledge or dependency in lws itself about pthreads. How the locking is implemented is entirely up to the user code.

    -

    Libev / Libuv support

    +

    +Libev / Libuv support

    You can select either or both

        -DLWS_WITH_LIBEV=1
         -DLWS_WITH_LIBUV=1
     

    at cmake configure-time. The user application may use one of the context init options flags

        LWS_SERVER_OPTION_LIBEV
         LWS_SERVER_OPTION_LIBUV
     

    to indicate it will use either of the event libraries.

    -

    Extension option control from user code

    +

    +Extension option control from user code

    User code may set per-connection extension options now, using a new api lws_set_extension_option().

    This should be called from the ESTABLISHED callback like this

    1 lws_set_extension_option(wsi, "permessage-deflate",
    2  "rx_buf_size", "12"); /* 1 << 12 */

    If the extension is not active (missing or not negotiated for the connection, or extensions are disabled on the library) the call is just returns -1. Otherwise the connection's extension has its named option changed.

    The extension may decide to alter or disallow the change, in the example above permessage-deflate restricts the size of his rx output buffer also considering the protocol's rx_buf_size member.

    -

    Client connections as HTTP[S] rather than WS[S]

    +

    +Client connections as HTTP[S] rather than WS[S]

    You may open a generic http client connection using the same struct lws_client_connect_info used to create client ws[s] connections.

    To stay in http[s], set the optional info member "method" to point to the string "GET" instead of the default NULL.

    After the server headers are processed, when payload from the server is available the callback LWS_CALLBACK_RECEIVE_CLIENT_HTTP will be made.

    You can choose whether to process the data immediately, or queue a callback when an outgoing socket is writeable to provide flow control, and process the data in the writable callback.

    Either way you use the api lws_http_client_read() to access the data, eg

    -
    1 case LWS_CALLBACK_RECEIVE_CLIENT_HTTP:
    2  {
    3  char buffer[1024 + LWS_PRE];
    4  char *px = buffer + LWS_PRE;
    5  int lenx = sizeof(buffer) - LWS_PRE;
    6 
    7  lwsl_notice("LWS_CALLBACK_RECEIVE_CLIENT_HTTP\n");
    8 
    9  /*
    10  * Often you need to flow control this by something
    11  * else being writable. In that case call the api
    12  * to get a callback when writable here, and do the
    13  * pending client read in the writeable callback of
    14  * the output.
    15  */
    16  if (lws_http_client_read(wsi, &px, &lenx) < 0)
    17  return -1;
    18  while (lenx--)
    19  putchar(*px++);
    20  }
    21  break;

    Using lws v2 vhosts

    +
    1 case LWS_CALLBACK_RECEIVE_CLIENT_HTTP:
    2  {
    3  char buffer[1024 + LWS_PRE];
    4  char *px = buffer + LWS_PRE;
    5  int lenx = sizeof(buffer) - LWS_PRE;
    6 
    7  lwsl_notice("LWS_CALLBACK_RECEIVE_CLIENT_HTTP\n");
    8 
    9  /*
    10  * Often you need to flow control this by something
    11  * else being writable. In that case call the api
    12  * to get a callback when writable here, and do the
    13  * pending client read in the writeable callback of
    14  * the output.
    15  */
    16  if (lws_http_client_read(wsi, &px, &lenx) < 0)
    17  return -1;
    18  while (lenx--)
    19  putchar(*px++);
    20  }
    21  break;

    Notice that if you will use SSL client connections on a vhost, you must prepare the client SSL context for the vhost after creating the vhost, since this is not normally done if the vhost was set up to listen / serve. Call the api lws_init_vhost_client_ssl() to also allow client SSL on the vhost.

    +

    +Using lws vhosts

    If you set LWS_SERVER_OPTION_EXPLICIT_VHOSTS options flag when you create your context, it won't create a default vhost using the info struct members for compatibility. Instead you can call lws_create_vhost() afterwards to attach one or more vhosts manually.

    1 LWS_VISIBLE struct lws_vhost *
    2 lws_create_vhost(struct lws_context *context,
    3  struct lws_context_creation_info *info,
    4  struct lws_http_mount *mounts);

    lws_create_vhost() uses the same info struct as lws_create_context(), it ignores members related to context and uses the ones meaningful for vhost (marked with VH in libwebsockets.h).

    1 struct lws_context_creation_info {
    2  int port; /* VH */
    3  const char *iface; /* VH */
    4  const struct lws_protocols *protocols; /* VH */
    5  const struct lws_extension *extensions; /* VH */
    6 ...

    When you attach the vhost, if the vhost's port already has a listen socket then both vhosts share it and use SNI (is SSL in use) or the Host: header from the client to select the right one. Or if no other vhost already listening the a new listen socket is created.

    There are some new members but mainly it's stuff you used to set at context creation time.

    -

    How lws matches hostname or SNI to a vhost

    +

    +How lws matches hostname or SNI to a vhost

    LWS first strips any trailing :port number.

    Then it tries to find an exact name match for a vhost listening on the correct port, ie, if SNI or the Host: header provided abc.com:1234, it will match on a vhost named abc.com that is listening on port 1234.

    If there is no exact match, lws will consider wildcard matches, for example if cats.abc.com:1234 is provided by the client by SNI or Host: header, it will accept a vhost "abc.com" listening on port 1234. If there was a better, exact, match, it will have been chosen in preference to this.

    Connections with SSL will still have the client go on to check the certificate allows wildcards and error out if not.

    -

    Using lws v2 mounts on a vhost

    +

    +Using lws mounts on a vhost

    The last argument to lws_create_vhost() lets you associate a linked list of lws_http_mount structures with that vhost's URL 'namespace', in a similar way that unix lets you mount filesystems into areas of your / filesystem how you like and deal with the contents transparently.

    1 struct lws_http_mount {
    2  struct lws_http_mount *mount_next;
    3  const char *mountpoint; /* mountpoint in http pathspace, eg, "/" */
    4  const char *origin; /* path to be mounted, eg, "/var/www/warmcat.com" */
    5  const char *def; /* default target, eg, "index.html" */
    6 
    7  struct lws_protocol_vhost_options *cgienv;
    8 
    9  int cgi_timeout;
    10  int cache_max_age;
    11 
    12  unsigned int cache_reusable:1;
    13  unsigned int cache_revalidate:1;
    14  unsigned int cache_intermediaries:1;
    15 
    16  unsigned char origin_protocol;
    17  unsigned char mountpoint_len;
    18 };

    The last mount structure should have a NULL mount_next, otherwise it should point to the 'next' mount structure in your list.

    Both the mount structures and the strings must persist until the context is destroyed, since they are not copied but used in place.

    @@ -213,7 +244,8 @@ space" as a virtual filesystem that may or may not be backed by a regular filesy
  • LWSMPRO_REDIR_HTTP and LWSMPRO_REDIR_HTTPS auto-redirect clients to the given origin URL.
  • LWSMPRO_CALLBACK causes the http connection to attach to the callback associated with the named protocol (which may be a plugin).
  • -

    Operation of LWSMPRO_CALLBACK mounts

    +

    +Operation of LWSMPRO_CALLBACK mounts

    The feature provided by CALLBACK type mounts is binding a part of the URL namespace to a named protocol callback handler.

    This allows protocol plugins to handle areas of the URL namespace. For example in test-server-v2.0.c, the URL area "/formtest" is associated with the plugin providing "protocol-post-demo" like this

    1 static const struct lws_http_mount mount_post = {
    2  NULL, /* linked-list pointer to next*/
    3  "/formtest", /* mountpoint in URL namespace on this vhost */
    4  "protocol-post-demo", /* handler */
    5  NULL, /* default filename if none given */
    6  NULL,
    7  0,
    8  0,
    9  0,
    10  0,
    11  0,
    12  LWSMPRO_CALLBACK, /* origin points to a callback */
    13  9, /* strlen("/formtest"), ie length of the mountpoint */
    14 };

    Client access to /formtest[anything] will be passed to the callback registered with the named protocol, which in this case is provided by a protocol plugin.

    diff --git a/doc/html/md_README.generic-sessions.html b/doc/html/md_README.generic-sessions.html index 0f4efdcd..fe30e5eb 100644 --- a/doc/html/md_README.generic-sessions.html +++ b/doc/html/md_README.generic-sessions.html @@ -65,10 +65,12 @@ $(document).ready(function(){initNavTree('md_README.generic-sessions.html','');}
    Notes about generic-sessions Plugin
    -

    Enabling for build

    +

    +Enabling lwsgs for build

    Enable at CMake with -DLWS_WITH_GENERIC_SESSIONS=1

    This also needs sqlite3 (libsqlite3-dev or similar package)

    -

    Introduction

    +

    +lwsgs Introduction

    The generic-sessions protocol plugin provides cookie-based login authentication for lws web and ws connections.

    The plugin handles everything about generic account registration, email verification, lost password, account deletion, and other generic account management.

    Other code, in another eg, ws protocol handler, only needs very high-level state information from generic-sessions, ie, which user the client is authenticated as. Everything underneath is managed in generic-sessions.

    @@ -86,21 +88,24 @@ $(document).ready(function(){initNavTree('md_README.generic-sessions.html','');}
  • 32-bit bitfield for authentication sectoring, mounts can provide a mask on the loggin-in session's associated server-side bitfield that must be set for access.
  • No code (just config) required for, eg, private URL namespace that requires login to access.
  • -

    Integration to HTML

    +

    +Lwsgs Integration to HTML

    Only three steps are needed to integrate lwsgs in your HTML.

    1) lwsgs HTML UI is bundled with the javascript it uses in lwsgs.js, so import that script file in your head section

    2) define an empty div of id "lwsgs" somewhere

    3) Call lwsgs_initial() in your page

    That's it. An example is below

    -
    1 <html>
    2  <head>
    3  <script src="lwsgs.js"></script>
    4  <style>
    5  .body { font-size: 12 }
    6  .gstitle { font-size: 18 }
    7  </style>
    8  </head>
    9  <body style="background-image:url(seats.jpg)">
    10  <table style="width:100%;transition: max-height 2s;">
    11  <tr>
    12  <td style="vertical-align:top;text-align:left;width=200px">
    13  <img src="lwsgs-logo.png">
    14  </td>
    15  <td style="vertical-align:top;float:right">
    16  <div id=lwsgs style="text-align:right;background-color: rgba(255, 255, 255, 0.8);"></div>
    17  </td>
    18  </tr>
    19  </table>
    20  </form>
    21 
    22  <script>lwsgs_initial();</script>
    23 
    24  </body>
    25 </html>

    Overall Flow

    +
    1 <html>
    2  <head>
    3  <script src="lwsgs.js"></script>
    4  <style>
    5  .body { font-size: 12 }
    6  .gstitle { font-size: 18 }
    7  </style>
    8  </head>
    9  <body style="background-image:url(seats.jpg)">
    10  <table style="width:100%;transition: max-height 2s;">
    11  <tr>
    12  <td style="vertical-align:top;text-align:left;width=200px">
    13  <img src="lwsgs-logo.png">
    14  </td>
    15  <td style="vertical-align:top;float:right">
    16  <div id=lwsgs style="text-align:right;background-color: rgba(255, 255, 255, 0.8);"></div>
    17  </td>
    18  </tr>
    19  </table>
    20  </form>
    21 
    22  <script>lwsgs_initial();</script>
    23 
    24  </body>
    25 </html>

    +Lwsgs Overall Flow@

    When the protocol is initialized, it gets per-vhost information from the config, such as where the sqlite3 databases are to be stored. The admin username and sha-1 of the admin password are also taken from here.

    In the mounts using protocol-generic-sessions, a cookie is maintained against any requests; if no cookie was active on the initial request a new session is created with no attached user.

    So there should always be an active session after any transactions with the server.

    In the example html going to the mount /lwsgs loads a login / register page as the default.

    The <form> in the login page contains 'next url' hidden inputs that let the html 'program' where the form handler will go after a successful admin login, a successful user login and a failed login.

    After a successful login, the sqlite record at the server for the current session is updated to have the logged-in username associated with it.

    -

    Configuration

    -

    "auth-mask" defines the autorization sector bits that must be enabled on the session to gain access.

    +

    +Lwsgs Configuration

    +

    "auth-mask" defines the authorization sector bits that must be enabled on the session to gain access.

    "auth-mask" 0 is the default.

    • b0 is set if you are logged in as a user at all.
    • @@ -121,16 +126,21 @@ $(document).ready(function(){initNavTree('md_README.generic-sessions.html','');}

    The real protocol that makes use of generic-sessions must also be listed and any configuration it needs given

    1 "protocol-lws-messageboard": {
    2  "status": "ok",
    3  "message-db": "/var/www/sessions/messageboard.sqlite3"
    4 },

    Notice the real application uses his own sqlite db, no details about how generic-sessions works or how it stores data are available to it.

    -

    Password Confounder

    +

    +Lwsgs Password Confounder

    You can also define a per-vhost confounder shown in the example above, used when aggregating the password with the salt when it is hashed. Any attacker will also need to get the confounder along with the database, which you can make harder by making the config dir only eneterable / readable by root.

    -

    Preparing the db directory

    +

    +Lwsgs Preparing the db directory

    You will have to prepare the db directory so it's suitable for the lwsws user to use, that usually means apache, eg

    -
    1 # mkdir -p /var/www/sessions
    2 # chown root:apache /var/www/sessions
    3 # chmod 770 /var/www/sessions

    Email configuration

    +
    1 # mkdir -p /var/www/sessions
    2 # chown root:apache /var/www/sessions
    3 # chmod 770 /var/www/sessions

    +Lwsgs Email configuration

    lwsgs will can send emails by talking to an SMTP server on localhost:25. That will usually be sendmail or postfix, you should confirm that works first by itself using the mail application to send on it.

    lwsgs has been tested on stock Fedora sendmail and postfix.

    -

    Integration with another protocol

    +

    +Lwsgs Integration with another protocol

    lwsgs is designed to provide sessions and accounts in a standalone and generic way.

    But it's not useful by itself, there will always be the actual application who wants to make use of generic-sessions features.

    +

    We provide the "messageboard" plugin as an example of how to integrate with your actual application protocol.

    The basic approach is the 'real' protocol handler (usually a plugin itself) subclasses the generic-sessions plugin and calls through to it by default.

    The "real" protocol handler entirely deals with ws-related stuff itself, since generic-sessions does not use ws. But for

      @@ -145,7 +155,7 @@ $(document).ready(function(){initNavTree('md_README.generic-sessions.html','');}
      1 struct per_session_data__myapp {
      2  void *pss_gs;
      3 ...
      4 
      5  pss->pss_gs = malloc(vhd->gsp->per_session_data_size);

      The allocation reserved for generic-sessions is then used as user_space when the real protocol calls through to the generic-sessions callback

      1 vhd->gsp->callback(wsi, reason, &pss->pss_gs, in, len);

      In that way the "real" protocol can subclass generic-sessions functionality.

      To ease management of these secondary allocations, there are callbacks that occur when a wsi binds to a protocol and when the binding is dropped. These should be used to malloc and free and kind of per-connection secondary allocations.

      -
      1 case LWS_CALLBACK_HTTP_BIND_PROTOCOL:
      2  if (!pss || pss->pss_gs)
      3  break;
      4 
      5  pss->pss_gs = malloc(vhd->gsp->per_session_data_size);
      6  if (!pss->pss_gs)
      7  return -1;
      8 
      9  memset(pss->pss_gs, 0, vhd->gsp->per_session_data_size);
      10  break;
      11 
      12 case LWS_CALLBACK_HTTP_DROP_PROTOCOL:
      13  if (vhd->gsp->callback(wsi, reason, pss ? pss->pss_gs : NULL, in, len))
      14  return -1;
      15 
      16  if (pss->pss_gs) {
      17  free(pss->pss_gs);
      18  pss->pss_gs = NULL;
      19  }
      20  break;

      Getting session-specific information from another protocol

      +
      1 case LWS_CALLBACK_HTTP_BIND_PROTOCOL:
      2  if (!pss || pss->pss_gs)
      3  break;
      4 
      5  pss->pss_gs = malloc(vhd->gsp->per_session_data_size);
      6  if (!pss->pss_gs)
      7  return -1;
      8 
      9  memset(pss->pss_gs, 0, vhd->gsp->per_session_data_size);
      10  break;
      11 
      12 case LWS_CALLBACK_HTTP_DROP_PROTOCOL:
      13  if (vhd->gsp->callback(wsi, reason, pss ? pss->pss_gs : NULL, in, len))
      14  return -1;
      15 
      16  if (pss->pss_gs) {
      17  free(pss->pss_gs);
      18  pss->pss_gs = NULL;
      19  }
      20  break;

      #section gsapsib Getting session-specific information from another protocol

      At least at the time when someone tries to upgrade an http(s) connection to ws(s) with your real protocol, it is necessary to confirm the cookie the http(s) connection has with generic-sessions and find out his username and other info.

      Generic sessions lets another protocol check it again by calling his callback, and lws itself provides a generic session info struct to pass the related data

      1 struct lws_session_info {
      2  char username[32];
      3  char email[100];
      4  char ip[72];
      5  unsigned int mask;
      6  char session[42];
      7 };
      8 
      9 struct lws_session_info sinfo;
      10 ...
      11 vhd->gsp->callback(wsi, LWS_CALLBACK_SESSION_INFO,
      12  &pss->pss_gs, &sinfo, 0);

      After the call to generic-sessions, the results can be

      diff --git a/doc/html/md_README.generic-table.html b/doc/html/md_README.generic-table.html new file mode 100644 index 00000000..17941704 --- /dev/null +++ b/doc/html/md_README.generic-table.html @@ -0,0 +1,171 @@ + + + + + + +libwebsockets: Notes about generic-table + + + + + + + + + + + +
      +
      + + + + + + + +
      +
      libwebsockets +
      +
      Lightweight C library for HTML5 websockets
      +
      +
      + + + +
      +
      + +
      +
      +
      + +
      +
      +
      +
      Notes about generic-table
      +
      +
      +

      +What is generic-table?

      +

      Generic-table is a JSON schema and client-side JS file that makes it easy to display live, table structured HTML over a ws link.

      +

      An example plugin and index.html using it are provided, but lwsgt itself doesn't have its own plugin, it's just a JSON schema and client-side JS that other plugins can use to simplify displaying live, table-based data without having to reinvent the wheel each time.

      +

      The ws protocol sends JSON describing the table, and then JSON updating the table contents when it chooses, the brower table is updated automatically, live.

      +
      +lwsgt-overview.png +
      + +

      +Enabling for build

      +

      Enable the demo plugin at CMake with -DLWS_WITH_PLUGINS=1

      +

      +Integrating with your html

      +
        +
      • In your HEAD section, include lwsgt.js
      • +
      +
      1 <script src="lwsgt.js"></script>
        +
      • Also in your HEAD section, style the lwsgt CSS, eg
      • +
      +
      1 <style>
      2 .lwsgt_title { font-size: 24; text-align:center }
      3 .lwsgt_breadcrumbs { font-size: 18; text-align:left }
      4 .lwsgt_table { font-size: 14; padding:12px; margin: 12px; align:center }
      5 .lwsgt_hdr { font-size: 18; text-align:center;
      6  background-color: rgba(40, 40, 40, 0.8); color: white }
      7 .lwsgt_tr { padding: 10px }
      8 .lwsgt_td { padding: 3px }
      9 </style>

      You can skip this but the result will be less beautiful until some CSS is provided.

      +
        +
      • In your body section, declare a div with an id (can be whatever you want)
      • +
      +
      1 <tr><td><div id="lwsgt1" class="group1"></div></td></tr>

      lwsgt JS will put its content there.

      +
        +
      • Finally in a <script> at the end of your page, instantiate lwsgt and provide a custom callback for clickable links
      • +
      +
      1 <script>
      2 var v1 = new lwsgt_initial("Dir listing demo",
      3  "protocol-lws-table-dirlisting",
      4  "lwsgt1", "lwsgt_dir_click", "v1");
      5 
      6 function lwsgt_dir_click(gt, u, col, row)
      7 {
      8  if (u[0] == '=') { /* change directory */
      9  window[gt].lwsgt_ws.send(u.substring(1, u.length));
      10  return;
      11  }
      12  var win = window.open(u, '_blank');
      13  win.focus();
      14 }
      15 
      16 </script>

      In the callback, you can recover the ws object by window[gt].lwsgt_ws.

      +

      +Lwsgt constructor

      +

      To instantiate the ws link and lwsgt instance, your HTML must call a lwsgt constructor for each region on the page managed by lwsgt.

      +

      var myvar = new lwsgt_initial(title, ws_protocol, div_id, click_cb, myvar);

      +

      All of the arguments are strings.

      + + + + + + + + + + + + + +
      Parameter Description
      title Title string to go above the table
      ws_protocol Protocol name string to use when making ws connection
      div_id HTML id of div to fill with content
      click_cb Callback function name string to handle clickable links
      myvar Name of var used to hold this instantiation globally
      +

      Note "myvar" is needed so it can be passed to the click handling callback.

      +

      +Lwsgt click handling function

      +

      When a clickable link produced by lwsgt is clicked, the function named in the click_cb parameter to lwsgt_initial is called.

      +

      That function is expected to take four parameters, eg

      +

      function lwsgt_dir_click(gt, u, col, row)

      + + + + + + + + + + + +
      Parameter Description
      gt Name of global var holding this lwsgt context (ie, myvar)
      u Link "url" string
      col Table column number link is from
      row Table row number link is from
      +

      +Generic-table JSON

      +

      Column layout

      +

      When the ws connection is established, the protocol should send a JSON message describing the table columns. For example

      +
      1 "cols": [
      2  { "name": "Date" },
      3  { "name": "Size", "align": "right" },
      4  { "name": "Icon" },
      5  { "name": "Name", "href": "uri"},
      6  { "name": "uri", "hide": "1" }
      7  ]
      8 }
        +
      • This describes 5 columns
      • +
      • Only four columns (not "uri") should be visible
      • +
      • "Name" should be presented as a clickable link using "uri" as the destination, when a "uri" field is presented.
      • +
      • "Size" field should be presented aligned to the right
      • +
      +

      Breadcrumbs

      +

      When a view is hierarchical, it's useful to provide a "path" with links back in the "path", known as "breadcrumbs".

      +

      Elements before the last one should provide a "url" member as well as the displayable name, which is used to create the link destination.

      +

      The last element, being the current displayed page should not have a url member and be displayed without link style.

      +
      1 "breadcrumbs":[{"name":"top", "url": "/" }, {"name":"mydir"}]

      Table data

      +

      The actual file data consists of an array of rows, containing the columns mentioned in the original "cols" section.

      +
      1 "data":[
      2  {
      3  "Icon":" ",
      4  "Date":"2015-Feb-06 03:08:35 +0000",
      5  "Size":"1406",
      6  "uri":"./serve//favicon.ico",
      7  "Name":"favicon.ico"
      8  }
      9 ]

      +Setting up protocol-lws-table-dirlisting

      +

      The example protocol needs two mounts, one to provide the index.html, js and the protocol itself

      +
      1 {
      2  "mountpoint": "/dirtest",
      3  "origin": "file:///usr/share/libwebsockets-test-server/generic-table",
      4  "origin": "callback://protocol-lws-table-dirlisting",
      5  "default": "index.html",
      6  "pmo": [{
      7  "dir": "/usr/share/libwebsockets-test-server"
      8  }]
      9 },

      The protocol wants a per-mount option (PMO) to tell it the base directory it is serving from, named "dir".

      +

      The other mount is there to simply serve items that get clicked on from the table in a secure way

      +
      1 {
      2  "mountpoint": "/dirtest/serve",
      3  "origin": "file:///usr/share/libwebsockets-test-server",
      4  "default": "index.html"
      5 },

      This last bit is not related to using lwsgt itself.

      +
      +
      + + + + diff --git a/doc/html/md_README.lwsws.html b/doc/html/md_README.lwsws.html index 85f779c1..c46ef8a9 100644 --- a/doc/html/md_README.lwsws.html +++ b/doc/html/md_README.lwsws.html @@ -65,29 +65,40 @@ $(document).ready(function(){initNavTree('md_README.lwsws.html','');});
      Notes about lwsws
    -

    Libwebsockets Web Server

    +

    +Libwebsockets Web Server

    lwsws is an implementation of a very lightweight, ws-capable generic web server, which uses libwebsockets to implement everything underneath.

    -

    Build

    +

    If you are basically implementing a standalone server with lws, you can avoid reinventing the wheel and use a debugged server including lws.

    +

    +Build

    Just enable -DLWS_WITH_LWSWS=1 at cmake-time.

    It enables libuv and plugin support automatically.

    -

    Configuration

    -

    lwsws uses JSON config files, they're pure JSON but # may be used to turn the rest of the line into a comment.

    -

    There's also a single substitution, if a string contains "_lws_ddir_", then that is replaced with the LWS install data directory path, eg, "/usr/share" or whatever was set when LWS was built + installed. That lets you refer to installed paths without having to change the config if your install path was different.

    +

    +Lwsws Configuration

    +

    lwsws uses JSON config files, they're pure JSON except:

    +
      +
    • '#' may be used to turn the rest of the line into a comment.
    • +
    • There's also a single substitution, if a string contains "_lws_ddir_", then that is replaced with the LWS install data directory path, eg, "/usr/share" or whatever was set when LWS was built + installed. That lets you refer to installed paths without having to change the config if your install path was different.
    • +

    There is a single file intended for global settings

    /etc/lwsws/conf

    1 # these are the server global settings
    2 # stuff related to vhosts should go in one
    3 # file per vhost in ../conf.d/
    4 
    5 {
    6  "global": {
    7  "uid": "48", # apache user
    8  "gid": "48", # apache user
    9  "count-threads": "1",
    10  "server-string": "myserver v1", # returned in http headers
    11  "init-ssl": "yes"
    12  }
    13 }

    and a config directory intended to take one file per vhost

    -

    /etc/lwsws/conf.d/warmcat.com

    1 {
    2  "vhosts": [{
    3  "name": "warmcat.com",
    4  "port": "443",
    5  "interface": "eth0", # optional
    6  "host-ssl-key": "/etc/pki/tls/private/warmcat.com.key", # if given enable ssl
    7  "host-ssl-cert": "/etc/pki/tls/certs/warmcat.com.crt",
    8  "host-ssl-ca": "/etc/pki/tls/certs/warmcat.com.cer",
    9  "mounts": [{ # autoserve
    10  "mountpoint": "/",
    11  "origin": "file:///var/www/warmcat.com",
    12  "default": "index.html"
    13  }]
    14  }]
    15 }

    To get started quickly, an example config reproducing the old test server on port 7681, non-SSL is provided. To set it up

    1 # mkdir -p /etc/lwsws/conf.d /var/log/lwsws
    2 # cp ./lwsws/etc-lwsws-conf-EXAMPLE /etc/lwsws/conf
    3 # cp ./lwsws/etc-lwsws-conf.d-localhost-EXAMPLE /etc/lwsws/conf.d/test-server
    4 # sudo lwsws

    Vhosts

    +

    /etc/lwsws/conf.d/warmcat.com

    1 {
    2  "vhosts": [{
    3  "name": "warmcat.com",
    4  "port": "443",
    5  "interface": "eth0", # optional
    6  "host-ssl-key": "/etc/pki/tls/private/warmcat.com.key", # if given enable ssl
    7  "host-ssl-cert": "/etc/pki/tls/certs/warmcat.com.crt",
    8  "host-ssl-ca": "/etc/pki/tls/certs/warmcat.com.cer",
    9  "mounts": [{ # autoserve
    10  "mountpoint": "/",
    11  "origin": "file:///var/www/warmcat.com",
    12  "default": "index.html"
    13  }]
    14  }]
    15 }

    To get started quickly, an example config reproducing the old test server on port 7681, non-SSL is provided. To set it up

    1 # mkdir -p /etc/lwsws/conf.d /var/log/lwsws
    2 # cp ./lwsws/etc-lwsws-conf-EXAMPLE /etc/lwsws/conf
    3 # cp ./lwsws/etc-lwsws-conf.d-localhost-EXAMPLE /etc/lwsws/conf.d/test-server
    4 # sudo lwsws

    +Lwsws Vhosts

    One server can run many vhosts, where SSL is in use SNI is used to match the connection to a vhost and its vhost-specific SSL keys during SSL negotiation.

    Listing multiple vhosts looks something like this

    1 {
    2  "vhosts": [ {
    3  "name": "localhost",
    4  "port": "443",
    5  "host-ssl-key": "/etc/pki/tls/private/libwebsockets.org.key",
    6  "host-ssl-cert": "/etc/pki/tls/certs/libwebsockets.org.crt",
    7  "host-ssl-ca": "/etc/pki/tls/certs/libwebsockets.org.cer",
    8  "mounts": [{
    9  "mountpoint": "/",
    10  "origin": "file:///var/www/libwebsockets.org",
    11  "default": "index.html"
    12  }, {
    13  "mountpoint": "/testserver",
    14  "origin": "file:///usr/local/share/libwebsockets-test-server",
    15  "default": "test.html"
    16  }],
    17  # which protocols are enabled for this vhost, and optional
    18  # vhost-specific config options for the protocol
    19  #
    20  "ws-protocols": [{
    21  "warmcat,timezoom": {
    22  "status": "ok"
    23  }
    24  }]
    25  },
    26  {
    27  "name": "localhost",
    28  "port": "7681",
    29  "host-ssl-key": "/etc/pki/tls/private/libwebsockets.org.key",
    30  "host-ssl-cert": "/etc/pki/tls/certs/libwebsockets.org.crt",
    31  "host-ssl-ca": "/etc/pki/tls/certs/libwebsockets.org.cer",
    32  "mounts": [{
    33  "mountpoint": "/",
    34  "origin": ">https://localhost"
    35  }]
    36  },
    37  {
    38  "name": "localhost",
    39  "port": "80",
    40  "mounts": [{
    41  "mountpoint": "/",
    42  "origin": ">https://localhost"
    43  }]
    44  }
    45 
    46  ]
    47 }

    That sets up three vhosts all called "localhost" on ports 443 and 7681 with SSL, and port 80 without SSL but with a forced redirect to https://localhost

    -

    Vhost name and port

    +

    +Lwsws Vhost name and port sharing

    The vhost name field is used to match on incoming SNI or Host: header, so it must always be the host name used to reach the vhost externally.

    • Vhosts may have the same name and different ports, these will each create a listening socket on the appropriate port.
    • Vhosts may also have the same port and different name: these will be treated as true vhosts on one listening socket and the active vhost decided at SSL negotiation time (via SNI) or if no SSL, then after the Host: header from the client has been parsed.
    -

    Protocols

    +

    +Lwsws Protocols

    Vhosts by default have available the union of any initial protocols from context creation time, and any protocols exposed by plugins.

    Vhosts can select which plugins they want to offer and give them per-vhost settings using this syntax

    1 "ws-protocols": [{
    2  "warmcat-timezoom": {
    3  "status": "ok"
    4  }
    5 }]

    The "x":"y" parameters like "status":"ok" are made available to the protocol during its per-vhost LWS_CALLBACK_PROTOCOL_INIT ( is a pointer to a linked list of struct lws_protocol_vhost_options containing the name and value pointers).

    -

    To indicate that a protocol should be used when no Protocol: header is sent by the client, you can use "default": "1"

    1 "ws-protocols": [{
    2  "warmcat-timezoom": {
    3  "status": "ok",
    4  "default": "1"
    5  }
    6 }]

    Other vhost options

    +

    To indicate that a protocol should be used when no Protocol: header is sent by the client, you can use "default": "1"

    1 "ws-protocols": [{
    2  "warmcat-timezoom": {
    3  "status": "ok",
    4  "default": "1"
    5  }
    6 }]

    +Lwsws Other vhost options

    • If the three options host-ssl-cert, host-ssl-ca and host-ssl-key are given, then the vhost supports SSL.
    @@ -112,7 +123,8 @@ $(document).ready(function(){initNavTree('md_README.lwsws.html','');});
    1 "`ssl-option-set`": "268435456"
    • "`ssl-option-clear'": "<decimal>" Clears the SSL option flag value for the vhost. It may be used multiple times and OR's the flags together.
    -

    Mounts

    +

    +Lwsws Mounts

    Where mounts are given in the vhost definition, then directory contents may be auto-served if it matches the mountpoint.

    Mount protocols are used to control what kind of translation happens

      @@ -123,7 +135,8 @@ $(document).ready(function(){initNavTree('md_README.lwsws.html','');});
    • ^http:// or ^https:// these cause any url matching the mountpoint to issue a redirect to the origin url
    • cgi:// this causes any matching url to be given to the named cgi, eg
      1 {
      2  "mountpoint": "/git",
      3  "origin": "cgi:///var/www/cgi-bin/cgit",
      4  "default": "/"
      5 }, {
      6  "mountpoint": "/cgit-data",
      7  "origin": "file:///usr/share/cgit",
      8  "default": "/"
      9 },
      would cause the url /git/myrepo to pass "myrepo" to the cgi /var/www/cgi-bin/cgit and send the results to the client.
    -

    Other mount options

    +

    +Lwsws Other mount options

    1) Some protocols may want "per-mount options" in name:value format. You can provide them using "pmo"

               {
                 "mountpoint": "/stuff",
                 "origin": "callback://myprotocol",
    @@ -135,7 +148,8 @@ $(document).ready(function(){initNavTree('md_README.lwsws.html','');});
     

    3) It's also possible to set the cgi timeout (in secs) per cgi:// mount, like this

    1 "cgi-timeout": "30"

    4) callback:// protocol may be used when defining a mount to associate a named protocol callback with the URL namespace area. For example

    1 {
    2  "mountpoint": "/formtest",
    3  "origin": "callback://protocol-post-demo"
    4 }

    All handling of client access to /formtest[anything] will be passed to the callback registered to the protocol "protocol-post-demo".

    This is useful for handling POST http body content or general non-cgi http payload generation inside a plugin.

    See the related notes in README.coding.md

    -

    5) Cache policy of the files in the mount can also be set. If no options are given, the content is marked uncacheable.

    1 {
    2  "mountpoint": "/",
    3  "origin": "file:///var/www/mysite.com",
    4  "cache-max-age": "60", # seconds
    5  "cache-reuse": "1", # allow reuse at client at all
    6  "cache-revalidate": "1", # check it with server each time
    7  "cache-intermediaries": "1" # allow intermediary caches to hold
    8 }

    6) You can also define a list of additional mimetypes per-mount

    1 "extra-mimetypes": {
    2  ".zip": "application/zip",
    3  ".doc": "text/evil"
    4  }

    Plugins

    +

    5) Cache policy of the files in the mount can also be set. If no options are given, the content is marked uncacheable.

    1 {
    2  "mountpoint": "/",
    3  "origin": "file:///var/www/mysite.com",
    4  "cache-max-age": "60", # seconds
    5  "cache-reuse": "1", # allow reuse at client at all
    6  "cache-revalidate": "1", # check it with server each time
    7  "cache-intermediaries": "1" # allow intermediary caches to hold
    8 }

    6) You can also define a list of additional mimetypes per-mount

    1 "extra-mimetypes": {
    2  ".zip": "application/zip",
    3  ".doc": "text/evil"
    4  }

    +Lwsws Plugins

    Protcols and extensions may also be provided from "plugins", these are lightweight dynamic libraries. They are scanned for at init time, and any protocols and extensions found are added to the list given at context creation time.

    Protocols receive init (LWS_CALLBACK_PROTOCOL_INIT) and destruction (LWS_CALLBACK_PROTOCOL_DESTROY) callbacks per-vhost, and there are arrangements they can make per-vhost allocations and get hold of the correct pointer from the wsi at the callback.

    This allows a protocol to choose to strictly segregate data on a per-vhost basis, and also allows the plugin to handle its own initialization and context storage.

    @@ -148,14 +162,18 @@ $(document).ready(function(){initNavTree('md_README.lwsws.html','');});
  • lws_protocol_vh_priv_get(vhost, protocol)
  • dumb increment, mirror and status protocol plugins are provided as examples.

    -

    Additional plugin search paths

    -

    Packages that have their own lws plugins can install them in their own preferred dir and ask lwsws to scan there by using a config fragment like this, in its own conf.d/ file managed by the other package

    1 {
    2  "global": {
    3  "plugin-dir": "/usr/local/share/coherent-timeline/plugins"
    4  }
    5 }

    lws-server-status plugin

    +

    +Additional plugin search paths

    +

    Packages that have their own lws plugins can install them in their own preferred dir and ask lwsws to scan there by using a config fragment like this, in its own conf.d/ file managed by the other package

    1 {
    2  "global": {
    3  "plugin-dir": "/usr/local/share/coherent-timeline/plugins"
    4  }
    5 }

    +lws-server-status plugin

    One provided protocol can be used to monitor the server status.

    Enable the protocol like this on a vhost's ws-protocols section

    1 "lws-server-status": {
    2  "status": "ok",
    3  "update-ms": "5000"
    4 }

    "update-ms" is used to control how often updated JSON is sent on a ws link.

    And map the provided HTML into the vhost in the mounts section

    1 {
    2  "mountpoint": "/server-status",
    3  "origin": "file:///usr/local/share/libwebsockets-test-server/server-status",
    4  "default": "server-status.html"
    5 }

    You might choose to put it on its own vhost which has "interface": "lo", so it's not externally visible.

    -

    Integration with Systemd

    +

    +Lwsws Integration with Systemd

    lwsws needs a service file like this as /usr/lib/systemd/system/lwsws.service

    1 [Unit]
    2 Description=Libwebsockets Web Server
    3 After=syslog.target
    4 
    5 [Service]
    6 ExecStart=/usr/local/bin/lwsws
    7 StandardError=null
    8 
    9 [Install]
    10 WantedBy=multi-user.target

    You can find this prepared in ./lwsws/usr-lib-systemd-system-lwsws.service

    -

    Integration with logrotate

    +

    +Lwsws Integration with logrotate

    For correct operation with logrotate, /etc/logrotate.d/lwsws (if that's where we're putting the logs) should contain

    1 /var/log/lwsws/*log {
    2  copytruncate
    3  missingok
    4  notifempty
    5  delaycompress
    6 }

    You can find this prepared in /lwsws/etc-logrotate.d-lwsws

    Prepare the log directory like this

    1 sudo mkdir /var/log/lwsws
    2 sudo chmod 700 /var/log/lwsws
    diff --git a/doc/html/md_README.test-apps.html b/doc/html/md_README.test-apps.html index 4039ae18..ebf04393 100644 --- a/doc/html/md_README.test-apps.html +++ b/doc/html/md_README.test-apps.html @@ -82,47 +82,58 @@ $(document).ready(function(){initNavTree('md_README.test-apps.html','');});

    This is the original way lws implemented servers, plugins and libuv are not required, but without plugins separating the protocol code directly, the combined code is all squidged together and is much less maintainable.

    This method is still supported in lws but all ongoing and future work is being done in protocol plugins only.

    Notes about lws test apps

    -

    Testing server with a browser

    +

    +Testing server with a browser

    If you run libwebsockets-test-server and point your browser (eg, Chrome) to

        http://127.0.0.1:7681
     

    It will fetch a script in the form of test.html, and then run the script in there on the browser to open a websocket connection. Incrementing numbers should appear in the browser display.

    By default the test server logs to both stderr and syslog, you can control what is logged using -d <log level>, see later.

    -

    Running test server as a Daemon

    +

    +Running test server as a Daemon

    You can use the -D option on the test server to have it fork into the background and return immediately. In this daemonized mode all stderr is disabled and logging goes only to syslog, eg, /var/log/messages or similar.

    The server maintains a lockfile at /tmp/.lwsts-lock that contains the pid of the master process, and deletes this file when the master process terminates.

    To stop the daemon, do

    1 $ kill cat /tmp/.lwsts-lock

    If it finds a stale lock (the pid mentioned in the file does not exist any more) it will delete the lock and create a new one during startup.

    If the lock is valid, the daemon will exit with a note on stderr that it was already running.

    -

    Using SSL on the server side

    +

    +Using SSL on the server side

    To test it using SSL/WSS, just run the test server with

    1 $ libwebsockets-test-server --ssl

    and use the URL

    1 https://127.0.0.1:7681

    The connection will be entirely encrypted using some generated certificates that your browser will not accept, since they are not signed by any real Certificate Authority. Just accept the certificates in the browser and the connection will proceed in first https and then websocket wss, acting exactly the same.

    test-server.c is all that is needed to use libwebsockets for serving both the script html over http and websockets.

    -

    Testing websocket client support

    +

    +Testing websocket client support

    If you run the test server as described above, you can also connect to it using the test client as well as a browser.

    1 $ libwebsockets-test-client localhost

    will by default connect to the test server on localhost:7681 and print the dumb increment number from the server at the same time as drawing random circles in the mirror protocol; if you connect to the test server using a browser at the same time you will be able to see the circles being drawn.

    The test client supports SSL too, use

    1 $ libwebsockets-test-client localhost --ssl -s

    the -s tells it to accept the default selfsigned cert from the server, otherwise it will strictly fail the connection if there is no CA cert to validate the server's certificate.

    -

    Choosing between test server variations

    +

    +Choosing between test server variations

    If you will be doing standalone serving with lws, ideally you should avoid making your own server at all, and use lwsws with your own protocol plugins.

    The second best option is follow test-server-v2.0.c, which uses a mount to autoserve a directory, and lws protocol plugins for ws, without needing any user callback code (other than what's needed in the protocol plugin).

    For those two options libuv is needed to support the protocol plugins, if that's not possible then the other variations with their own protocol code should be considered.

    -

    Testing simple echo

    +

    +Testing simple echo

    You can test against echo.websockets.org as a sanity test like this (the client connects to port 80 by default):

    1 $ libwebsockets-test-echo --client echo.websocket.org

    This echo test is of limited use though because it doesn't negotiate any protocol. You can run the same test app as a local server, by default on localhost:7681

    1 $ libwebsockets-test-echo

    and do the echo test against the local echo server

    1 $ libwebsockets-test-echo --client localhost --port 7681

    If you add the --ssl switch to both the client and server, you can also test with an encrypted link.

    -

    Testing SSL on the client side

    +

    +Testing SSL on the client side

    To test SSL/WSS client action, just run the client test with

    1 $ libwebsockets-test-client localhost --ssl

    By default the client test applet is set to accept selfsigned certificates used by the test server, this is indicated by the use_ssl var being set to 2. Set it to 1 to reject any server certificate that it doesn't have a trusted CA cert for.

    -

    Using the websocket ping utility

    +

    +Using the websocket ping utility

    libwebsockets-test-ping connects as a client to a remote websocket server and pings it like the normal unix ping utility.

    1 $ libwebsockets-test-ping localhost
    2 handshake OK for protocol lws-mirror-protocol
    3 Websocket PING localhost.localdomain (127.0.0.1) 64 bytes of data.
    4 64 bytes from localhost: req=1 time=0.1ms
    5 64 bytes from localhost: req=2 time=0.1ms
    6 64 bytes from localhost: req=3 time=0.1ms
    7 64 bytes from localhost: req=4 time=0.2ms
    8 64 bytes from localhost: req=5 time=0.1ms
    9 64 bytes from localhost: req=6 time=0.2ms
    10 64 bytes from localhost: req=7 time=0.2ms
    11 64 bytes from localhost: req=8 time=0.1ms
    12 ^C
    13 --- localhost.localdomain websocket ping statistics ---
    14 8 packets transmitted, 8 received, 0% packet loss, time 7458ms
    15 rtt min/avg/max = 0.110/0.185/0.218 ms
    16 $

    By default it sends 64 byte payload packets using the 04 PING packet opcode type. You can change the payload size using the -s= flag, up to a maximum of 125 mandated by the 04 standard.

    Using the lws-mirror protocol that is provided by the test server, libwebsockets-test-ping can also use larger payload sizes up to 4096 is BINARY packets; lws-mirror will copy them back to the client and they appear as a PONG. Use the -m flag to select this operation.

    The default interval between pings is 1s, you can use the -i= flag to set this, including fractions like -i=0.01 for 10ms interval.

    Before you can even use the PING opcode that is part of the standard, you must complete a handshake with a specified protocol. By default lws-mirror-protocol is used which is supported by the test server. But if you are using it on another server, you can specify the protcol to handshake with by --protocol=protocolname

    -

    Fraggle test app

    +

    +fraggle Fraggle test app

    By default it runs in server mode

    1 $ libwebsockets-test-fraggle
    2 libwebsockets test fraggle
    3 (C) Copyright 2010-2011 Andy Green <andy@warmcat.com> licensed under LGPL2.1
    4  Compiled with SSL support, not using it
    5  Listening on port 7681
    6 server sees client connect
    7 accepted v06 connection
    8 Spamming 360 random fragments
    9 Spamming session over, len = 371913. sum = 0x2D3C0AE
    10 Spamming 895 random fragments
    11 Spamming session over, len = 875970. sum = 0x6A74DA1
    12 ...

    You need to run a second session in client mode, you have to give the -c switch and the server address at least:

    1 $ libwebsockets-test-fraggle -c localhost
    2 libwebsockets test fraggle
    3 (C) Copyright 2010-2011 Andy Green <andy@warmcat.com> licensed under LGPL2.1
    4  Client mode
    5 Connecting to localhost:7681
    6 denied deflate-stream extension
    7 handshake OK for protocol fraggle-protocol
    8 client connects to server
    9 EOM received 371913 correctly from 360 fragments
    10 EOM received 875970 correctly from 895 fragments
    11 EOM received 247140 correctly from 258 fragments
    12 EOM received 695451 correctly from 692 fragments
    13 ...

    The fraggle test sends a random number up to 1024 fragmented websocket frames each of a random size between 1 and 2001 bytes in a single message, then sends a checksum and starts sending a new randomly sized and fragmented message.

    The fraggle test client receives the same message fragments and computes the same checksum using websocket framing to see when the message has ended. It then accepts the server checksum message and compares that to its checksum.

    -

    proxy support

    +

    +proxy support

    The http_proxy environment variable is respected by the client connection code for both ws:// and wss://. It doesn't support authentication.

    -

    You use it like this

    1 $ export http_proxy=myproxy.com:3128
    2 $ libwebsockets-test-client someserver.com

    debug logging

    +

    You use it like this

    1 $ export http_proxy=myproxy.com:3128
    2 $ libwebsockets-test-client someserver.com

    +debug logging

    By default logging of severity "notice", "warn" or "err" is enabled to stderr.

    Again by default other logging is compiled in but disabled from printing.

    -

    If you want to eliminate the debug logging below notice in severity, use the --disable-debug configure option to have it removed from the code by the preprocesser.

    -

    If you want to see more detailed debug logs, you can control a bitfield to select which logs types may print using the lws_set_log_level() api, in the test apps you can use -d <number> to control this. The types of logging available are (OR together the numbers to select multiple)

    +

    By default debug logs below "notice" in severity are not compiled in. To get them included, add this option in CMAKE

    +
    1 $ cmake .. -DCMAKE_BUILD_TYPE=DEBUG

    If you want to see more detailed debug logs, you can control a bitfield to select which logs types may print using the lws_set_log_level() api, in the test apps you can use -d <number> to control this. The types of logging available are (OR together the numbers to select multiple)

    • 1 ERR
    • 2 WARN
    • @@ -135,13 +146,16 @@ $(document).ready(function(){initNavTree('md_README.test-apps.html','');});
    • 256 CLIENT
    • 512 LATENCY
    -

    Websocket version supported

    +

    +Websocket version supported

    The final IETF standard is supported for both client and server, protocol version 13.

    -

    Latency Tracking

    +

    +Latency Tracking

    Since libwebsockets runs using poll() and a single threaded approach, any unexpected latency coming from system calls would be bad news. There's now a latency tracking scheme that can be built in with --with-latency at configure-time, logging the time taken for system calls to complete and if the whole action did complete that time or was deferred.

    You can see the detailed data by enabling logging level 512 (eg, -d 519 on the test server to see that and the usual logs), however even without that the "worst" latency is kept and reported to the logs with NOTICE severity when the context is destroyed.

    Some care is needed interpreting them, if the action completed the first figure (in us) is the time taken for the whole action, which may have retried through the poll loop many times and will depend on network roundtrip times. High figures here don't indicate a problem. The figure in us reported after "lat" in the logging is the time taken by this particular attempt. High figures here may indicate a problem, or if you system is loaded with another app at that time, such as the browser, it may simply indicate the OS gave preferential treatment to the other app during that call.

    -

    Autobahn Test Suite

    +

    +Autobahn Test Suite

    Lws can be tested against the autobahn websocket fuzzer.

    1) pip install autobahntestsuite

    2) wstest -m fuzzingserver

    @@ -154,9 +168,10 @@ $(document).ready(function(){initNavTree('md_README.test-apps.html','');});

    5) In a browser go to the directory you ran wstest in (eg, /projects/libwebsockets)

    file:///projects/libwebsockets/reports/clients/index.html

    to see the results

    -

    Autobahn Test Notes

    +

    +Autobahn Test Notes

    1) Autobahn tests the user code + lws implementation. So to get the same results, you need to follow test-echo.c in terms of user implmentation.

    -

    2) Some of the tests make no sense for Libwebsockets to support and we fail them.

    +

    2) Two of the tests make no sense for Libwebsockets to support and we fail them.

    • Tests 2.10 + 2.11: sends multiple pings on one connection. Lws policy is to only allow one active ping in flight on each connection, the rest are dropped. The autobahn test itself admits this is not part of the standard, just someone's random opinion about how they think a ws server should act. So we will fail this by design and it is no problem about RFC6455 compliance.
    diff --git a/doc/html/navtreedata.js b/doc/html/navtreedata.js index 5f232002..f0e7b5b1 100644 --- a/doc/html/navtreedata.js +++ b/doc/html/navtreedata.js @@ -2,11 +2,97 @@ var NAVTREE = [ [ "libwebsockets", "index.html", [ [ "Libwebsockets API introduction", "index.html", null ], - [ "Notes about building lws", "md_README.build.html", null ], - [ "Notes about lwsws", "md_README.lwsws.html", null ], - [ "Notes about coding with lws", "md_README.coding.html", null ], - [ "Notes about generic-sessions Plugin", "md_README.generic-sessions.html", null ], - [ "Overview of lws test apps", "md_README.test-apps.html", null ], + [ "Notes about building lws", "md_README.build.html", [ + [ "Introduction to CMake", "md_README.build.html#cm", null ], + [ "Building the library and test apps", "md_README.build.html#build1", null ], + [ "Building on Unix:", "md_README.build.html#bu", null ], + [ "Quirk of cmake", "md_README.build.html#cmq", null ], + [ "Building on Windows (Visual Studio)", "md_README.build.html#cmw", null ], + [ "Building on Windows (MinGW)", "md_README.build.html#cmwmgw", null ], + [ "Building on mbed3", "md_README.build.html#mbed3", null ], + [ "Setting compile options", "md_README.build.html#cmco", [ + [ "Command line", "md_README.build.html#cmcocl", null ], + [ "Unix GUI", "md_README.build.html#cmcoug", null ], + [ "Windows GUI", "md_README.build.html#cmcowg", null ] + ] ], + [ "wolfSSL/CyaSSL replacement for OpenSSL", "md_README.build.html#wolf", null ], + [ "Compiling libwebsockets with wolfSSL", "md_README.build.html#wolf1", null ], + [ "Compiling libwebsockets with CyaSSL", "md_README.build.html#cya", null ], + [ "Building plugins outside of lws itself", "md_README.build.html#extplugins", null ], + [ "Reproducing HTTP2.0 tests", "md_README.build.html#http2rp", null ], + [ "Cross compiling", "md_README.build.html#cross", null ], + [ "Memory efficiency", "md_README.build.html#mem", null ] + ] ], + [ "Notes about lwsws", "md_README.lwsws.html", [ + [ "Libwebsockets Web Server", "md_README.lwsws.html#lwsws", null ], + [ "Build", "md_README.lwsws.html#lwswsb", null ], + [ "Lwsws Configuration", "md_README.lwsws.html#lwswsc", null ], + [ "Lwsws Vhosts", "md_README.lwsws.html#lwswsv", null ], + [ "Lwsws Vhost name and port sharing", "md_README.lwsws.html#lwswsvn", null ], + [ "Lwsws Protocols", "md_README.lwsws.html#lwswspr", null ], + [ "Lwsws Other vhost options", "md_README.lwsws.html#lwswsovo", null ], + [ "Lwsws Mounts", "md_README.lwsws.html#lwswsm", null ], + [ "Lwsws Other mount options", "md_README.lwsws.html#lwswsomo", null ], + [ "Lwsws Plugins", "md_README.lwsws.html#lwswspl", null ], + [ "Additional plugin search paths", "md_README.lwsws.html#lwswsplaplp", null ], + [ "lws-server-status plugin", "md_README.lwsws.html#lwswsssp", null ], + [ "Lwsws Integration with Systemd", "md_README.lwsws.html#lwswssysd", null ], + [ "Lwsws Integration with logrotate", "md_README.lwsws.html#lwswslr", null ] + ] ], + [ "Notes about coding with lws", "md_README.coding.html", [ + [ "Daemonization", "md_README.coding.html#dae", null ], + [ "Maximum number of connections", "md_README.coding.html#conns", null ], + [ "Libwebsockets is singlethreaded", "md_README.coding.html#evtloop", null ], + [ "Only send data when socket writeable", "md_README.coding.html#writeable", null ], + [ "Do not rely on only your own WRITEABLE requests appearing", "md_README.coding.html#otherwr", null ], + [ "Closing connections from the user side", "md_README.coding.html#closing", null ], + [ "Fragmented messages", "md_README.coding.html#frags", null ], + [ "Debug Logging", "md_README.coding.html#debuglog", null ], + [ "External Polling Loop support", "md_README.coding.html#extpoll", null ], + [ "Using with in c++ apps", "md_README.coding.html#cpp", null ], + [ "Availability of header information", "md_README.coding.html#headerinfo", null ], + [ "TCP Keepalive", "md_README.coding.html#ka", null ], + [ "Optimizing SSL connections", "md_README.coding.html#sslopt", null ], + [ "Async nature of client connections", "md_README.coding.html#clientasync", null ], + [ "Lws platform-independent file access apis", "md_README.coding.html#fileapi", null ], + [ "ECDH Support", "md_README.coding.html#ecdh", null ], + [ "SMP / Multithreaded service", "md_README.coding.html#smp", null ], + [ "Libev / Libuv support", "md_README.coding.html#libevuv", null ], + [ "Extension option control from user code", "md_README.coding.html#extopts", null ], + [ "Client connections as HTTP[S] rather than WS[S]", "md_README.coding.html#httpsclient", null ], + [ "Using lws vhosts", "md_README.coding.html#vhosts", null ], + [ "How lws matches hostname or SNI to a vhost", "md_README.coding.html#sni", null ], + [ "Using lws mounts on a vhost", "md_README.coding.html#mounts", null ], + [ "Operation of LWSMPRO_CALLBACK mounts", "md_README.coding.html#mountcallback", null ] + ] ], + [ "Notes about generic-sessions Plugin", "md_README.generic-sessions.html", [ + [ "Enabling lwsgs for build", "md_README.generic-sessions.html#gseb", null ], + [ "lwsgs Introduction", "md_README.generic-sessions.html#gsi", null ], + [ "Lwsgs Integration to HTML", "md_README.generic-sessions.html#gsin", null ], + [ "Lwsgs Overall Flow@", "md_README.generic-sessions.html#gsof", null ], + [ "Lwsgs Configuration", "md_README.generic-sessions.html#gsconf", null ], + [ "Lwsgs Password Confounder", "md_README.generic-sessions.html#gspwc", null ], + [ "Lwsgs Preparing the db directory", "md_README.generic-sessions.html#gsprep", null ], + [ "Lwsgs Email configuration", "md_README.generic-sessions.html#gsrmail", null ], + [ "Lwsgs Integration with another protocol", "md_README.generic-sessions.html#gsap", null ] + ] ], + [ "Overview of lws test apps", "md_README.test-apps.html", [ + [ "Testing server with a browser", "md_README.test-apps.html#tsb", null ], + [ "Running test server as a Daemon", "md_README.test-apps.html#tsd", null ], + [ "Using SSL on the server side", "md_README.test-apps.html#sssl", null ], + [ "Testing websocket client support", "md_README.test-apps.html#wscl", null ], + [ "Choosing between test server variations", "md_README.test-apps.html#choosingts", null ], + [ "Testing simple echo", "md_README.test-apps.html#echo", null ], + [ "Testing SSL on the client side", "md_README.test-apps.html#tassl", null ], + [ "Using the websocket ping utility", "md_README.test-apps.html#taping", null ], + [ "fraggle Fraggle test app", "md_README.test-apps.html#ta", null ], + [ "proxy support", "md_README.test-apps.html#taproxy", null ], + [ "debug logging", "md_README.test-apps.html#talog", null ], + [ "Websocket version supported", "md_README.test-apps.html#ws13", null ], + [ "Latency Tracking", "md_README.test-apps.html#latency", null ], + [ "Autobahn Test Suite", "md_README.test-apps.html#autobahn", null ], + [ "Autobahn Test Notes", "md_README.test-apps.html#autobahnnotes", null ] + ] ], [ "Deprecated List", "deprecated.html", null ], [ "Modules", "modules.html", "modules" ], [ "Data Structures", "annotated.html", [ @@ -37,7 +123,8 @@ var NAVTREEINDEX = "annotated.html", "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5ac962efd35abf6c402f9fb14aa14f5016", "group__sha.html#ga7b09ab74646266f0b555103b3bb8dfe5", -"libwebsockets_8h.html#a42394a38f08a97420c98127358cfeedbad9cdc12a796e6c7d912278834d9c7dde" +"libwebsockets_8h.html#a42394a38f08a97420c98127358cfeedbad9cdc12a796e6c7d912278834d9c7dde", +"structlws__process__html__args.html#a362547891ee0d693f3900a1f807ea475" ]; var SYNCONMSG = 'click to disable panel synchronisation'; diff --git a/doc/html/navtreeindex0.js b/doc/html/navtreeindex0.js index f6f1e694..4871d7d2 100644 --- a/doc/html/navtreeindex0.js +++ b/doc/html/navtreeindex0.js @@ -37,28 +37,28 @@ var NAVTREEINDEX0 = "globals_l.html":[9,1,0,1], "globals_type.html":[9,1,2], "group__HTTP-headers-create.html":[7,6,3], -"group__HTTP-headers-create.html#ga29b7d6d2ddfdbaff3d8b607e7e3151b6":[9,0,0,0,41], "group__HTTP-headers-create.html#ga29b7d6d2ddfdbaff3d8b607e7e3151b6":[7,6,3,3], -"group__HTTP-headers-create.html#ga2b36bf44405755ff51c1939303b995a8":[9,0,0,0,38], +"group__HTTP-headers-create.html#ga29b7d6d2ddfdbaff3d8b607e7e3151b6":[9,0,0,0,41], "group__HTTP-headers-create.html#ga2b36bf44405755ff51c1939303b995a8":[7,6,3,0], -"group__HTTP-headers-create.html#ga4887605ff2242a54db3a7fa01f6f864b":[9,0,0,0,76], +"group__HTTP-headers-create.html#ga2b36bf44405755ff51c1939303b995a8":[9,0,0,0,38], "group__HTTP-headers-create.html#ga4887605ff2242a54db3a7fa01f6f864b":[7,6,3,4], -"group__HTTP-headers-create.html#gacc76a5babcb4dce1b01b1955aa7a2faf":[9,0,0,0,40], +"group__HTTP-headers-create.html#ga4887605ff2242a54db3a7fa01f6f864b":[9,0,0,0,76], "group__HTTP-headers-create.html#gacc76a5babcb4dce1b01b1955aa7a2faf":[7,6,3,2], +"group__HTTP-headers-create.html#gacc76a5babcb4dce1b01b1955aa7a2faf":[9,0,0,0,40], "group__HTTP-headers-create.html#gaf74adb761b22566ad70004882712dce1":[7,6,3,1], "group__HTTP-headers-create.html#gaf74adb761b22566ad70004882712dce1":[9,0,0,0,39], "group__HTTP-headers-read.html":[7,6,4], -"group__HTTP-headers-read.html#ga2c0597b2ef1d2cee35736c338bcbd17b":[7,6,4,7], "group__HTTP-headers-read.html#ga2c0597b2ef1d2cee35736c338bcbd17b":[9,0,0,0,143], -"group__HTTP-headers-read.html#ga594f3d0ece5b09c2ccf9f98ea533bb4e":[9,0,0,0,97], +"group__HTTP-headers-read.html#ga2c0597b2ef1d2cee35736c338bcbd17b":[7,6,4,7], "group__HTTP-headers-read.html#ga594f3d0ece5b09c2ccf9f98ea533bb4e":[7,6,4,5], -"group__HTTP-headers-read.html#ga6ce6aa1c0155ea42b7708bed271d1c77":[9,0,0,0,95], +"group__HTTP-headers-read.html#ga594f3d0ece5b09c2ccf9f98ea533bb4e":[9,0,0,0,97], "group__HTTP-headers-read.html#ga6ce6aa1c0155ea42b7708bed271d1c77":[7,6,4,3], +"group__HTTP-headers-read.html#ga6ce6aa1c0155ea42b7708bed271d1c77":[9,0,0,0,95], "group__HTTP-headers-read.html#ga6e747906f9d76532ec118d6ef418b82e":[9,0,0,0,31], -"group__HTTP-headers-read.html#ga84e9ce5e71a77501a0998ac403a984c2":[9,0,0,0,93], "group__HTTP-headers-read.html#ga84e9ce5e71a77501a0998ac403a984c2":[7,6,4,2], -"group__HTTP-headers-read.html#ga8ade0e1ffb0da7e62b989d8d867bf6c8":[9,0,0,0,98], +"group__HTTP-headers-read.html#ga84e9ce5e71a77501a0998ac403a984c2":[9,0,0,0,93], "group__HTTP-headers-read.html#ga8ade0e1ffb0da7e62b989d8d867bf6c8":[7,6,4,6], +"group__HTTP-headers-read.html#ga8ade0e1ffb0da7e62b989d8d867bf6c8":[9,0,0,0,98], "group__HTTP-headers-read.html#gaa427cad61a9a5e3004afd65c4527b5e9":[7,6,4,4], "group__HTTP-headers-read.html#gaa427cad61a9a5e3004afd65c4527b5e9":[9,0,0,0,96], "group__HTTP-headers-read.html#gga6e747906f9d76532ec118d6ef418b82ea03293996964a8bb617215508908048d4":[9,0,0,0,31,42], @@ -156,8 +156,8 @@ var NAVTREEINDEX0 = "group__Protocols-and-Plugins.html":[7,10], "group__Protocols-and-Plugins.html#ga106b37ae9c247e84d191ab09441adc43":[7,10,4], "group__Protocols-and-Plugins.html#ga106b37ae9c247e84d191ab09441adc43":[9,0,0,0,77], -"group__Protocols-and-Plugins.html#ga25754726d97c5f519d313e691a9fe29d":[7,10,9], "group__Protocols-and-Plugins.html#ga25754726d97c5f519d313e691a9fe29d":[9,0,0,0,151], +"group__Protocols-and-Plugins.html#ga25754726d97c5f519d313e691a9fe29d":[7,10,9], "group__Protocols-and-Plugins.html#ga40994491e1567f91f579d2b444775266":[9,0,0,0,12], "group__Protocols-and-Plugins.html#ga72ad550786ca7976463589d347e62112":[7,10,5], "group__Protocols-and-Plugins.html#ga72ad550786ca7976463589d347e62112":[9,0,0,0,89], @@ -196,8 +196,8 @@ var NAVTREEINDEX0 = "group__client.html#ga4f44b8230e6732816ca5cd8d1aaaf340":[9,0,0,0,102], "group__client.html#ga96f3dbad54b2853969cfa933d66871ce":[9,0,0,0,21], "group__client.html#ga96f3dbad54b2853969cfa933d66871ce":[7,2,1], -"group__client.html#gac6a8558b4410961a880241c2ac1271e2":[9,0,0,0,60], "group__client.html#gac6a8558b4410961a880241c2ac1271e2":[7,2,3], +"group__client.html#gac6a8558b4410961a880241c2ac1271e2":[9,0,0,0,60], "group__client.html#gga96f3dbad54b2853969cfa933d66871cea7051e79bb97b69862f2ff00ae5298ec7":[9,0,0,0,21,0], "group__client.html#gga96f3dbad54b2853969cfa933d66871cea89866ab6a749aaa1684158c55f826b35":[9,0,0,0,21,2], "group__client.html#gga96f3dbad54b2853969cfa933d66871ceafc72c0ffbc7462bdddd4ce7bd99ac092":[9,0,0,0,21,1], @@ -206,48 +206,48 @@ var NAVTREEINDEX0 = "group__context-and-vhost.html#ga06e77ce2916f8bc9826ef8d9d68e3932":[9,0,0,0,94], "group__context-and-vhost.html#ga0c54c667ccd9b8b3dddcd123ca72f87c":[7,4,7], "group__context-and-vhost.html#ga0c54c667ccd9b8b3dddcd123ca72f87c":[9,0,0,0,66], -"group__context-and-vhost.html#ga341064721add2618ae1b29717493a212":[7,4,14], "group__context-and-vhost.html#ga341064721add2618ae1b29717493a212":[9,0,0,0,158], -"group__context-and-vhost.html#ga41c2d763f78cc248df3b9f8645dbd2a5":[7,4,3], +"group__context-and-vhost.html#ga341064721add2618ae1b29717493a212":[7,4,14], "group__context-and-vhost.html#ga41c2d763f78cc248df3b9f8645dbd2a5":[9,0,0,0,23], +"group__context-and-vhost.html#ga41c2d763f78cc248df3b9f8645dbd2a5":[7,4,3], "group__context-and-vhost.html#ga7e9d5405547a457d86e0b4f0ae2bb1c4":[7,4,11], "group__context-and-vhost.html#ga7e9d5405547a457d86e0b4f0ae2bb1c4":[9,0,0,0,133], -"group__context-and-vhost.html#ga8db03e19a372e34ac25cf21af894a02c":[7,4,12], "group__context-and-vhost.html#ga8db03e19a372e34ac25cf21af894a02c":[9,0,0,0,150], +"group__context-and-vhost.html#ga8db03e19a372e34ac25cf21af894a02c":[7,4,12], "group__context-and-vhost.html#ga8ee0314028755f1ddfa9428e09b4fddb":[7,4,4], "group__context-and-vhost.html#ga8ee0314028755f1ddfa9428e09b4fddb":[9,0,0,0,63], "group__context-and-vhost.html#ga94e6cc2223c4eec316b13bcebc3628b6":[7,4,10], "group__context-and-vhost.html#ga94e6cc2223c4eec316b13bcebc3628b6":[9,0,0,0,108], -"group__context-and-vhost.html#ga98d88c9080fd89c37114363a6474ea73":[7,4,13], "group__context-and-vhost.html#ga98d88c9080fd89c37114363a6474ea73":[9,0,0,0,157], +"group__context-and-vhost.html#ga98d88c9080fd89c37114363a6474ea73":[7,4,13], "group__context-and-vhost.html#gae2134657cdd2ea7a59e13ad314e4c50d":[7,4,9], "group__context-and-vhost.html#gae2134657cdd2ea7a59e13ad314e4c50d":[9,0,0,0,107], "group__context-and-vhost.html#gaeb12f934bfd178bd2132a9e73fc641da":[7,4,5], "group__context-and-vhost.html#gaeb12f934bfd178bd2132a9e73fc641da":[9,0,0,0,64], -"group__context-and-vhost.html#gaf2fff58562caab7510c41eeac85a8648":[7,4,6], "group__context-and-vhost.html#gaf2fff58562caab7510c41eeac85a8648":[9,0,0,0,65], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a1b2f8bde0f62adc7ebe81b2043f34c0c":[7,4,3,8], +"group__context-and-vhost.html#gaf2fff58562caab7510c41eeac85a8648":[7,4,6], "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a1b2f8bde0f62adc7ebe81b2043f34c0c":[9,0,0,0,23,8], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a1cc4562d05cba52a6dfa0697a65ade0d":[7,4,3,2], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a1b2f8bde0f62adc7ebe81b2043f34c0c":[7,4,3,8], "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a1cc4562d05cba52a6dfa0697a65ade0d":[9,0,0,0,23,2], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a273d9975675130de0c6dc937dde7c8a6":[7,4,3,3], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a1cc4562d05cba52a6dfa0697a65ade0d":[7,4,3,2], "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a273d9975675130de0c6dc937dde7c8a6":[9,0,0,0,23,3], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a274ed462a1a9239eb6ddf9007f5b7092":[7,4,3,0], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a273d9975675130de0c6dc937dde7c8a6":[7,4,3,3], "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a274ed462a1a9239eb6ddf9007f5b7092":[9,0,0,0,23,0], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a34ab36e68c0d593b6f19b8d5ef1240a9":[7,4,3,4], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a274ed462a1a9239eb6ddf9007f5b7092":[7,4,3,0], "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a34ab36e68c0d593b6f19b8d5ef1240a9":[9,0,0,0,23,4], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a4832187186c4d130c68051214cd42ada":[7,4,3,10], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a34ab36e68c0d593b6f19b8d5ef1240a9":[7,4,3,4], "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a4832187186c4d130c68051214cd42ada":[9,0,0,0,23,10], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a4933347a821e73c3f1e13fb6bfc7ad93":[7,4,3,5], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a4832187186c4d130c68051214cd42ada":[7,4,3,10], "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a4933347a821e73c3f1e13fb6bfc7ad93":[9,0,0,0,23,5], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a6582c985ee0ceaadc1d277030eae2d7c":[7,4,3,1], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a4933347a821e73c3f1e13fb6bfc7ad93":[7,4,3,5], "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a6582c985ee0ceaadc1d277030eae2d7c":[9,0,0,0,23,1], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a7fed6a527c8d5e0acac1b4179644583a":[7,4,3,11], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a6582c985ee0ceaadc1d277030eae2d7c":[7,4,3,1], "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a7fed6a527c8d5e0acac1b4179644583a":[9,0,0,0,23,11], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a9637e9001d8c8b2521086bcafbd8a941":[7,4,3,13], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a7fed6a527c8d5e0acac1b4179644583a":[7,4,3,11], "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a9637e9001d8c8b2521086bcafbd8a941":[9,0,0,0,23,13], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5aa0158b4e85420811e6b0f1378c6ded0f":[7,4,3,7], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5a9637e9001d8c8b2521086bcafbd8a941":[7,4,3,13], "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5aa0158b4e85420811e6b0f1378c6ded0f":[9,0,0,0,23,7], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5ac56a8a6590e74a8016d0fae09fb404fc":[7,4,3,6], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5ac56a8a6590e74a8016d0fae09fb404fc":[9,0,0,0,23,6] +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5aa0158b4e85420811e6b0f1378c6ded0f":[7,4,3,7], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5ac56a8a6590e74a8016d0fae09fb404fc":[9,0,0,0,23,6], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5ac56a8a6590e74a8016d0fae09fb404fc":[7,4,3,6] }; diff --git a/doc/html/navtreeindex1.js b/doc/html/navtreeindex1.js index f707c949..b895bd67 100644 --- a/doc/html/navtreeindex1.js +++ b/doc/html/navtreeindex1.js @@ -1,15 +1,15 @@ var NAVTREEINDEX1 = { -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5ac962efd35abf6c402f9fb14aa14f5016":[7,4,3,14], "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5ac962efd35abf6c402f9fb14aa14f5016":[9,0,0,0,23,14], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5aca5d42820b65eac5618ec3f0bd8a1160":[7,4,3,16], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5ac962efd35abf6c402f9fb14aa14f5016":[7,4,3,14], "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5aca5d42820b65eac5618ec3f0bd8a1160":[9,0,0,0,23,16], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5accc9d0d11d1124a21659586164b0962e":[7,4,3,12], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5aca5d42820b65eac5618ec3f0bd8a1160":[7,4,3,16], "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5accc9d0d11d1124a21659586164b0962e":[9,0,0,0,23,12], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5af62887536e25e053e68741006dba46d8":[7,4,3,15], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5accc9d0d11d1124a21659586164b0962e":[7,4,3,12], "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5af62887536e25e053e68741006dba46d8":[9,0,0,0,23,15], -"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5aff121db04a10cf8b2c5df9d4f2b89f1e":[7,4,3,9], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5af62887536e25e053e68741006dba46d8":[7,4,3,15], "group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5aff121db04a10cf8b2c5df9d4f2b89f1e":[9,0,0,0,23,9], +"group__context-and-vhost.html#gga41c2d763f78cc248df3b9f8645dbd2a5aff121db04a10cf8b2c5df9d4f2b89f1e":[7,4,3,9], "group__ev.html":[7,21], "group__ev.html#ga3b0ffd4d2b4fa791c0fd75353a330208":[9,0,0,0,8], "group__ev.html#ga3fdd23ded693b21853356dc9eaef5ccc":[9,0,0,0,71], @@ -20,17 +20,17 @@ var NAVTREEINDEX1 = "group__extensions.html#ga4cdbe42d872e21a448a947714d6c607e":[9,0,0,0,75], "group__extensions.html#ga6fb3e2c3dfb9d64dc87026a4e99c128b":[7,5,5], "group__extensions.html#ga6fb3e2c3dfb9d64dc87026a4e99c128b":[9,0,0,0,74], -"group__extensions.html#gaae7169b2cd346b34fa33d0250db2afd0":[7,5,3], "group__extensions.html#gaae7169b2cd346b34fa33d0250db2afd0":[9,0,0,0,9], +"group__extensions.html#gaae7169b2cd346b34fa33d0250db2afd0":[7,5,3], "group__extensions.html#gacc9f55936dc165257a2e1f7d47bce89e":[9,0,0,0,25], "group__extensions.html#gacc9f55936dc165257a2e1f7d47bce89e":[7,5,4], "group__extensions.html#gae0e24e1768f83a7fb07896ce975704b9":[7,5,7], "group__extensions.html#gae0e24e1768f83a7fb07896ce975704b9":[9,0,0,0,131], "group__extensions.html#gae9993815eee72c6070300a0ae2f022d7":[9,0,0,0,26], -"group__extensions.html#ggacc9f55936dc165257a2e1f7d47bce89ea1c86adf924c8786a12bee9687094673e":[9,0,0,0,25,1], "group__extensions.html#ggacc9f55936dc165257a2e1f7d47bce89ea1c86adf924c8786a12bee9687094673e":[7,5,4,1], -"group__extensions.html#ggacc9f55936dc165257a2e1f7d47bce89ea5265abe3e1c3f64412f2affe7bffd880":[9,0,0,0,25,2], +"group__extensions.html#ggacc9f55936dc165257a2e1f7d47bce89ea1c86adf924c8786a12bee9687094673e":[9,0,0,0,25,1], "group__extensions.html#ggacc9f55936dc165257a2e1f7d47bce89ea5265abe3e1c3f64412f2affe7bffd880":[7,5,4,2], +"group__extensions.html#ggacc9f55936dc165257a2e1f7d47bce89ea5265abe3e1c3f64412f2affe7bffd880":[9,0,0,0,25,2], "group__extensions.html#ggacc9f55936dc165257a2e1f7d47bce89eaabcf56c456c1ff6e81dc82586a16f14c":[9,0,0,0,25,0], "group__extensions.html#ggacc9f55936dc165257a2e1f7d47bce89eaabcf56c456c1ff6e81dc82586a16f14c":[7,5,4,0], "group__extensions.html#ggae9993815eee72c6070300a0ae2f022d7a05b74161bfab0f815d7fd47b85e20bfc":[9,0,0,0,26,9], @@ -68,24 +68,24 @@ var NAVTREEINDEX1 = "group__form-parsing.html#ga162f86762173a2bc8c28497941d74815":[9,0,0,0,136], "group__form-parsing.html#ga2da476217166da02704b90d3a8d4f3cd":[7,6,0,6], "group__form-parsing.html#ga2da476217166da02704b90d3a8d4f3cd":[9,0,0,0,140], -"group__form-parsing.html#ga3fbe378632f85ec9a14cc2c1687bf05f":[7,6,0,5], "group__form-parsing.html#ga3fbe378632f85ec9a14cc2c1687bf05f":[9,0,0,0,139], -"group__form-parsing.html#ga41a74a822771d3dce89751aa3bce28ae":[9,0,0,0,30], +"group__form-parsing.html#ga3fbe378632f85ec9a14cc2c1687bf05f":[7,6,0,5], "group__form-parsing.html#ga41a74a822771d3dce89751aa3bce28ae":[7,6,0,1], +"group__form-parsing.html#ga41a74a822771d3dce89751aa3bce28ae":[9,0,0,0,30], "group__form-parsing.html#ga5a70527c0861c2ffa3d29333a6aa7f8e":[7,6,0,0], "group__form-parsing.html#ga5a70527c0861c2ffa3d29333a6aa7f8e":[9,0,0,0,15], "group__form-parsing.html#ga83835bf250ee3d4a60f36a182f2b8d24":[7,6,0,4], "group__form-parsing.html#ga83835bf250ee3d4a60f36a182f2b8d24":[9,0,0,0,138], "group__form-parsing.html#ga9ad9ebf5ea1a7108415ed7e04cb231d2":[7,6,0,7], "group__form-parsing.html#ga9ad9ebf5ea1a7108415ed7e04cb231d2":[9,0,0,0,141], -"group__form-parsing.html#gaaa482f07dad3f04b391cccf0a814e13b":[7,6,0,3], "group__form-parsing.html#gaaa482f07dad3f04b391cccf0a814e13b":[9,0,0,0,137], -"group__form-parsing.html#gga41a74a822771d3dce89751aa3bce28aea2d25de44865bd44e5a3903a2bab9ca83":[9,0,0,0,30,2], +"group__form-parsing.html#gaaa482f07dad3f04b391cccf0a814e13b":[7,6,0,3], "group__form-parsing.html#gga41a74a822771d3dce89751aa3bce28aea2d25de44865bd44e5a3903a2bab9ca83":[7,6,0,1,2], -"group__form-parsing.html#gga41a74a822771d3dce89751aa3bce28aea6ce2a55a4c3695cdb640c893d95bd3a7":[9,0,0,0,30,1], +"group__form-parsing.html#gga41a74a822771d3dce89751aa3bce28aea2d25de44865bd44e5a3903a2bab9ca83":[9,0,0,0,30,2], "group__form-parsing.html#gga41a74a822771d3dce89751aa3bce28aea6ce2a55a4c3695cdb640c893d95bd3a7":[7,6,0,1,1], -"group__form-parsing.html#gga41a74a822771d3dce89751aa3bce28aead3a958e7719ac273c3ba4f684f00c87f":[9,0,0,0,30,0], +"group__form-parsing.html#gga41a74a822771d3dce89751aa3bce28aea6ce2a55a4c3695cdb640c893d95bd3a7":[9,0,0,0,30,1], "group__form-parsing.html#gga41a74a822771d3dce89751aa3bce28aead3a958e7719ac273c3ba4f684f00c87f":[7,6,0,1,0], +"group__form-parsing.html#gga41a74a822771d3dce89751aa3bce28aead3a958e7719ac273c3ba4f684f00c87f":[9,0,0,0,30,0], "group__generic-sessions.html":[7,10,0], "group__generic-sessions.html#ga7c2dc7bfb4ccb91c5d771f9e9ea237e1":[7,10,0,5], "group__generic-sessions.html#ga7c2dc7bfb4ccb91c5d771f9e9ea237e1":[9,0,0,0,33], @@ -138,12 +138,12 @@ var NAVTREEINDEX1 = "group__html-chunked-substitution.html#ggabc3b93f68c8bdd857ad32913628dfa8daf06c31278cb67d7eec4b2b8157b9ad25":[9,0,0,0,18,9], "group__html-chunked-substitution.html#ggabc3b93f68c8bdd857ad32913628dfa8dafac24097912a70f224166528ce44b83b":[9,0,0,0,18,7], "group__http.html":[7,6], -"group__http.html#ga8fbf01e473ac421fc33ad9f8da8b8a25":[9,0,0,0,100], "group__http.html#ga8fbf01e473ac421fc33ad9f8da8b8a25":[7,6,7], -"group__http.html#gac8a4a71240857dc6b2ed70456b6923f4":[9,0,0,0,120], +"group__http.html#ga8fbf01e473ac421fc33ad9f8da8b8a25":[9,0,0,0,100], "group__http.html#gac8a4a71240857dc6b2ed70456b6923f4":[7,6,9], -"group__http.html#gad27aed6c66a41b2b89ffe4da2a309e8a":[9,0,0,0,101], +"group__http.html#gac8a4a71240857dc6b2ed70456b6923f4":[9,0,0,0,120], "group__http.html#gad27aed6c66a41b2b89ffe4da2a309e8a":[7,6,8], +"group__http.html#gad27aed6c66a41b2b89ffe4da2a309e8a":[9,0,0,0,101], "group__httpft.html":[7,6,2], "group__httpft.html#ga29e1123f6d56cd777b3e5bf9ca40f9e5":[9,0,0,0,125], "group__httpft.html#gab393a06d3d2722af4c3f8b06842c80d7":[7,6,2,1], @@ -152,15 +152,15 @@ var NAVTREEINDEX1 = "group__httpft.html#gab4da87a4800413f15e7aba649fb1d77c":[9,0,0,0,84], "group__log.html":[7,7], "group__log.html#ga14542b84d2c76efa7814124bb10f9c5f":[9,0,0,0,28], -"group__log.html#ga244647f9e1bf0097ccdde66d74f41e26":[9,0,0,0,132], "group__log.html#ga244647f9e1bf0097ccdde66d74f41e26":[7,7,0], +"group__log.html#ga244647f9e1bf0097ccdde66d74f41e26":[9,0,0,0,132], "group__log.html#ga42e39775c6b69b7251bdbf5a2cdd5dcd":[9,0,0,0,156], "group__log.html#ga42e39775c6b69b7251bdbf5a2cdd5dcd":[7,7,3], "group__log.html#ga74eb146969f0595e12ea835851b4588e":[9,0,0,0,37], "group__log.html#ga898b1f03872ad019f507d4e35bbefa90":[9,0,0,0,155], "group__log.html#ga898b1f03872ad019f507d4e35bbefa90":[7,7,2], -"group__log.html#gab7c0fc936cc9f1eb58e2bb234c15147c":[7,7,1], "group__log.html#gab7c0fc936cc9f1eb58e2bb234c15147c":[9,0,0,0,154], +"group__log.html#gab7c0fc936cc9f1eb58e2bb234c15147c":[7,7,1], "group__log.html#gaf5f07837692b2f231a79da8a058288aa":[9,0,0,0,36], "group__log.html#gga14542b84d2c76efa7814124bb10f9c5fa083a44e71966a0e768426e477e1bc358":[9,0,0,0,28,8], "group__log.html#gga14542b84d2c76efa7814124bb10f9c5fa2be9c1d50d05756078e9abc72c9e50cc":[9,0,0,0,28,5], @@ -174,29 +174,29 @@ var NAVTREEINDEX1 = "group__log.html#gga14542b84d2c76efa7814124bb10f9c5fae4235ca28326353e283bc7dd1b39bd86":[9,0,0,0,28,9], "group__log.html#gga14542b84d2c76efa7814124bb10f9c5faff4895280366d59ef0c5e9f4578241af":[9,0,0,0,28,0], "group__misc.html":[7,8], -"group__misc.html#ga0af4f7d2dd375aeedcfa7eb0e1101c4b":[9,0,0,0,80], "group__misc.html#ga0af4f7d2dd375aeedcfa7eb0e1101c4b":[7,8,2], +"group__misc.html#ga0af4f7d2dd375aeedcfa7eb0e1101c4b":[9,0,0,0,80], "group__misc.html#ga0e705d498e8c8500649a26ba30a1e106":[9,0,0,0,118], "group__misc.html#ga1ec0d9faac5d3a5824d765c287c043aa":[9,0,0,0,113], "group__misc.html#ga1ec0d9faac5d3a5824d765c287c043aa":[7,8,8], -"group__misc.html#ga33bf2635033710b25f931b57ed663e1e":[9,0,0,0,112], "group__misc.html#ga33bf2635033710b25f931b57ed663e1e":[7,8,7], -"group__misc.html#ga58f906c6be0ca80efd813f694569dd4a":[9,0,0,0,90], +"group__misc.html#ga33bf2635033710b25f931b57ed663e1e":[9,0,0,0,112], "group__misc.html#ga58f906c6be0ca80efd813f694569dd4a":[7,8,6], -"group__misc.html#ga629f48268fd1856b54b11172991b97d9":[9,0,0,0,81], +"group__misc.html#ga58f906c6be0ca80efd813f694569dd4a":[9,0,0,0,90], "group__misc.html#ga629f48268fd1856b54b11172991b97d9":[7,8,3], -"group__misc.html#ga8930fe36a3f3eefe4a6a4fd499d8e899":[9,0,0,0,85], +"group__misc.html#ga629f48268fd1856b54b11172991b97d9":[9,0,0,0,81], "group__misc.html#ga8930fe36a3f3eefe4a6a4fd499d8e899":[7,8,5], +"group__misc.html#ga8930fe36a3f3eefe4a6a4fd499d8e899":[9,0,0,0,85], "group__misc.html#gaa194584fff9698f3b280658f770ccd0f":[9,0,0,0,153], "group__misc.html#gaa194584fff9698f3b280658f770ccd0f":[7,8,10], -"group__misc.html#gab321ed812f46f6dc7ef9e3ca6f00cf1b":[9,0,0,0,130], "group__misc.html#gab321ed812f46f6dc7ef9e3ca6f00cf1b":[7,8,9], -"group__misc.html#gac6abfc0b2bd5b2f09281a4432bb2f5f0":[9,0,0,0,83], +"group__misc.html#gab321ed812f46f6dc7ef9e3ca6f00cf1b":[9,0,0,0,130], "group__misc.html#gac6abfc0b2bd5b2f09281a4432bb2f5f0":[7,8,4], -"group__misc.html#gacae4d7b6a8d22e4c2d82ff8b12c1e234":[9,0,0,0,79], +"group__misc.html#gac6abfc0b2bd5b2f09281a4432bb2f5f0":[9,0,0,0,83], "group__misc.html#gacae4d7b6a8d22e4c2d82ff8b12c1e234":[7,8,1], -"group__misc.html#gace5171b1dbbc03ec89a98f8afdb5c9af":[9,0,0,0,67], +"group__misc.html#gacae4d7b6a8d22e4c2d82ff8b12c1e234":[9,0,0,0,79], "group__misc.html#gace5171b1dbbc03ec89a98f8afdb5c9af":[7,8,0], +"group__misc.html#gace5171b1dbbc03ec89a98f8afdb5c9af":[9,0,0,0,67], "group__net.html":[7,9], "group__net.html#ga092e5f473b3347f03ffeef8a950080f3":[7,9,1], "group__net.html#ga092e5f473b3347f03ffeef8a950080f3":[9,0,0,0,86], @@ -207,21 +207,21 @@ var NAVTREEINDEX1 = "group__net.html#gad0df22db2be9fc65a667a1e83f9a92a4":[7,9,0], "group__net.html#gad0df22db2be9fc65a667a1e83f9a92a4":[9,0,0,0,54], "group__pur.html":[7,12], -"group__pur.html#ga9cc82f06e5ae7e71458626d7a39a5865":[7,12,1], "group__pur.html#ga9cc82f06e5ae7e71458626d7a39a5865":[9,0,0,0,142], +"group__pur.html#ga9cc82f06e5ae7e71458626d7a39a5865":[7,12,1], "group__pur.html#gab15187efcfa256b7c928562c182b92a3":[7,12,0], "group__pur.html#gab15187efcfa256b7c928562c182b92a3":[9,0,0,0,109], "group__sending-data.html":[7,13], "group__sending-data.html#ga98b099cf8c1c7e38ad78501f270e193d":[7,13,0], "group__sending-data.html#ga98b099cf8c1c7e38ad78501f270e193d":[9,0,0,0,32], -"group__sending-data.html#gafd5fdd285a0e25ba7e3e1051deec1001":[7,13,1], "group__sending-data.html#gafd5fdd285a0e25ba7e3e1051deec1001":[9,0,0,0,152], +"group__sending-data.html#gafd5fdd285a0e25ba7e3e1051deec1001":[7,13,1], "group__sending-data.html#gga98b099cf8c1c7e38ad78501f270e193da10047eb05b5e1c298151dc47a5b44826":[7,13,0,2], "group__sending-data.html#gga98b099cf8c1c7e38ad78501f270e193da10047eb05b5e1c298151dc47a5b44826":[9,0,0,0,32,2], "group__sending-data.html#gga98b099cf8c1c7e38ad78501f270e193da115440f272a5d55518adfc8099acfee3":[7,13,0,5], "group__sending-data.html#gga98b099cf8c1c7e38ad78501f270e193da115440f272a5d55518adfc8099acfee3":[9,0,0,0,32,8], -"group__sending-data.html#gga98b099cf8c1c7e38ad78501f270e193da220d8e8652d9b97fb66e476e2a60ffce":[9,0,0,0,32,9], "group__sending-data.html#gga98b099cf8c1c7e38ad78501f270e193da220d8e8652d9b97fb66e476e2a60ffce":[7,13,0,6], +"group__sending-data.html#gga98b099cf8c1c7e38ad78501f270e193da220d8e8652d9b97fb66e476e2a60ffce":[9,0,0,0,32,9], "group__sending-data.html#gga98b099cf8c1c7e38ad78501f270e193da6e556322ff8f205bf311608f7f6e6559":[9,0,0,0,32,4], "group__sending-data.html#gga98b099cf8c1c7e38ad78501f270e193da80e8f169fda236c56bfb795ed62903db":[7,13,0,0], "group__sending-data.html#gga98b099cf8c1c7e38ad78501f270e193da80e8f169fda236c56bfb795ed62903db":[9,0,0,0,32,0], @@ -240,14 +240,14 @@ var NAVTREEINDEX1 = "group__service.html#ga53e3d0801dfda7960a7249dd559e68a2":[9,0,0,0,52], "group__service.html#ga9b3cc4473fd8848e5bbee7f310712939":[7,0,5], "group__service.html#ga9b3cc4473fd8848e5bbee7f310712939":[9,0,0,0,129], -"group__service.html#gad82efa5466d14a9f05aa06416375b28d":[9,0,0,0,127], "group__service.html#gad82efa5466d14a9f05aa06416375b28d":[7,0,3], +"group__service.html#gad82efa5466d14a9f05aa06416375b28d":[9,0,0,0,127], "group__service.html#gaebf426eda371ba23642fc11d8e0ace6b":[7,0,4], "group__service.html#gaebf426eda371ba23642fc11d8e0ace6b":[9,0,0,0,128], -"group__service.html#gaf95bd0c663d6516a0c80047d9b1167a8":[9,0,0,0,126], "group__service.html#gaf95bd0c663d6516a0c80047d9b1167a8":[7,0,2], +"group__service.html#gaf95bd0c663d6516a0c80047d9b1167a8":[9,0,0,0,126], "group__sha.html":[7,11], "group__sha.html#ga66316e6a5a0644a09d5a10e919dfdd8d":[7,11,0], "group__sha.html#ga66316e6a5a0644a09d5a10e919dfdd8d":[9,0,0,0,44], -"group__sha.html#ga7b09ab74646266f0b555103b3bb8dfe5":[7,11,2] +"group__sha.html#ga7b09ab74646266f0b555103b3bb8dfe5":[9,0,0,0,135] }; diff --git a/doc/html/navtreeindex2.js b/doc/html/navtreeindex2.js index d7c5e55b..ee0f0af3 100644 --- a/doc/html/navtreeindex2.js +++ b/doc/html/navtreeindex2.js @@ -1,6 +1,6 @@ var NAVTREEINDEX2 = { -"group__sha.html#ga7b09ab74646266f0b555103b3bb8dfe5":[9,0,0,0,135], +"group__sha.html#ga7b09ab74646266f0b555103b3bb8dfe5":[7,11,2], "group__sha.html#gaf39765e4a3b413efb65e4698b2ec3575":[7,11,1], "group__sha.html#gaf39765e4a3b413efb65e4698b2ec3575":[9,0,0,0,45], "group__smtp.html":[7,14], @@ -10,35 +10,35 @@ var NAVTREEINDEX2 = "group__smtp.html#ga25298a5afc1074e13b2d5711a86432b2":[9,0,0,0,69], "group__smtp.html#ga5e535e346d92a9daf00be33abf79d4eb":[7,14,2], "group__smtp.html#ga5e535e346d92a9daf00be33abf79d4eb":[9,0,0,0,68], -"group__smtp.html#ga77fc9b56a1bb39484844981ec375fc29":[7,14,4], "group__smtp.html#ga77fc9b56a1bb39484844981ec375fc29":[9,0,0,0,70], +"group__smtp.html#ga77fc9b56a1bb39484844981ec375fc29":[7,14,4], "group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0a1dfec948a864205cec875f63cbe0d4ad":[7,14,1,3], "group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0a1dfec948a864205cec875f63cbe0d4ad":[9,0,0,0,34,3], -"group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0a29e5b0ecf75375b5a643faa3d6222b7c":[7,14,1,0], "group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0a29e5b0ecf75375b5a643faa3d6222b7c":[9,0,0,0,34,0], +"group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0a29e5b0ecf75375b5a643faa3d6222b7c":[7,14,1,0], "group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0a2c2ed16ffc572326e3040684084b21d5":[7,14,1,8], "group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0a2c2ed16ffc572326e3040684084b21d5":[9,0,0,0,34,8], "group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0a38fba41f28d754e38079b31418a86a69":[7,14,1,7], "group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0a38fba41f28d754e38079b31418a86a69":[9,0,0,0,34,7], "group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0a85e3c452950c09a79086bff4b9be5c14":[7,14,1,6], "group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0a85e3c452950c09a79086bff4b9be5c14":[9,0,0,0,34,6], -"group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0a929bb4623ff3f585108aba2a1b047fab":[7,14,1,4], "group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0a929bb4623ff3f585108aba2a1b047fab":[9,0,0,0,34,4], -"group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0aae20a0cb95b97a70f6b45d0ed2d5be83":[7,14,1,5], +"group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0a929bb4623ff3f585108aba2a1b047fab":[7,14,1,4], "group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0aae20a0cb95b97a70f6b45d0ed2d5be83":[9,0,0,0,34,5], -"group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0ab61778f70ecac007b334bb14942eb41d":[9,0,0,0,34,2], +"group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0aae20a0cb95b97a70f6b45d0ed2d5be83":[7,14,1,5], "group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0ab61778f70ecac007b334bb14942eb41d":[7,14,1,2], -"group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0ab89442b7a3ca2b94c3cdcf33756eb933":[7,14,1,1], +"group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0ab61778f70ecac007b334bb14942eb41d":[9,0,0,0,34,2], "group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0ab89442b7a3ca2b94c3cdcf33756eb933":[9,0,0,0,34,1], +"group__smtp.html#gga116be79bf44f9dc2a97f46e051fe4dc0ab89442b7a3ca2b94c3cdcf33756eb933":[7,14,1,1], "group__sock-adopt.html":[7,15], -"group__sock-adopt.html#gab2d045df0f81afe00891aaed312d552b":[7,15,1], "group__sock-adopt.html#gab2d045df0f81afe00891aaed312d552b":[9,0,0,0,43], -"group__sock-adopt.html#gabe71b7462afb21c767bdc67334f305af":[7,15,0], +"group__sock-adopt.html#gab2d045df0f81afe00891aaed312d552b":[7,15,1], "group__sock-adopt.html#gabe71b7462afb21c767bdc67334f305af":[9,0,0,0,42], +"group__sock-adopt.html#gabe71b7462afb21c767bdc67334f305af":[7,15,0], "group__timeout.html":[7,3], "group__timeout.html#ga2c0aa4b9c3c55bae7b35cbfac3246c87":[9,0,0,0,35], -"group__timeout.html#gaced9f9237f6172fed9f730a2af51345a":[9,0,0,0,134], "group__timeout.html#gaced9f9237f6172fed9f730a2af51345a":[7,3,0], +"group__timeout.html#gaced9f9237f6172fed9f730a2af51345a":[9,0,0,0,134], "group__timeout.html#gga2c0aa4b9c3c55bae7b35cbfac3246c87a0d6b956db11acb6d263af3ea054a914e":[9,0,0,0,35,12], "group__timeout.html#gga2c0aa4b9c3c55bae7b35cbfac3246c87a0eef059426f37d00b75142d4dc3e25e3":[9,0,0,0,35,3], "group__timeout.html#gga2c0aa4b9c3c55bae7b35cbfac3246c87a1104c39d0177378713a9332ab7a9d7fe":[9,0,0,0,35,4], @@ -56,13 +56,13 @@ var NAVTREEINDEX2 = "group__timeout.html#gga2c0aa4b9c3c55bae7b35cbfac3246c87ad7ebebb506afd30c48e1e5e3a578cd30":[9,0,0,0,35,1], "group__timeout.html#gga2c0aa4b9c3c55bae7b35cbfac3246c87ae8b3de955cec5da5ea52fe040f914501":[9,0,0,0,35,10], "group__urlendec.html":[7,6,5], -"group__urlendec.html#gaa373a9c16acdd96c395af61ab915ece3":[7,6,5,0], "group__urlendec.html#gaa373a9c16acdd96c395af61ab915ece3":[9,0,0,0,144], -"group__urlendec.html#gabc2888476e50e001c875c1a8abf455b7":[7,6,5,1], +"group__urlendec.html#gaa373a9c16acdd96c395af61ab915ece3":[7,6,5,0], "group__urlendec.html#gabc2888476e50e001c875c1a8abf455b7":[9,0,0,0,145], +"group__urlendec.html#gabc2888476e50e001c875c1a8abf455b7":[7,6,5,1], "group__usercb.html":[7,16], -"group__usercb.html#gad4fcb82e68d60ffacca61a3f783a0a2f":[7,16,0], "group__usercb.html#gad4fcb82e68d60ffacca61a3f783a0a2f":[9,0,0,0,7], +"group__usercb.html#gad4fcb82e68d60ffacca61a3f783a0a2f":[7,16,0], "group__usercb.html#gad62860e19975ba4c4af401c3cdb6abf7":[9,0,0,0,19], "group__usercb.html#gad62860e19975ba4c4af401c3cdb6abf7":[7,16,1], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a026502768778b8d79d62dd0fe4375fc6":[9,0,0,0,19,17], @@ -80,8 +80,8 @@ var NAVTREEINDEX2 = "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a1df60f314710236f9b53efbf468da768":[9,0,0,0,19,33], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a1df60f314710236f9b53efbf468da768":[7,16,1,33], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a23b90b5e5146e760bc3123ae1fd2a6e5":[9,0,0,0,19,40], -"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a24d39bf1cfc0bad9d92da9ac1717e439":[9,0,0,0,19,0], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a24d39bf1cfc0bad9d92da9ac1717e439":[7,16,1,0], +"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a24d39bf1cfc0bad9d92da9ac1717e439":[9,0,0,0,19,0], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a2db02fc6e1c17ab62b52109d1aa9d738":[9,0,0,0,19,7], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a2db02fc6e1c17ab62b52109d1aa9d738":[7,16,1,7], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a2fce9a8608220f32abbf1422a5498804":[9,0,0,0,19,14], @@ -103,8 +103,8 @@ var NAVTREEINDEX2 = "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a7e12418eec9bce85735e6460176ab604":[7,16,1,3], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a7ec8e2e9557ee02a4fc9f7dec7e2babc":[9,0,0,0,19,11], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a7ec8e2e9557ee02a4fc9f7dec7e2babc":[7,16,1,11], -"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a838b18d255c1b94a533287ba302a2eba":[9,0,0,0,19,5], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a838b18d255c1b94a533287ba302a2eba":[7,16,1,5], +"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a838b18d255c1b94a533287ba302a2eba":[9,0,0,0,19,5], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a8909732521d379179003d97ab7a05428":[9,0,0,0,19,35], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a8909732521d379179003d97ab7a05428":[7,16,1,35], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a89862929a72bff65257ca1d51a0fce4d":[9,0,0,0,19,52], @@ -114,17 +114,17 @@ var NAVTREEINDEX2 = "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a909cc2a7018864b0b71abacc4058fd8f":[7,16,1,24], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a982579753e70e59a9ea13ce628ac891a":[9,0,0,0,19,56], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7a982579753e70e59a9ea13ce628ac891a":[7,16,1,39], -"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7aa46f705dcf97502e95627ffde614f98b":[7,16,1,37], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7aa46f705dcf97502e95627ffde614f98b":[9,0,0,0,19,37], -"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7aa536e574a642ff3ab9e12bff7ba2c6a2":[7,16,1,2], +"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7aa46f705dcf97502e95627ffde614f98b":[7,16,1,37], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7aa536e574a642ff3ab9e12bff7ba2c6a2":[9,0,0,0,19,2], +"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7aa536e574a642ff3ab9e12bff7ba2c6a2":[7,16,1,2], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7aa627548e1296e654fcfab463ec3c9587":[9,0,0,0,19,15], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7aa627548e1296e654fcfab463ec3c9587":[7,16,1,15], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7aa87d2e82fffa42c3680c7403ef94216e":[9,0,0,0,19,34], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7aa87d2e82fffa42c3680c7403ef94216e":[7,16,1,34], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7aaffd08a5cae791c9f3c38ee242203900":[9,0,0,0,19,46], -"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ab69783a9fbf2ca71ad70706bda77b412":[9,0,0,0,19,32], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ab69783a9fbf2ca71ad70706bda77b412":[7,16,1,32], +"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ab69783a9fbf2ca71ad70706bda77b412":[9,0,0,0,19,32], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ab884f3d5f8a6126a0d34c0172f5e3725":[9,0,0,0,19,53], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7abbbe7a0a67c5866ca9109d46823fc5b1":[9,0,0,0,19,8], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7abbbe7a0a67c5866ca9109d46823fc5b1":[7,16,1,8], @@ -140,8 +140,8 @@ var NAVTREEINDEX2 = "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7aca834dc035b7f7486f9ce40fde54fe9e":[7,16,1,30], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7accd8753672d319a30b4b4c2fb775e84d":[9,0,0,0,19,20], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7accd8753672d319a30b4b4c2fb775e84d":[7,16,1,20], -"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ad5d34583e3556e153eda91620b48cc49":[7,16,1,27], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ad5d34583e3556e153eda91620b48cc49":[9,0,0,0,19,27], +"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ad5d34583e3556e153eda91620b48cc49":[7,16,1,27], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ad724974204d51d688f569c5d387b967d":[9,0,0,0,19,43], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ad87774f1c7784cf632e1e2f5b51036e1":[9,0,0,0,19,48], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ad8c6207b0c4e732f3d507f0fb79370e8":[9,0,0,0,19,1], @@ -150,18 +150,18 @@ var NAVTREEINDEX2 = "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7adfb41c92e2522712207ef7f2462b5e34":[7,16,1,31], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ae4986291b7a810fe290851d73bebeb1c":[9,0,0,0,19,21], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ae4986291b7a810fe290851d73bebeb1c":[7,16,1,21], -"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ae5ad65d779b7eab32ab67ceff91a3bac":[9,0,0,0,19,23], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ae5ad65d779b7eab32ab67ceff91a3bac":[7,16,1,23], +"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ae5ad65d779b7eab32ab67ceff91a3bac":[9,0,0,0,19,23], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ae8d1de0bb56e03aa58cb4d44b18edd2e":[9,0,0,0,19,12], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ae8d1de0bb56e03aa58cb4d44b18edd2e":[7,16,1,12], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ae9734e1d7af2abf291665ce9e4a728d3":[9,0,0,0,19,19], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7ae9734e1d7af2abf291665ce9e4a728d3":[7,16,1,19], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7af6cf80e57aae8ba0a57a5c456b1fe026":[9,0,0,0,19,55], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7afc4b2f72cc9e424a750b506ce0cc4310":[9,0,0,0,19,51], -"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7afd8fd77a1cc9405fcb4f26915d7f2d01":[7,16,1,29], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7afd8fd77a1cc9405fcb4f26915d7f2d01":[9,0,0,0,19,29], -"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7afedadfb3cde37a8ea4c84ed535f26d09":[9,0,0,0,19,16], +"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7afd8fd77a1cc9405fcb4f26915d7f2d01":[7,16,1,29], "group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7afedadfb3cde37a8ea4c84ed535f26d09":[7,16,1,16], +"group__usercb.html#ggad62860e19975ba4c4af401c3cdb6abf7afedadfb3cde37a8ea4c84ed535f26d09":[9,0,0,0,19,16], "group__uv.html":[7,22], "group__uv.html#ga097c89497824d4de225a85a00661fc89":[9,0,0,0,110], "group__uv.html#ga3c75cd6ec3f80fc0a0c8ead4c4e71a15":[9,0,0,0,111], @@ -172,20 +172,20 @@ var NAVTREEINDEX2 = "group__vhost-mounts.html":[7,4,0], "group__vhost-mounts.html#ga31eca18e50cb4357480f2fcad36ff437":[7,4,0,2], "group__vhost-mounts.html#ga31eca18e50cb4357480f2fcad36ff437":[9,0,0,0,29], -"group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437a13ab58b01ac6e05f595977f1e0f0db69":[7,4,0,2,3], "group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437a13ab58b01ac6e05f595977f1e0f0db69":[9,0,0,0,29,3], +"group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437a13ab58b01ac6e05f595977f1e0f0db69":[7,4,0,2,3], "group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437a1e9f0842b0e85db50fe648ed4ba9a4b0":[7,4,0,2,0], "group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437a1e9f0842b0e85db50fe648ed4ba9a4b0":[9,0,0,0,29,0], "group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437a42f2361cfe76cd287fa8fcfc502357e2":[7,4,0,2,2], "group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437a42f2361cfe76cd287fa8fcfc502357e2":[9,0,0,0,29,2], "group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437a8894d16316863077dfe530963ca59f67":[9,0,0,0,29,5], "group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437a8894d16316863077dfe530963ca59f67":[7,4,0,2,5], -"group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437a946a88cf9c852eed2c0317f4115d19da":[7,4,0,2,6], "group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437a946a88cf9c852eed2c0317f4115d19da":[9,0,0,0,29,6], -"group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437aec137a2434851bd856ceebfb697b9970":[7,4,0,2,4], +"group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437a946a88cf9c852eed2c0317f4115d19da":[7,4,0,2,6], "group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437aec137a2434851bd856ceebfb697b9970":[9,0,0,0,29,4], -"group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437afbd10eb4777517ed1f6bfdcf3b9ea1d1":[9,0,0,0,29,1], +"group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437aec137a2434851bd856ceebfb697b9970":[7,4,0,2,4], "group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437afbd10eb4777517ed1f6bfdcf3b9ea1d1":[7,4,0,2,1], +"group__vhost-mounts.html#gga31eca18e50cb4357480f2fcad36ff437afbd10eb4777517ed1f6bfdcf3b9ea1d1":[9,0,0,0,29,1], "group__wsclose.html":[7,17], "group__wsclose.html#gaa1c863415d1783cd8de7938aa6efa262":[9,0,0,0,62], "group__wsclose.html#gaa1c863415d1783cd8de7938aa6efa262":[7,17,1], @@ -204,17 +204,17 @@ var NAVTREEINDEX2 = "group__wsclose.html#ggae399c571df32ba532c0ca67da9284985a4b8a3b7ce6f731e5248e4b0fb64a5044":[7,17,0,5], "group__wsclose.html#ggae399c571df32ba532c0ca67da9284985a68b3d34bebd88547dcfa5cadba0acd6c":[9,0,0,0,22,7], "group__wsclose.html#ggae399c571df32ba532c0ca67da9284985a68b3d34bebd88547dcfa5cadba0acd6c":[7,17,0,6], -"group__wsclose.html#ggae399c571df32ba532c0ca67da9284985a7aef2da0062da606eeb35aaca5cf9050":[7,17,0,7], "group__wsclose.html#ggae399c571df32ba532c0ca67da9284985a7aef2da0062da606eeb35aaca5cf9050":[9,0,0,0,22,8], +"group__wsclose.html#ggae399c571df32ba532c0ca67da9284985a7aef2da0062da606eeb35aaca5cf9050":[7,17,0,7], "group__wsclose.html#ggae399c571df32ba532c0ca67da9284985a9737a68759e739856b150ff9dfa30218":[9,0,0,0,22,2], "group__wsclose.html#ggae399c571df32ba532c0ca67da9284985a9737a68759e739856b150ff9dfa30218":[7,17,0,1], -"group__wsclose.html#ggae399c571df32ba532c0ca67da9284985ac6a161822783ee873be1c66f48d14e0e":[9,0,0,0,22,11], "group__wsclose.html#ggae399c571df32ba532c0ca67da9284985ac6a161822783ee873be1c66f48d14e0e":[7,17,0,10], +"group__wsclose.html#ggae399c571df32ba532c0ca67da9284985ac6a161822783ee873be1c66f48d14e0e":[9,0,0,0,22,11], "group__wsclose.html#ggae399c571df32ba532c0ca67da9284985acc9a317c70363dd88e823e066b2c73b7":[9,0,0,0,22,0], -"group__wsclose.html#ggae399c571df32ba532c0ca67da9284985ad0869604d79e13700ae5d196a431b350":[7,17,0,11], "group__wsclose.html#ggae399c571df32ba532c0ca67da9284985ad0869604d79e13700ae5d196a431b350":[9,0,0,0,22,12], -"group__wsclose.html#ggae399c571df32ba532c0ca67da9284985ad09e68295eabdddcba4e332fbea70ae5":[7,17,0,8], +"group__wsclose.html#ggae399c571df32ba532c0ca67da9284985ad0869604d79e13700ae5d196a431b350":[7,17,0,11], "group__wsclose.html#ggae399c571df32ba532c0ca67da9284985ad09e68295eabdddcba4e332fbea70ae5":[9,0,0,0,22,9], +"group__wsclose.html#ggae399c571df32ba532c0ca67da9284985ad09e68295eabdddcba4e332fbea70ae5":[7,17,0,8], "group__wsclose.html#ggae399c571df32ba532c0ca67da9284985ad2b477a91c8445bf34ecd43977f9b390":[7,17,0,12], "group__wsclose.html#ggae399c571df32ba532c0ca67da9284985ad2b477a91c8445bf34ecd43977f9b390":[9,0,0,0,22,13], "group__wsclose.html#ggae399c571df32ba532c0ca67da9284985af90cb98d983ad3d4c79df9b6f3d4a4d2":[9,0,0,0,22,5], @@ -222,16 +222,16 @@ var NAVTREEINDEX2 = "group__wsstatus.html":[7,18], "group__wsstatus.html#ga08e9ee165fca503fd9427d55cfecac37":[9,0,0,0,105], "group__wsstatus.html#ga08e9ee165fca503fd9427d55cfecac37":[7,18,3], -"group__wsstatus.html#ga26a140623d202dd2bf2004deb6994baa":[9,0,0,0,106], "group__wsstatus.html#ga26a140623d202dd2bf2004deb6994baa":[7,18,4], +"group__wsstatus.html#ga26a140623d202dd2bf2004deb6994baa":[9,0,0,0,106], "group__wsstatus.html#ga2bb3655329b4651cd06f79ee3a764421":[7,18,6], "group__wsstatus.html#ga2bb3655329b4651cd06f79ee3a764421":[9,0,0,0,123], -"group__wsstatus.html#ga3df5045656dfb6b0e63a38de2dca79d2":[9,0,0,0,91], "group__wsstatus.html#ga3df5045656dfb6b0e63a38de2dca79d2":[7,18,1], -"group__wsstatus.html#ga4ad226d5e01024b4046f4a5a37199aa1":[7,18,2], +"group__wsstatus.html#ga3df5045656dfb6b0e63a38de2dca79d2":[9,0,0,0,91], "group__wsstatus.html#ga4ad226d5e01024b4046f4a5a37199aa1":[9,0,0,0,104], -"group__wsstatus.html#gaccd9c59336efad8af0554f79cc5966fd":[7,18,0], +"group__wsstatus.html#ga4ad226d5e01024b4046f4a5a37199aa1":[7,18,2], "group__wsstatus.html#gaccd9c59336efad8af0554f79cc5966fd":[9,0,0,0,78], +"group__wsstatus.html#gaccd9c59336efad8af0554f79cc5966fd":[7,18,0], "group__wsstatus.html#gaeca4afc94b1f026034f99cbba37e2f85":[7,18,5], "group__wsstatus.html#gaeca4afc94b1f026034f99cbba37e2f85":[9,0,0,0,114], "hierarchy.html":[8,2], diff --git a/doc/html/navtreeindex3.js b/doc/html/navtreeindex3.js index 6acf7ad2..5cc461fd 100644 --- a/doc/html/navtreeindex3.js +++ b/doc/html/navtreeindex3.js @@ -16,10 +16,90 @@ var NAVTREEINDEX3 = "libwebsockets_8h.html#aff42d53861afdc1a6edfb999ba688ecb":[9,0,0,0,10], "libwebsockets_8h_source.html":[9,0,0,0], "md_README.build.html":[1], +"md_README.build.html#bu":[1,2], +"md_README.build.html#build1":[1,1], +"md_README.build.html#cm":[1,0], +"md_README.build.html#cmco":[1,7], +"md_README.build.html#cmcocl":[1,7,0], +"md_README.build.html#cmcoug":[1,7,1], +"md_README.build.html#cmcowg":[1,7,2], +"md_README.build.html#cmq":[1,3], +"md_README.build.html#cmw":[1,4], +"md_README.build.html#cmwmgw":[1,5], +"md_README.build.html#cross":[1,13], +"md_README.build.html#cya":[1,10], +"md_README.build.html#extplugins":[1,11], +"md_README.build.html#http2rp":[1,12], +"md_README.build.html#mbed3":[1,6], +"md_README.build.html#mem":[1,14], +"md_README.build.html#wolf":[1,8], +"md_README.build.html#wolf1":[1,9], "md_README.coding.html":[3], +"md_README.coding.html#clientasync":[3,13], +"md_README.coding.html#closing":[3,5], +"md_README.coding.html#conns":[3,1], +"md_README.coding.html#cpp":[3,9], +"md_README.coding.html#dae":[3,0], +"md_README.coding.html#debuglog":[3,7], +"md_README.coding.html#ecdh":[3,15], +"md_README.coding.html#evtloop":[3,2], +"md_README.coding.html#extopts":[3,18], +"md_README.coding.html#extpoll":[3,8], +"md_README.coding.html#fileapi":[3,14], +"md_README.coding.html#frags":[3,6], +"md_README.coding.html#headerinfo":[3,10], +"md_README.coding.html#httpsclient":[3,19], +"md_README.coding.html#ka":[3,11], +"md_README.coding.html#libevuv":[3,17], +"md_README.coding.html#mountcallback":[3,23], +"md_README.coding.html#mounts":[3,22], +"md_README.coding.html#otherwr":[3,4], +"md_README.coding.html#smp":[3,16], +"md_README.coding.html#sni":[3,21], +"md_README.coding.html#sslopt":[3,12], +"md_README.coding.html#vhosts":[3,20], +"md_README.coding.html#writeable":[3,3], "md_README.generic-sessions.html":[4], +"md_README.generic-sessions.html#gsap":[4,8], +"md_README.generic-sessions.html#gsconf":[4,4], +"md_README.generic-sessions.html#gseb":[4,0], +"md_README.generic-sessions.html#gsi":[4,1], +"md_README.generic-sessions.html#gsin":[4,2], +"md_README.generic-sessions.html#gsof":[4,3], +"md_README.generic-sessions.html#gsprep":[4,6], +"md_README.generic-sessions.html#gspwc":[4,5], +"md_README.generic-sessions.html#gsrmail":[4,7], "md_README.lwsws.html":[2], +"md_README.lwsws.html#lwsws":[2,0], +"md_README.lwsws.html#lwswsb":[2,1], +"md_README.lwsws.html#lwswsc":[2,2], +"md_README.lwsws.html#lwswslr":[2,13], +"md_README.lwsws.html#lwswsm":[2,7], +"md_README.lwsws.html#lwswsomo":[2,8], +"md_README.lwsws.html#lwswsovo":[2,6], +"md_README.lwsws.html#lwswspl":[2,9], +"md_README.lwsws.html#lwswsplaplp":[2,10], +"md_README.lwsws.html#lwswspr":[2,5], +"md_README.lwsws.html#lwswsssp":[2,11], +"md_README.lwsws.html#lwswssysd":[2,12], +"md_README.lwsws.html#lwswsv":[2,3], +"md_README.lwsws.html#lwswsvn":[2,4], "md_README.test-apps.html":[5], +"md_README.test-apps.html#autobahn":[5,13], +"md_README.test-apps.html#autobahnnotes":[5,14], +"md_README.test-apps.html#choosingts":[5,4], +"md_README.test-apps.html#echo":[5,5], +"md_README.test-apps.html#latency":[5,12], +"md_README.test-apps.html#sssl":[5,2], +"md_README.test-apps.html#ta":[5,8], +"md_README.test-apps.html#talog":[5,10], +"md_README.test-apps.html#taping":[5,7], +"md_README.test-apps.html#taproxy":[5,9], +"md_README.test-apps.html#tassl":[5,6], +"md_README.test-apps.html#tsb":[5,0], +"md_README.test-apps.html#tsd":[5,1], +"md_README.test-apps.html#ws13":[5,11], +"md_README.test-apps.html#wscl":[5,3], "modules.html":[7], "pages.html":[], "structlws__cgi__args.html":[8,0,0], @@ -169,55 +249,5 @@ var NAVTREEINDEX3 = "structlws__pollfd.html#ac393db6fc7fb6ed8fe7ca20936908ee9":[8,0,16,0], "structlws__pollfd.html#ae7cecfe7511c59d4a3a44f876d030932":[8,0,16,2], "structlws__process__html__args.html":[7,6,1,0], -"structlws__process__html__args.html#a11859d8bedd379fbf64543b25c65fe14":[7,6,1,0,3], -"structlws__process__html__args.html#a362547891ee0d693f3900a1f807ea475":[7,6,1,0,0], -"structlws__process__html__args.html#a754513f2311241cabb0cd1c90d7307ef":[7,6,1,0,1], -"structlws__process__html__args.html#a8be7fd396a1942ea2449a2fda990ff99":[7,6,1,0,2], -"structlws__process__html__state.html":[7,6,1,1], -"structlws__process__html__state.html#a3b113e00c03a2fded51b1c85ff5bf077":[7,6,1,1,6], -"structlws__process__html__state.html#a53234f2948812c7208a256f9f5b23c20":[7,6,1,1,2], -"structlws__process__html__state.html#a693d2fb45378afee5da29b539c1ea644":[7,6,1,1,3], -"structlws__process__html__state.html#a71982bc1cbd8cf876ca0f545144404eb":[7,6,1,1,5], -"structlws__process__html__state.html#adcafd17704775b4bbeea9561fb340968":[7,6,1,1,0], -"structlws__process__html__state.html#af0732884ef891e24fe5fa237ebaa21a3":[7,6,1,1,4], -"structlws__process__html__state.html#af21119890fdfebe28fb5c4dabfc1bdf5":[7,6,1,1,1], -"structlws__protocol__vhost__options.html":[7,4,2], -"structlws__protocol__vhost__options.html":[7,4,0,0], -"structlws__protocol__vhost__options.html#a0640a92513c70ee6b9b295a9ad1658e7":[7,4,0,0,3], -"structlws__protocol__vhost__options.html#a0640a92513c70ee6b9b295a9ad1658e7":[7,4,2,3], -"structlws__protocol__vhost__options.html#abc714ddb4171756fc8196e9823a1e21c":[7,4,0,0,1], -"structlws__protocol__vhost__options.html#abc714ddb4171756fc8196e9823a1e21c":[7,4,2,1], -"structlws__protocol__vhost__options.html#acf9db77f8eb64cd4e314be9b43d8a8b9":[7,4,2,0], -"structlws__protocol__vhost__options.html#acf9db77f8eb64cd4e314be9b43d8a8b9":[7,4,0,0,0], -"structlws__protocol__vhost__options.html#afd99fbc90be51ea2465b550c2ec47822":[7,4,0,0,2], -"structlws__protocol__vhost__options.html#afd99fbc90be51ea2465b550c2ec47822":[7,4,2,2], -"structlws__protocols.html":[7,10,1], -"structlws__protocols.html#a0d1d4996d81b2f5e125bcec981e461c5":[7,10,1,4], -"structlws__protocols.html#a0e63edb457a613c3fa4271e0a8f19624":[7,10,1,2], -"structlws__protocols.html#a3cbd903ad076736ae934a54cae36580e":[7,10,1,5], -"structlws__protocols.html#a6b632018590c2b1bbe43fbab6d5e6fac":[7,10,1,1], -"structlws__protocols.html#a9bbd85f591ffb4259711cb5acbb05bea":[7,10,1,3], -"structlws__protocols.html#acabf94c1a9bfe7be0387fbb0e0c56b2d":[7,10,1,0], -"structlws__session__info.html":[7,10,0,2], -"structlws__session__info.html#a3d57a70b6e7181d95a8bec429b1a7697":[7,10,0,2,4], -"structlws__session__info.html#a4353b5dd19400b2b15edfd7cee1e4cd5":[7,10,0,2,3], -"structlws__session__info.html#a53eed02325e8717a53297391e3e98fac":[7,10,0,2,1], -"structlws__session__info.html#a94b813cfc6b0da4b182659de30038ad3":[7,10,0,2,0], -"structlws__session__info.html#afb924864b70f40372920688a5c1c895e":[7,10,0,2,2], -"structlws__token__limits.html":[7,6,4,1], -"structlws__token__limits.html#a6ec712306cbf8585bce7a56758a3ceff":[7,6,4,1,0], -"structlws__tokens.html":[7,6,6], -"structlws__tokens.html":[7,6,4,0], -"structlws__tokens.html#a855b7375d1d58516c0ecd4b60e9a7766":[7,6,4,0,1], -"structlws__tokens.html#a855b7375d1d58516c0ecd4b60e9a7766":[7,6,6,1], -"structlws__tokens.html#a9f3635412bc71a5cb78e9862b55f10cd":[7,6,4,0,0], -"structlws__tokens.html#a9f3635412bc71a5cb78e9862b55f10cd":[7,6,6,0], -"structlwsgw__hash.html":[7,10,0,1], -"structlwsgw__hash.html#a29435f5cf78747d4257695b0f141d164":[7,10,0,1,0], -"structlwsgw__hash__bin.html":[7,10,0,0], -"structlwsgw__hash__bin.html#ac92f50d9471058525d110597a4e0de6b":[7,10,0,0,0], -"structpollfd.html":[8,0,26], -"structpollfd.html#aafb457d11cac415faf0e1e2b825118c2":[8,0,26,2], -"structpollfd.html#ac9b2f2c5b1f9a7487eb57e67cd4960ef":[8,0,26,0], -"structpollfd.html#af084f089bdece61d177f85782d6673d0":[8,0,26,1] +"structlws__process__html__args.html#a11859d8bedd379fbf64543b25c65fe14":[7,6,1,0,3] }; diff --git a/doc/html/navtreeindex4.js b/doc/html/navtreeindex4.js new file mode 100644 index 00000000..e9af076f --- /dev/null +++ b/doc/html/navtreeindex4.js @@ -0,0 +1,53 @@ +var NAVTREEINDEX4 = +{ +"structlws__process__html__args.html#a362547891ee0d693f3900a1f807ea475":[7,6,1,0,0], +"structlws__process__html__args.html#a754513f2311241cabb0cd1c90d7307ef":[7,6,1,0,1], +"structlws__process__html__args.html#a8be7fd396a1942ea2449a2fda990ff99":[7,6,1,0,2], +"structlws__process__html__state.html":[7,6,1,1], +"structlws__process__html__state.html#a3b113e00c03a2fded51b1c85ff5bf077":[7,6,1,1,6], +"structlws__process__html__state.html#a53234f2948812c7208a256f9f5b23c20":[7,6,1,1,2], +"structlws__process__html__state.html#a693d2fb45378afee5da29b539c1ea644":[7,6,1,1,3], +"structlws__process__html__state.html#a71982bc1cbd8cf876ca0f545144404eb":[7,6,1,1,5], +"structlws__process__html__state.html#adcafd17704775b4bbeea9561fb340968":[7,6,1,1,0], +"structlws__process__html__state.html#af0732884ef891e24fe5fa237ebaa21a3":[7,6,1,1,4], +"structlws__process__html__state.html#af21119890fdfebe28fb5c4dabfc1bdf5":[7,6,1,1,1], +"structlws__protocol__vhost__options.html":[7,4,0,0], +"structlws__protocol__vhost__options.html":[7,4,2], +"structlws__protocol__vhost__options.html#a0640a92513c70ee6b9b295a9ad1658e7":[7,4,2,3], +"structlws__protocol__vhost__options.html#a0640a92513c70ee6b9b295a9ad1658e7":[7,4,0,0,3], +"structlws__protocol__vhost__options.html#abc714ddb4171756fc8196e9823a1e21c":[7,4,0,0,1], +"structlws__protocol__vhost__options.html#abc714ddb4171756fc8196e9823a1e21c":[7,4,2,1], +"structlws__protocol__vhost__options.html#acf9db77f8eb64cd4e314be9b43d8a8b9":[7,4,0,0,0], +"structlws__protocol__vhost__options.html#acf9db77f8eb64cd4e314be9b43d8a8b9":[7,4,2,0], +"structlws__protocol__vhost__options.html#afd99fbc90be51ea2465b550c2ec47822":[7,4,0,0,2], +"structlws__protocol__vhost__options.html#afd99fbc90be51ea2465b550c2ec47822":[7,4,2,2], +"structlws__protocols.html":[7,10,1], +"structlws__protocols.html#a0d1d4996d81b2f5e125bcec981e461c5":[7,10,1,4], +"structlws__protocols.html#a0e63edb457a613c3fa4271e0a8f19624":[7,10,1,2], +"structlws__protocols.html#a3cbd903ad076736ae934a54cae36580e":[7,10,1,5], +"structlws__protocols.html#a6b632018590c2b1bbe43fbab6d5e6fac":[7,10,1,1], +"structlws__protocols.html#a9bbd85f591ffb4259711cb5acbb05bea":[7,10,1,3], +"structlws__protocols.html#acabf94c1a9bfe7be0387fbb0e0c56b2d":[7,10,1,0], +"structlws__session__info.html":[7,10,0,2], +"structlws__session__info.html#a3d57a70b6e7181d95a8bec429b1a7697":[7,10,0,2,4], +"structlws__session__info.html#a4353b5dd19400b2b15edfd7cee1e4cd5":[7,10,0,2,3], +"structlws__session__info.html#a53eed02325e8717a53297391e3e98fac":[7,10,0,2,1], +"structlws__session__info.html#a94b813cfc6b0da4b182659de30038ad3":[7,10,0,2,0], +"structlws__session__info.html#afb924864b70f40372920688a5c1c895e":[7,10,0,2,2], +"structlws__token__limits.html":[7,6,4,1], +"structlws__token__limits.html#a6ec712306cbf8585bce7a56758a3ceff":[7,6,4,1,0], +"structlws__tokens.html":[7,6,6], +"structlws__tokens.html":[7,6,4,0], +"structlws__tokens.html#a855b7375d1d58516c0ecd4b60e9a7766":[7,6,6,1], +"structlws__tokens.html#a855b7375d1d58516c0ecd4b60e9a7766":[7,6,4,0,1], +"structlws__tokens.html#a9f3635412bc71a5cb78e9862b55f10cd":[7,6,6,0], +"structlws__tokens.html#a9f3635412bc71a5cb78e9862b55f10cd":[7,6,4,0,0], +"structlwsgw__hash.html":[7,10,0,1], +"structlwsgw__hash.html#a29435f5cf78747d4257695b0f141d164":[7,10,0,1,0], +"structlwsgw__hash__bin.html":[7,10,0,0], +"structlwsgw__hash__bin.html#ac92f50d9471058525d110597a4e0de6b":[7,10,0,0,0], +"structpollfd.html":[8,0,26], +"structpollfd.html#aafb457d11cac415faf0e1e2b825118c2":[8,0,26,2], +"structpollfd.html#ac9b2f2c5b1f9a7487eb57e67cd4960ef":[8,0,26,0], +"structpollfd.html#af084f089bdece61d177f85782d6673d0":[8,0,26,1] +}; diff --git a/doc/latex/md_README.build.tex b/doc/latex/md_README.build.tex index 560c5e31..0293700a 100644 --- a/doc/latex/md_README.build.tex +++ b/doc/latex/md_README.build.tex @@ -1,5 +1,4 @@ -\subsection*{Introduction to C\+Make } - +\hypertarget{md_README.build_cm}{}\section{Introduction to C\+Make}\label{md_README.build_cm} C\+Make is a multi-\/platform build tool that can generate build files for many different target platforms. See more info at \href{http://www.cmake.org}{\tt http\+://www.\+cmake.\+org} C\+Make also allows/recommends you to do \char`\"{}out of source\char`\"{}-\/builds, that is, the build files are separated from your sources, so there is no need to create elaborate clean scripts to get a clean source tree, instead you simply remove your build directory. @@ -13,16 +12,10 @@ Libwebsockets has been tested to build successfully on the following platforms w \item Linux (x86 and A\+RM) \item O\+SX \item Net\+B\+SD -\end{DoxyItemize} - -\subsection*{Building the library and test apps } - +\end{DoxyItemize}\hypertarget{md_README.build_build1}{}\section{Building the library and test apps}\label{md_README.build_build1} The project settings used by C\+Make to generate the platform specific build files is called \href{CMakeLists.txt}{\tt C\+Make\+Lists.\+txt}. C\+Make then uses one of its \char`\"{}\+Generators\char`\"{} to output a Visual Studio project or Make file for instance. To see a list of the available generators for your platform, simply run the \char`\"{}cmake\char`\"{} command. -Note that by default Open\+S\+SL will be linked, if you don\textquotesingle{}t want S\+SL support see below on how to toggle compile options. - -\subsection*{Building on Unix\+: } - +Note that by default Open\+S\+SL will be linked, if you don\textquotesingle{}t want S\+SL support see below on how to toggle compile options.\hypertarget{md_README.build_bu}{}\section{Building on Unix\+:}\label{md_README.build_bu} \begin{DoxyEnumerate} \item Install C\+Make 2.\+8 or greater\+: \href{http://cmake.org/cmake/resources/software.html}{\tt http\+://cmake.\+org/cmake/resources/software.\+html} (Most Unix distributions comes with a packaged version also) @@ -79,14 +72,8 @@ To get it to build on latest openssl (2016-\/04-\/10) it needed this approach \begin{DoxyCode} 1 $ cmake .. -DCMAKE\_BUILD\_TYPE=DEBUG \end{DoxyCode} - - -\subsection*{Quirk of cmake } - -When changing cmake options, for some reason the only way to get it to see the changes sometimes is delete the contents of your build directory and do the cmake from scratch. - -\subsection*{Building on Windows (Visual Studio) } - +\hypertarget{md_README.build_cmq}{}\section{Quirk of cmake}\label{md_README.build_cmq} +When changing cmake options, for some reason the only way to get it to see the changes sometimes is delete the contents of your build directory and do the cmake from scratch.\hypertarget{md_README.build_cmw}{}\section{Building on Windows (\+Visual Studio)}\label{md_README.build_cmw} \begin{DoxyEnumerate} \item Install C\+Make 2.\+6 or greater\+: \href{http://cmake.org/cmake/resources/software.html}{\tt http\+://cmake.\+org/cmake/resources/software.\+html} @@ -121,10 +108,7 @@ When changing cmake options, for some reason the only way to get it to see the c \item userenv.\+lib \end{DoxyItemize} \item If you\textquotesingle{}re using libuv, you must make sure to compile libuv with the same multithread-\/dll / Mtd attributes as libwebsockets itself -\end{DoxyEnumerate} - -\subsection*{Building on Windows (Min\+GW) } - +\end{DoxyEnumerate}\hypertarget{md_README.build_cmwmgw}{}\section{Building on Windows (\+Min\+G\+W)}\label{md_README.build_cmwmgw} \begin{DoxyEnumerate} \item Install Min\+GW\+: \href{http://sourceforge.net/projects/mingw/files}{\tt http\+://sourceforge.\+net/projects/mingw/files} @@ -179,24 +163,7 @@ a) Add the following lines to C\+:.h\+: 1 $ make 2 $ make install \end{DoxyCode} - - -\subsection*{Setting compile options } - -To set compile time flags you can either use one of the C\+Make gui applications or do it via command line. - -\subsection*{Command line } - -To list avaialable options (ommit the H if you don\textquotesingle{}t want the help text)\+: \begin{DoxyVerb} cmake -LH .. -\end{DoxyVerb} - - -Then to set an option and build (for example turn off S\+SL support)\+: \begin{DoxyVerb} cmake -DLWS_WITH_SSL=0 .. -\end{DoxyVerb} - or cmake -\/\+D\+L\+W\+S\+\_\+\+W\+I\+T\+H\+\_\+\+S\+SL\+:B\+O\+OL=O\+FF .. - -\subsection*{Building on mbed3 } - +\hypertarget{md_README.build_mbed3}{}\section{Building on mbed3}\label{md_README.build_mbed3} M\+B\+E\+D3 is a non-\/posix embedded OS targeted on Cortex M class chips. \href{https://www.mbed.com/}{\tt https\+://www.\+mbed.\+com/} @@ -229,28 +196,24 @@ and cd into it 7) yotta install -8) yotta build - -\subsection*{Unix G\+UI } - -If you have a curses-\/enabled build you simply type\+: (not all packages include this, my debian install does not for example). \begin{DoxyVerb} ccmake +8) yotta build\hypertarget{md_README.build_cmco}{}\section{Setting compile options}\label{md_README.build_cmco} +To set compile time flags you can either use one of the C\+Make gui applications or do it via command line.\hypertarget{md_README.build_cmcocl}{}\subsection{Command line}\label{md_README.build_cmcocl} +To list avaialable options (omit the H if you don\textquotesingle{}t want the help text)\+: \begin{DoxyVerb} cmake -LH .. \end{DoxyVerb} -\subsection*{Windows G\+UI } - -On windows C\+Make comes with a gui application\+: Start -\/$>$ Programs -\/$>$ C\+Make -\/$>$ C\+Make (cmake-\/gui) - -\subsection*{wolf\+S\+S\+L/\+Cya\+S\+SL replacement for Open\+S\+SL } - +Then to set an option and build (for example turn off S\+SL support)\+: \begin{DoxyVerb} cmake -DLWS_WITH_SSL=0 .. +\end{DoxyVerb} + or cmake -\/\+D\+L\+W\+S\+\_\+\+W\+I\+T\+H\+\_\+\+S\+SL\+:B\+O\+OL=O\+FF ..\hypertarget{md_README.build_cmcoug}{}\subsection{Unix G\+UI}\label{md_README.build_cmcoug} +If you have a curses-\/enabled build you simply type\+: (not all packages include this, my debian install does not for example). \begin{DoxyVerb} ccmake +\end{DoxyVerb} +\hypertarget{md_README.build_cmcowg}{}\subsection{Windows G\+UI}\label{md_README.build_cmcowg} +On windows C\+Make comes with a gui application\+: Start -\/$>$ Programs -\/$>$ C\+Make -\/$>$ C\+Make (cmake-\/gui)\hypertarget{md_README.build_wolf}{}\section{wolf\+S\+S\+L/\+Cya\+S\+S\+L replacement for Open\+S\+SL}\label{md_README.build_wolf} wolf\+S\+S\+L/\+Cya\+S\+SL is a lightweight S\+SL library targeted at embedded systems\+: \href{https://www.wolfssl.com/wolfSSL/Products-wolfssl.html}{\tt https\+://www.\+wolfssl.\+com/wolf\+S\+S\+L/\+Products-\/wolfssl.\+html} It contains a Open\+S\+SL compatibility layer which makes it possible to pretty much link to it instead of Open\+S\+SL, giving a much smaller footprint. -{\bfseries N\+O\+TE}\+: wolfssl needs to be compiled using the {\ttfamily -\/-\/enable-\/opensslextra} flag for this to work. - -\subsection*{Compiling libwebsockets with wolf\+S\+SL } - +{\bfseries N\+O\+TE}\+: wolfssl needs to be compiled using the {\ttfamily -\/-\/enable-\/opensslextra} flag for this to work.\hypertarget{md_README.build_wolf1}{}\section{Compiling libwebsockets with wolf\+S\+SL}\label{md_README.build_wolf1} \begin{DoxyCode} 1 cmake .. -DLWS\_USE\_WOLFSSL=1 \(\backslash\) @@ -259,10 +222,7 @@ It contains a Open\+S\+SL compatibility layer which makes it possible to pretty \end{DoxyCode} -{\bfseries N\+O\+TE}\+: On windows use the .lib file extension for {\ttfamily L\+W\+S\+\_\+\+W\+O\+L\+F\+S\+S\+L\+\_\+\+L\+I\+B\+R\+A\+R\+I\+ES} instead. - -\subsection*{Compiling libwebsockets with Cya\+S\+SL } - +{\bfseries N\+O\+TE}\+: On windows use the .lib file extension for {\ttfamily L\+W\+S\+\_\+\+W\+O\+L\+F\+S\+S\+L\+\_\+\+L\+I\+B\+R\+A\+R\+I\+ES} instead.\hypertarget{md_README.build_cya}{}\section{Compiling libwebsockets with Cya\+S\+SL}\label{md_README.build_cya} \begin{DoxyCode} 1 cmake .. -DLWS\_USE\_CYASSL=1 \(\backslash\) @@ -271,21 +231,7 @@ It contains a Open\+S\+SL compatibility layer which makes it possible to pretty \end{DoxyCode} -{\bfseries N\+O\+TE}\+: On windows use the .lib file extension for {\ttfamily L\+W\+S\+\_\+\+C\+Y\+A\+S\+S\+L\+\_\+\+L\+I\+B\+R\+A\+R\+I\+ES} instead. - -\subsection*{Compiling libwebsockets with Polar\+S\+SL } - -Caution... at some point Polar\+S\+SL became Mbed\+T\+LS. But it did not happen all at once. The name changed first then at mbed\+T\+LS 2.\+0 the apis changed. So eg in Fedora 22, there is an \char`\"{}mbedtls\char`\"{} package which is actually using polarssl for the include dir and polarssl apis... this should be treated as polarssl then. - -Example config for this case is -\begin{DoxyCode} -1 cmake .. -DLWS\_USE\_POLARSSL=1 -DLWS\_POLARSSL\_LIBRARIES=/usr/lib64/libmbedtls.so \(\backslash\) -2 -DLWS\_POLARSSL\_INCLUDE\_DIRS=/usr/include/polarssl/ -\end{DoxyCode} - - -\subsection*{Building plugins outside of lws itself } - +{\bfseries N\+O\+TE}\+: On windows use the .lib file extension for {\ttfamily L\+W\+S\+\_\+\+C\+Y\+A\+S\+S\+L\+\_\+\+L\+I\+B\+R\+A\+R\+I\+ES} instead.\hypertarget{md_README.build_extplugins}{}\section{Building plugins outside of lws itself}\label{md_README.build_extplugins} The directory ./plugin-\/standalone/ shows how easy it is to create plugins outside of lws itself. First build lws itself with -\/\+D\+L\+W\+S\+\_\+\+W\+I\+T\+H\+\_\+\+P\+L\+U\+G\+I\+NS, then use the same flow to build the standalone plugin \begin{DoxyCode} 1 cd ./plugin-standalone @@ -307,10 +253,7 @@ Otherwise if you run lwsws or libwebsockets-\/test-\/server-\/v2.\+0, it will no 5 lwsts[21257]: libprotocol\_lws\_server\_status.so 6 lwsts[21257]: libprotocol\_lws\_status.so \end{DoxyCode} - If you have multiple vhosts, you must enable plugins at the vhost additionally, discovered plugins are not enabled automatically for security reasons. You do this using info-\/$>$pvo or for lwsws, in the J\+S\+ON config. - -\subsection*{Reproducing H\+T\+T\+P2.\+0 tests } - + If you have multiple vhosts, you must enable plugins at the vhost additionally, discovered plugins are not enabled automatically for security reasons. You do this using info-\/$>$pvo or for lwsws, in the J\+S\+ON config.\hypertarget{md_README.build_http2rp}{}\section{Reproducing H\+T\+T\+P2.\+0 tests}\label{md_README.build_http2rp} You must have built and be running lws against a version of openssl that has A\+L\+PN / N\+PN. Most distros still have older versions. You\textquotesingle{}ll know it\textquotesingle{}s right by seeing \begin{DoxyCode} 1 lwsts[4752]: Compiled with OpenSSL support @@ -327,10 +270,7 @@ For non-\/\+S\+SL H\+T\+T\+P2.\+0 upgrade \begin{DoxyCode} 1 $ nghttp -nvas https://localhost:7681/test.html \end{DoxyCode} - - -\subsection*{Cross compiling } - +\hypertarget{md_README.build_cross}{}\section{Cross compiling}\label{md_README.build_cross} To enable cross-\/compiling {\bfseries libwebsockets} using C\+Make you need to create a \char`\"{}\+Toolchain file\char`\"{} that you supply to C\+Make when generating your build files. C\+Make will then use the cross compilers and build paths specified in this file to look for dependencies and such. {\bfseries Libwebsockets} includes an example toolchain file \href{cross-arm-linux-gnueabihf.cmake}{\tt cross-\/arm-\/linux-\/gnueabihf.\+cmake} you can use as a starting point. @@ -345,10 +285,7 @@ The commandline to configure for cross with this would look like {\bfseries N\+O\+TE}\+: start from an E\+M\+P\+TY build directory if you had a non-\/cross build in there before the settings will be cached and your changes ignored. -Additional information on cross compilation with C\+Make\+: \href{http://www.vtk.org/Wiki/CMake_Cross_Compiling}{\tt http\+://www.\+vtk.\+org/\+Wiki/\+C\+Make\+\_\+\+Cross\+\_\+\+Compiling} - -\subsection*{Memory efficiency } - +Additional information on cross compilation with C\+Make\+: \href{http://www.vtk.org/Wiki/CMake_Cross_Compiling}{\tt http\+://www.\+vtk.\+org/\+Wiki/\+C\+Make\+\_\+\+Cross\+\_\+\+Compiling}\hypertarget{md_README.build_mem}{}\section{Memory efficiency}\label{md_README.build_mem} Embedded server-\/only configuration without extensions (ie, no compression on websocket connections), but with full v13 websocket features and http server, built on A\+RM Cortex-\/\+A9\+: Update at 8dac94d (2013-\/02-\/18) diff --git a/doc/latex/md_README.coding.tex b/doc/latex/md_README.coding.tex index db1a4538..015c0b21 100644 --- a/doc/latex/md_README.coding.tex +++ b/doc/latex/md_README.coding.tex @@ -1,16 +1,11 @@ -\subsection*{Daemonization } - +\hypertarget{md_README.coding_dae}{}\section{Daemonization}\label{md_README.coding_dae} There\textquotesingle{}s a helper api {\ttfamily lws\+\_\+daemonize} built by default that does everything you need to daemonize well, including creating a lock file. If you\textquotesingle{}re making what\textquotesingle{}s basically a daemon, just call this early in your init to fork to a headless background process and exit the starting process. -Notice stdout, stderr, stdin are all redirected to /dev/null to enforce your daemon is headless, so you\textquotesingle{}ll need to sort out alternative logging, by, eg, syslog. - -\subsection*{Maximum number of connections } - +Notice stdout, stderr, stdin are all redirected to /dev/null to enforce your daemon is headless, so you\textquotesingle{}ll need to sort out alternative logging, by, eg, syslog.\hypertarget{md_README.coding_conns}{}\section{Maximum number of connections}\label{md_README.coding_conns} The maximum number of connections the library can deal with is decided when it starts by querying the OS to find out how many file descriptors it is allowed to open (1024 on Fedora for example). It then allocates arrays that allow up to that many connections, minus whatever other file descriptors are in use by the user code. -If you want to restrict that allocation, or increase it, you can use ulimit or similar to change the avaiable number of file descriptors, and when restarted {\bfseries libwebsockets} will adapt accordingly. - -\subsection*{Libwebsockets is singlethreaded } +If you want to restrict that allocation, or increase it, you can use ulimit or similar to change the avaiable number of file descriptors, and when restarted {\bfseries libwebsockets} will adapt accordingly.\hypertarget{md_README.coding_evtloop}{}\section{Libwebsockets is singlethreaded}\label{md_README.coding_evtloop} +Libwebsockets works in a serialized event loop, in a single thread. Directly performing websocket actions from other threads is not allowed. Aside from the internal data being inconsistent in {\ttfamily forked()} processes, the scope of a {\ttfamily wsi} ({\ttfamily struct websocket}) can end at any time during service with the socket closing and the {\ttfamily wsi} freed. @@ -32,10 +27,7 @@ If you need to service other socket or file descriptors as well as the websocket If you insist on trying to use it from multiple threads, take special care if you might simultaneously create more than one context from different threads. -S\+S\+L\+\_\+library\+\_\+init() is called from the context create api and it also is not reentrant. So at least create the contexts sequentially. - -\subsection*{Only send data when socket writeable } - +S\+S\+L\+\_\+library\+\_\+init() is called from the context create api and it also is not reentrant. So at least create the contexts sequentially.\hypertarget{md_README.coding_writeable}{}\section{Only send data when socket writeable}\label{md_README.coding_writeable} You should only send data on a websocket connection from the user callback {\ttfamily L\+W\+S\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+S\+E\+R\+V\+E\+R\+\_\+\+W\+R\+I\+T\+E\+A\+B\+LE} (or {\ttfamily L\+W\+S\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+C\+L\+I\+E\+N\+T\+\_\+\+W\+R\+I\+T\+E\+A\+B\+LE} for clients). If you want to send something, do not just send it but request a callback when the socket is writeable using @@ -48,28 +40,19 @@ If you want to send something, do not just send it but request a callback when t Usually you will get called back immediately next time around the service loop, but if your peer is slow or temporarily inactive the callback will be delayed accordingly. Generating what to write and sending it should be done in the ...W\+R\+I\+T\+E\+A\+B\+LE callback. -See the test server code for an example of how to do this. - -\subsection*{Do not rely on only your own W\+R\+I\+T\+E\+A\+B\+LE requests appearing } - +See the test server code for an example of how to do this.\hypertarget{md_README.coding_otherwr}{}\section{Do not rely on only your own W\+R\+I\+T\+E\+A\+B\+L\+E requests appearing}\label{md_README.coding_otherwr} Libwebsockets may generate additional {\ttfamily L\+W\+S\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+C\+L\+I\+E\+N\+T\+\_\+\+W\+R\+I\+T\+E\+A\+B\+LE} events if it met network conditions where it had to buffer your send data internally. So your code for {\ttfamily L\+W\+S\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+C\+L\+I\+E\+N\+T\+\_\+\+W\+R\+I\+T\+E\+A\+B\+LE} needs to own the decision about what to send, it can\textquotesingle{}t assume that just because the writeable callback came it really is time to send something. -It\textquotesingle{}s quite possible you get an \textquotesingle{}extra\textquotesingle{} writeable callback at any time and just need to {\ttfamily return 0} and wait for the expected callback later. - -\subsection*{Closing connections from the user side } - +It\textquotesingle{}s quite possible you get an \textquotesingle{}extra\textquotesingle{} writeable callback at any time and just need to {\ttfamily return 0} and wait for the expected callback later.\hypertarget{md_README.coding_closing}{}\section{Closing connections from the user side}\label{md_README.coding_closing} When you want to close a connection, you do it by returning {\ttfamily -\/1} from a callback for that connection. You can provoke a callback by calling {\ttfamily 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. If the socket knows the connection is dead, because the peer closed or there was an affirmitive network error like a F\+IN coming, then {\bfseries libwebsockets} will take care of closing the connection automatically. -If you have a silently dead connection, it\textquotesingle{}s possible to enter a state where the send pipe on the connection is choked but no ack will ever come, so the dead connection will never become writeable. To cover that, you can use T\+CP keepalives (see later in this document) - -\subsection*{Fragmented messages } - +If you have a silently dead connection, it\textquotesingle{}s possible to enter a state where the send pipe on the connection is choked but no ack will ever come, so the dead connection will never become writeable. To cover that, you can use T\+CP keepalives (see later in this document) or pings.\hypertarget{md_README.coding_frags}{}\section{Fragmented messages}\label{md_README.coding_frags} To support fragmented messages you need to check for the final frame of a message with {\ttfamily lws\+\_\+is\+\_\+final\+\_\+fragment}. This check can be combined with {\ttfamily libwebsockets\+\_\+remaining\+\_\+packet\+\_\+payload} to gather the whole contents of a message, eg\+: @@ -95,10 +78,7 @@ To support fragmented messages you need to check for the final frame of a messag \end{DoxyCode} -The test app libwebsockets-\/test-\/fraggle sources also show how to deal with fragmented messages. - -\subsection*{Debug Logging } - +The test app libwebsockets-\/test-\/fraggle sources also show how to deal with fragmented messages.\hypertarget{md_README.coding_debuglog}{}\section{Debug Logging}\label{md_README.coding_debuglog} Also using {\ttfamily lws\+\_\+set\+\_\+log\+\_\+level} api you may provide a custom callback to actually emit the log string. By default, this points to an internal emit function that sends to stderr. Setting it to {\ttfamily N\+U\+LL} leaves it as it is instead. A helper function {\ttfamily \hyperlink{group__log_gab7c0fc936cc9f1eb58e2bb234c15147c}{lwsl\+\_\+emit\+\_\+syslog()}} is exported from the library to simplify logging to syslog. You still need to use {\ttfamily setlogmask}, {\ttfamily openlog} and {\ttfamily closelog} in your user code. @@ -116,8 +96,15 @@ The logging apis are made available for user code. The difference between notice and info is that notice will be logged by default whereas info is ignored by default. -\subsection*{External Polling Loop support } +If you are not building with \+\_\+\+D\+E\+B\+UG defined, ie, without this + +\begin{DoxyCode} +1 $ cmake .. -DCMAKE\_BUILD\_TYPE=DEBUG +\end{DoxyCode} + + +then log levels below notice do not actually get compiled in.\hypertarget{md_README.coding_extpoll}{}\section{External Polling Loop support}\label{md_README.coding_extpoll} {\bfseries libwebsockets} maintains an internal {\ttfamily poll()} array for all of its sockets, but you can instead integrate the sockets into an external polling array. That\textquotesingle{}s needed if {\bfseries libwebsockets} will cooperate with an existing poll array maintained by another server. Four callbacks {\ttfamily L\+W\+S\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+A\+D\+D\+\_\+\+P\+O\+L\+L\+\_\+\+FD}, {\ttfamily L\+W\+S\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+D\+E\+L\+\_\+\+P\+O\+L\+L\+\_\+\+FD}, {\ttfamily L\+W\+S\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+S\+E\+T\+\_\+\+M\+O\+D\+E\+\_\+\+P\+O\+L\+L\+\_\+\+FD} and {\ttfamily L\+W\+S\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+C\+L\+E\+A\+R\+\_\+\+M\+O\+D\+E\+\_\+\+P\+O\+L\+L\+\_\+\+FD} appear in the callback for protocol 0 and allow interface code to manage socket descriptors in other poll loops. @@ -133,10 +120,7 @@ Also note that when integrating a foreign event loop like libev or libuv where i \item be sure you set .events to .revents value as well in the synthesized pollfd \item check the built-\/in support for the event loop if possible (eg, ./lib/libuv.c) to see how it interfaces to lws \item use L\+W\+S\+\_\+\+P\+O\+L\+L\+H\+UP / L\+W\+S\+\_\+\+P\+O\+L\+L\+IN / L\+W\+S\+\_\+\+P\+O\+L\+L\+O\+UT from \hyperlink{libwebsockets_8h}{libwebsockets.\+h} to avoid losing windows compatibility -\end{DoxyItemize} - -\subsection*{Using with in c++ apps } - +\end{DoxyItemize}\hypertarget{md_README.coding_cpp}{}\section{Using with in c++ apps}\label{md_README.coding_cpp} The library is ready for use by C++ apps. You can get started quickly by copying the test server @@ -153,14 +137,12 @@ and building it in C++ like this \end{DoxyCode} -{\ttfamily I\+N\+S\+T\+A\+L\+L\+\_\+\+D\+A\+T\+A\+D\+IR} is only needed because the test server uses it as shipped, if you remove the references to it in your app you don\textquotesingle{}t need to define it on the g++ line either. +{\ttfamily I\+N\+S\+T\+A\+L\+L\+\_\+\+D\+A\+T\+A\+D\+IR} is only needed because the test server uses it as shipped, if you remove the references to it in your app you don\textquotesingle{}t need to define it on the g++ line either.\hypertarget{md_README.coding_headerinfo}{}\section{Availability of header information}\label{md_README.coding_headerinfo} +H\+T\+TP Header information is managed by a pool of \char`\"{}ah\char`\"{} structs. These are a limited resource so there is pressure to free the headers and return the ah to the pool for reuse. -\subsection*{Availability of header information } - -From v1.\+2 of the library onwards, the H\+T\+TP header content is {\ttfamily free()}d as soon as the websocket connection is established. For websocket servers, you can copy interesting headers by handling {\ttfamily L\+W\+S\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+F\+I\+L\+T\+E\+R\+\_\+\+P\+R\+O\+T\+O\+C\+O\+L\+\_\+\+C\+O\+N\+N\+E\+C\+T\+I\+ON} callback, for clients there\textquotesingle{}s a new callback just for this purpose {\ttfamily L\+W\+S\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+C\+L\+I\+E\+N\+T\+\_\+\+F\+I\+L\+T\+E\+R\+\_\+\+P\+R\+E\+\_\+\+E\+S\+T\+A\+B\+L\+I\+SH}. - -\subsection*{T\+CP Keepalive } +For that reason header information on H\+T\+TP connections that get upgraded to websockets is lost after the E\+S\+T\+A\+B\+L\+I\+S\+H\+ED callback. Anything important that isn\textquotesingle{}t processed by user code before then should be copied out for later. +For H\+T\+TP connections that don\textquotesingle{}t upgrade, header info remains available the whole time.\hypertarget{md_README.coding_ka}{}\section{T\+C\+P Keepalive}\label{md_README.coding_ka} It is possible for a connection which is not being used to send to die silently somewhere between the peer and the side not sending. In this case by default T\+CP will just not report anything and you will never get any more incoming data or sign the link is dead until you try to send. To deal with getting a notification of that situation, you can choose to enable T\+CP keepalives on all {\bfseries libwebsockets} sockets, when you create the context. @@ -169,10 +151,7 @@ To enable keepalive, set the ka\+\_\+time member of the context creation paramet With keepalive enabled, the T\+CP layer will send control packets that should stimulate a response from the peer without affecting link traffic. If the response is not coming, the socket will announce an error at {\ttfamily poll()} forcing a close. -Note that B\+S\+Ds don\textquotesingle{}t support keepalive time / probes / interval per-\/socket like Linux does. On those systems you can enable keepalive by a nonzero value in {\ttfamily ka\+\_\+time}, but the systemwide kernel settings for the time / probes/ interval are used, regardless of what nonzero value is in {\ttfamily ka\+\_\+time}. - -\subsection*{Optimizing S\+SL connections } - +Note that B\+S\+Ds don\textquotesingle{}t support keepalive time / probes / interval per-\/socket like Linux does. On those systems you can enable keepalive by a nonzero value in {\ttfamily ka\+\_\+time}, but the systemwide kernel settings for the time / probes/ interval are used, regardless of what nonzero value is in {\ttfamily ka\+\_\+time}.\hypertarget{md_README.coding_sslopt}{}\section{Optimizing S\+S\+L connections}\label{md_README.coding_sslopt} There\textquotesingle{}s a member {\ttfamily ssl\+\_\+cipher\+\_\+list} in the {\ttfamily \hyperlink{structlws__context__creation__info}{lws\+\_\+context\+\_\+creation\+\_\+info}} struct which allows the user code to restrict the possible cipher selection at context-\/creation time. You might want to look into that to stop the ssl peers selecting a cipher which is too computationally expensive. To use it, point it to a string like \begin{DoxyVerb} `"RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL"` @@ -181,10 +160,7 @@ You might want to look into that to stop the ssl peers selecting a cipher which if left {\ttfamily N\+U\+LL}, then the \char`\"{}\+D\+E\+F\+A\+U\+L\+T\char`\"{} set of ciphers are all possible to select. -You can also set it to {\ttfamily \char`\"{}\+A\+L\+L\char`\"{}} to allow everything (including insecure ciphers). - -\subsection*{Async nature of client connections } - +You can also set it to {\ttfamily \char`\"{}\+A\+L\+L\char`\"{}} to allow everything (including insecure ciphers).\hypertarget{md_README.coding_clientasync}{}\section{Async nature of client connections}\label{md_README.coding_clientasync} When you call {\ttfamily \hyperlink{structlws__client__connect__info}{lws\+\_\+client\+\_\+connect\+\_\+info}(..)} and get a {\ttfamily wsi} back, it does not mean your connection is active. It just means it started trying to connect. Your client connection is actually active only when you receive {\ttfamily L\+W\+S\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+C\+L\+I\+E\+N\+T\+\_\+\+E\+S\+T\+A\+B\+L\+I\+S\+H\+ED} for it. @@ -195,8 +171,9 @@ After attempting the connection and getting back a non-\/{\ttfamily N\+U\+LL} {\ As usual, see \href{test-server/test-client.c}{\tt test-\/client.\+c} for example code. -\subsection*{Lws platform-\/independent file access apis } +Notice that the client connection api tries to progress the connection somewhat before returning. That means it\textquotesingle{}s possible to get callbacks like C\+O\+N\+N\+E\+C\+T\+I\+O\+N\+\_\+\+E\+R\+R\+OR on the new connection before your user code had a chance to get the wsi returned to identify it (in fact if the connection did fail early, N\+U\+LL will be returned instead of the wsi anyway). +To avoid that problem, you can fill in {\ttfamily pwsi} in the client connection info struct to point to a struct lws that get filled in early by the client connection api with the related wsi. You can then check for that in the callback to confirm the identity of the failing client connection.\hypertarget{md_README.coding_fileapi}{}\section{Lws platform-\/independent file access apis}\label{md_README.coding_fileapi} lws now exposes his internal platform file abstraction in a way that can be both used by user code to make it platform-\/agnostic, and be overridden or subclassed by user code. This allows things like handling the U\+RI \char`\"{}directory space\char`\"{} as a virtual filesystem that may or may not be backed by a regular filesystem. One example use is serving files from inside large compressed archive storage without having to unpack anything except the file being requested. @@ -234,10 +211,7 @@ and then can use helpers to also leverage these platform-\/independent file hand \end{DoxyCode} -The user code can also override or subclass the file operations, to either wrap or replace them. An example is shown in test server. - -\subsection*{E\+C\+DH Support } - +The user code can also override or subclass the file operations, to either wrap or replace them. An example is shown in test server.\hypertarget{md_README.coding_ecdh}{}\section{E\+C\+D\+H Support}\label{md_README.coding_ecdh} E\+C\+DH Certs are now supported. Enable the C\+Make option \begin{DoxyVerb} cmake .. -DLWS_SSL_SERVER_WITH_ECDH_CERT=1 \end{DoxyVerb} @@ -246,10 +220,7 @@ E\+C\+DH Certs are now supported. Enable the C\+Make option \begin{DoxyVerb} \end{DoxyVerb} -to build in support and select it at runtime. - -\subsection*{S\+MP / Multithreaded service } - +to build in support and select it at runtime.\hypertarget{md_README.coding_smp}{}\section{S\+M\+P / Multithreaded service}\label{md_README.coding_smp} S\+MP support is integrated into L\+WS without any internal threading. It\textquotesingle{}s very simple to use, libwebsockets-\/test-\/server-\/pthread shows how to do it, use -\/j $<$n$>$ argument there to control the number of service threads up to 32. Two new members are added to the info struct \begin{DoxyVerb} unsigned int count_threads; @@ -277,10 +248,7 @@ Because lws will limit the requested number of actual threads supported accordin It\textquotesingle{}s required to implement locking in the user code in the same way that libwebsockets-\/test-\/server-\/pthread does it, for the FD locking callbacks. -There is no knowledge or dependency in lws itself about pthreads. How the locking is implemented is entirely up to the user code. - -\subsection*{Libev / Libuv support } - +There is no knowledge or dependency in lws itself about pthreads. How the locking is implemented is entirely up to the user code.\hypertarget{md_README.coding_libevuv}{}\section{Libev / Libuv support}\label{md_README.coding_libevuv} You can select either or both \begin{DoxyVerb} -DLWS_WITH_LIBEV=1 -DLWS_WITH_LIBUV=1 \end{DoxyVerb} @@ -291,10 +259,7 @@ at cmake configure-\/time. The user application may use one of the context init \end{DoxyVerb} -to indicate it will use either of the event libraries. - -\subsection*{Extension option control from user code } - +to indicate it will use either of the event libraries.\hypertarget{md_README.coding_extopts}{}\section{Extension option control from user code}\label{md_README.coding_extopts} User code may set per-\/connection extension options now, using a new api {\ttfamily \hyperlink{group__extensions_gae0e24e1768f83a7fb07896ce975704b9}{lws\+\_\+set\+\_\+extension\+\_\+option()}}. This should be called from the E\+S\+T\+A\+B\+L\+I\+S\+H\+ED callback like this @@ -306,10 +271,7 @@ This should be called from the E\+S\+T\+A\+B\+L\+I\+S\+H\+ED callback like this If the extension is not active (missing or not negotiated for the connection, or extensions are disabled on the library) the call is just returns -\/1. Otherwise the connection\textquotesingle{}s extension has its named option changed. -The extension may decide to alter or disallow the change, in the example above permessage-\/deflate restricts the size of his rx output buffer also considering the protocol\textquotesingle{}s rx\+\_\+buf\+\_\+size member. - -\subsection*{Client connections as H\+T\+TP\mbox{[}S\mbox{]} rather than WS\mbox{[}S\mbox{]} } - +The extension may decide to alter or disallow the change, in the example above permessage-\/deflate restricts the size of his rx output buffer also considering the protocol\textquotesingle{}s rx\+\_\+buf\+\_\+size member.\hypertarget{md_README.coding_httpsclient}{}\section{Client connections as H\+T\+T\+P\mbox{[}\+S\mbox{]} rather than W\+S\mbox{[}\+S\mbox{]}}\label{md_README.coding_httpsclient} You may open a generic http client connection using the same struct \hyperlink{structlws__client__connect__info}{lws\+\_\+client\+\_\+connect\+\_\+info} used to create client ws\mbox{[}s\mbox{]} connections. To stay in http\mbox{[}s\mbox{]}, set the optional info member \char`\"{}method\char`\"{} to point to the string \char`\"{}\+G\+E\+T\char`\"{} instead of the default N\+U\+LL. @@ -346,8 +308,7 @@ Either way you use the api {\ttfamily lws\+\_\+http\+\_\+client\+\_\+read()} to \end{DoxyCode} -\subsection*{Using lws v2 vhosts } - +Notice that if you will use S\+SL client connections on a vhost, you must prepare the client S\+SL context for the vhost after creating the vhost, since this is not normally done if the vhost was set up to listen / serve. Call the api \hyperlink{group__client_ga4f44b8230e6732816ca5cd8d1aaaf340}{lws\+\_\+init\+\_\+vhost\+\_\+client\+\_\+ssl()} to also allow client S\+SL on the vhost.\hypertarget{md_README.coding_vhosts}{}\section{Using lws vhosts}\label{md_README.coding_vhosts} If you set L\+W\+S\+\_\+\+S\+E\+R\+V\+E\+R\+\_\+\+O\+P\+T\+I\+O\+N\+\_\+\+E\+X\+P\+L\+I\+C\+I\+T\+\_\+\+V\+H\+O\+S\+TS options flag when you create your context, it won\textquotesingle{}t create a default vhost using the info struct members for compatibility. Instead you can call \hyperlink{group__context-and-vhost_ga0c54c667ccd9b8b3dddcd123ca72f87c}{lws\+\_\+create\+\_\+vhost()} afterwards to attach one or more vhosts manually. @@ -374,10 +335,14 @@ If you set L\+W\+S\+\_\+\+S\+E\+R\+V\+E\+R\+\_\+\+O\+P\+T\+I\+O\+N\+\_\+\+E\+X\+ When you attach the vhost, if the vhost\textquotesingle{}s port already has a listen socket then both vhosts share it and use S\+NI (is S\+SL in use) or the Host\+: header from the client to select the right one. Or if no other vhost already listening the a new listen socket is created. -There are some new members but mainly it\textquotesingle{}s stuff you used to set at context creation time. +There are some new members but mainly it\textquotesingle{}s stuff you used to set at context creation time.\hypertarget{md_README.coding_sni}{}\section{How lws matches hostname or S\+N\+I to a vhost}\label{md_README.coding_sni} +L\+WS first strips any trailing \+:port number. -\subsection*{Using lws v2 mounts on a vhost } +Then it tries to find an exact name match for a vhost listening on the correct port, ie, if S\+NI or the Host\+: header provided abc.\+com\+:1234, it will match on a vhost named abc.\+com that is listening on port 1234. +If there is no exact match, lws will consider wildcard matches, for example if cats.\+abc.\+com\+:1234 is provided by the client by S\+NI or Host\+: header, it will accept a vhost \char`\"{}abc.\+com\char`\"{} listening on port 1234. If there was a better, exact, match, it will have been chosen in preference to this. + +Connections with S\+SL will still have the client go on to check the certificate allows wildcards and error out if not.\hypertarget{md_README.coding_mounts}{}\section{Using lws mounts on a vhost}\label{md_README.coding_mounts} The last argument to \hyperlink{group__context-and-vhost_ga0c54c667ccd9b8b3dddcd123ca72f87c}{lws\+\_\+create\+\_\+vhost()} lets you associate a linked list of \hyperlink{structlws__http__mount}{lws\+\_\+http\+\_\+mount} structures with that vhost\textquotesingle{}s U\+RL \textquotesingle{}namespace\textquotesingle{}, in a similar way that unix lets you mount filesystems into areas of your / filesystem how you like and deal with the contents transparently. @@ -429,10 +394,7 @@ Both the mount structures and the strings must persist until the context is dest \item L\+W\+S\+M\+P\+R\+O\+\_\+\+C\+GI associates the url namespace with the given C\+GI executable, which runs when the U\+RL is accessed and the output provided to the client. \item L\+W\+S\+M\+P\+R\+O\+\_\+\+R\+E\+D\+I\+R\+\_\+\+H\+T\+TP and L\+W\+S\+M\+P\+R\+O\+\_\+\+R\+E\+D\+I\+R\+\_\+\+H\+T\+T\+PS auto-\/redirect clients to the given origin U\+RL. \item L\+W\+S\+M\+P\+R\+O\+\_\+\+C\+A\+L\+L\+B\+A\+CK causes the http connection to attach to the callback associated with the named protocol (which may be a plugin). -\end{DoxyItemize} - -\subsection*{Operation of L\+W\+S\+M\+P\+R\+O\+\_\+\+C\+A\+L\+L\+B\+A\+CK mounts } - +\end{DoxyItemize}\hypertarget{md_README.coding_mountcallback}{}\section{Operation of L\+W\+S\+M\+P\+R\+O\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K mounts}\label{md_README.coding_mountcallback} The feature provided by C\+A\+L\+L\+B\+A\+CK type mounts is binding a part of the U\+RL namespace to a named protocol callback handler. This allows protocol plugins to handle areas of the U\+RL namespace. For example in test-\/server-\/v2.\+0.\+c, the U\+RL area \char`\"{}/formtest\char`\"{} is associated with the plugin providing \char`\"{}protocol-\/post-\/demo\char`\"{} like this diff --git a/doc/latex/md_README.generic-sessions.tex b/doc/latex/md_README.generic-sessions.tex index 70871c7a..58523aa5 100644 --- a/doc/latex/md_README.generic-sessions.tex +++ b/doc/latex/md_README.generic-sessions.tex @@ -1,11 +1,7 @@ -\subsection*{Enabling for build } - +\hypertarget{md_README.generic-sessions_gseb}{}\section{Enabling lwsgs for build}\label{md_README.generic-sessions_gseb} Enable at C\+Make with -\/\+D\+L\+W\+S\+\_\+\+W\+I\+T\+H\+\_\+\+G\+E\+N\+E\+R\+I\+C\+\_\+\+S\+E\+S\+S\+I\+O\+NS=1 -This also needs sqlite3 (libsqlite3-\/dev or similar package) - -\subsection*{Introduction } - +This also needs sqlite3 (libsqlite3-\/dev or similar package)\hypertarget{md_README.generic-sessions_gsi}{}\section{lwsgs Introduction}\label{md_README.generic-sessions_gsi} The generic-\/sessions protocol plugin provides cookie-\/based login authentication for lws web and ws connections. The plugin handles everything about generic account registration, email verification, lost password, account deletion, and other generic account management. @@ -26,10 +22,7 @@ Other code, in another eg, ws protocol handler, only needs very high-\/level sta \item Eliminates server-\/side scripting with a few rewritten symbols and javascript on client side \item 32-\/bit bitfield for authentication sectoring, mounts can provide a mask on the loggin-\/in session\textquotesingle{}s associated server-\/side bitfield that must be set for access. \item No code (just config) required for, eg, private U\+RL namespace that requires login to access. -\end{DoxyItemize} - -\subsection*{Integration to H\+T\+ML } - +\end{DoxyItemize}\hypertarget{md_README.generic-sessions_gsin}{}\section{Lwsgs Integration to H\+T\+ML}\label{md_README.generic-sessions_gsin} Only three steps are needed to integrate lwsgs in your H\+T\+ML. 1) lwsgs H\+T\+ML UI is bundled with the javascript it uses in {\ttfamily lwsgs.\+js}, so import that script file in your head section @@ -68,8 +61,7 @@ That\textquotesingle{}s it. An example is below 24 25 \end{DoxyCode} - \subsection*{Overall Flow } - +\hypertarget{md_README.generic-sessions_gsof}{}\section{Lwsgs Overall Flow@}\label{md_README.generic-sessions_gsof} When the protocol is initialized, it gets per-\/vhost information from the config, such as where the sqlite3 databases are to be stored. The admin username and sha-\/1 of the admin password are also taken from here. In the mounts using protocol-\/generic-\/sessions, a cookie is maintained against any requests; if no cookie was active on the initial request a new session is created with no attached user. @@ -80,11 +72,8 @@ In the example html going to the mount /lwsgs loads a login / register page as t The $<$form$>$ in the login page contains \textquotesingle{}next url\textquotesingle{} hidden inputs that let the html \textquotesingle{}program\textquotesingle{} where the form handler will go after a successful admin login, a successful user login and a failed login. -After a successful login, the sqlite record at the server for the current session is updated to have the logged-\/in username associated with it. - -\subsection*{Configuration } - -\char`\"{}auth-\/mask\char`\"{} defines the autorization sector bits that must be enabled on the session to gain access. +After a successful login, the sqlite record at the server for the current session is updated to have the logged-\/in username associated with it.\hypertarget{md_README.generic-sessions_gsconf}{}\section{Lwsgs Configuration}\label{md_README.generic-sessions_gsconf} +\char`\"{}auth-\/mask\char`\"{} defines the authorization sector bits that must be enabled on the session to gain access. \char`\"{}auth-\/mask\char`\"{} 0 is the default. @@ -191,14 +180,8 @@ The real protocol that makes use of generic-\/sessions must also be listed and a \end{DoxyCode} -Notice the real application uses his own sqlite db, no details about how generic-\/sessions works or how it stores data are available to it. - -\subsection*{Password Confounder } - -You can also define a per-\/vhost confounder shown in the example above, used when aggregating the password with the salt when it is hashed. Any attacker will also need to get the confounder along with the database, which you can make harder by making the config dir only eneterable / readable by root. - -\subsection*{Preparing the db directory } - +Notice the real application uses his own sqlite db, no details about how generic-\/sessions works or how it stores data are available to it.\hypertarget{md_README.generic-sessions_gspwc}{}\section{Lwsgs Password Confounder}\label{md_README.generic-sessions_gspwc} +You can also define a per-\/vhost confounder shown in the example above, used when aggregating the password with the salt when it is hashed. Any attacker will also need to get the confounder along with the database, which you can make harder by making the config dir only eneterable / readable by root.\hypertarget{md_README.generic-sessions_gsprep}{}\section{Lwsgs Preparing the db directory}\label{md_README.generic-sessions_gsprep} You will have to prepare the db directory so it\textquotesingle{}s suitable for the lwsws user to use, that usually means apache, eg @@ -207,20 +190,16 @@ You will have to prepare the db directory so it\textquotesingle{}s suitable for 2 # chown root:apache /var/www/sessions 3 # chmod 770 /var/www/sessions \end{DoxyCode} - - -\subsection*{Email configuration } - +\hypertarget{md_README.generic-sessions_gsrmail}{}\section{Lwsgs Email configuration}\label{md_README.generic-sessions_gsrmail} lwsgs will can send emails by talking to an S\+M\+TP server on localhost\+:25. That will usually be sendmail or postfix, you should confirm that works first by itself using the {\ttfamily mail} application to send on it. -lwsgs has been tested on stock Fedora sendmail and postfix. - -\subsection*{Integration with another protocol } - +lwsgs has been tested on stock Fedora sendmail and postfix.\hypertarget{md_README.generic-sessions_gsap}{}\section{Lwsgs Integration with another protocol}\label{md_README.generic-sessions_gsap} lwsgs is designed to provide sessions and accounts in a standalone and generic way. But it\textquotesingle{}s not useful by itself, there will always be the actual application who wants to make use of generic-\/sessions features. +We provide the \char`\"{}messageboard\char`\"{} plugin as an example of how to integrate with your actual application protocol. + The basic approach is the \textquotesingle{}real\textquotesingle{} protocol handler (usually a plugin itself) subclasses the generic-\/sessions plugin and calls through to it by default. The \char`\"{}real\char`\"{} protocol handler entirely deals with ws-\/related stuff itself, since generic-\/sessions does not use ws. But for @@ -292,7 +271,7 @@ To ease management of these secondary allocations, there are callbacks that occu \end{DoxyCode} -\subsection*{Getting session-\/specific information from another protocol } +\#section gsapsib Getting session-\/specific information from another protocol At least at the time when someone tries to upgrade an http(s) connection to ws(s) with your real protocol, it is necessary to confirm the cookie the http(s) connection has with generic-\/sessions and find out his username and other info. diff --git a/doc/latex/md_README.lwsws.tex b/doc/latex/md_README.lwsws.tex index afe0aeda..2a52cf61 100644 --- a/doc/latex/md_README.lwsws.tex +++ b/doc/latex/md_README.lwsws.tex @@ -1,18 +1,17 @@ -\subsection*{Libwebsockets Web Server } - +\hypertarget{md_README.lwsws_lwsws}{}\section{Libwebsockets Web Server}\label{md_README.lwsws_lwsws} lwsws is an implementation of a very lightweight, ws-\/capable generic web server, which uses libwebsockets to implement everything underneath. -\subsection*{Build } - +If you are basically implementing a standalone server with lws, you can avoid reinventing the wheel and use a debugged server including lws.\hypertarget{md_README.lwsws_lwswsb}{}\section{Build}\label{md_README.lwsws_lwswsb} Just enable -\/\+D\+L\+W\+S\+\_\+\+W\+I\+T\+H\+\_\+\+L\+W\+S\+WS=1 at cmake-\/time. -It enables libuv and plugin support automatically. +It enables libuv and plugin support automatically.\hypertarget{md_README.lwsws_lwswsc}{}\section{Lwsws Configuration}\label{md_README.lwsws_lwswsc} +lwsws uses J\+S\+ON config files, they\textquotesingle{}re pure J\+S\+ON except\+: -\subsection*{Configuration } -lwsws uses J\+S\+ON config files, they\textquotesingle{}re pure J\+S\+ON but \# may be used to turn the rest of the line into a comment. - -There\textquotesingle{}s also a single substitution, if a string contains \char`\"{}\+\_\+lws\+\_\+ddir\+\_\+\char`\"{}, then that is replaced with the L\+WS install data directory path, eg, \char`\"{}/usr/share\char`\"{} or whatever was set when L\+WS was built + installed. That lets you refer to installed paths without having to change the config if your install path was different. +\begin{DoxyItemize} +\item \textquotesingle{}\#\textquotesingle{} may be used to turn the rest of the line into a comment. +\item There\textquotesingle{}s also a single substitution, if a string contains \char`\"{}\+\_\+lws\+\_\+ddir\+\_\+\char`\"{}, then that is replaced with the L\+WS install data directory path, eg, \char`\"{}/usr/share\char`\"{} or whatever was set when L\+WS was built + installed. That lets you refer to installed paths without having to change the config if your install path was different. +\end{DoxyItemize} There is a single file intended for global settings @@ -59,8 +58,7 @@ There is a single file intended for global settings 3 # cp ./lwsws/etc-lwsws-conf.d-localhost-EXAMPLE /etc/lwsws/conf.d/test-server 4 # sudo lwsws \end{DoxyCode} - \subsection*{Vhosts } - +\hypertarget{md_README.lwsws_lwswsv}{}\section{Lwsws Vhosts}\label{md_README.lwsws_lwswsv} One server can run many vhosts, where S\+SL is in use S\+NI is used to match the connection to a vhost and its vhost-\/specific S\+SL keys during S\+SL negotiation. Listing multiple vhosts looks something like this @@ -115,20 +113,14 @@ Listing multiple vhosts looks something like this \end{DoxyCode} -That sets up three vhosts all called \char`\"{}localhost\char`\"{} on ports 443 and 7681 with S\+SL, and port 80 without S\+SL but with a forced redirect to \href{https://localhost}{\tt https\+://localhost} - -\subsection*{Vhost name and port } - +That sets up three vhosts all called \char`\"{}localhost\char`\"{} on ports 443 and 7681 with S\+SL, and port 80 without S\+SL but with a forced redirect to \href{https://localhost}{\tt https\+://localhost}\hypertarget{md_README.lwsws_lwswsvn}{}\section{Lwsws Vhost name and port sharing}\label{md_README.lwsws_lwswsvn} The vhost name field is used to match on incoming S\+NI or Host\+: header, so it must always be the host name used to reach the vhost externally. \begin{DoxyItemize} \item Vhosts may have the same name and different ports, these will each create a listening socket on the appropriate port. \item Vhosts may also have the same port and different name\+: these will be treated as true vhosts on one listening socket and the active vhost decided at S\+SL negotiation time (via S\+NI) or if no S\+SL, then after the Host\+: header from the client has been parsed. -\end{DoxyItemize} - -\subsection*{Protocols } - +\end{DoxyItemize}\hypertarget{md_README.lwsws_lwswspr}{}\section{Lwsws Protocols}\label{md_README.lwsws_lwswspr} Vhosts by default have available the union of any initial protocols from context creation time, and any protocols exposed by plugins. Vhosts can select which plugins they want to offer and give them per-\/vhost settings using this syntax @@ -152,10 +144,7 @@ To indicate that a protocol should be used when no Protocol\+: header is sent by 5 \} 6 \}] \end{DoxyCode} - - -\subsection*{Other vhost options } - +\hypertarget{md_README.lwsws_lwswsovo}{}\section{Lwsws Other vhost options}\label{md_README.lwsws_lwswsovo} \begin{DoxyItemize} \item If the three options {\ttfamily host-\/ssl-\/cert}, {\ttfamily host-\/ssl-\/ca} and {\ttfamily host-\/ssl-\/key} are given, then the vhost supports S\+SL. @@ -199,10 +188,7 @@ would equate to \begin{DoxyItemize} \item \char`\"{}`ssl-\/option-\/clear\textquotesingle{}\char`\"{}\+: \char`\"{}$<$decimal$>$\char`\"{} Clears the S\+SL option flag value for the vhost. It may be used multiple times and OR\textquotesingle{}s the flags together. -\end{DoxyItemize} - -\subsection*{Mounts } - +\end{DoxyItemize}\hypertarget{md_README.lwsws_lwswsm}{}\section{Lwsws Mounts}\label{md_README.lwsws_lwswsm} Where mounts are given in the vhost definition, then directory contents may be auto-\/served if it matches the mountpoint. Mount protocols are used to control what kind of translation happens @@ -238,10 +224,7 @@ Eg, with this mountpoint 9 \}, \end{DoxyCode} would cause the url /git/myrepo to pass \char`\"{}myrepo\char`\"{} to the cgi /var/www/cgi-\/bin/cgit and send the results to the client. -\end{DoxyItemize} - -\subsection*{Other mount options } - +\end{DoxyItemize}\hypertarget{md_README.lwsws_lwswsomo}{}\section{Lwsws Other mount options}\label{md_README.lwsws_lwswsomo} 1) Some protocols may want \char`\"{}per-\/mount options\char`\"{} in name\+:value format. You can provide them using \char`\"{}pmo\char`\"{} \begin{DoxyVerb} { "mountpoint": "/stuff", "origin": "callback://myprotocol", @@ -302,10 +285,7 @@ See the related notes in R\+E\+A\+D\+M\+E.\+coding.\+md 3 ".doc": "text/evil" 4 \} \end{DoxyCode} - - -\subsection*{Plugins } - +\hypertarget{md_README.lwsws_lwswspl}{}\section{Lwsws Plugins}\label{md_README.lwsws_lwswspl} Protcols and extensions may also be provided from \char`\"{}plugins\char`\"{}, these are lightweight dynamic libraries. They are scanned for at init time, and any protocols and extensions found are added to the list given at context creation time. Protocols receive init (L\+W\+S\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+P\+R\+O\+T\+O\+C\+O\+L\+\_\+\+I\+N\+IT) and destruction (L\+W\+S\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+P\+R\+O\+T\+O\+C\+O\+L\+\_\+\+D\+E\+S\+T\+R\+OY) callbacks per-\/vhost, and there are arrangements they can make per-\/vhost allocations and get hold of the correct pointer from the wsi at the callback. @@ -323,10 +303,7 @@ To help that happen conveniently, there are some new apis \item lws\+\_\+protocol\+\_\+vh\+\_\+priv\+\_\+get(vhost, protocol) \end{DoxyItemize} -dumb increment, mirror and status protocol plugins are provided as examples. - -\subsection*{Additional plugin search paths } - +dumb increment, mirror and status protocol plugins are provided as examples.\hypertarget{md_README.lwsws_lwswsplaplp}{}\section{Additional plugin search paths}\label{md_README.lwsws_lwswsplaplp} Packages that have their own lws plugins can install them in their own preferred dir and ask lwsws to scan there by using a config fragment like this, in its own conf.\+d/ file managed by the other package \begin{DoxyCode} 1 \{ @@ -335,10 +312,7 @@ Packages that have their own lws plugins can install them in their own preferred 4 \} 5 \} \end{DoxyCode} - - -\subsection*{lws-\/server-\/status plugin } - +\hypertarget{md_README.lwsws_lwswsssp}{}\section{lws-\/server-\/status plugin}\label{md_README.lwsws_lwswsssp} One provided protocol can be used to monitor the server status. Enable the protocol like this on a vhost\textquotesingle{}s ws-\/protocols section @@ -358,10 +332,7 @@ And map the provided H\+T\+ML into the vhost in the mounts section 4 "default": "server-status.html" 5 \} \end{DoxyCode} - You might choose to put it on its own vhost which has \char`\"{}interface\char`\"{}\+: \char`\"{}lo\char`\"{}, so it\textquotesingle{}s not externally visible. - -\subsection*{Integration with Systemd } - + You might choose to put it on its own vhost which has \char`\"{}interface\char`\"{}\+: \char`\"{}lo\char`\"{}, so it\textquotesingle{}s not externally visible.\hypertarget{md_README.lwsws_lwswssysd}{}\section{Lwsws Integration with Systemd}\label{md_README.lwsws_lwswssysd} lwsws needs a service file like this as {\ttfamily /usr/lib/systemd/system/lwsws.service} \begin{DoxyCode} 1 [Unit] @@ -377,10 +348,7 @@ lwsws needs a service file like this as {\ttfamily /usr/lib/systemd/system/lwsws \end{DoxyCode} -You can find this prepared in {\ttfamily ./lwsws/usr-\/lib-\/systemd-\/system-\/lwsws.service} - -\subsection*{Integration with logrotate } - +You can find this prepared in {\ttfamily ./lwsws/usr-\/lib-\/systemd-\/system-\/lwsws.service}\hypertarget{md_README.lwsws_lwswslr}{}\section{Lwsws Integration with logrotate}\label{md_README.lwsws_lwswslr} For correct operation with logrotate, {\ttfamily /etc/logrotate.d/lwsws} (if that\textquotesingle{}s where we\textquotesingle{}re putting the logs) should contain \begin{DoxyCode} 1 /var/log/lwsws/*log \{ diff --git a/doc/latex/md_README.test-apps.tex b/doc/latex/md_README.test-apps.tex index 76c7844f..2a5a729b 100644 --- a/doc/latex/md_README.test-apps.tex +++ b/doc/latex/md_README.test-apps.tex @@ -30,20 +30,14 @@ This is the original way lws implemented servers, plugins and libuv are not requ This method is still supported in lws but all ongoing and future work is being done in protocol plugins only. -\section*{Notes about lws test apps } - -\subsection*{Testing server with a browser } - +\section*{Notes about lws test apps }\hypertarget{md_README.test-apps_tsb}{}\section{Testing server with a browser}\label{md_README.test-apps_tsb} If you run \href{test-server/test-server.c}{\tt libwebsockets-\/test-\/server} and point your browser (eg, Chrome) to \begin{DoxyVerb} http://127.0.0.1:7681 \end{DoxyVerb} It will fetch a script in the form of {\ttfamily test.\+html}, and then run the script in there on the browser to open a websocket connection. Incrementing numbers should appear in the browser display. -By default the test server logs to both stderr and syslog, you can control what is logged using {\ttfamily -\/d $<$log level$>$}, see later. - -\subsection*{Running test server as a Daemon } - +By default the test server logs to both stderr and syslog, you can control what is logged using {\ttfamily -\/d $<$log level$>$}, see later.\hypertarget{md_README.test-apps_tsd}{}\section{Running test server as a Daemon}\label{md_README.test-apps_tsd} You can use the -\/D option on the test server to have it fork into the background and return immediately. In this daemonized mode all stderr is disabled and logging goes only to syslog, eg, {\ttfamily /var/log/messages} or similar. The server maintains a lockfile at {\ttfamily /tmp/.lwsts-\/lock} that contains the pid of the master process, and deletes this file when the master process terminates. @@ -54,10 +48,7 @@ To stop the daemon, do \end{DoxyCode} If it finds a stale lock (the pid mentioned in the file does not exist any more) it will delete the lock and create a new one during startup. -If the lock is valid, the daemon will exit with a note on stderr that it was already running. - -\subsection*{Using S\+SL on the server side } - +If the lock is valid, the daemon will exit with a note on stderr that it was already running.\hypertarget{md_README.test-apps_sssl}{}\section{Using S\+S\+L on the server side}\label{md_README.test-apps_sssl} To test it using S\+S\+L/\+W\+SS, just run the test server with \begin{DoxyCode} 1 $ libwebsockets-test-server --ssl @@ -68,10 +59,7 @@ To test it using S\+S\+L/\+W\+SS, just run the test server with \end{DoxyCode} The connection will be entirely encrypted using some generated certificates that your browser will not accept, since they are not signed by any real Certificate Authority. Just accept the certificates in the browser and the connection will proceed in first https and then websocket wss, acting exactly the same. -\href{test-server/test-server.c}{\tt test-\/server.\+c} is all that is needed to use libwebsockets for serving both the script html over http and websockets. - -\subsection*{Testing websocket client support } - +\href{test-server/test-server.c}{\tt test-\/server.\+c} is all that is needed to use libwebsockets for serving both the script html over http and websockets.\hypertarget{md_README.test-apps_wscl}{}\section{Testing websocket client support}\label{md_README.test-apps_wscl} If you run the test server as described above, you can also connect to it using the test client as well as a browser. @@ -90,18 +78,12 @@ The test client supports S\+SL too, use \end{DoxyCode} -the -\/s tells it to accept the default selfsigned cert from the server, otherwise it will strictly fail the connection if there is no CA cert to validate the server\textquotesingle{}s certificate. - -\subsection*{Choosing between test server variations } - +the -\/s tells it to accept the default selfsigned cert from the server, otherwise it will strictly fail the connection if there is no CA cert to validate the server\textquotesingle{}s certificate.\hypertarget{md_README.test-apps_choosingts}{}\section{Choosing between test server variations}\label{md_README.test-apps_choosingts} If you will be doing standalone serving with lws, ideally you should avoid making your own server at all, and use lwsws with your own protocol plugins. The second best option is follow test-\/server-\/v2.\+0.\+c, which uses a mount to autoserve a directory, and lws protocol plugins for ws, without needing any user callback code (other than what\textquotesingle{}s needed in the protocol plugin). -For those two options libuv is needed to support the protocol plugins, if that\textquotesingle{}s not possible then the other variations with their own protocol code should be considered. - -\subsection*{Testing simple echo } - +For those two options libuv is needed to support the protocol plugins, if that\textquotesingle{}s not possible then the other variations with their own protocol code should be considered.\hypertarget{md_README.test-apps_echo}{}\section{Testing simple echo}\label{md_README.test-apps_echo} You can test against {\ttfamily echo.\+websockets.\+org} as a sanity test like this (the client connects to port {\ttfamily 80} by default)\+: @@ -118,18 +100,12 @@ This echo test is of limited use though because it doesn\textquotesingle{}t nego \begin{DoxyCode} 1 $ libwebsockets-test-echo --client localhost --port 7681 \end{DoxyCode} - If you add the {\ttfamily -\/-\/ssl} switch to both the client and server, you can also test with an encrypted link. - -\subsection*{Testing S\+SL on the client side } - + If you add the {\ttfamily -\/-\/ssl} switch to both the client and server, you can also test with an encrypted link.\hypertarget{md_README.test-apps_tassl}{}\section{Testing S\+S\+L on the client side}\label{md_README.test-apps_tassl} To test S\+S\+L/\+W\+SS client action, just run the client test with \begin{DoxyCode} 1 $ libwebsockets-test-client localhost --ssl \end{DoxyCode} - By default the client test applet is set to accept selfsigned certificates used by the test server, this is indicated by the {\ttfamily use\+\_\+ssl} var being set to {\ttfamily 2}. Set it to {\ttfamily 1} to reject any server certificate that it doesn\textquotesingle{}t have a trusted CA cert for. - -\subsection*{Using the websocket ping utility } - + By default the client test applet is set to accept selfsigned certificates used by the test server, this is indicated by the {\ttfamily use\+\_\+ssl} var being set to {\ttfamily 2}. Set it to {\ttfamily 1} to reject any server certificate that it doesn\textquotesingle{}t have a trusted CA cert for.\hypertarget{md_README.test-apps_taping}{}\section{Using the websocket ping utility}\label{md_README.test-apps_taping} libwebsockets-\/test-\/ping connects as a client to a remote websocket server and pings it like the normal unix ping utility. \begin{DoxyCode} 1 $ libwebsockets-test-ping localhost @@ -155,10 +131,7 @@ Using the lws-\/mirror protocol that is provided by the test server, libwebsocke The default interval between pings is 1s, you can use the -\/i= flag to set this, including fractions like {\ttfamily -\/i=0.\+01} for 10ms interval. -Before you can even use the P\+I\+NG opcode that is part of the standard, you must complete a handshake with a specified protocol. By default lws-\/mirror-\/protocol is used which is supported by the test server. But if you are using it on another server, you can specify the protcol to handshake with by {\ttfamily -\/-\/protocol=protocolname} - -\subsection*{Fraggle test app } - +Before you can even use the P\+I\+NG opcode that is part of the standard, you must complete a handshake with a specified protocol. By default lws-\/mirror-\/protocol is used which is supported by the test server. But if you are using it on another server, you can specify the protcol to handshake with by {\ttfamily -\/-\/protocol=protocolname}\hypertarget{md_README.test-apps_ta}{}\section{fraggle Fraggle test app}\label{md_README.test-apps_ta} By default it runs in server mode \begin{DoxyCode} 1 $ libwebsockets-test-fraggle @@ -192,10 +165,7 @@ By default it runs in server mode \end{DoxyCode} The fraggle test sends a random number up to 1024 fragmented websocket frames each of a random size between 1 and 2001 bytes in a single message, then sends a checksum and starts sending a new randomly sized and fragmented message. -The fraggle test client receives the same message fragments and computes the same checksum using websocket framing to see when the message has ended. It then accepts the server checksum message and compares that to its checksum. - -\subsection*{proxy support } - +The fraggle test client receives the same message fragments and computes the same checksum using websocket framing to see when the message has ended. It then accepts the server checksum message and compares that to its checksum.\hypertarget{md_README.test-apps_taproxy}{}\section{proxy support}\label{md_README.test-apps_taproxy} The http\+\_\+proxy environment variable is respected by the client connection code for both {\ttfamily ws\+://} and {\ttfamily wss\+://}. It doesn\textquotesingle{}t support authentication. You use it like this @@ -203,15 +173,18 @@ You use it like this 1 $ export http\_proxy=myproxy.com:3128 2 $ libwebsockets-test-client someserver.com \end{DoxyCode} - - -\subsection*{debug logging } - +\hypertarget{md_README.test-apps_talog}{}\section{debug logging}\label{md_README.test-apps_talog} By default logging of severity \char`\"{}notice\char`\"{}, \char`\"{}warn\char`\"{} or \char`\"{}err\char`\"{} is enabled to stderr. Again by default other logging is compiled in but disabled from printing. -If you want to eliminate the debug logging below notice in severity, use the {\ttfamily -\/-\/disable-\/debug} configure option to have it removed from the code by the preprocesser. +By default debug logs below \char`\"{}notice\char`\"{} in severity are not compiled in. To get them included, add this option in C\+M\+A\+KE + + +\begin{DoxyCode} +1 $ cmake .. -DCMAKE\_BUILD\_TYPE=DEBUG +\end{DoxyCode} + If you want to see more detailed debug logs, you can control a bitfield to select which logs types may print using the {\ttfamily \hyperlink{group__log_ga244647f9e1bf0097ccdde66d74f41e26}{lws\+\_\+set\+\_\+log\+\_\+level()}} api, in the test apps you can use {\ttfamily -\/d $<$number$>$} to control this. The types of logging available are (OR together the numbers to select multiple) @@ -227,22 +200,13 @@ If you want to see more detailed debug logs, you can control a bitfield to selec \item 128 E\+X\+T\+E\+N\+S\+I\+ON \item 256 C\+L\+I\+E\+NT \item 512 L\+A\+T\+E\+N\+CY -\end{DoxyItemize} - -\subsection*{Websocket version supported } - -The final I\+E\+TF standard is supported for both client and server, protocol version 13. - -\subsection*{Latency Tracking } - +\end{DoxyItemize}\hypertarget{md_README.test-apps_ws13}{}\section{Websocket version supported}\label{md_README.test-apps_ws13} +The final I\+E\+TF standard is supported for both client and server, protocol version 13.\hypertarget{md_README.test-apps_latency}{}\section{Latency Tracking}\label{md_README.test-apps_latency} Since libwebsockets runs using {\ttfamily poll()} and a single threaded approach, any unexpected latency coming from system calls would be bad news. There\textquotesingle{}s now a latency tracking scheme that can be built in with {\ttfamily -\/-\/with-\/latency} at configure-\/time, logging the time taken for system calls to complete and if the whole action did complete that time or was deferred. You can see the detailed data by enabling logging level 512 (eg, {\ttfamily -\/d 519} on the test server to see that and the usual logs), however even without that the \char`\"{}worst\char`\"{} latency is kept and reported to the logs with N\+O\+T\+I\+CE severity when the context is destroyed. -Some care is needed interpreting them, if the action completed the first figure (in us) is the time taken for the whole action, which may have retried through the poll loop many times and will depend on network roundtrip times. High figures here don\textquotesingle{}t indicate a problem. The figure in us reported after \char`\"{}lat\char`\"{} in the logging is the time taken by this particular attempt. High figures here may indicate a problem, or if you system is loaded with another app at that time, such as the browser, it may simply indicate the OS gave preferential treatment to the other app during that call. - -\subsection*{Autobahn Test Suite } - +Some care is needed interpreting them, if the action completed the first figure (in us) is the time taken for the whole action, which may have retried through the poll loop many times and will depend on network roundtrip times. High figures here don\textquotesingle{}t indicate a problem. The figure in us reported after \char`\"{}lat\char`\"{} in the logging is the time taken by this particular attempt. High figures here may indicate a problem, or if you system is loaded with another app at that time, such as the browser, it may simply indicate the OS gave preferential treatment to the other app during that call.\hypertarget{md_README.test-apps_autobahn}{}\section{Autobahn Test Suite}\label{md_README.test-apps_autobahn} Lws can be tested against the autobahn websocket fuzzer. 1) pip install autobahntestsuite @@ -265,13 +229,10 @@ fill in \char`\"{}libwebsockets\char`\"{} in \char`\"{}\+User Agent Identifier\c \href{file:///projects/libwebsockets/reports/clients/index.html}{\tt file\+:///projects/libwebsockets/reports/clients/index.\+html} -to see the results - -\subsection*{Autobahn Test Notes } - +to see the results\hypertarget{md_README.test-apps_autobahnnotes}{}\section{Autobahn Test Notes}\label{md_README.test-apps_autobahnnotes} 1) Autobahn tests the user code + lws implementation. So to get the same results, you need to follow test-\/echo.\+c in terms of user implmentation. -2) Some of the tests make no sense for Libwebsockets to support and we fail them. +2) Two of the tests make no sense for Libwebsockets to support and we fail them. \begin{DoxyItemize}