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