lwsws conf mount extra mimetypes
[platform/upstream/libwebsockets.git] / README.lwsws.md
1 Libwebsockets Web Server
2 ------------------------
3
4 lwsws is an implementation of a very lightweight, ws-capable generic web
5 server, which uses libwebsockets to implement everything underneath.
6
7 Build
8 -----
9
10 Just enable -DLWS_WITH_LWSWS=1 at cmake-time.
11
12 It enables libuv and plugin support automatically.
13
14
15 Configuration
16 -------------
17
18 lwsws uses JSON config files, they're pure JSON but # may be used to turn the rest of the line into a comment.
19
20 There is a single file intended for global settings
21
22 /etc/lwsws/conf
23
24 ```
25 # these are the server global settings
26 # stuff related to vhosts should go in one
27 # file per vhost in ../conf.d/
28
29 {
30   "global": {
31    "uid": "48",  # apache user
32    "gid": "48",  # apache user
33    "count-threads": "1",
34    "server-string": "myserver v1", # returned in http headers
35    "init-ssl": "yes"
36  }
37 }
38 ```
39
40 and a config directory intended to take one file per vhost
41
42 /etc/lwsws/conf.d/warmcat.com
43
44 ```
45 {
46         "vhosts": [{
47                 "name": "warmcat.com",
48                 "port": "443",
49                 "interface": "eth0",  # optional
50                 "host-ssl-key": "/etc/pki/tls/private/warmcat.com.key",  # if given enable ssl
51                 "host-ssl-cert": "/etc/pki/tls/certs/warmcat.com.crt",
52                 "host-ssl-ca": "/etc/pki/tls/certs/warmcat.com.cer",
53                 "mounts": [{  # autoserve
54                         "mountpoint": "/",
55                         "origin": "file:///var/www/warmcat.com",
56                         "default": "index.html"
57                 }]
58         }]
59 }
60 ```
61
62 Vhosts
63 ------
64
65 One server can run many vhosts, where SSL is in use SNI is used to match
66 the connection to a vhost and its vhost-specific SSL keys during SSL
67 negotiation.
68
69 Listing multiple vhosts looks something like this
70
71 ```
72 {
73  "vhosts": [ {
74      "name": "localhost",
75      "port": "443",
76      "host-ssl-key":  "/etc/pki/tls/private/libwebsockets.org.key",
77      "host-ssl-cert": "/etc/pki/tls/certs/libwebsockets.org.crt",
78      "host-ssl-ca":   "/etc/pki/tls/certs/libwebsockets.org.cer",
79      "mounts": [{
80        "mountpoint": "/",
81        "origin": "file:///var/www/libwebsockets.org",
82        "default": "index.html"
83        }, {
84         "mountpoint": "/testserver",
85         "origin": "file:///usr/local/share/libwebsockets-test-server",
86         "default": "test.html"
87        }],
88      # which protocols are enabled for this vhost, and optional
89      # vhost-specific config options for the protocol
90      #
91      "ws-protocols": [{
92        "warmcat,timezoom": {
93          "status": "ok"
94        }
95      }]
96     },
97     {
98     "name": "localhost",
99     "port": "7681",
100      "host-ssl-key":  "/etc/pki/tls/private/libwebsockets.org.key",
101      "host-ssl-cert": "/etc/pki/tls/certs/libwebsockets.org.crt",
102      "host-ssl-ca":   "/etc/pki/tls/certs/libwebsockets.org.cer",
103      "mounts": [{
104        "mountpoint": "/",
105        "origin": ">https://localhost"
106      }]
107    },
108     {
109     "name": "localhost",
110     "port": "80",
111      "mounts": [{
112        "mountpoint": "/",
113        "origin": ">https://localhost"
114      }]
115    }
116
117   ]
118 }
119 ```
120
121 That sets up three vhosts all called "localhost" on ports 443 and 7681 with SSL, and port 80 without SSL but with a forced redirect to https://localhost
122
123
124 Vhost name and port
125 -------------------
126
127 The vhost name field is used to match on incoming SNI or Host: header, so it
128 must always be the host name used to reach the vhost externally.
129
130  - Vhosts may have the same name and different ports, these will each create a
131 listening socket on the appropriate port.
132
133  - Vhosts may also have the same port and different name: these will be treated as
134 true vhosts on one listening socket and the active vhost decided at SSL
135 negotiation time (via SNI) or if no SSL, then after the Host: header from
136 the client has been parsed.
137
138
139 Protocols
140 ---------
141
142 Vhosts by default have available the union of any initial protocols from context creation time, and
143 any protocols exposed by plugins.
144
145 Vhosts can select which plugins they want to offer and give them per-vhost settings using this syntax
146
147 ```     
148      "ws-protocols": [{
149        "warmcat-timezoom": {
150          "status": "ok"
151        }
152      }]
153
154 ```
155
156 The "x":"y" parameters like "status":"ok" are made available to the protocol during its per-vhost
157 LWS_CALLBACK_PROTOCOL_INIT (@in is a pointer to a linked list of struct lws_protocol_vhost_options
158 containing the name and value pointers).
159
160 To indicate that a protocol should be used when no Protocol: header is sent
161 by the client, you can use "default": "1"
162
163 ```     
164      "ws-protocols": [{
165        "warmcat-timezoom": {
166          "status": "ok",
167          "default": "1"
168        }
169      }]
170
171 ```
172
173
174 Other vhost options
175 -------------------
176
177  - If the three options `host-ssl-cert`, `host-ssl-ca` and `host-ssl-key` are given, then the vhost supports SSL.
178
179  Each vhost may have its own certs, SNI is used during the initial connection negotiation to figure out which certs to use by the server name it's asking for from the request DNS name.
180
181  - `keeplive-timeout` (in secs) defaults to 60 for lwsws, it may be set as a vhost option
182
183  - `interface` lets you specify which network interface to listen on, if not given listens on all
184
185  - "`unix-socket`": "1" causes the unix socket specified in the interface option to be used instead of an INET socket
186
187  - "`sts`": "1" causes lwsws to send a Strict Transport Security header with responses that informs the client he should never accept to connect to this address using http.  This is needed to get the A+ security rating from SSL Labs for your server.
188
189  - "`access-log`": "filepath"   sets where apache-compatible access logs will be written
190
191  - `"enable-client-ssl"`: `"1"` enables the vhost's client SSL context, you will need this if you plan to create client conections on the vhost that will use SSL.  You don't need it if you only want http / ws client connections.
192
193  - "`ciphers`": "<cipher list>"   sets the allowed list of ciphers and key exchange protocols for the vhost.  The default list is restricted to only those providing PFS (Perfect Forward Secrecy) on the author's Fedora system.
194  
195  If you need to allow weaker ciphers,you can provide an alternative list here per-vhost.
196  
197  - "`ecdh-curve`": "<curve name>"   The default ecdh curve is "prime256v1", but you can override it here, per-vhost
198
199
200 Mounts
201 ------
202
203 Where mounts are given in the vhost definition, then directory contents may
204 be auto-served if it matches the mountpoint.
205
206 Mount protocols are used to control what kind of translation happens
207
208  - file://  serve the uri using the remainder of the url past the mountpoint based on the origin directory.
209
210  Eg, with this mountpoint
211
212 ```
213        {
214         "mountpoint": "/",
215         "origin": "file:///var/www/mysite.com",
216         "default": "/"
217        }
218 ```
219
220  The uri /file.jpg would serve /var/www/mysite.com/file.jpg, since / matched.
221
222  - ^http:// or ^https://  these cause any url matching the mountpoint to issue a redirect to the origin url
223
224  - cgi://   this causes any matching url to be given to the named cgi, eg
225
226 ```
227        {
228         "mountpoint": "/git",
229         "origin": "cgi:///var/www/cgi-bin/cgit",
230         "default": "/"
231        }, {
232         "mountpoint": "/cgit-data",
233         "origin": "file:///usr/share/cgit",
234         "default": "/"
235        },
236 ```
237
238  would cause the url /git/myrepo to pass "myrepo" to the cgi /var/www/cgi-bin/cgit and send the results to the client.
239
240 Note: currently only a fixed set of mimetypes are supported.
241
242
243 Other mount options
244 -------------------
245
246 1) When using a cgi:// protcol origin at a mountpoint, you may also give cgi environment variables specific to the mountpoint like this
247
248 ```
249        {
250         "mountpoint": "/git",
251         "origin": "cgi:///var/www/cgi-bin/cgit",
252         "default": "/",
253         "cgi-env": [{
254                 "CGIT_CONFIG": "/etc/cgitrc/libwebsockets.org"
255         }]
256        }
257 ```
258
259  This allows you to customize one cgi depending on the mountpoint (and / or vhost).
260
261 2) It's also possible to set the cgi timeout (in secs) per cgi:// mount, like this
262
263 ```
264         "cgi-timeout": "30"
265 ```
266
267 3) `callback://` protocol may be used when defining a mount to associate a
268 named protocol callback with the URL namespace area.  For example
269
270 ```
271        {
272         "mountpoint": "/formtest",
273         "origin": "callback://protocol-post-demo"
274        }
275 ```
276
277 All handling of client access to /formtest[anything] will be passed to the
278 callback registered to the protocol "protocol-post-demo".
279
280 This is useful for handling POST http body content or general non-cgi http
281 payload generation inside a plugin.
282
283 See the related notes in README.coding.md
284
285 4) Cache policy of the files in the mount can also be set.  If no
286 options are given, the content is marked uncacheable.
287
288        {
289         "mountpoint": "/",
290         "origin": "file:///var/www/mysite.com",
291         "cache-max-age": "60",      # seconds
292         "cache-reuse": "1",         # allow reuse at client at all
293         "cache-revalidate": "1",    # check it with server each time
294         "cache-intermediaries": "1" # allow intermediary caches to hold
295        }
296
297
298 4) You can also define a list of additional mimetypes per-mount
299
300         "extra-mimetypes": {
301                  ".zip": "application/zip",
302                  ".doc": "text/evil"
303          }
304
305
306 Plugins
307 -------
308
309 Protcols and extensions may also be provided from "plugins", these are
310 lightweight dynamic libraries.  They are scanned for at init time, and
311 any protocols and extensions found are added to the list given at context
312 creation time.
313
314 Protocols receive init (LWS_CALLBACK_PROTOCOL_INIT) and destruction
315 (LWS_CALLBACK_PROTOCOL_DESTROY) callbacks per-vhost, and there are arrangements
316 they can make per-vhost allocations and get hold of the correct pointer from
317 the wsi at the callback.
318
319 This allows a protocol to choose to strictly segregate data on a per-vhost
320 basis, and also allows the plugin to handle its own initialization and
321 context storage.
322
323 To help that happen conveniently, there are some new apis
324
325  - lws_vhost_get(wsi)
326  - lws_protocol_get(wsi)
327  - lws_callback_on_writable_all_protocol_vhost(vhost, protocol)
328  - lws_protocol_vh_priv_zalloc(vhost, protocol, size)
329  - lws_protocol_vh_priv_get(vhost, protocol)
330  
331 dumb increment, mirror and status protocol plugins are provided as examples.
332
333
334 Additional plugin search paths
335 ------------------------------
336
337 Packages that have their own lws plugins can install them in their own
338 preferred dir and ask lwsws to scan there by using a config fragment
339 like this, in its own conf.d/ file managed by the other package
340
341 {
342   "global": {
343    "plugin-dir": "/usr/local/share/coherent-timeline/plugins"
344   }
345 }
346
347
348 lws-server-status plugin
349 ------------------------
350
351 One provided protocol can be used to monitor the server status.
352
353 Enable the protocol like this on a vhost's ws-protocols section
354
355        "lws-server-status": {
356          "status": "ok",
357          "update-ms": "5000"
358        }
359
360 "update-ms" is used to control how often updated JSON is sent on a ws link.
361
362 And map the provided HTML into the vhost in the mounts section
363
364        {
365         "mountpoint": "/server-status",
366         "origin": "file:///usr/local/share/libwebsockets-test-server/server-status",
367         "default": "server-status.html"
368        }
369
370 You might choose to put it on its own vhost which has "interface": "lo", so it's not
371 externally visible.
372
373
374 Integration with Systemd
375 ------------------------
376
377 lwsws needs a service file like this as `/usr/lib/systemd/system/lwsws.service`
378
379 ```
380 [Unit]
381 Description=Libwebsockets Web Server
382 After=syslog.target
383
384 [Service]
385 ExecStart=/usr/local/bin/lwsws
386 StandardError=null
387
388 [Install]
389 WantedBy=multi-user.target
390
391 ```
392
393 You can find this prepared in `./lwsws/usr-lib-systemd-system-lwsws.service`
394
395
396 Integration with logrotate
397 --------------------------
398
399 For correct operation with logrotate, `/etc/logrotate.d/lwsws` (if that's
400 where we're putting the logs) should contain
401
402 ```
403 /var/log/lwsws/*log {
404     copytruncate
405     missingok
406     notifempty
407     delaycompress
408 }
409 ```
410
411 You can find this prepared in `/lwsws/etc-logrotate.d-lwsws`
412
413 Prepare the log directory like this
414
415 ```
416 sudo mkdir /var/log/lwsws
417 sudo chmod 700 /var/log/lwsws
418 ```