• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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