summaryrefslogtreecommitdiffstatshomepage
path: root/plugins/weblit/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/weblit/README.md')
-rw-r--r--plugins/weblit/README.md239
1 files changed, 239 insertions, 0 deletions
diff --git a/plugins/weblit/README.md b/plugins/weblit/README.md
new file mode 100644
index 00000000000..55d6085d22b
--- /dev/null
+++ b/plugins/weblit/README.md
@@ -0,0 +1,239 @@
+# weblit
+
+A web framework for luv (ported from luvit/lit)
+
+Weblit is a collection of lit packages that together form a nice web framework.
+
+## weblit/app
+
+This is the core of the framework. It's export value is the app itself. The
+config functions can be chained off this config for super terse syntax.
+
+```lua
+require('weblit/app')
+
+ .bind({
+ host = "0.0.0.0",
+ port = 8080
+ })
+
+ .use(require('weblit/logger'))
+ .use(require('weblit/auto-headers'))
+ .use(require('weblit/etag-cache'))
+
+ .route({
+ method = "GET",
+ path = "/do/:user/:action",
+ domain = "*.myapp.io"
+ }, function (req, res, go)
+ -- Handle route
+ end)
+
+ .start()
+
+```
+
+### bind(options)
+
+Use this to configure your server. You can bind to multiple addresses and
+ports. For example, the same server can listen on port `8080` using normal HTTP
+while also listening on port `8443` using HTTPS.
+
+```lua
+-- Listen on port 8080 internally using plain HTTP.
+.bind({
+ host = "127.0.0.1",
+ port = 8080
+})
+
+-- Also listen on port 8443 externally using encrypted HTTPS.
+.bind({
+ host = "0.0.0.0",
+ port = 8443,
+ tls = {
+ cert = module:load("cert.pem"),
+ key = module:load("key.pem",
+ }
+})
+```
+
+The `host` option defaults to `"127.0.0.1"`. The default port depends on if
+you're running as root and if the connection is TLS encrypted.
+
+ | Root | User
+------|-----:|------:
+HTTP | 80 | 8080
+HTTPS | 442 | 8443
+
+
+### use(middleware)
+
+This adds a raw middleware to the chain. It's signature is:
+
+```lua
+.use(function (req, res, go)
+ -- Log the request table
+ p("request", req)
+ -- Hand off to the next layer.
+ return go()
+end)
+```
+
+The `req` table will contain information about the HTTP request. This includes
+several fields:
+
+ - `socket` - The raw libuv `uv_tty_t` socket.
+ - `method` - The HTTP request method verb like `GET` or `POST`.
+ - `path` - The raw HTTP request path (including query string).
+ - `headers` - A list of headers. Each header is a table with two entries for
+ key and value. For convenience, there are special `__index` and
+ `__newindex` metamethods that let you treat this like a case insensitive
+ key/value store.
+ - `version` - The HTTP version (Usually either `1.0` or `1.1`).
+ - `keepAlive` - A flag telling you if this should be a keepalive connection.
+ - `body` - The request body as a string. In the future, this may also be a stream.
+
+The `res` table also has some conventions used to form the response a piece at a
+time. Initially it contains:
+
+ - `code` - The response status code. Initially contains `404`.
+ - `headers` - Another special headers table like in `req`.
+ - `body` - The response body to send. Initially contains `"Not Found\n"`.
+
+The `go` function is to be called if you wish to not handle a request. This
+allows other middleware layers to get a chance to respond to the request. Use a
+tail call if there is nothing more to do.
+
+Otherwise do further processing after `go` returns. At this point, all inner
+layers have finished and a response is ready in `res`.
+
+### route(options, middleware)
+
+Route is like use, but allows you to pre-filter the requests before the middleware
+is called.
+
+```lua
+.route({
+ method = "PUT",
+ path = "/upload/:username"
+}, function (req, res, go)
+ local url = saveFile(req.params.username, req.body)
+ res.code = 201
+ res.headers.Location = url
+end)
+```
+
+The route options accept several parameters:
+
+ - `method` - This is a simple filter on a specific HTTP method verb.
+ - `path` - This is either an exact match or can contain patterns. Segments
+ looking like `:name` will match single path segments while `:name:` will
+ match multiple segments. The matches will go into `req.params`. Also any
+ query string will be stripped off, parsed out, and stored in `req.query`.
+ - `host` - Will filter against the `Host` header. This can be an exact match
+ or a glob match like `*.mydomain.org`.
+ - `filter` - Filter is a custom lua function that accepts `req` and returns
+ `true` or `false`.
+
+If the request matches all the requirements, then the middleware is called the
+same as with `use`.
+
+### start
+
+Bind to the port(s), listen on the socket(s) and start accepting connections.
+
+## weblit/logger
+
+This is a simple middleware that logs the request method, url and user agent.
+It also includes the response status code.
+
+Make sure to use it at the top of your middleware chain so that it's able to see
+the final response code sent to the client.
+
+```lua
+.use(require('weblit/logger'))
+```
+
+## weblit/auto-headers
+
+This implements lots of conventions and useful defaults that help your app
+implement a proper HTTP server.
+
+You should always use this near the top of the list. The only middleware that
+goes before this is the logger.
+
+
+```lua
+.use(require('weblit/auto-headers'))
+```
+
+## weblit/etag-cache
+
+This caches responses in memory keyed by etag. If there is no etag, but there
+is a response body, it will use the body to generate an etag.
+
+Put this in your list after auto-headers, but before custom server logic.
+
+```lua
+.use(require('weblit/etag-cache'))
+```
+
+## weblit/static
+
+This middleware serves static files to the user. Use this to serve your client-
+side web assets.
+
+Usage is pretty simplistic for now.
+
+```lua
+local static = require('weblit/static')
+app.use(static("path/to/static/assets"))
+```
+
+If you want to only match a sub-path, use the router.
+
+```lua
+app.route({
+ path = "/blog/:path:"
+}, static(pathJoin(module.dir, "articles")))
+```
+
+The `path` param will be used if it exists and the full path will be used
+otherwise.
+
+## weblit/websocket
+
+This implements a websocket upgrade handler. You can choose the subprotocol and
+other routing information.
+
+```lua
+app.websocket({
+ path = "/v2/socket", -- Prefix for matching
+ protocol = "virgo/2.0", -- Restrict to a websocket sub-protocol
+}, function (req, read, write)
+ -- Log the request headers
+ p(req)
+ -- Log and echo all messages
+ for message in read do
+ write(message)
+ end
+ -- End the stream
+ write()
+end)
+```
+
+
+## weblit
+
+This is the metapackage that simply includes the other modules.
+
+It exposes the other modules as a single exports table.
+
+```lua
+exports.app = require('weblit/app')
+exports.autoHeaders = require('weblit/auto-headers')
+exports.etagCache = require('weblit/etag-cache')
+exports.logger = require('weblit/logger')
+exports.static = require('weblit/static')
+exports.websocket = require('weblit/websocket')
+```