plugin_core
plugin_core contains the core features for generic request handling, static files, log files and buffer limits.
Socket addresses
The following address formats can be used:
IPv4
Either with port 192.168.0.1:80
or without 192.168.0.1
; you can either use real IPs or 0.0.0.0
to listen on all network interfaces.
IPv6
Similar to IPv4; just put the IPv6 between “[” and “]” like this: [::1]:80
(IPv6 localhost with port 80).
Please note that lighttpd always listens to IPv6 only (some platforms listen to IPv4 too on [::] by default).
Unix domain sockets
A unix domain socket needs a filename where the socket is placed; use unix:/path/to/socket
as socket address.
Please don’t put unix domain sockets in /tmp
. Use /var/run/lighttpd/
or something like that, where only root or selected “trusted” users can create files.
This may be not supported in all places where a socket address can be specified.
Options
debug.log_request_handling (option)
enable debug output for request handling
debug.log_request_handling value;
Example
debug.log_request_handling true;
static.range_requests (option)
enabled ranged requests
static.range_requests value;
Example
static.range_requests false;
keepalive.timeout (option)
how long a keep-alive connection is kept open (in seconds)
keepalive.timeout timeout;
Example
keepalive.timeout 30;
keepalive.requests (option)
maximum number of requests a client is allowed to make in one connection
keepalive.requests requests;
Example
keepalive.requests 10;
etag.use (option)
list of properties used to calculate etag; specify empty list to disable etags. Available: "inode", "mtime", "size"
etag.use properties;
Example
etag.use ();
stat.async (option)
enables async stat() calls
stat.async value;
If a filename is in lighttpd’s stat “cache”, lighttpd assumes the kernel still has the entry in memory, and stat()
therefore is unlikely to block.
Otherwise it will ask a background thread to call stat()
, so the main worker threads are not waiting on a slow disk (or a network filesystem), but only if stat.async
is enabled.
If you know your disk is fast enough (perhaps a ramdisk?) and want to save the context switch to the background thread you can disable this.
buffer_request_body (option)
enable buffering request body on disk
buffer_request_body value;
Some backends like to wait for the complete response before forwarding/handling it. For this they require this option to save some memory.
strict.post_content_length (option)
require Content-Length for POST requests
strict.post_content_length value;
Some clients don’t send Content-Length for POST requests with empty body; they should send Content-Length: 0
. When this check is enabled they’ll get a 411 Length required
error.
static.exclude_extensions (option)
don't deliver static files with one of the listed extensions
static.exclude_extensions extensions;
Example
static.exclude_extensions [ ".php", ".htaccess", ".htpasswd" ];
server.name (option)
server name; is used in some places instead of the HTTP request hostname if the latter was not specified in the (HTTP/1.0) request
server.name hostname;
Even HTTP/1.0 clients usually specify a Host: header; without Host: header you could only run one domain on one IP address.
This option is for the rare case that you want to handle clients without Host: header support in a nice way.
Example
server.name "lighttpd.net";
server.tag (option)
used to display server name + version in different places (HTTP response header, CGI environment, mod_dirlist footer, ...)
server.tag tag;
The default is “lighttpd/” + the current version.
mime_types (option)
maps file extensions to MIME types
mime_types mapping;
Default MIME type is “application/octet-stream”. The sources contain a mimetypes example config with many standard mappings.
The longest matching suffix is used (".tar.gz"
always wins over ".gz"
), and in case of duplicate entries the last one is used.
Example
mime_types [ ".htm" => "text/html", ".txt" => "text/plain; charset=utf-8" ];
Actions needed from lua
These action are not needed (or usable) in non-lua configs.
list (action)
(lua) combines a list of actions into one action, only needed in lua
list actions;
- actions
- list of actions to combine
when (action)
(lua) build a conditional block (only usable in lua)
when (condition, action1, action2);
- condition
- A condition; can only be constructed in lua
- action1
- action to run if condition was true or lua "nil"
- action2
- (optional) action to run if condition was false
Mapping URL paths to filenames
docroot (action)
sets doc-root, and builds physical path for requested file
docroot patterns;
- patterns
- One or more patterns to build docroot from
Uses patterns to build document roots (base location of files to server).
docroot
uses the first pattern that results in an existing directory; otherwise it uses the last entry.
You’ll want the docroot
action before alias
actions!
Example
docroot ("/var/www/vhosts/$0/htdocs", "/var/www/default/htdocs");
alias (action)
sets doc-root depending on a matching prefix
alias mapping;
- mapping
- maps prefix to base location on disk
The prefix is removed from the URL path before it is appended to the base location.
You’ll want the docroot
action before alias
actions!
Patterns are supported for alias targets as in docroot
. As only one pattern per prefix can be given alias
does not check whether the target exists.
Trailing slashes in the prefix used to indicate “directory handling” and get ignored for matching; “directory handling” is now always on.
That means URL paths only match at separator boundaries; the prefix /a
(and /a/
) matches the paths /a
, /a/
and /a/b
, but not /ab
.
Example
docroot ("/var/www/vhosts/$0/htdocs", "/var/www/default/htdocs");
alias [
"/phpmyadmin/" => "/usr/share/phpmyadmin",
"/pma/" => "/usr/share/phpmyadmin",
"/.well-known/openpgpkey/" => "/var/lib/gnupg/wks/$0/",
];
alias "/favicon.ico" => "/var/www/favicon.ico";
index (action)
default filenames to show in a directory
index filenames;
- filenames
- filenames to look for
If the physical path is a directory search for the specified filenames; prefix a filename with ‘/’ to search in the doc-root.
It works like this:
- if current physical path points to a regular file do nothing
- walk through the list of filenames to look for:
- if filename does not start with ‘/’ and the current physical path doesn’t point to a directory, ignore the entry
- if filename does not start with ‘/’ and the url didn’t end in a ‘/’, redirect request to url with ‘/’ appended
- if filename does not start with ‘/’ search for it in current physical path (which is a directory)
- if filename does start with ‘/’ search for it in the doc-root
Example
setup {
module_load "mod_dirlist";
}
# if a directory was requested, first search for some default files
index ["index.php", "index.html", "/index.php"];
# if none of them did exists show a simple directory listing
dirlist;
# ... + handle PHP and static files
pathinfo (action)
splits physical path into existing file/directory and the remaining PATH_INFO
pathinfo;
Searches for the longest prefix of the physical path name that exists, splitting only at the directory separator /
; also never leaves the document root (technically speaking the filename can’t get shorter than the document root).
Example
The following example maps http://example.com/index.php/some/site
to the file /var/www/index.php
with PATH_INFO=/some/site
(given /var/www/index.php
is a normal file).
docroot "/var/www";
pathinfo;
if phys.path =$ ".php" { fastcgi "unix:/var/run/lighttpd/php.sock"; }
Example
The following example maps http://example.com/some/site
to the file /var/www/index.php
with PATH_INFO=/some/site
(given /var/www/index.php
is a normal file, and /var/www/some
does not exist).
docroot "/var/www";
pathinfo;
index ("index.php");
if phys.path =$ ".php" { fastcgi "unix:/var/run/lighttpd/php.sock"; }
Generating responses
static (action)
handle GET and HEAD requests with a static file from disk
static;
This action is automatically appended to the global config (unless a lua config is specified at the command line).
Does nothing if:
- the request is already handled
- no physical path was set (missing
docroot
,alias
, …) - the physical path points to a directory
All other problems lead to an error page, for example:
- wrong request method (405)
- file not found (404)
- couldn’t open file (403)
- filename matches
static.exclude_extensions
(403) - …
static_no_fail (action)
handle GET and HEAD requests with a static file from disk
static_no_fail;
same as static
, but doesn’t return any error pages; instead request handling continues.
respond (action)
returns a quick response with optional body
respond (status, content);
- status
- HTTP response status code
- content
- (optional) pattern for response body
Generates a simple response (our favorite benchmark handler).
The body is parsed as pattern.
Example
respond 403 => "Forbidden";
Example
respond 200 => "benchmark content!";
Logging
Log levels
For standard logging (“error.log”) lighttpd knows the following levels:
debug
info
warning
error
-
abort
(right before terminating the process) -
backend
(for log data from backends, like FastCGI stderr stream)
Log targets
The following log targets are known:
- not logging: empty string
- files:
file:/var/log/error.log
or just/var/log/error.log
- stderr:
stderr:
orstderr
- syslog:
syslog:
(not supported yet) - pipes:
pipe:command
or| command
(not supported yet)
Unknown strings are mapped to stderr
.
log (action)
overwrite log targets for all log levels
log map;
- map
- mapping log levels (or default) to log targets
Example
log [
"error" => "/var/log/lighttpd/error.log",
"abort" => "/var/log/lighttpd/error.log",
"backend" => "/var/log/lighttpd/backend.log",
default => "/var/log/lighttpd/debug.log",
];
log.write (action)
writes a log message to the "info" log level
log.write message;
- message
- message pattern string
Writes the specified message to the log using level info
; the message is parsed as pattern.
Example
log.write "hello world";
log (setup)
sets default log targets for all log levels
log map;
- map
- mapping log levels (or default) to log targets
Example
setup {
log [
"error" => "/var/log/lighttpd/error.log",
"abort" => "/var/log/lighttpd/error.log",
"backend" => "/var/log/lighttpd/backend.log",
default => "/var/log/lighttpd/debug.log",
];
}
log.timestamp (setup)
sets the format string to use for timestamps in the log
log.timestamp format;
- format
- a strftime format string
See strftime for the format string syntax.
The default format string is "%d/%b/%Y %T %Z"
.
Connection environment
The connection environment is a set of variable with names and values (both simple strings). CGI backends will forward the environment in addition to the standard CGI environment variables.
The connection environment overwrites the standard CGI values.
env.set (action)
sets a connection environment variable
env.set (name, value);
- name
- the variable name to set
- value
- the pattern value to set
The value is parsed as pattern.
Example
env.set "INFO" => "%{req.path}";
env.add (action)
sets a connection environment variable if not already set
env.add (name, value);
- name
- the variable name to set
- value
- the pattern value to set
The value is parsed as pattern. env.add
does not overwrite already existing values.
Example
env.add "INFO" => "%{req.path}";
env.remove (action)
removes a connection environment variable
env.remove name;
- name
- the variable name to remove
Example
env.remove "INFO";
env.clear (action)
removes all connection environment variables
env.clear;
Example
env.clear;
Response header
All header values that get set are parsed as patterns.
header.add (action)
adds a new response header line
header.add (name, value);
- name
- header name
- value
- pattern header value
The HTTP spec requires that multiple headers with the same name could be merged by joining their values with “,”.
In real life this doesn’t work always, especially not for “Cookie” headers; so this action actually adds a separate header line.
Example
header.add "Cache-Control" => "public";
header.append (action)
appends value to response header line
header.append (name, value);
- name
- header name
- value
- pattern header value
If header already exists appends new value separated by “, “; otherwise adds a new header line.
header.overwrite (action)
overwrite response header line or add new one
header.overwrite (name, value);
- name
- header name
- value
- pattern header value
If header already exists overwrites the value; otherwise a new line gets added.
header.remove (action)
remove existing response header
header.remove name;
- name
- header name
Example
# ... some PHP handling
# wait for response headers to be ready
if resp.status >= 0 {
header.remove "X-Powered-By";
}
set_status (action)
modify HTTP status code
set_status;
Modifies the HTTP status code, but doesn’t handle the request in any way.
Later actions could overwrite the status, or a backend (FastCGI, proxy, …) might overwrite it if the response is parsed later.
Only works if some action actually handled the request.
Lighttpd will generate error pages (if it knows the code) if the action that handled the request didn’t generate a response body and a body is allowed.
Example
# hide all 404s at end of config by setting 403
static;
if resp.status == 404 { set_status 403; }
Request headers
All header values that get set are parsed as patterns.
req_header.add (action)
adds a new request header line
req_header.add (name, value);
- name
- header name
- value
- pattern header value
Same as header.add for request headers.
req_header.append (action)
appends value to request header line
req_header.append (name, value);
- name
- header name
- value
- pattern header value
Same as header.append for request headers.
req_header.overwrite (action)
overwrite request header line or add new one
req_header.overwrite (name, value);
- name
- header name
- value
- pattern header value
Same as header.overwrite for request headers.
req_header.remove (action)
remove existing request header
req_header.remove name;
- name
- header name
Same as header.remove for request headers.
Example
Remove Accept-Encoding
request header to workaround the BREACH vulnerability in https.
if request.scheme == "https" {
# create a copy of the header value
req_header.add "HTTPS-Accept-Encoding" => '%{req.header[Accept-Encoding]}';
req_header.remove "Accept-Encoding";
}
io.buffer_out (action)
set memory limit for outgoing chunkqueues (default is 256KiB)
io.buffer_out limit;
- limit
- limit in bytes (0 means unlimited)
Example
io.buffer_out 512kbyte;
io.buffer_in (action)
set memory limit for incoming chunkqueues (default is 256KiB)
io.buffer_in limit;
- limit
- limit in bytes (0 means unlimited)
Example
io.buffer_in 512kbyte;
map (action)
maps the result of a pattern to a user defined action
map (pattern, mapping);
- pattern
- the evaluation of this pattern is used as key in the mapping
- mapping
- maps strings (or default) to actions
The pattern is parsed as pattern. Have a look at mod_vhost for special mappings on hostnames.
Example
map "%{req.path}" => [
"/" => {
respond 200 => "root";
},
"/news" => {
respond 200 => "news";
},
default => {
respond 404;
},
];
listen (setup)
listen to a socket address, see above for accepted formats (default TCP port is 80)
listen socket-address;
- socket-address
- socket address to listen to
Example
setup {
listen "0.0.0.0";
listen "[::]";
listen "127.0.0.1:8080";
}
workers (setup)
sets worker count; each worker runs in its own thread and works on the connections it gets assigned from the master worker
workers count;
- count
- number of workers (default is 1)
Example
setup {
workers 2;
}
workers.cpu_affinity (setup)
binds worker threads to a cpu, only available on Linux systems
workers.cpu_affinity mapping;
- mapping
- list of integers or a list of lists of integers
Example
workers.cpu_affinity [0, 1];
module_load (setup)
load the given module(s)
module_load names;
- names
- string or list of strings with the module name(s)
modules can be “loaded” more than once without error
Example
setup {
module_load "mod_rewrite";
}
io.timeout (setup)
sets the global I/O timeout (wait for network read and write)
io.timeout timeout;
- timeout
- timeout value in seconds, default is 300s
stat_cache.ttl (setup)
set TTL for stat cache entries
stat_cache.ttl ttl;
- ttl
- time to live in seconds, default is 10s
tasklet_pool.threads (setup)
sets number of background threads for blocking tasks
tasklet_pool.threads threads;
- threads
- number of threads
For example the stat cache uses such background threads.
if threads = 0
the tasks are run in foreground (no background threads).
if threads < 0
all worker share a GThreadPool.
if threads > 0
each worker has its own thread pool with threads
threads.
fetch.files_static (setup)
starts a Fetch API provider
fetch.files_static (name, filename-pattern);
- name
- name of the storage
- filename-pattern
- A filename pattern including exactly on *
Loads all filenames matching the wildcard pattern (which must include exactly on *
) into the fetch storage.
Example
setup {
fetch.files_static "sni" => "/etc/certs/lighttpd_sni_*.pem";
}