ah: require parsing complete before detach
[platform/upstream/libwebsockets.git] / README.coding.md
index 342aa3d..c1c4a3f 100644 (file)
@@ -120,6 +120,34 @@ the send pipe on the connection is choked but no ack will ever come, so the
 dead connection will never become writeable.  To cover that, you can use TCP
 keepalives (see later in this document) or pings.
 
+@section gzip Serving from inside a zip file
+
+Lws now supports serving gzipped files from inside a zip container.  Thanks to
+Per Bothner for contributing the code.
+
+This has the advtantage that if the client can accept GZIP encoding, lws can
+simply send the gzip-compressed file from inside the zip file with no further
+processing, saving time and bandwidth.
+
+In the case the client can't understand gzip compression, lws automatically
+decompressed the file and sends it normally.
+
+Clients with limited storage and RAM will find this useful; the memory needed
+for the inflate case is constrained so that only one input buffer at a time
+is ever in memory.
+
+To use this feature, ensure LWS_WITH_ZIP_FOPS is enabled at CMake (it is by
+default).
+
+`libwebsockets-test-server-v2.0` includes a mount using this technology
+already, run that test server and navigate to http://localhost:7681/ziptest/candide.html
+
+This will serve the book Candide in html, together with two jpgs, all from
+inside a .zip file in /usr/[local/]share-libwebsockets-test-server/candide.zip
+
+Usage is otherwise automatic, if you arrange a mount that points to the zipfile,
+eg, "/ziptest" -> "mypath/test.zip", then URLs like `/ziptest/index.html` will be
+servied from `index.html` inside `mypath/test.zip`
 
 @section frags Fragmented messages
 
@@ -347,30 +375,51 @@ and then can use helpers to also leverage these platform-independent
 file handling apis
 
 ```
-       static inline lws_fop_fd_t
+       lws_fop_fd_t
        `lws_plat_file_open`(struct lws_plat_file_ops *fops, const char *filename,
-                          lws_filepos_t *filelen, lws_fop_flags_t *flags)
-       static inline int
+                          lws_fop_flags_t *flags)
+       int
        `lws_plat_file_close`(lws_fop_fd_t fop_fd)
 
-       static inline unsigned long
+       unsigned long
        `lws_plat_file_seek_cur`(lws_fop_fd_t fop_fd, lws_fileofs_t offset)
 
-       static inline int
+       int
        `lws_plat_file_read`(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
                   uint8_t *buf, lws_filepos_t len)
 
-       static inline int
+       int
        `lws_plat_file_write`(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
                   uint8_t *buf, lws_filepos_t len )
 ```
 
+Generic helpers are provided which provide access to generic fops information or
+call through to the above fops
+
+```
+lws_filepos_t
+lws_vfs_tell(lws_fop_fd_t fop_fd);
+
+lws_filepos_t
+lws_vfs_get_length(lws_fop_fd_t fop_fd);
+
+uint32_t
+lws_vfs_get_mod_time(lws_fop_fd_t fop_fd);
+
+lws_fileofs_t
+lws_vfs_file_seek_set(lws_fop_fd_t fop_fd, lws_fileofs_t offset);
+
+lws_fileofs_t
+lws_vfs_file_seek_end(lws_fop_fd_t fop_fd, lws_fileofs_t offset);
+```
+
+
 The user code can also override or subclass the file operations, to either
 wrap or replace them.  An example is shown in test server.
 
 ### Changes from v2.1 and before fops
 
-There are three changes:
+There are several changes:
 
 1) 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.
 
@@ -378,6 +427,135 @@ There are three changes:
 
 3) Everything is wrapped in typedefs.  See lws-plat-unix.c for examples of how to implement.
 
+4) Position in the file, File Length, and a copy of Flags left after open are now generically held in the fop_fd.
+VFS implementation must set and manage this generic information now.  See the implementations in lws-plat-unix.c for
+examples.
+
+5) The file length is no longer set at a pointer provided by the open() fop.  The api `lws_vfs_get_length()` is provided to
+get the file length after open.
+
+6) If your file namespace is virtual, ie, is not reachable by platform fops directly, you must set LWS_FOP_FLAG_VIRTUAL
+on the flags during open.
+
+7) There is an optional `mod_time` uint32_t member in the generic fop_fd.  If you are able to set it during open, you
+should indicate it by setting `LWS_FOP_FLAG_MOD_TIME_VALID` on the flags.
+
+@section rawfd RAW file descriptor polling
+
+LWS allows you to include generic platform file descriptors in the lws service / poll / event loop.
+
+Open your fd normally and then
+
+```
+       lws_sock_file_fd_type u;
+
+       u.filefd = your_open_file_fd;
+
+       if (!lws_adopt_descriptor_vhost(vhost, 0, u,
+                                       "protocol-name-to-bind-to",
+                                       optional_wsi_parent_or_NULL)) {
+               // failed
+       }
+
+       // OK
+```
+
+A wsi is created for the file fd that acts like other wsi, you will get these
+callbacks on the named protocol
+
+```
+       LWS_CALLBACK_RAW_ADOPT_FILE
+       LWS_CALLBACK_RAW_RX_FILE
+       LWS_CALLBACK_RAW_WRITEABLE_FILE
+       LWS_CALLBACK_RAW_CLOSE_FILE
+```
+
+starting with LWS_CALLBACK_RAW_ADOPT_FILE.
+
+`protocol-lws-raw-test` plugin provides a method for testing this with
+`libwebsockets-test-server-v2.0`:
+
+The plugin creates a FIFO on your system called "/tmp/lws-test-raw"
+
+You can feed it data through the FIFO like this
+
+```
+  $ sudo sh -c "echo hello > /tmp/lws-test-raw"
+```
+
+This plugin simply prints the data.  But it does it through the lws event
+loop / service poll.
+
+@section rawsrvsocket RAW server socket descriptor polling
+
+You can also enable your vhost to accept RAW socket connections, in addition to
+HTTP[s] and WS[s].  If the first bytes written on the connection are not a
+valid HTTP method, then the connection switches to RAW mode.
+
+This is disabled by default, you enable it by setting the `.options` flag
+LWS_SERVER_OPTION_FALLBACK_TO_RAW when creating the vhost.
+
+RAW mode socket connections receive the following callbacks
+
+```
+       LWS_CALLBACK_RAW_ADOPT
+       LWS_CALLBACK_RAW_RX
+       LWS_CALLBACK_RAW_WRITEABLE
+       LWS_CALLBACK_RAW_CLOSE
+```
+
+You can control which protocol on your vhost handles these RAW mode
+incoming connections by marking the selected protocol with a pvo `raw`, eg
+
+```
+        "protocol-lws-raw-test": {
+                 "status": "ok",
+                 "raw": "1"
+        },
+```
+
+The "raw" pvo marks this protocol as being used for RAW connections.
+
+`protocol-lws-raw-test` plugin provides a method for testing this with
+`libwebsockets-test-server-v2.0`:
+
+Run libwebsockets-test-server-v2.0 and connect to it by telnet, eg
+
+```
+    $ telnet 127.0.0.1 7681
+```
+
+type something that isn't a valid HTTP method and enter, before the
+connection times out.  The connection will switch to RAW mode using this
+protocol, and pass the unused rx as a raw RX callback.
+    
+The test protocol echos back what was typed on telnet to telnet.
+
+@section rawclientsocket RAW client socket descriptor polling
+
+You can now also open RAW socket connections in client mode.
+
+Follow the usual method for creating a client connection, but set the
+`info.method` to "RAW".  When the connection is made, the wsi will be
+converted to RAW mode and operate using the same callbacks as the
+server RAW sockets described above.
+
+The libwebsockets-test-client supports this using raw:// URLS.  To
+test, open a netcat listener in one window
+
+```
+ $ nc -l 9999
+```
+
+and in another window, connect to it using the test client
+
+```
+ $ libwebsockets-test-client raw://127.0.0.1:9999
+```
+
+The connection should succeed, and text typed in the netcat window (including a CRLF)
+will be received in the client.
+
 @section ecdh ECDH Support
 
 ECDH Certs are now supported.  Enable the CMake option
@@ -390,6 +568,32 @@ ECDH Certs are now supported.  Enable the CMake option
 
 to build in support and select it at runtime.
 
+@section sslinfo SSL info callbacks
+
+OpenSSL allows you to receive callbacks for various events defined in a
+bitmask in openssl/ssl.h.  The events include stuff like TLS Alerts.
+
+By default, lws doesn't register for these callbacks.
+
+However if you set the info.ssl_info_event_mask to nonzero (ie, set some
+of the bits in it like `SSL_CB_ALERT` at vhost creation time, then
+connections to that vhost will call back using LWS_CALLBACK_SSL_INFO
+for the wsi, and the `in` parameter will be pointing to a struct of
+related args:
+
+```
+struct lws_ssl_info {
+       int where;
+       int ret;
+};
+```
+
+The default callback handler in lws has a handler for LWS_CALLBACK_SSL_INFO
+which prints the related information,  You can test it using the switch
+-S -s  on `libwebsockets-test-server-v2.0`.
+
+Returning nonzero from the callback will close the wsi.
+
 @section smp SMP / Multithreaded service
 
 SMP support is integrated into LWS without any internal threading.  It's
@@ -684,6 +888,40 @@ This allocation is only deleted / replaced when the connection accesses a
 URL region with a different protocol (or the default protocols[0] if no
 CALLBACK area matches it).
 
+@section BINDTODEV SO_BIND_TO_DEVICE
+
+The .bind_iface flag in the context / vhost creation struct lets you
+declare that you want all traffic for listen and transport on that
+vhost to be strictly bound to the network interface named in .iface.
+
+This Linux-only feature requires SO_BIND_TO_DEVICE, which in turn
+requires CAP_NET_RAW capability... root has this capability.
+
+However this feature needs to apply the binding also to accepted
+sockets during normal operation, which implies the server must run
+the whole time as root.
+
+You can avoid this by using the Linux capabilities feature to have
+the unprivileged user inherit just the CAP_NET_RAW capability.
+
+You can confirm this with the test server
+
+
+```
+ $ sudo /usr/local/bin/libwebsockets-test-server -u agreen -i eno1 -k
+```
+
+The part that ensures the capability is inherited by the unprivileged
+user is
+
+```
+#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
+                        info.caps[0] = CAP_NET_RAW;
+                        info.count_caps = 1;
+#endif
+```
+
+
 @section dim Dimming webpage when connection lost
 
 The lws test plugins' html provides useful feedback on the webpage about if it