1Notes about coding with lws 2=========================== 3 4@section era Old lws and lws v2.0 5 6Originally lws only supported the "manual" method of handling everything in the 7user callback found in test-server.c / test-server-http.c. 8 9Since v2.0, the need for most or all of this manual boilerplate has been 10eliminated: the protocols[0] http stuff is provided by a generic lib export 11`lws_callback_http_dummy()`. You can serve parts of your filesystem at part of 12the URL space using mounts, the dummy http callback will do the right thing. 13 14It's much preferred to use the "automated" v2.0 type scheme, because it's less 15code and it's easier to support. 16 17The minimal examples all use the modern, recommended way. 18 19If you just need generic serving capability, without the need to integrate lws 20to some other app, consider not writing any server code at all, and instead use 21the generic server `lwsws`, and writing your special user code in a standalone 22"plugin". The server is configured for mounts etc using JSON, see 23./READMEs/README.lwsws.md. 24 25Although the "plugins" are dynamically loaded if you use lwsws or lws built 26with libuv, actually they may perfectly well be statically included if that 27suits your situation better, eg, ESP32 test server, where the platform does 28not support processes or dynamic loading, just #includes the plugins 29one after the other and gets the same benefit from the same code. 30 31Isolating and collating the protocol code in one place also makes it very easy 32to maintain and understand. 33 34So it if highly recommended you put your protocol-specific code into the 35form of a "plugin" at the source level, even if you have no immediate plan to 36use it dynamically-loaded. 37 38@section writeable Only send data when socket writeable 39 40You should only send data on a websocket connection from the user callback 41`LWS_CALLBACK_SERVER_WRITEABLE` (or `LWS_CALLBACK_CLIENT_WRITEABLE` for 42clients). 43 44If you want to send something, do NOT just send it but request a callback 45when the socket is writeable using 46 47 - `lws_callback_on_writable(wsi)` for a specific `wsi`, or 48 49 - `lws_callback_on_writable_all_protocol(protocol)` for all connections 50using that protocol to get a callback when next writeable. 51 52Usually you will get called back immediately next time around the service 53loop, but if your peer is slow or temporarily inactive the callback will be 54delayed accordingly. Generating what to write and sending it should be done 55in the ...WRITEABLE callback. 56 57See the test server code for an example of how to do this. 58 59Otherwise evolved libs like libuv get this wrong, they will allow you to "send" 60anything you want but it only uses up your local memory (and costs you 61memcpys) until the socket can actually accept it. It is much better to regulate 62your send action by the downstream peer readiness to take new data in the first 63place, avoiding all the wasted buffering. 64 65Libwebsockets' concept is that the downstream peer is truly the boss, if he, 66or our connection to him, cannot handle anything new, we should not generate 67anything new for him. This is how unix shell piping works, you may have 68`cat a.txt | grep xyz > remote", but actually that does not cat anything from 69a.txt while remote cannot accept anything new. 70 71@section oneper Only one lws_write per WRITEABLE callback 72 73From v2.5, lws strictly enforces only one lws_write() per WRITEABLE callback. 74 75You will receive a message about "Illegal back-to-back write of ... detected" 76if there is a second lws_write() before returning to the event loop. 77 78This is because with http/2, the state of the network connection carrying a 79wsi is unrelated to any state of the wsi. The situation on http/1 where a 80new request implied a new tcp connection and new SSL buffer, so you could 81assume some window for writes is no longer true. Any lws_write() can fail 82and be buffered for completion by lws; it will be auto-completed by the 83event loop. 84 85Note that if you are handling your own http responses, writing the headers 86needs to be done with a separate lws_write() from writing any payload. That 87means after writing the headers you must call `lws_callback_on_writable(wsi)` 88and send any payload from the writable callback. 89 90@section otherwr Do not rely on only your own WRITEABLE requests appearing 91 92Libwebsockets may generate additional `LWS_CALLBACK_CLIENT_WRITEABLE` events 93if it met network conditions where it had to buffer your send data internally. 94 95So your code for `LWS_CALLBACK_CLIENT_WRITEABLE` needs to own the decision 96about what to send, it can't assume that just because the writeable callback 97came something is ready to send. 98 99It's quite possible you get an 'extra' writeable callback at any time and 100just need to `return 0` and wait for the expected callback later. 101 102@section dae Daemonization 103 104There's a helper api `lws_daemonize` built by default that does everything you 105need to daemonize well, including creating a lock file. If you're making 106what's basically a daemon, just call this early in your init to fork to a 107headless background process and exit the starting process. 108 109Notice stdout, stderr, stdin are all redirected to /dev/null to enforce your 110daemon is headless, so you'll need to sort out alternative logging, by, eg, 111syslog via `lws_set_log_level(..., lwsl_emit_syslog)`. 112 113@section conns Maximum number of connections 114 115The maximum number of connections the library can deal with is decided when 116it starts by querying the OS to find out how many file descriptors it is 117allowed to open (1024 on Fedora for example). It then allocates arrays that 118allow up to that many connections, minus whatever other file descriptors are 119in use by the user code. 120 121If you want to restrict that allocation, or increase it, you can use ulimit or 122similar to change the available number of file descriptors, and when restarted 123**libwebsockets** will adapt accordingly. 124 125@section peer_limits optional LWS_WITH_PEER_LIMITS 126 127If you select `LWS_WITH_PEER_LIMITS` at cmake, then lws will track peer IPs 128and monitor how many connections and ah resources they are trying to use 129at one time. You can choose to limit these at context creation time, using 130`info.ip_limit_ah` and `info.ip_limit_wsi`. 131 132Note that although the ah limit is 'soft', ie, the connection will just wait 133until the IP is under the ah limit again before attaching a new ah, the 134wsi limit is 'hard', lws will drop any additional connections from the 135IP until it's under the limit again. 136 137If you use these limits, you should consider multiple clients may simultaneously 138try to access the site through NAT, etc. So the limits should err on the side 139of being generous, while still making it impossible for one IP to exhaust 140all the server resources. 141 142@section evtloop Libwebsockets is singlethreaded 143 144Libwebsockets works in a serialized event loop, in a single thread. It supports 145the default poll() backend, and libuv, libev, and libevent event loop 146libraries that also take this locking-free, nonblocking event loop approach that 147is not threadsafe. There are several advantages to this technique, but one 148disadvantage, it doesn't integrate easily if there are multiple threads that 149want to use libwebsockets. 150 151However integration to multithreaded apps is possible if you follow some guidelines. 152 1531) Aside from two APIs, directly calling lws apis from other threads is not allowed. 154 1552) If you want to keep a list of live wsi, you need to use lifecycle callbacks on 156the protocol in the service thread to manage the list, with your own locking. 157Typically you use an ESTABLISHED callback to add ws wsi to your list and a CLOSED 158callback to remove them. 159 1603) LWS regulates your write activity by being able to let you know when you may 161write more on a connection. That reflects the reality that you cannot succeed to 162send data to a peer that has no room for it, so you should not generate or buffer 163write data until you know the peer connection can take more. 164 165Other libraries pretend that the guy doing the writing is the boss who decides 166what happens, and absorb as much as you want to write to local buffering. That does 167not scale to a lot of connections, because it will exhaust your memory and waste 168time copying data around in memory needlessly. 169 170The truth is the receiver, along with the network between you, is the boss who 171decides what will happen. If he stops accepting data, no data will move. LWS is 172designed to reflect that. 173 174If you have something to send, you call `lws_callback_on_writable()` on the 175connection, and when it is writeable, you will get a `LWS_CALLBACK_SERVER_WRITEABLE` 176callback, where you should generate the data to send and send it with `lws_write()`. 177 178You cannot send data using `lws_write()` outside of the WRITEABLE callback. 179 1804) For multithreaded apps, this corresponds to a need to be able to provoke the 181`lws_callback_on_writable()` action and to wake the service thread from its event 182loop wait (sleeping in `poll()` or `epoll()` or whatever). The rules above 183mean directly sending data on the connection from another thread is out of the 184question. 185 186Therefore the two apis mentioned above that may be used from another thread are 187 188 - For LWS using the default poll() event loop, `lws_callback_on_writable()` 189 190 - For LWS using libuv/libev/libevent event loop, `lws_cancel_service()` 191 192If you are using the default poll() event loop, one "foreign thread" at a time may 193call `lws_callback_on_writable()` directly for a wsi. You need to use your own 194locking around that to serialize multiple thread access to it. 195 196If you implement LWS_CALLBACK_GET_THREAD_ID in protocols[0], then LWS will detect 197when it has been called from a foreign thread and automatically use 198`lws_cancel_service()` to additionally wake the service loop from its wait. 199 200For libuv/libev/libevent event loop, they cannot handle being called from other 201threads. So there is a slightly different scheme, you may call `lws_cancel_service()` 202to force the event loop to end immediately. This then broadcasts a callback (in the 203service thread context) `LWS_CALLBACK_EVENT_WAIT_CANCELLED`, to all protocols on all 204vhosts, where you can perform your own locking and walk a list of wsi that need 205`lws_callback_on_writable()` calling on them. 206 207`lws_cancel_service()` is very cheap to call. 208 2095) The obverse of this truism about the receiver being the boss is the case where 210we are receiving. If we get into a situation we actually can't usefully 211receive any more, perhaps because we are passing the data on and the guy we want 212to send to can't receive any more, then we should "turn off RX" by using the 213RX flow control API, `lws_rx_flow_control(wsi, 0)`. When something happens where we 214can accept more RX, (eg, we learn our onward connection is writeable) we can call 215it again to re-enable it on the incoming wsi. 216 217LWS stops calling back about RX immediately you use flow control to disable RX, it 218buffers the data internally if necessary. So you will only see RX when you can 219handle it. When flow control is disabled, LWS stops taking new data in... this makes 220the situation known to the sender by TCP "backpressure", the tx window fills and the 221sender finds he cannot write any more to the connection. 222 223See the mirror protocol implementations for example code. 224 225If you need to service other socket or file descriptors as well as the 226websocket ones, you can combine them together with the websocket ones 227in one poll loop, see "External Polling Loop support" below, and 228still do it all in one thread / process context. If the need is less 229architectural, you can also create RAW mode client and serving sockets; this 230is how the lws plugin for the ssh server works. 231 232@section anonprot Working without a protocol name 233 234Websockets allows connections to negotiate without a protocol name... 235in that case by default it will bind to the first protocol in your 236vhost protocols[] array. 237 238You can tell the vhost to use a different protocol by attaching a 239pvo (per-vhost option) to the 240 241``` 242/* 243 * this sets a per-vhost, per-protocol option name:value pair 244 * the effect is to set this protocol to be the default one for the vhost, 245 * ie, selected if no Protocol: header is sent with the ws upgrade. 246 */ 247 248static const struct lws_protocol_vhost_options pvo_opt = { 249 NULL, 250 NULL, 251 "default", 252 "1" 253}; 254 255static const struct lws_protocol_vhost_options pvo = { 256 NULL, 257 &pvo_opt, 258 "my-protocol", 259 "" 260}; 261 262... 263 264 context_info.pvo = &pvo; 265... 266 267``` 268 269Will select "my-protocol" from your protocol list (even if it came 270in by plugin) as being the target of client connections that don't 271specify a protocol. 272 273@section closing Closing connections from the user side 274 275When you want to close a connection, you do it by returning `-1` from a 276callback for that connection. 277 278You can provoke a callback by calling `lws_callback_on_writable` on 279the wsi, then notice in the callback you want to close it and just return -1. 280But usually, the decision to close is made in a callback already and returning 281-1 is simple. 282 283If the socket knows the connection is dead, because the peer closed or there 284was an affirmitive network error like a FIN coming, then **libwebsockets** will 285take care of closing the connection automatically. 286 287If you have a silently dead connection, it's possible to enter a state where 288the send pipe on the connection is choked but no ack will ever come, so the 289dead connection will never become writeable. To cover that, you can use TCP 290keepalives (see later in this document) or pings. 291 292@section gzip Serving from inside a zip file 293 294Lws now supports serving gzipped files from inside a zip container. Thanks to 295Per Bothner for contributing the code. 296 297This has the advtantage that if the client can accept GZIP encoding, lws can 298simply send the gzip-compressed file from inside the zip file with no further 299processing, saving time and bandwidth. 300 301In the case the client can't understand gzip compression, lws automatically 302decompressed the file and sends it normally. 303 304Clients with limited storage and RAM will find this useful; the memory needed 305for the inflate case is constrained so that only one input buffer at a time 306is ever in memory. 307 308To use this feature, ensure LWS_WITH_ZIP_FOPS is enabled at CMake. 309 310`libwebsockets-test-server-v2.0` includes a mount using this technology 311already, run that test server and navigate to http://localhost:7681/ziptest/candide.html 312 313This will serve the book Candide in html, together with two jpgs, all from 314inside a .zip file in /usr/[local/]share-libwebsockets-test-server/candide.zip 315 316Usage is otherwise automatic, if you arrange a mount that points to the zipfile, 317eg, "/ziptest" -> "mypath/test.zip", then URLs like `/ziptest/index.html` will be 318servied from `index.html` inside `mypath/test.zip` 319 320@section frags Fragmented messages 321 322To support fragmented messages you need to check for the final 323frame of a message with `lws_is_final_fragment`. This 324check can be combined with `libwebsockets_remaining_packet_payload` 325to gather the whole contents of a message, eg: 326 327``` 328 case LWS_CALLBACK_RECEIVE: 329 { 330 Client * const client = (Client *)user; 331 const size_t remaining = lws_remaining_packet_payload(wsi); 332 333 if (!remaining && lws_is_final_fragment(wsi)) { 334 if (client->HasFragments()) { 335 client->AppendMessageFragment(in, len, 0); 336 in = (void *)client->GetMessage(); 337 len = client->GetMessageLength(); 338 } 339 340 client->ProcessMessage((char *)in, len, wsi); 341 client->ResetMessage(); 342 } else 343 client->AppendMessageFragment(in, len, remaining); 344 } 345 break; 346``` 347 348The test app libwebsockets-test-fraggle sources also show how to 349deal with fragmented messages. 350 351 352@section debuglog Debug Logging 353 354Also using `lws_set_log_level` api you may provide a custom callback to actually 355emit the log string. By default, this points to an internal emit function 356that sends to stderr. Setting it to `NULL` leaves it as it is instead. 357 358A helper function `lwsl_emit_syslog()` is exported from the library to simplify 359logging to syslog. You still need to use `setlogmask`, `openlog` and `closelog` 360in your user code. 361 362The logging apis are made available for user code. 363 364- `lwsl_err(...)` 365- `lwsl_warn(...)` 366- `lwsl_notice(...)` 367- `lwsl_info(...)` 368- `lwsl_debug(...)` 369 370The difference between notice and info is that notice will be logged by default 371whereas info is ignored by default. 372 373If you are not building with _DEBUG defined, ie, without this 374 375``` 376 $ cmake .. -DCMAKE_BUILD_TYPE=DEBUG 377``` 378 379then log levels below notice do not actually get compiled in. 380 381@section asan Building with ASAN 382 383Under GCC you can select for the build to be instrumented with the Address 384Sanitizer, using `cmake .. -DCMAKE_BUILD_TYPE=DEBUG -DLWS_WITH_ASAN=1`. LWS is routinely run during development with valgrind, but ASAN is capable of finding different issues at runtime, like operations which are not strictly defined in the C 385standard and depend on platform behaviours. 386 387Run your application like this 388 389``` 390 $ sudo ASAN_OPTIONS=verbosity=2:halt_on_error=1 /usr/local/bin/lwsws 391``` 392 393and attach gdb to catch the place it halts. 394 395@section extpoll External Polling Loop support 396 397**libwebsockets** maintains an internal `poll()` array for all of its 398sockets, but you can instead integrate the sockets into an 399external polling array. That's needed if **libwebsockets** will 400cooperate with an existing poll array maintained by another 401server. 402 403Three callbacks `LWS_CALLBACK_ADD_POLL_FD`, `LWS_CALLBACK_DEL_POLL_FD` 404and `LWS_CALLBACK_CHANGE_MODE_POLL_FD` appear in the callback for protocol 0 405and allow interface code to manage socket descriptors in other poll loops. 406 407You can pass all pollfds that need service to `lws_service_fd()`, even 408if the socket or file does not belong to **libwebsockets** it is safe. 409 410If **libwebsocket** handled it, it zeros the pollfd `revents` field before returning. 411So you can let **libwebsockets** try and if `pollfd->revents` is nonzero on return, 412you know it needs handling by your code. 413 414Also note that when integrating a foreign event loop like libev or libuv where 415it doesn't natively use poll() semantics, and you must return a fake pollfd 416reflecting the real event: 417 418 - be sure you set .events to .revents value as well in the synthesized pollfd 419 420 - check the built-in support for the event loop if possible (eg, ./lib/libuv.c) 421 to see how it interfaces to lws 422 423 - use LWS_POLLHUP / LWS_POLLIN / LWS_POLLOUT from libwebsockets.h to avoid 424 losing windows compatibility 425 426You also need to take care about "forced service" somehow... these are cases 427where the network event was consumed, incoming data was all read, for example, 428but the work arising from it was not completed. There will not be any more 429network event to trigger the remaining work, Eg, we read compressed data, but 430we did not use up all the decompressed data before returning to the event loop 431because we had to write some of it. 432 433Lws provides an API to determine if anyone is waiting for forced service, 434`lws_service_adjust_timeout(context, 1, tsi)`, normally tsi is 0. If it returns 4350, then at least one connection has pending work you can get done by calling 436`lws_service_tsi(context, -1, tsi)`, again normally tsi is 0. 437 438For eg, the default poll() event loop, or libuv/ev/event, lws does this 439checking for you and handles it automatically. But in the external polling 440loop case, you must do it explicitly. Handling it after every normal service 441triggered by the external poll fd should be enough, since the situations needing 442it are initially triggered by actual network events. 443 444An example of handling it is shown in the test-server code specific to 445external polling. 446 447@section cpp Using with in c++ apps 448 449The library is ready for use by C++ apps. You can get started quickly by 450copying the test server 451 452``` 453 $ cp test-apps/test-server.c test.cpp 454``` 455 456and building it in C++ like this 457 458``` 459 $ g++ -DINSTALL_DATADIR=\"/usr/share\" -ocpptest test.cpp -lwebsockets 460``` 461 462`INSTALL_DATADIR` is only needed because the test server uses it as shipped, if 463you remove the references to it in your app you don't need to define it on 464the g++ line either. 465 466 467@section headerinfo Availability of header information 468 469HTTP Header information is managed by a pool of "ah" structs. These are a 470limited resource so there is pressure to free the headers and return the ah to 471the pool for reuse. 472 473For that reason header information on HTTP connections that get upgraded to 474websockets is lost after the ESTABLISHED callback. Anything important that 475isn't processed by user code before then should be copied out for later. 476 477For HTTP connections that don't upgrade, header info remains available the 478whole time. 479 480@section http2compat Code Requirements for HTTP/2 compatibility 481 482Websocket connections only work over http/1, so there is nothing special to do 483when you want to enable -DLWS_WITH_HTTP2=1. 484 485The internal http apis already follow these requirements and are compatible with 486http/2 already. So if you use stuff like mounts and serve stuff out of the 487filesystem, there's also nothing special to do. 488 489However if you are getting your hands dirty with writing response headers, or 490writing bulk data over http/2, you need to observe these rules so that it will 491work over both http/1.x and http/2 the same. 492 4931) LWS_PRE requirement applies on ALL lws_write(). For http/1, you don't have 494to take care of LWS_PRE for http data, since it is just sent straight out. 495For http/2, it will write up to LWS_PRE bytes behind the buffer start to create 496the http/2 frame header. 497 498This has implications if you treated the input buffer to lws_write() as const... 499it isn't any more with http/2, up to 9 bytes behind the buffer will be trashed. 500 5012) Headers are encoded using a sophisticated scheme in http/2. The existing 502header access apis are already made compatible for incoming headers, 503for outgoing headers you must: 504 505 - observe the LWS_PRE buffer requirement mentioned above 506 507 - Use `lws_add_http_header_status()` to add the transaction status (200 etc) 508 509 - use lws apis `lws_add_http_header_by_name()` and `lws_add_http_header_by_token()` 510 to put the headers into the buffer (these will translate what is actually 511 written to the buffer depending on if the connection is in http/2 mode or not) 512 513 - use the `lws api lws_finalize_http_header()` api after adding the last 514 response header 515 516 - write the header using lws_write(..., `LWS_WRITE_HTTP_HEADERS`); 517 518 3) http/2 introduces per-stream transmit credit... how much more you can send 519 on a stream is decided by the peer. You start off with some amount, as the 520 stream sends stuff lws will reduce your credit accordingly, when it reaches 521 zero, you must not send anything further until lws receives "more credit" for 522 that stream the peer. Lws will suppress writable callbacks if you hit 0 until 523 more credit for the stream appears, and lws built-in file serving (via mounts 524 etc) already takes care of observing the tx credit restrictions. However if 525 you write your own code that wants to send http data, you must consult the 526 `lws_get_peer_write_allowance()` api to find out the state of your tx credit. 527 For http/1, it will always return (size_t)-1, ie, no limit. 528 529 This is orthogonal to the question of how much space your local side's kernel 530 will make to buffer your send data on that connection. So although the result 531 from `lws_get_peer_write_allowance()` is "how much you can send" logically, 532 and may be megabytes if the peer allows it, you should restrict what you send 533 at one time to whatever your machine will generally accept in one go, and 534 further reduce that amount if `lws_get_peer_write_allowance()` returns 535 something smaller. If it returns 0, you should not consume or send anything 536 and return having asked for callback on writable, it will only come back when 537 more tx credit has arrived for your stream. 538 539 4) Header names with captital letters are illegal in http/2. Header names in 540 http/1 are case insensitive. So if you generate headers by name, change all 541 your header name strings to lower-case to be compatible both ways. 542 543 5) Chunked Transfer-encoding is illegal in http/2, http/2 peers will actively 544 reject it. Lws takes care of removing the header and converting CGIs that 545 emit chunked into unchunked automatically for http/2 connections. 546 547If you follow these rules, your code will automatically work with both http/1.x 548and http/2. 549 550@section ka TCP Keepalive 551 552It is possible for a connection which is not being used to send to die 553silently somewhere between the peer and the side not sending. In this case 554by default TCP will just not report anything and you will never get any more 555incoming data or sign the link is dead until you try to send. 556 557To deal with getting a notification of that situation, you can choose to 558enable TCP keepalives on all **libwebsockets** sockets, when you create the 559context. 560 561To enable keepalive, set the ka_time member of the context creation parameter 562struct to a nonzero value (in seconds) at context creation time. You should 563also fill ka_probes and ka_interval in that case. 564 565With keepalive enabled, the TCP layer will send control packets that should 566stimulate a response from the peer without affecting link traffic. If the 567response is not coming, the socket will announce an error at `poll()` forcing 568a close. 569 570Note that BSDs don't support keepalive time / probes / interval per-socket 571like Linux does. On those systems you can enable keepalive by a nonzero 572value in `ka_time`, but the systemwide kernel settings for the time / probes/ 573interval are used, regardless of what nonzero value is in `ka_time`. 574 575 576@section sslopt Optimizing SSL connections 577 578There's a member `ssl_cipher_list` in the `lws_context_creation_info` struct 579which allows the user code to restrict the possible cipher selection at 580context-creation time. 581 582You might want to look into that to stop the ssl peers selecting a cipher which 583is too computationally expensive. To use it, point it to a string like 584 585 `"RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL"` 586 587if left `NULL`, then the "DEFAULT" set of ciphers are all possible to select. 588 589You can also set it to `"ALL"` to allow everything (including insecure ciphers). 590 591 592@section sslcerts Passing your own cert information direct to SSL_CTX 593 594For most users it's enough to pass the SSL certificate and key information by 595giving filepaths to the info.ssl_cert_filepath and info.ssl_private_key_filepath 596members when creating the vhost. 597 598If you want to control that from your own code instead, you can do so by leaving 599the related info members NULL, and setting the info.options flag 600LWS_SERVER_OPTION_CREATE_VHOST_SSL_CTX at vhost creation time. That will create 601the vhost SSL_CTX without any certificate, and allow you to use the callback 602LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS to add your certificate to 603the SSL_CTX directly. The vhost SSL_CTX * is in the user parameter in that 604callback. 605 606@section clientasync Async nature of client connections 607 608When you call `lws_client_connect_info(..)` and get a `wsi` back, it does not 609mean your connection is active. It just means it started trying to connect. 610 611Your client connection is actually active only when you receive 612`LWS_CALLBACK_CLIENT_ESTABLISHED` for it. 613 614There's a 5 second timeout for the connection, and it may give up or die for 615other reasons, if any of that happens you'll get a 616`LWS_CALLBACK_CLIENT_CONNECTION_ERROR` callback on protocol 0 instead for the 617`wsi`. 618 619After attempting the connection and getting back a non-`NULL` `wsi` you should 620loop calling `lws_service()` until one of the above callbacks occurs. 621 622As usual, see [test-client.c](../test-apps/test-client.c) for example code. 623 624Notice that the client connection api tries to progress the connection 625somewhat before returning. That means it's possible to get callbacks like 626CONNECTION_ERROR on the new connection before your user code had a chance to 627get the wsi returned to identify it (in fact if the connection did fail early, 628NULL will be returned instead of the wsi anyway). 629 630To avoid that problem, you can fill in `pwsi` in the client connection info 631struct to point to a struct lws that get filled in early by the client 632connection api with the related wsi. You can then check for that in the 633callback to confirm the identity of the failing client connection. 634 635 636@section fileapi Lws platform-independent file access apis 637 638lws now exposes his internal platform file abstraction in a way that can be 639both used by user code to make it platform-agnostic, and be overridden or 640subclassed by user code. This allows things like handling the URI "directory 641space" as a virtual filesystem that may or may not be backed by a regular 642filesystem. One example use is serving files from inside large compressed 643archive storage without having to unpack anything except the file being 644requested. 645 646The test server shows how to use it, basically the platform-specific part of 647lws prepares a file operations structure that lives in the lws context. 648 649The user code can get a pointer to the file operations struct 650 651``` 652 LWS_VISIBLE LWS_EXTERN struct lws_plat_file_ops * 653 `lws_get_fops`(struct lws_context *context); 654``` 655 656and then can use helpers to also leverage these platform-independent 657file handling apis 658 659``` 660 lws_fop_fd_t 661 `lws_plat_file_open`(struct lws_plat_file_ops *fops, const char *filename, 662 lws_fop_flags_t *flags) 663 int 664 `lws_plat_file_close`(lws_fop_fd_t fop_fd) 665 666 unsigned long 667 `lws_plat_file_seek_cur`(lws_fop_fd_t fop_fd, lws_fileofs_t offset) 668 669 int 670 `lws_plat_file_read`(lws_fop_fd_t fop_fd, lws_filepos_t *amount, 671 uint8_t *buf, lws_filepos_t len) 672 673 int 674 `lws_plat_file_write`(lws_fop_fd_t fop_fd, lws_filepos_t *amount, 675 uint8_t *buf, lws_filepos_t len ) 676``` 677 678Generic helpers are provided which provide access to generic fops information or 679call through to the above fops 680 681``` 682lws_filepos_t 683lws_vfs_tell(lws_fop_fd_t fop_fd); 684 685lws_filepos_t 686lws_vfs_get_length(lws_fop_fd_t fop_fd); 687 688uint32_t 689lws_vfs_get_mod_time(lws_fop_fd_t fop_fd); 690 691lws_fileofs_t 692lws_vfs_file_seek_set(lws_fop_fd_t fop_fd, lws_fileofs_t offset); 693 694lws_fileofs_t 695lws_vfs_file_seek_end(lws_fop_fd_t fop_fd, lws_fileofs_t offset); 696``` 697 698 699The user code can also override or subclass the file operations, to either 700wrap or replace them. An example is shown in test server. 701 702### Changes from v2.1 and before fops 703 704There are several changes: 705 7061) Pre-2.2 fops directly used platform file descriptors. Current fops returns and accepts a wrapper type lws_fop_fd_t which is a pointer to a malloc'd struct containing information specific to the filesystem implementation. 707 7082) Pre-2.2 fops bound the fops to a wsi. This is completely removed, you just give a pointer to the fops struct that applies to this file when you open it. Afterwards, the operations in the fops just need the lws_fop_fd_t returned from the open. 709 7103) Everything is wrapped in typedefs. See lws-plat-unix.c for examples of how to implement. 711 7124) Position in the file, File Length, and a copy of Flags left after open are now generically held in the fop_fd. 713VFS implementation must set and manage this generic information now. See the implementations in lws-plat-unix.c for 714examples. 715 7165) The file length is no longer set at a pointer provided by the open() fop. The api `lws_vfs_get_length()` is provided to 717get the file length after open. 718 7196) If your file namespace is virtual, ie, is not reachable by platform fops directly, you must set LWS_FOP_FLAG_VIRTUAL 720on the flags during open. 721 7227) There is an optional `mod_time` uint32_t member in the generic fop_fd. If you are able to set it during open, you 723should indicate it by setting `LWS_FOP_FLAG_MOD_TIME_VALID` on the flags. 724 725@section rawfd RAW file descriptor polling 726 727LWS allows you to include generic platform file descriptors in the lws service / poll / event loop. 728 729Open your fd normally and then 730 731``` 732 lws_sock_file_fd_type u; 733 734 u.filefd = your_open_file_fd; 735 736 if (!lws_adopt_descriptor_vhost(vhost, 0, u, 737 "protocol-name-to-bind-to", 738 optional_wsi_parent_or_NULL)) { 739 // failed 740 } 741 742 // OK 743``` 744 745A wsi is created for the file fd that acts like other wsi, you will get these 746callbacks on the named protocol 747 748``` 749 LWS_CALLBACK_RAW_ADOPT_FILE 750 LWS_CALLBACK_RAW_RX_FILE 751 LWS_CALLBACK_RAW_WRITEABLE_FILE 752 LWS_CALLBACK_RAW_CLOSE_FILE 753``` 754 755starting with LWS_CALLBACK_RAW_ADOPT_FILE. 756 757The minimal example `raw/minimal-raw-file` demonstrates how to use it. 758 759`protocol-lws-raw-test` plugin also provides a method for testing this with 760`libwebsockets-test-server-v2.0`: 761 762The plugin creates a FIFO on your system called "/tmp/lws-test-raw" 763 764You can feed it data through the FIFO like this 765 766``` 767 $ sudo sh -c "echo hello > /tmp/lws-test-raw" 768``` 769 770This plugin simply prints the data. But it does it through the lws event 771loop / service poll. 772 773@section rawsrvsocket RAW server socket descriptor polling 774 775You can also enable your vhost to accept RAW socket connections, in addition to 776HTTP[s] and WS[s]. If the first bytes written on the connection are not a 777valid HTTP method, then the connection switches to RAW mode. 778 779This is disabled by default, you enable it by setting the `.options` flag 780LWS_SERVER_OPTION_FALLBACK_TO_APPLY_LISTEN_ACCEPT_CONFIG, and setting 781`.listen_accept_role` to `"raw-skt"` when creating the vhost. 782 783RAW mode socket connections receive the following callbacks 784 785``` 786 LWS_CALLBACK_RAW_ADOPT 787 LWS_CALLBACK_RAW_RX 788 LWS_CALLBACK_RAW_WRITEABLE 789 LWS_CALLBACK_RAW_CLOSE 790``` 791 792You can control which protocol on your vhost handles these RAW mode 793incoming connections by setting the vhost info struct's `.listen_accept_protocol` 794to the vhost protocol name to use. 795 796`protocol-lws-raw-test` plugin provides a method for testing this with 797`libwebsockets-test-server-v2.0`: 798 799Run libwebsockets-test-server-v2.0 and connect to it by telnet, eg 800 801``` 802 $ telnet 127.0.0.1 7681 803``` 804 805type something that isn't a valid HTTP method and enter, before the 806connection times out. The connection will switch to RAW mode using this 807protocol, and pass the unused rx as a raw RX callback. 808 809The test protocol echos back what was typed on telnet to telnet. 810 811@section rawclientsocket RAW client socket descriptor polling 812 813You can now also open RAW socket connections in client mode. 814 815Follow the usual method for creating a client connection, but set the 816`info.method` to "RAW". When the connection is made, the wsi will be 817converted to RAW mode and operate using the same callbacks as the 818server RAW sockets described above. 819 820The libwebsockets-test-client supports this using raw:// URLS. To 821test, open a netcat listener in one window 822 823``` 824 $ nc -l 9999 825``` 826 827and in another window, connect to it using the test client 828 829``` 830 $ libwebsockets-test-client raw://127.0.0.1:9999 831``` 832 833The connection should succeed, and text typed in the netcat window (including a CRLF) 834will be received in the client. 835 836@section rawudp RAW UDP socket integration 837 838Lws provides an api to create, optionally bind, and adopt a RAW UDP 839socket (RAW here means an uninterpreted normal UDP socket, not a 840"raw socket"). 841 842``` 843LWS_VISIBLE LWS_EXTERN struct lws * 844lws_create_adopt_udp(struct lws_vhost *vhost, int port, int flags, 845 const char *protocol_name, struct lws *parent_wsi); 846``` 847 848`flags` should be `LWS_CAUDP_BIND` if the socket will receive packets. 849 850The callbacks `LWS_CALLBACK_RAW_ADOPT`, `LWS_CALLBACK_RAW_CLOSE`, 851`LWS_CALLBACK_RAW_RX` and `LWS_CALLBACK_RAW_WRITEABLE` apply to the 852wsi. But UDP is different than TCP in some fundamental ways. 853 854For receiving on a UDP connection, data becomes available at 855`LWS_CALLBACK_RAW_RX` as usual, but because there is no specific 856connection with UDP, it is necessary to also get the source address of 857the data separately, using `struct lws_udp * lws_get_udp(wsi)`. 858You should take a copy of the `struct lws_udp` itself (not the 859pointer) and save it for when you want to write back to that peer. 860 861Writing is also a bit different for UDP. By default, the system has no 862idea about the receiver state and so asking for a `callback_on_writable()` 863always believes that the socket is writeable... the callback will 864happen next time around the event loop. 865 866With UDP, there is no single "connection". You need to write with sendto() and 867direct the packets to a specific destination. To return packets to a 868peer who sent something earlier and you copied his `struct lws_udp`, you 869use the .sa and .salen members as the last two parameters of the sendto(). 870 871The kernel may not accept to buffer / write everything you wanted to send. 872So you are responsible to watch the result of sendto() and resend the 873unsent part next time (which may involve adding new protocol headers to 874the remainder depending on what you are doing). 875 876@section ecdh ECDH Support 877 878ECDH Certs are now supported. Enable the CMake option 879 880 cmake .. -DLWS_SSL_SERVER_WITH_ECDH_CERT=1 881 882**and** the info->options flag 883 884 LWS_SERVER_OPTION_SSL_ECDH 885 886to build in support and select it at runtime. 887 888@section sslinfo SSL info callbacks 889 890OpenSSL allows you to receive callbacks for various events defined in a 891bitmask in openssl/ssl.h. The events include stuff like TLS Alerts. 892 893By default, lws doesn't register for these callbacks. 894 895However if you set the info.ssl_info_event_mask to nonzero (ie, set some 896of the bits in it like `SSL_CB_ALERT` at vhost creation time, then 897connections to that vhost will call back using LWS_CALLBACK_SSL_INFO 898for the wsi, and the `in` parameter will be pointing to a struct of 899related args: 900 901``` 902struct lws_ssl_info { 903 int where; 904 int ret; 905}; 906``` 907 908The default callback handler in lws has a handler for LWS_CALLBACK_SSL_INFO 909which prints the related information, You can test it using the switch 910-S -s on `libwebsockets-test-server-v2.0`. 911 912Returning nonzero from the callback will close the wsi. 913 914@section smp SMP / Multithreaded service 915 916SMP support is integrated into LWS without any internal threading. It's 917very simple to use, libwebsockets-test-server-pthread shows how to do it, 918use -j n argument there to control the number of service threads up to 32. 919 920Two new members are added to the info struct 921 922 unsigned int count_threads; 923 unsigned int fd_limit_per_thread; 924 925leave them at the default 0 to get the normal singlethreaded service loop. 926 927Set count_threads to n to tell lws you will have n simultaneous service threads 928operating on the context. 929 930There is still a single listen socket on one port, no matter how many 931service threads. 932 933When a connection is made, it is accepted by the service thread with the least 934connections active to perform load balancing. 935 936The user code is responsible for spawning n threads running the service loop 937associated to a specific tsi (Thread Service Index, 0 .. n - 1). See 938the libwebsockets-test-server-pthread for how to do. 939 940If you leave fd_limit_per_thread at 0, then the process limit of fds is shared 941between the service threads; if you process was allowed 1024 fds overall then 942each thread is limited to 1024 / n. 943 944You can set fd_limit_per_thread to a nonzero number to control this manually, eg 945the overall supported fd limit is less than the process allowance. 946 947You can control the context basic data allocation for multithreading from Cmake 948using -DLWS_MAX_SMP=, if not given it's set to 1. The serv_buf allocation 949for the threads (currently 4096) is made at runtime only for active threads. 950 951Because lws will limit the requested number of actual threads supported 952according to LWS_MAX_SMP, there is an api lws_get_count_threads(context) to 953discover how many threads were actually allowed when the context was created. 954 955See the test-server-pthreads.c sample for how to use. 956 957@section smplocking SMP Locking Helpers 958 959Lws provide a set of pthread mutex helpers that reduce to no code or 960variable footprint in the case that LWS_MAX_SMP == 1. 961 962Define your user mutex like this 963 964``` 965 lws_pthread_mutex(name); 966``` 967 968If LWS_MAX_SMP > 1, this produces `pthread_mutex_t name;`. In the case 969LWS_MAX_SMP == 1, it produces nothing. 970 971Likewise these helpers for init, destroy, lock and unlock 972 973 974``` 975 void lws_pthread_mutex_init(pthread_mutex_t *lock) 976 void lws_pthread_mutex_destroy(pthread_mutex_t *lock) 977 void lws_pthread_mutex_lock(pthread_mutex_t *lock) 978 void lws_pthread_mutex_unlock(pthread_mutex_t *lock) 979``` 980 981resolve to nothing if LWS_MAX_SMP == 1, otherwise produce the equivalent 982pthread api. 983 984pthreads is required in lws only if LWS_MAX_SMP > 1. 985 986 987@section libevuv libev / libuv / libevent support 988 989You can select either or both 990 991 -DLWS_WITH_LIBEV=1 992 -DLWS_WITH_LIBUV=1 993 -DLWS_WITH_LIBEVENT=1 994 995at cmake configure-time. The user application may use one of the 996context init options flags 997 998 LWS_SERVER_OPTION_LIBEV 999 LWS_SERVER_OPTION_LIBUV 1000 LWS_SERVER_OPTION_LIBEVENT 1001 1002to indicate it will use one of the event libraries at runtime. 1003 1004libev and libevent headers conflict, they both define critical constants like 1005EV_READ to different values. Attempts to discuss clearing that up with both 1006libevent and libev did not get anywhere useful. Therefore CMakeLists.txt will 1007error out if you enable both LWS_WITH_LIBEV and LWS_WITH_LIBEVENT. 1008 1009In addition depending on libev / compiler version, building anything with libev 1010apis using gcc may blow strict alias warnings (which are elevated to errors in 1011lws). I did some googling at found these threads related to it, the issue goes 1012back at least to 2010 on and off 1013 1014https://github.com/redis/hiredis/issues/434 1015https://bugs.gentoo.org/show_bug.cgi?id=615532 1016http://lists.schmorp.de/pipermail/libev/2010q1/000916.html 1017http://lists.schmorp.de/pipermail/libev/2010q1/000920.html 1018http://lists.schmorp.de/pipermail/libev/2010q1/000923.html 1019 1020We worked around this problem by disabling -Werror on the parts of lws that 1021use libev. FWIW as of Dec 2019 using Fedora 31 libev 4.27.1 and its gcc 9.2.1 1022doesn't seem to trigger the problem even without the workaround. 1023 1024For these reasons and the response I got trying to raise these issues with 1025them, if you have a choice about event loop, I would gently encourage you 1026to avoid libev. Where lws uses an event loop itself, eg in lwsws, we use 1027libuv. 1028 1029@section extopts Extension option control from user code 1030 1031User code may set per-connection extension options now, using a new api 1032`lws_set_extension_option()`. 1033 1034This should be called from the ESTABLISHED callback like this 1035``` 1036 lws_set_extension_option(wsi, "permessage-deflate", 1037 "rx_buf_size", "12"); /* 1 << 12 */ 1038``` 1039 1040If the extension is not active (missing or not negotiated for the 1041connection, or extensions are disabled on the library) the call is 1042just returns -1. Otherwise the connection's extension has its 1043named option changed. 1044 1045The extension may decide to alter or disallow the change, in the 1046example above permessage-deflate restricts the size of his rx 1047output buffer also considering the protocol's rx_buf_size member. 1048 1049 1050@section httpsclient Client connections as HTTP[S] rather than WS[S] 1051 1052You may open a generic http client connection using the same 1053struct lws_client_connect_info used to create client ws[s] 1054connections. 1055 1056To stay in http[s], set the optional info member "method" to 1057point to the string "GET" instead of the default NULL. 1058 1059After the server headers are processed, when payload from the 1060server is available the callback LWS_CALLBACK_RECEIVE_CLIENT_HTTP 1061will be made. 1062 1063You can choose whether to process the data immediately, or 1064queue a callback when an outgoing socket is writeable to provide 1065flow control, and process the data in the writable callback. 1066 1067Either way you use the api `lws_http_client_read()` to access the 1068data, eg 1069 1070``` 1071 case LWS_CALLBACK_RECEIVE_CLIENT_HTTP: 1072 { 1073 char buffer[1024 + LWS_PRE]; 1074 char *px = buffer + LWS_PRE; 1075 int lenx = sizeof(buffer) - LWS_PRE; 1076 1077 lwsl_notice("LWS_CALLBACK_RECEIVE_CLIENT_HTTP\n"); 1078 1079 /* 1080 * Often you need to flow control this by something 1081 * else being writable. In that case call the api 1082 * to get a callback when writable here, and do the 1083 * pending client read in the writeable callback of 1084 * the output. 1085 */ 1086 if (lws_http_client_read(wsi, &px, &lenx) < 0) 1087 return -1; 1088 while (lenx--) 1089 putchar(*px++); 1090 } 1091 break; 1092``` 1093 1094Notice that if you will use SSL client connections on a vhost, you must 1095prepare the client SSL context for the vhost after creating the vhost, since 1096this is not normally done if the vhost was set up to listen / serve. Call 1097the api lws_init_vhost_client_ssl() to also allow client SSL on the vhost. 1098 1099@section clipipe Pipelining Client Requests to same host 1100 1101If you are opening more client requests to the same host and port, you 1102can give the flag LCCSCF_PIPELINE on `info.ssl_connection` to indicate 1103you wish to pipeline them. 1104 1105Without the flag, the client connections will occur concurrently using a 1106socket and tls wrapper if requested for each connection individually. 1107That is fast, but resource-intensive. 1108 1109With the flag, lws will queue subsequent client connections on the first 1110connection to the same host and port. When it has confirmed from the 1111first connection that pipelining / keep-alive is supported by the server, 1112it lets the queued client pipeline connections send their headers ahead 1113of time to create a pipeline of requests on the server side. 1114 1115In this way only one tcp connection and tls wrapper is required to transfer 1116all the transactions sequentially. It takes a little longer but it 1117can make a significant difference to resources on both sides. 1118 1119If lws learns from the first response header that keepalive is not possible, 1120then it marks itself with that information and detaches any queued clients 1121to make their own individual connections as a fallback. 1122 1123Lws can also intelligently combine multiple ongoing client connections to 1124the same host and port into a single http/2 connection with multiple 1125streams if the server supports it. 1126 1127Unlike http/1 pipelining, with http/2 the client connections all occur 1128simultaneously using h2 stream multiplexing inside the one tcp + tls 1129connection. 1130 1131You can turn off the h2 client support either by not building lws with 1132`-DLWS_WITH_HTTP2=1` or giving the `LCCSCF_NOT_H2` flag in the client 1133connection info struct `ssl_connection` member. 1134 1135@section vhosts Using lws vhosts 1136 1137If you set LWS_SERVER_OPTION_EXPLICIT_VHOSTS options flag when you create 1138your context, it won't create a default vhost using the info struct 1139members for compatibility. Instead you can call lws_create_vhost() 1140afterwards to attach one or more vhosts manually. 1141 1142``` 1143 LWS_VISIBLE struct lws_vhost * 1144 lws_create_vhost(struct lws_context *context, 1145 struct lws_context_creation_info *info); 1146``` 1147 1148lws_create_vhost() uses the same info struct as lws_create_context(), 1149it ignores members related to context and uses the ones meaningful 1150for vhost (marked with VH in libwebsockets.h). 1151 1152``` 1153 struct lws_context_creation_info { 1154 int port; /* VH */ 1155 const char *iface; /* VH */ 1156 const struct lws_protocols *protocols; /* VH */ 1157 const struct lws_extension *extensions; /* VH */ 1158 ... 1159``` 1160 1161When you attach the vhost, if the vhost's port already has a listen socket 1162then both vhosts share it and use SNI (is SSL in use) or the Host: header 1163from the client to select the right one. Or if no other vhost already 1164listening the a new listen socket is created. 1165 1166There are some new members but mainly it's stuff you used to set at 1167context creation time. 1168 1169 1170@section sni How lws matches hostname or SNI to a vhost 1171 1172LWS first strips any trailing :port number. 1173 1174Then it tries to find an exact name match for a vhost listening on the correct 1175port, ie, if SNI or the Host: header provided abc.com:1234, it will match on a 1176vhost named abc.com that is listening on port 1234. 1177 1178If there is no exact match, lws will consider wildcard matches, for example 1179if cats.abc.com:1234 is provided by the client by SNI or Host: header, it will 1180accept a vhost "abc.com" listening on port 1234. If there was a better, exact, 1181match, it will have been chosen in preference to this. 1182 1183Connections with SSL will still have the client go on to check the 1184certificate allows wildcards and error out if not. 1185 1186 1187 1188@section mounts Using lws mounts on a vhost 1189 1190The last argument to lws_create_vhost() lets you associate a linked 1191list of lws_http_mount structures with that vhost's URL 'namespace', in 1192a similar way that unix lets you mount filesystems into areas of your / 1193filesystem how you like and deal with the contents transparently. 1194 1195``` 1196 struct lws_http_mount { 1197 struct lws_http_mount *mount_next; 1198 const char *mountpoint; /* mountpoint in http pathspace, eg, "/" */ 1199 const char *origin; /* path to be mounted, eg, "/var/www/warmcat.com" */ 1200 const char *def; /* default target, eg, "index.html" */ 1201 1202 struct lws_protocol_vhost_options *cgienv; 1203 1204 int cgi_timeout; 1205 int cache_max_age; 1206 1207 unsigned int cache_reusable:1; 1208 unsigned int cache_revalidate:1; 1209 unsigned int cache_intermediaries:1; 1210 1211 unsigned char origin_protocol; 1212 unsigned char mountpoint_len; 1213 }; 1214``` 1215 1216The last mount structure should have a NULL mount_next, otherwise it should 1217point to the 'next' mount structure in your list. 1218 1219Both the mount structures and the strings must persist until the context is 1220destroyed, since they are not copied but used in place. 1221 1222`.origin_protocol` should be one of 1223 1224``` 1225 enum { 1226 LWSMPRO_HTTP, 1227 LWSMPRO_HTTPS, 1228 LWSMPRO_FILE, 1229 LWSMPRO_CGI, 1230 LWSMPRO_REDIR_HTTP, 1231 LWSMPRO_REDIR_HTTPS, 1232 LWSMPRO_CALLBACK, 1233 }; 1234``` 1235 1236 - LWSMPRO_FILE is used for mapping url namespace to a filesystem directory and 1237serve it automatically. 1238 1239 - LWSMPRO_CGI associates the url namespace with the given CGI executable, which 1240runs when the URL is accessed and the output provided to the client. 1241 1242 - LWSMPRO_REDIR_HTTP and LWSMPRO_REDIR_HTTPS auto-redirect clients to the given 1243origin URL. 1244 1245 - LWSMPRO_CALLBACK causes the http connection to attach to the callback 1246associated with the named protocol (which may be a plugin). 1247 1248 1249@section mountcallback Operation of LWSMPRO_CALLBACK mounts 1250 1251The feature provided by CALLBACK type mounts is binding a part of the URL 1252namespace to a named protocol callback handler. 1253 1254This allows protocol plugins to handle areas of the URL namespace. For example 1255in test-server-v2.0.c, the URL area "/formtest" is associated with the plugin 1256providing "protocol-post-demo" like this 1257 1258``` 1259 static const struct lws_http_mount mount_post = { 1260 NULL, /* linked-list pointer to next*/ 1261 "/formtest", /* mountpoint in URL namespace on this vhost */ 1262 "protocol-post-demo", /* handler */ 1263 NULL, /* default filename if none given */ 1264 NULL, 1265 0, 1266 0, 1267 0, 1268 0, 1269 0, 1270 LWSMPRO_CALLBACK, /* origin points to a callback */ 1271 9, /* strlen("/formtest"), ie length of the mountpoint */ 1272 }; 1273``` 1274 1275Client access to /formtest[anything] will be passed to the callback registered 1276with the named protocol, which in this case is provided by a protocol plugin. 1277 1278Access by all methods, eg, GET and POST are handled by the callback. 1279 1280protocol-post-demo deals with accepting and responding to the html form that 1281is in the test server HTML. 1282 1283When a connection accesses a URL related to a CALLBACK type mount, the 1284connection protocol is changed until the next access on the connection to a 1285URL outside the same CALLBACK mount area. User space on the connection is 1286arranged to be the size of the new protocol user space allocation as given in 1287the protocol struct. 1288 1289This allocation is only deleted / replaced when the connection accesses a 1290URL region with a different protocol (or the default protocols[0] if no 1291CALLBACK area matches it). 1292 1293This "binding connection to a protocol" lifecycle in managed by 1294`LWS_CALLBACK_HTTP_BIND_PROTOCOL` and `LWS_CALLBACK_HTTP_DROP_PROTOCOL`. 1295Because of HTTP/1.1 connection pipelining, one connection may perform 1296many transactions, each of which may map to different URLs and need 1297binding to different protocols. So these messages are used to 1298create the binding of the wsi to your protocol including any 1299allocations, and to destroy the binding, at which point you should 1300destroy any related allocations. 1301 1302@section BINDTODEV SO_BIND_TO_DEVICE 1303 1304The .bind_iface flag in the context / vhost creation struct lets you 1305declare that you want all traffic for listen and transport on that 1306vhost to be strictly bound to the network interface named in .iface. 1307 1308This Linux-only feature requires SO_BIND_TO_DEVICE, which in turn 1309requires CAP_NET_RAW capability... root has this capability. 1310 1311However this feature needs to apply the binding also to accepted 1312sockets during normal operation, which implies the server must run 1313the whole time as root. 1314 1315You can avoid this by using the Linux capabilities feature to have 1316the unprivileged user inherit just the CAP_NET_RAW capability. 1317 1318You can confirm this with the test server 1319 1320 1321``` 1322 $ sudo /usr/local/bin/libwebsockets-test-server -u agreen -i eno1 -k 1323``` 1324 1325The part that ensures the capability is inherited by the unprivileged 1326user is 1327 1328``` 1329#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) 1330 info.caps[0] = CAP_NET_RAW; 1331 info.count_caps = 1; 1332#endif 1333``` 1334 1335 1336@section dim Dimming webpage when connection lost 1337 1338The lws test plugins' html provides useful feedback on the webpage about if it 1339is still connected to the server, by greying out the page if not. You can 1340also add this to your own html easily 1341 1342 - include lws-common.js from your HEAD section 1343 1344 \<script src="/lws-common.js">\</script> 1345 1346 - dim the page during initialization, in a script section on your page 1347 1348 lws_gray_out(true,{'zindex':'499'}); 1349 1350 - in your ws onOpen(), remove the dimming 1351 1352 lws_gray_out(false); 1353 1354 - in your ws onClose(), reapply the dimming 1355 1356 lws_gray_out(true,{'zindex':'499'}); 1357 1358@section errstyle Styling http error pages 1359 1360In the code, http errors should be handled by `lws_return_http_status()`. 1361 1362There are basically two ways... the vhost can be told to redirect to an "error 1363page" URL in response to specifically a 404... this is controlled by the 1364context / vhost info struct (`struct lws_context_creation_info`) member 1365`.error_document_404`... if non-null the client is redirected to this string. 1366 1367If it wasn't redirected, then the response code html is synthesized containing 1368the user-selected text message and attempts to pull in `/error.css` for styling. 1369 1370If this file exists, it can be used to style the error page. See 1371https://libwebsockets.org/git/badrepo for an example of what can be done ( 1372and https://libwebsockets.org/error.css for the corresponding css). 1373 1374