win32: enable 64-bit file lengths
[platform/upstream/libwebsockets.git] / README.lwsws.md
index a8722b0..12ad81e 100644 (file)
@@ -1,26 +1,32 @@
 Notes about lwsws
 =================
 
-Libwebsockets Web Server
-------------------------
+@section lwsws Libwebsockets Web Server
 
 lwsws is an implementation of a very lightweight, ws-capable generic web
 server, which uses libwebsockets to implement everything underneath.
 
-Build
------
+If you are basically implementing a standalone server with lws, you can avoid
+reinventing the wheel and use a debugged server including lws.
+
+
+@section lwswsb Build
 
 Just enable -DLWS_WITH_LWSWS=1 at cmake-time.
 
 It enables libuv and plugin support automatically.
 
+NOTICE on Ubuntu, the default libuv package is called "libuv-0.10".  This is ancient.
+
+You should replace this with libuv1 and libuv1-dev before proceeding.
+
+@section lwswsc Lwsws Configuration
 
-Configuration
--------------
+lwsws uses JSON config files, they're pure JSON except:
 
-lwsws uses JSON config files, they're pure JSON but # may be used to turn the rest of the line into a comment.
+ - '#' may be used to turn the rest of the line into a comment.
 
-There's also a single substitution, if a string contains "_lws_ddir_", then that is
+ - There's also a single substitution, if a string contains "_lws_ddir_", then that is
 replaced with the LWS install data directory path, eg, "/usr/share" or whatever was
 set when LWS was built + installed.  That lets you refer to installed paths without
 having to change the config if your install path was different.
@@ -39,6 +45,7 @@ There is a single file intended for global settings
           "gid": "48",  # apache user
           "count-threads": "1",
           "server-string": "myserver v1", # returned in http headers
+          "ws-pingpong-secs": "200", # confirm idle established ws connections this often
           "init-ssl": "yes"
         }
        }
@@ -71,8 +78,22 @@ on port 7681, non-SSL is provided.  To set it up
        # cp ./lwsws/etc-lwsws-conf.d-localhost-EXAMPLE /etc/lwsws/conf.d/test-server
        # sudo lwsws
 ```
-Vhosts
-------
+
+@section lwsogo Other Global Options
+
+ - `reject-service-keywords` allows you to return an HTTP error code and message of your choice
+if a keyword is found in the user agent
+
+```
+   "reject-service-keywords": [{
+        "scumbot": "404 Not Found"
+   }]
+```
+
+ - `timeout-secs` lets you set the global timeout for various network-related
+ operations in lws, in seconds.  It defaults to 5.
+@section lwswsv Lwsws Vhosts
 
 One server can run many vhosts, where SSL is in use SNI is used to match
 the connection to a vhost and its vhost-specific SSL keys during SSL
@@ -132,8 +153,7 @@ Listing multiple vhosts looks something like this
 That sets up three vhosts all called "localhost" on ports 443 and 7681 with SSL, and port 80 without SSL but with a forced redirect to https://localhost
 
 
-Vhost name and port
--------------------
+@section lwswsvn Lwsws Vhost name and port sharing
 
 The vhost name field is used to match on incoming SNI or Host: header, so it
 must always be the host name used to reach the vhost externally.
@@ -147,8 +167,7 @@ negotiation time (via SNI) or if no SSL, then after the Host: header from
 the client has been parsed.
 
 
-Protocols
----------
+@section lwswspr Lwsws Protocols
 
 Vhosts by default have available the union of any initial protocols from context creation time, and
 any protocols exposed by plugins.
@@ -178,8 +197,7 @@ by the client, you can use "default": "1"
 ```
 
 
-Other vhost options
--------------------
+@section lwswsovo Lwsws Other vhost options
 
  - If the three options `host-ssl-cert`, `host-ssl-ca` and `host-ssl-key` are given, then the vhost supports SSL.
 
@@ -223,8 +241,23 @@ Other vhost options
  - "`ssl-option-clear'": "<decimal>"   Clears the SSL option flag value for the vhost.
  It may be used multiple times and OR's the flags together.
 
-Mounts
-------
+ - "`headers':: [{ "header1": "h1value", "header2": "h2value" }] 
+
+allows you to set arbitrary headers on every file served by the vhost
+
+recommended vhost headers for good client security are
+
+```
+                   "headers": [{
+                        "Content-Security-Policy": "script-src 'self'",
+                        "X-Content-Type-Options": "nosniff",
+                        "X-XSS-Protection": "1; mode=block",
+                        "X-Frame-Options": "SAMEORIGIN"
+                 }]
+
+```
+
+@section lwswsm Lwsws Mounts
 
 Where mounts are given in the vhost definition, then directory contents may
 be auto-served if it matches the mountpoint.
@@ -261,8 +294,7 @@ Mount protocols are used to control what kind of translation happens
 
 
 
-Other mount options
--------------------
+@section lwswsomo Lwsws Other mount options
 
 1) Some protocols may want "per-mount options" in name:value format.  You can
 provide them using "pmo"
@@ -329,8 +361,49 @@ options are given, the content is marked uncacheable.
                 }
 ```
 
-Plugins
--------
+Normally a file suffix MUST match one of the canned mimetypes or one of the extra
+mimetypes, or the file is not served.  This adds a little bit of security because
+even if there is a bug somewhere and the mount dirs are circumvented, lws will not
+serve, eg, /etc/passwd.
+
+If you provide an extra mimetype entry
+
+                       "*": ""
+
+Then any file is served, if the mimetype was not known then it is served without a
+Content-Type: header.
+
+7) A mount can be protected by HTTP Basic Auth.  This only makes sense when using
+https, since otherwise the password can be sniffed.
+
+You can add a `basic-auth` entry on a mount like this
+
+```
+{
+        "mountpoint": "/basic-auth",
+        "origin": "file://_lws_ddir_/libwebsockets-test-server/private",
+        "basic-auth": "/var/www/balogins-private"
+}
+```
+
+Before serving anything, lws will signal to the browser that a username / password
+combination is required, and it will pop up a dialog.  When the user has filled it
+in, lwsws checks the user:password string against the text file named in the `basic-auth`
+entry.
+
+The file should contain user:pass one per line
+
+```
+testuser:testpass
+myuser:hispass
+```
+
+The file should be readable by lwsws, and for a little bit of extra security not
+have a file suffix, so lws would reject to serve it even if it could find it on
+a mount.
+
+
+@section lwswspl Lwsws Plugins
 
 Protcols and extensions may also be provided from "plugins", these are
 lightweight dynamic libraries.  They are scanned for at init time, and
@@ -357,8 +430,7 @@ To help that happen conveniently, there are some new apis
 dumb increment, mirror and status protocol plugins are provided as examples.
 
 
-Additional plugin search paths
-------------------------------
+@section lwswsplaplp Additional plugin search paths
 
 Packages that have their own lws plugins can install them in their own
 preferred dir and ask lwsws to scan there by using a config fragment
@@ -371,8 +443,7 @@ like this, in its own conf.d/ file managed by the other package
        }
 ```
 
-lws-server-status plugin
-------------------------
+@section lwswsssp lws-server-status plugin
 
 One provided protocol can be used to monitor the server status.
 
@@ -383,7 +454,7 @@ Enable the protocol like this on a vhost's ws-protocols section
                 "update-ms": "5000"
               }
 ```
-"update-ms" is used to control how often updated JSON is sent on a ws link.
+`"update-ms"` is used to control how often updated JSON is sent on a ws link.
 
 And map the provided HTML into the vhost in the mounts section
 ```
@@ -394,31 +465,84 @@ And map the provided HTML into the vhost in the mounts section
               }
 ```
 You might choose to put it on its own vhost which has "interface": "lo", so it's not
-externally visible.
+externally visible, or use the Basic Auth support to require authentication to
+access it.
+
+`"hide-vhosts": "{0 | 1}"` lets you control if information about your vhosts is included.
+Since this includes mounts, you might not want to leak that information, mount names,
+etc.
+
+`"filespath":"{path}"` lets you give a server filepath which is read and sent to the browser
+on each refresh.  For example, you can provide server temperature information on most
+Linux systems by giving an appropriate path down /sys.
+
+This may be given multiple times.
+
+
+@section lwswsreload Lwsws Configuration Reload
+
+You may send lwsws a `HUP` signal, by, eg
+
+```
+$ sudo killall -HUP lwsws
+```
+
+This causes lwsws to "deprecate" the existing lwsws process, and remove and close all of
+its listen sockets, but otherwise allowing it to continue to run, until all
+of its open connections close.
+
+When a deprecated lwsws process has no open connections left, it is destroyed
+automatically.
+
+After sending the SIGHUP to the main lwsws process, a new lwsws process, which can
+pick up the newly-available listen sockets, and use the current configuration
+files, is automatically started.
+
+The new configuration may differ from the original one in arbitrary ways, the new
+context is created from scratch each time without reference to the original one.
+
+Notes
+
+1) Protocols that provide a "shared world" like mirror will have as many "worlds"
+as there are lwsws processes still active.  People connected to a deprecated lwsws
+process remain connected to the existing peers.
 
+But any new connections will apply to the new lwsws process, which does not share
+per-vhost "shared world" data with the deprecated process.  That means no new
+connections on the deprecated context, ie a "shrinking world" for those guys, and a
+"growing world" for people who connect after the SIGHUP.
 
-Integration with Systemd
-------------------------
+2) The new lwsws process owes nothing to the previous one.  It starts with fresh
+plugins, fresh configuration, fresh root privileges if that how you start it.
+
+The plugins may have been updated in arbitrary ways including struct size changes
+etc, and lwsws or lws may also have been updated arbitrarily.
+
+3) A root parent process is left up that is not able to do anything except
+respond to SIGHUP or SIGTERM.  Actual serving and network listening etc happens
+in child processes which use the privileges set in the lwsws config files.
+
+@section lwswssysd Lwsws Integration with Systemd
 
 lwsws needs a service file like this as `/usr/lib/systemd/system/lwsws.service`
 ```
-       [Unit]
-       Description=Libwebsockets Web Server
-       After=syslog.target
-       
-       [Service]
-       ExecStart=/usr/local/bin/lwsws
-       StandardError=null
-       
-       [Install]
-       WantedBy=multi-user.target
+[Unit]
+Description=Libwebsockets Web Server
+After=syslog.target
+
+[Service]
+ExecStart=/usr/local/bin/lwsws 
+ExecReload=/usr/bin/killall -s SIGHUP lwsws ; sleep 1 ; /usr/local/bin/lwsws
+StandardError=null
+
+[Install]
+WantedBy=multi-user.target
 ```
 
 You can find this prepared in `./lwsws/usr-lib-systemd-system-lwsws.service`
 
 
-Integration with logrotate
---------------------------
+@section lwswslr Lwsws Integration with logrotate
 
 For correct operation with logrotate, `/etc/logrotate.d/lwsws` (if that's
 where we're putting the logs) should contain