2
0
Fork 0

Compare commits

...

5 Commits

Author SHA1 Message Date
Stefan Bühler 698c1a54ef [doc] update my email address
Change-Id: If05298c4d7779000d800710e06134fc65b395db6
2023-07-13 01:00:01 +02:00
Stefan Bühler 6d7d0b784c [doc] convert http:// to https:// links if valid
Change-Id: I07cd924121f00e9682071cbfcc2c135b22428a41
2023-07-13 00:59:18 +02:00
Stefan Bühler 29d4a1543d [doc] convert from textile to markdown; don't allow simple text in section/description anymore
Change-Id: Ic6ee47465b934ba00cb92f2ab68a3a9d6ff01235
2023-07-13 00:14:37 +02:00
Stefan Bühler 7472bb4b18 [tests] fix cleanup if prepare fails
Change-Id: I6a7a8b2f3b0573256cc3ce12cfaf6355dd958c80
2023-07-12 17:00:07 +02:00
Stefan Bühler 69ca252e48 [tests] chmod -x tests/pylt/run.py
Change-Id: I2850413df92643066eda4e87635883484593853a
2023-07-12 16:58:35 +02:00
47 changed files with 1120 additions and 1238 deletions

View File

@ -29,7 +29,7 @@ THE SOFTWARE.
The doc/ directory contains some assets by 3rd parties:
From doc/bootstrap* (Apache License 2.0):
Copyright 2013 Twitter, Inc.
Licensed under http://www.apache.org/licenses/LICENSE-2.0
Licensed under https://www.apache.org/licenses/LICENSE-2.0
From doc/jquery-1.10.1.min.js (MIT License):
(c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license

View File

@ -143,7 +143,7 @@ while (<MIMETYPES>) {
}
# missing in /etc/mime.types;
# from http://www.iana.org/assignments/media-types/media-types.xhtml
# from https://www.iana.org/assignments/media-types/media-types.xhtml
add(".dtd", "application/xml-dtd");
@ -153,7 +153,7 @@ print <<EOF;
setup {
mime_types [
# /etc/mime.types
# and from http://www.iana.org/assignments/media-types/media-types.xhtml
# and from https://www.iana.org/assignments/media-types/media-types.xhtml
EOF

View File

@ -28,12 +28,12 @@
</div>
<h3>About this page</h3>
<p>This is a placeholder page installed by the Lighttpd2 package of this servers operating system.</p>
<p>Lighttpd is a webserver. To learn more about it, please visit <a href="http://www.lighttpd.net">http://www.lighttpd.net</a></p>
<p>Lighttpd is a webserver. To learn more about it, please visit <a href="https://www.lighttpd.net">https://www.lighttpd.net</a></p>
<h3>If you are the administrator of this server</h3>
<ul>
<li>Configuration files are most likely located in /etc/lighttpd2/</li>
<li>Logs are usually stored in /var/log/lighttpd2/</li>
<li>Please consult the documenation provided in the <a href="http://redmine.lighttpd.net/projects/lighttpd2/wiki">Lighttpd2 wiki</a></li>
<li>Please consult the documenation provided in the <a href="https://redmine.lighttpd.net/projects/lighttpd2/wiki">Lighttpd2 wiki</a></li>
<li>For discussions about Lighttpd, please join the IRC channel <a href="irc://irc.freenode.org/lighttpd">#lighttpd</a> on irc.freenode.org</li>
</ul>
<div id="logo" style="text-align: center;">

View File

@ -3,7 +3,7 @@
setup {
mime_types [
# /etc/mime.types
# and from http://www.iana.org/assignments/media-types/media-types.xhtml
# and from https://www.iana.org/assignments/media-types/media-types.xhtml
".a2l" => "application/A2L",
".aml" => "application/AML",

View File

@ -3,7 +3,7 @@
require 'rubygems'
require 'nokogiri'
require 'redcloth'
require 'kramdown'
require 'cgi'
@ -214,7 +214,7 @@ class Documentation
indent = real_lines.map { |l| _count_indent l }.min
code = lines.map { |line| _remove_indent(indent, line).rstrip }.join("\n") + "\n"
code = lines.map { |line| _remove_indent(indent, line) }.join() + "\n"
code.gsub(/\A\n+/, "").gsub(/\n\n+/, "\n\n").gsub(/\n+\Z/, "\n")
end
@ -222,9 +222,9 @@ class Documentation
@html.pre { @html.code { @html << _format_code(xml) } }
end
def _parse_textile(xml)
def _parse_markdown(xml)
tx = _format_code(xml)
@html << RedCloth.new(tx).to_html
@html << Kramdown::Document.new(tx, :auto_ids => false).to_html
end
def _parse_html(xml)
@ -238,8 +238,9 @@ class Documentation
xml.children.each do |child|
if child.text?
@html.p child.content.strip
elsif ['html','textile'].include? child.name
text = child.content.strip
raise "invalid non-empty text #{text.inspect}" if text != ""
elsif ['html','markdown'].include? child.name
self.send('_parse_' + child.name, child)
else
raise 'invalid description element ' + child.name
@ -425,8 +426,8 @@ class ModuleDocumentation < GenericModuleDocumentation
xml.children.each do |child|
if child.text?
text = child.content.strip
@html.p text if text.length > 0
elsif ['action','setup','option','html','textile','example','section'].include? child.name
raise "invalid non-empty text #{text.inspect}" if text != ""
elsif ['action','setup','option','html','markdown','example','section'].include? child.name
self.send('_parse_' + child.name, child)
else
raise 'invalid section element ' + child.name
@ -479,8 +480,8 @@ class AngelModuleDocumentation < GenericModuleDocumentation
xml.children.each do |child|
if child.text?
text = child.content.strip
@html.p text if text.length > 0
elsif ['item','html','textile','example','section'].include? child.name
raise "invalid non-empty text #{text.inspect}" if text != ""
elsif ['item','html','markdown','example','section'].include? child.name
self.send('_parse_' + child.name, child)
else
raise 'invalid section element ' + child.name
@ -543,8 +544,8 @@ class ChapterDocumentation < Documentation
xml.children.each do |child|
if child.text?
text = child.content.strip
@html.p text if text.length > 0
elsif ['html','textile','example','section'].include? child.name
raise "invalid non-empty text #{text.inspect}" if text != ""
elsif ['html','markdown','example','section'].include? child.name
self.send('_parse_' + child.name, child)
else
raise 'invalid section element ' + child.name
@ -736,7 +737,8 @@ end
if __FILE__ == $0
output_directory = ARGV[0] || '.'
output_directory = File.absolute_path(ARGV[0] || '.')
Dir.chdir(File.dirname(__FILE__))
if not system("xmllint --noout --schema doc_schema.xsd *.xml 2>&1")
STDERR.puts "Couldn't validate XML files"

View File

@ -1,178 +1,187 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Main Configuration">
<description>
<textile>
At the heart of each webserver is the configuration file. It controls the whole behaviour and therefore has to be mighty but at the same time easy enough to get the desired results without hassle.
In the lighttpd config you control how it reacts on requests. To achieve this you have to express some kind of logic - just like in a programming language.
</textile>
</description>
<description><markdown>
At the heart of each webserver is the configuration file. It controls the whole behaviour and therefore has to be mighty but at the same time easy enough to get the desired results without hassle.
In the lighttpd config you control how it reacts on requests. To achieve this you have to express some kind of logic just like in a programming language.
</markdown></description>
<section title="Basic Syntax">
<textile><![CDATA[
The syntax for the lighttpd 2.0 configuration file is somewhat similar to various programming languages - kind of a mixture. But don't be afraid, it is really simple. No pointers involved :)
The basic blocks are "values":#core_config__values, "variables":#core_config__variables, "function calls":#core_config__funcalls and "conditions":#core_config__conditions.
]]></textile>
<markdown><![CDATA[
The syntax for the lighttpd 2.0 configuration file is somewhat similar to various programming languages kind of a mixture. But don't be afraid, it is really simple. No pointers involved :)
The basic blocks are [values](#core_config__values), [variables](#core_config__variables), [function calls](#core_config__funcalls) and [conditions](#core_config__conditions).
]]></markdown>
</section>
<section title="Values" anchor="values">
<section title="Boolean">
<textile><![CDATA[
<markdown><![CDATA[
There are two boolean values:
* @true@
* @false@
]]></textile>
* `true`
* `false`
]]></markdown>
</section>
<section title="Integers">
<textile><![CDATA[
<markdown><![CDATA[
Integers are stored as signed ints with 64 bits (max value around 9 * 10^18). There are three basic ways to use them:
* decimal integers: starting with any non zero digit, like @128@
* octal integers: starting with a zero, like @0644@
* hexadecimal integers: starting with @0x@ like @0xff@
* decimal integers: starting with any non zero digit, like `128`
* octal integers: starting with a zero, like `0644`
* hexadecimal integers: starting with `0x` like `0xff`
All three can have a suffix representing a factor the number gets multiplied with:
* @byte@: @1@
* @kbyte@: @1024@
* @mbyte@: @1024*1024@
* @gbyte@: @1024*1024*1024@
* @tbyte@: @1024*1024*1024*1024@
* @pbyte@: @1024*1024*1024*1024*1024@
* @bit@: @1 / 8@
* @kbit@: @1024 / 8@
* @mbit@: @1024*1024 / 8@
* @gbit@: @1024*1024*1024 / 8@
* @tbit@: @1024*1024*1024*1024 / 8@
* @pbit@: @1024*1024*1024*1024*1024 / 8@
* @sec@: @1@
* @min@: @60@
* @hours@: @3600@
* @days@: @24*3600@
* `byte`: `1`
* `kbyte`: `1024`
* `mbyte`: `1024*1024`
* `gbyte`: `1024*1024*1024`
* `tbyte`: `1024*1024*1024*1024`
* `pbyte`: `1024*1024*1024*1024*1024`
* `bit`: `1 / 8`
* `kbit`: `1024 / 8`
* `mbit`: `1024*1024 / 8`
* `gbit`: `1024*1024*1024 / 8`
* `tbit`: `1024*1024*1024*1024 / 8`
* `pbit`: `1024*1024*1024*1024*1024 / 8`
* `sec`: `1`
* `min`: `60`
* `hours`: `3600`
* `days`: `24*3600`
For sizes the base unit is byte, and for intervals seconds.
]]></textile>
]]></markdown>
</section>
<section title="Strings">
<textile><![CDATA[
<markdown><![CDATA[
There are 4 ways to specify a string:
* @'hello world'@
* @"hello world"@
* @e'hello world'@
* @e"hello world"@
* `'hello world'`
* `"hello world"`
* `e'hello world'`
* `e"hello world"`
The basic escape rules are the same for both:
* @"\n"@ is a newline, @"\r"@ a carriage return, @"\t"@ a tab stop
* @"\\"@ is one @\@, @"\""@ is one double quote @"@ and @"\'"@ a single quote @'@
* escaping single/double quote is optional if the symbol is not used to terminate the string, i.e. @'\"'@ = @'"'@ and @"\'"@ = @"'"@
* @"\xNN"@: NN must be hexadecimal characters, and the string is replaced with the decoded 8-bit value as a single byte
* All other @\@ occurences are *not* removed from the string.
The @e'..'@ and @e"..."@ variant do not allow any occurences of the last kind to happen.
* `"\n"` is a newline, `"\r"` a carriage return, `"\t"` a tab stop
* `"\\"` is one `\`, `"\""` is one double quote `"` and `"\'"` a single quote `'`
* escaping single/double quote is optional if the symbol is not used to terminate the string, i.e. `'\"'` = `'"'` and `"\'"` = `"'"`
* `"\xNN"`: NN must be hexadecimal characters, and the string is replaced with the decoded 8-bit value as a single byte
* All other `\` occurences are **not** removed from the string.
The `e'..'` and `e"..."` variant do not allow any occurences of the last kind to happen.
All other characters are allowed (the strings are parsed as 8-bit binary; lighttpd2 usually doesn't care about the encoding).
]]></textile>
]]></markdown>
</section>
<section title="Lists">
<textile><![CDATA[
<markdown><![CDATA[
Lists are ordered collections of other values:
* @[1, true, "foo"]@ (simple list)
* @[]@ (empty list)
* @[1]@ (list with one element)
* @[[1,2],[3,4],5]@ (nested lists)
* @[1,2,]@ (final value can have a trailing @,@ too)
* @(1, 2, 3)@ (alternative brackets with more than one element)
Note that @(1)@ is not a list; parentheses can also be used to group expressions as in @1*(2+3)@, and it is therefore recommend to use only @[]@ to specify lists.
]]></textile>
* `[1, true, "foo"]` (simple list)
* `[]` (empty list)
* `[1]` (list with one element)
* `[[1,2],[3,4],5]` (nested lists)
* `[1,2,]` (final value can have a trailing `,` too)
* `(1, 2, 3)` (alternative brackets with more than one element)
Note that `(1)` is not a list; parentheses can also be used to group expressions as in `1*(2+3)`, and it is therefore recommend to use only `[]` to specify lists.
]]></markdown>
</section>
<section title="Key-Value Lists">
<textile><![CDATA[
<markdown><![CDATA[
Key-value lists associates keys to values (both can be of any type); the syntax is:
* @[ "a" => 1, "b" => 10 ]@
As with normal lists the final value can have a trailing @,@ too. You cannot mix simple values and key-value associations in one list (nesting them works).
* `[ "a" => 1, "b" => 10 ]`
The @key => value@ operator is also only syntactic sugar for a @[key, value]@ list, the above example is the same as:
* @[ [a, 1], [b, 10] ]@
As with normal lists the final value can have a trailing `,` too. You cannot mix simple values and key-value associations in one list (nesting them works).
The `key => value` operator is also only syntactic sugar for a `[key, value]` list, the above example is the same as:
* `[ [a, 1], [b, 10] ]`
This especially means that key-value lists are ordered too, although they can get converted to hash tables in certain function calls internally.
]]></textile>
]]></markdown>
</section>
<section title="Expressions">
<textile><![CDATA[
<markdown><![CDATA[
There are operators available for some value types:
* for integers: @+@, @-@, @*@ and @/@
* for strings: @+@ (concatenate two strings)
* for lists: @+@ (append lists)
* for integers: `+`, `-`, `*` and `/`
* for strings: `+` (concatenate two strings)
* for lists: `+` (append lists)
Also you can cast strings and booleans to integers and any value to strings:
* @cast(int) "256"@ (only supports decimal representations and no suffix like above)
* @cast(int) true@ (@true@ maps to @1@ and @false@ to @0@)
* @cast(string) 5@
* `cast(int) "256"` (only supports decimal representations and no suffix like above)
* `cast(int) true` (`true` maps to `1` and `false` to `0`)
* `cast(string) 5`
Expressions can be grouped to override default association:
* @3 * (1 + 2)@ vs. @3 * 1 + 2@ and so on
]]></textile>
* `3 * (1 + 2)` vs. `3 * 1 + 2` and so on
]]></markdown>
</section>
<section title="Action Blocks">
<textile><![CDATA[
<markdown><![CDATA[
An action block consists of a list of function calls (in action context) and conditionals; it is treated like a value, i.e. can be assigned to variables and used as parameter in function calls.
Action blocks can also contain variable assignments and setup blocks/function calls, which are not part of the "action block value" itself, but are evaluated while parsing the config.
The syntax is:
<pre>
```
{
log "hello world";
if req.path =$ ".hidden" { static; }
}
</pre>
```
The complete config is an action block too (but without the surrounding curly braces); conditionals also use action blocks for their branches.
Each action block that is not a condition branch starts a new nested variable scope;
]]></textile>
]]></markdown>
</section>
<section title="Variables" anchor="variables">
<textile><![CDATA[
Variable names start with a alphabetic character (@a-z@ and @A-Z@) or an underscore @_@, and are followed by alphanumeric characters, underscores @_@ and dots @.@; keywords are not allowed as variable names.
<markdown><![CDATA[
Variable names start with a alphabetic character (`a-z` and `A-Z`) or an underscore `_`, and are followed by alphanumeric characters, underscores `_` and dots `.`; keywords are not allowed as variable names.
Variables store values, and the name can be used in place of an actual value; later modifications to a variable have no influence on previous uses (i.e. are only evaluated while *parsing* the config).
Variables store values, and the name can be used in place of an actual value; later modifications to a variable have no influence on previous uses (i.e. are only evaluated while **parsing** the config).
Variables are assigned values with @=@ (and a terminating @;@)
Variables are assigned values with `=` (and a terminating `;`)
<pre>
```
my_types = [".txt" => "text/html"];
php = {
if phys.path =$ ".php" { fastcgi "unix:/var/run/lighttpd/php.sock"; }
};
</pre>
```
By default variables assignment overwrites an existing variable (in its previous scope) or, if it doesn't exist, creates a new one in the local scope (i.e. it will only be available in the current scope and nested descendants).
You can explicitly create a new variable in the local scope (hiding variables in parent scopes with the same name) by prefixing the assignment with @local@:
You can explicitly create a new variable in the local scope (hiding variables in parent scopes with the same name) by prefixing the assignment with `local`:
<pre>
```
local wwwpath = "/var/www/example.com";
</pre>
```
You can also create variables in the global scope by prefixing the assignment with @global@.
The main config already is in a nested scope (i.e. *not* the global scope). The global scope is not destroyed after config loading, and can be used in delayed config loading (say from SQL in the future).
You can also create variables in the global scope by prefixing the assignment with `global`.
The main config already is in a nested scope (i.e. **not** the global scope). The global scope is not destroyed after config loading, and can be used in delayed config loading (say from SQL in the future).
If a variable name is used in a context it will always use the definition from the nearest scope.
]]></textile>
]]></markdown>
<example>
<description>
<description><markdown>
This example illustrates that variables are evaluated while parsing the config.
</description>
</markdown></description>
<config>
foo = "bar";
if req.path == "/somepath" {
@ -184,9 +193,9 @@
</example>
<example>
<description>
<description><markdown>
This example illustrates scoping.
</description>
</markdown></description>
<config>
foo = "bar";
php = {
@ -200,57 +209,60 @@
</section>
<section title="Special Variables">
<textile><![CDATA[
@sys.*@ variables are readonly. right now the following @sys.*@ variables are available:
* @sys.pid@: the process id of lighttpd
* @sys.cwd@: the current working directory
* @sys.env.X@: the system environment variable with name @X@ (for any @X@)
]]></textile>
<markdown><![CDATA[
`sys.*` variables are readonly. right now the following `sys.*` variables are available:
* `sys.pid`: the process id of lighttpd
* `sys.cwd`: the current working directory
* `sys.env.X`: the system environment variable with name `X` (for any `X`)
]]></markdown>
</section>
</section>
<section title="Function calls" anchor="funcalls">
<textile><![CDATA[
<markdown><![CDATA[
There are three types of function calls:
* actions
* setups
* options
Actions can only be used in action (block) context, setups only in setup (block) context, and options can be used in both.
A setup context is started with the keyword @setup@, and is followed by either a single setup function call or a setup block.
A setup context is started with the keyword `setup`, and is followed by either a single setup function call or a setup block.
Setup function calls are run immediately when they occur (they are used to "setup" the webserver environment, like listening on TCP sockets, and setting default options), while action function calls are run for each request (mapping request urls to physical paths, handling requests, modifying the default options).
The actions, setups and options are provided by the "modules":index_modules.html#index_modules.
]]></textile>
The actions, setups and options are provided by the [modules](index_modules.html#index_modules).
]]></markdown>
<section title="Includes" anchor="includes">
<textile><![CDATA[
<markdown><![CDATA[
Includes are similar to function calls in the syntax, but are directly handled by the config parser. They are only allowed in action context, as they insert a reference to an action block at the point they are used.
There are three types of includes:
* @include "/etc/lighttpd/vhosts/*.conf";@: include files like the main config itself; the path can contain wildcards
* @include_shell "/etc/lighttpd/config_generator.sh";@: runs the specified command, and parses the output of it as config file
* @include_lua "/etc/lighttpd/complex.lua"@: includes a Lua config file. The single action to be executed must be returned in the global @actions@ variable (or leave it empty to do nothing). See also "@lua.handler@":mod_lua.html#mod_lua__action_lua-handler
* `include "/etc/lighttpd/vhosts/*.conf";`: include files like the main config itself; the path can contain wildcards
* `include_shell "/etc/lighttpd/config_generator.sh";`: runs the specified command, and parses the output of it as config file
* `include_lua "/etc/lighttpd/complex.lua"`: includes a Lua config file. The single action to be executed must be returned in the global `actions` variable (or leave it empty to do nothing). See also [`lua.handler`](mod_lua.html#mod_lua__action_lua-handler).
Includes also create a new nested scope.
]]></textile>
]]></markdown>
</section>
<section title="Debug Print">
<textile><![CDATA[
Similar to includes @__print@ is a special function, but is available in action and setup context. It logs the string values of its parameter(s) with log level "debug".
]]></textile>
<markdown><![CDATA[
Similar to includes `__print` is a special function, but is available in action and setup context. It logs the string values of its parameter(s) with log level "debug".
]]></markdown>
</section>
</section>
<section title="Conditions" anchor="conditions">
<textile><![CDATA[
Conditions (known from Lighttpd 1.x) are the equivalent to "if"s in most programming languages. There are also "else" and "elseif" equivalents.
They are created by a comparison of a condition variable and a value that is evaluated at runtime (for each request).
Conditions can be nested, and you can group them with @and@ and @or@ operators. @and@ binds stronger than @or@, although it is preferred to group them with parentheses.
]]></textile>
<markdown><![CDATA[
Conditions (known from Lighttpd 1.x) are the equivalent to "if"s in most programming languages. There are also "else" and "elseif" equivalents.
They are created by a comparison of a condition variable and a value that is evaluated at runtime (for each request).
Conditions can be nested, and you can group them with `and` and `or` operators. `and` binds stronger than `or`, although it is preferred to group them with parentheses.
]]></markdown>
<example>
<config>
@ -269,31 +281,34 @@
</example>
<section title="Syntax">
<textile><![CDATA[
<markdown><![CDATA[
The basic syntax forms are:
* @if <expr> { ... }@
* @if <expr> { ... } else { ... }@
* @if <expr> { ... } else if <expr2> { ... }@
* @if <expr> { ... } else if <expr2> { ... } ...@ (continue with @else@ or @else if@)
A condition expression @<expr>@ is:
* @(<expr>)@
* @<expr1> and <expr2>@
* @<expr1> or <expr1>@ (@<expr1> and <expr2> or <expr3>@ = @(<expr1> and <expr2>) or <expr3>@; @and@ has higher precedence)
* @<condvar> <op> <value>@ for @<condvar>@ being a condition variable (with a type different from boolean), @<op>@ an condition operator and @<value>@ a string or a number.
* @<condvar>@ or @!<condvar>@ for a boolean condition variable.
]]></textile>
* `if <expr> { ... }`
* `if <expr> { ... } else { ... }`
* `if <expr> { ... } else if <expr2> { ... }`
* `if <expr> { ... } else if <expr2> { ... } ...` (continue with `else` or `else if`)
A condition expression `<expr>` is:
* `(<expr>)`
* `<expr1> and <expr2>`
* `<expr1> or <expr1>` (`<expr1> and <expr2> or <expr3>` = `(<expr1> and <expr2>) or <expr3>`; `and` has higher precedence)
* `<condvar> <op> <value>` for `<condvar>` being a condition variable (with a type different from boolean), `<op>` an condition operator and `<value>` a string or a number.
* `<condvar>` or `!<condvar>` for a boolean condition variable.
]]></markdown>
</section>
<section title="Condition variables" anchor="condition_vars">
<textile><![CDATA[
<markdown><![CDATA[
There are three categories of condvars:
* request.xyz (can be abbreviated by req.xyz)
* physical.xyz (can be abbreviated by phys.xyz)
* response.xyz (can be abbreviated by resp.xyz)
table(table table-striped).
|_. variable |_. description |
| variable | description |
|----------|-------------|
| request.localip | ip address of the listing socket, the client connected to (filename for unix sockets) |
| request.localport | port number of the listening socket, -1 for unix sockets |
| request.remoteip | ip address of the client |
@ -308,7 +323,7 @@
| request.header["name"] | request header _name_ e.g. request.header["referer"] |
| request.is_handled | boolean condition, does request already have a handler (static, fastcgi..) |
| request.environment["name"] | (or short request.env["name"]) CGI environment |
| | |
|-|-|
| physical.path | physical path of the file to be served. e.g. document root + path |
| physical.exists | boolean condition, indicates whether the requested file (normal file, directory or even a special file) exists |
| physical.size | integer. size of the requested file. -1 if file doesn't exist |
@ -316,24 +331,26 @@
| physical.is_file | boolean condition, indicates whether the requested file is a normal file (e.g. no unix socket etc) |
| physical.docroot | document root |
| physical.pathinfo | pathinfo |
| | |
|-|-|
| response.status | response status code (blocks request until response header is available) |
| response.header["name"] | response header (blocks request until response header is available) |
]]></textile>
{:.table .table-striped}
]]></markdown>
</section>
<section title="Condition operators">
<textile><![CDATA[
table(table table-striped).
|_. op |_. description |_. op |_. description |
| <notextile>==</notextile> | compares two values on equality | != | negative == |
<markdown><![CDATA[
| op | description | op | description |
|----|-------------|----|-------------|
| == | compares two values on equality | != | negative == |
| <= | less than or equal | < | less than |
| >= | greater than or equal | > | greater than |
| =~ | regular expression match | !~ | negative =~ |
| =^ | prefix match | !^ | negative =^ |
| =$ | suffix match | !$ | negative =$ |
| =/ | cidr match | !/ | negative =/ |
]]></textile>
{:.table .table-striped}
]]></markdown>
</section>
</section>

View File

@ -1,39 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<angel-module xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Angel Configuration">
<description>
<textile>
lighttpd2 consists of two main binaries: the angel (@lighttpd2@) and the worker (@lighttpd2-worker@). The "main configuration":core_config.html#core_config is used by the worker, and this chapter describes the configuration for the angel.
A standard distribution should install a angel config in @/etc/lighttpd2/angel.conf@ with reasonable defaults which should work for most basic setups.
</textile>
</description>
<description><markdown>
lighttpd2 consists of two main binaries: the angel (`lighttpd2`) and the worker (`lighttpd2-worker`). The [main configuration](core_config.html#core_config) is used by the worker, and this chapter describes the configuration for the angel.
A standard distribution should install a angel config in `/etc/lighttpd2/angel.conf` with reasonable defaults which should work for most basic setups.
</markdown></description>
<section title="Angel concept">
<textile>
<markdown>
You can start the worker without the angel, but the angel provides some useful features:
* The angel itself usually runs as root (needed for example to bind to privileged ports), but will spawn the worker with dropped privileges (usually a user like @www-data@ is used). The worker doesn't do any privilege dropping itself.
* The angel itself usually runs as root (needed for example to bind to privileged ports), but will spawn the worker with dropped privileges (usually a user like `www-data` is used). The worker doesn't do any privilege dropping itself.
* The angel can open/create log files for the worker with root permissions
* The angel supports a graceful restart of the worker for config reloading: a new instance is spawned, and if it started successfully (checking config, ...) it will replace the old instance. The old instance will finish the remaining requests.
* The angel supports a graceful restart of the worker for config reloading: a new instance is spawned, and if it started successfully (checking config, ...) it will replace the old instance. The old instance will finish the remaining requests.
As the angel is responsible for creating the listening network sockets, it can keep them open all the time and no request is lost.
* The angel also does a simple supervise: if the worker crashes the angel will respawn it.
</textile>
</markdown>
</section>
<section title="Config items">
<textile>
The config syntax is very similar to the "main configuration":core_config, although it has no action blocks, setup blocks, conditionals and scopes.
</textile>
<markdown>
The config syntax is very similar to the [main configuration](core_config), although it has no action blocks, setup blocks, conditionals and scopes.
</markdown>
<item name="user">
<short>drops privileges for spawning the worker</short>
<parameter name="username">
<short>username to drop privileges to for spawning the worker</short>
</parameter>
<description>
<textile>
This item can only be specified once; if it is not specified it won't drop privileges at all, which is useful if the angel itself doesn't run as root. It should go without saying that you should never run the worker as root.
The username is also used to find all groups the user is in.
</textile>
</description>
<description><markdown>
This item can only be specified once; if it is not specified it won't drop privileges at all, which is useful if the angel itself doesn't run as root. It should go without saying that you should never run the worker as root.
The username is also used to find all groups the user is in.
</markdown></description>
<example>
<config>
user "www-data";
@ -46,12 +43,10 @@
<parameter name="groupname">
<short>groupname to drop privileges to for spawning the worker</short>
</parameter>
<description>
<textile>
Specify the main group to drop privileges to; a process can have multiple groups, and the others are given by the groups the user specified by @user@ is in.
The default is the main group of the user specified by @user@, or not dropping privileges at all.
</textile>
</description>
<description><markdown>
Specify the main group to drop privileges to; a process can have multiple groups, and the others are given by the groups the user specified by `user` is in.
The default is the main group of the user specified by `user`, or not dropping privileges at all.
</markdown></description>
<example>
<config>
group "www-data";
@ -62,13 +57,11 @@
<item name="binary">
<short>specifies path to worker binary</short>
<parameter name="path">
<short>path to the @lighttpd2-worker@ binary</short>
<short>path to the lighttpd2-worker binary</short>
</parameter>
<description>
<textile>
This item should only be needed if you didn't install the binaries at all (for testing).
</textile>
</description>
<description><markdown>
This item should only be needed if you didn't install the binaries at all (for testing).
</markdown></description>
<example>
<config>
binary "/home/source/lighttpd2/autobuild/src/main/lighttpd2-worker";
@ -81,11 +74,9 @@
<parameter name="path">
<short>path to the main config file</short>
</parameter>
<description>
<textile>
By default @/etc/lighttpd2/lighttpd.conf@ is used.
</textile>
</description>
<description><markdown>
By default `/etc/lighttpd2/lighttpd.conf` is used.
</markdown></description>
<example>
<config>
config "/etc/lighttpd2-test/lighttpd.conf";
@ -98,11 +89,9 @@
<parameter name="path">
<short>path to the lua config file</short>
</parameter>
<description>
<textile>
By default a normal config file is used; you must use either a normal config file or a lua config file.
</textile>
</description>
<description><markdown>
By default a normal config file is used; you must use either a normal config file or a lua config file.
</markdown></description>
<example>
<config>
luaconfig "/etc/lighttpd2/lighttpd.lua";
@ -115,11 +104,9 @@
<parameter name="path">
<short>path to the directory containing modules for the worker</short>
</parameter>
<description>
<textile>
This item should only be needed if you didn't install the binaries at all (for testing). For autotool builds the "real" module binaries are in a @.libs@ subdirectory.
</textile>
</description>
<description><markdown>
This item should only be needed if you didn't install the binaries at all (for testing). For autotool builds the "real" module binaries are in a `.libs` subdirectory.
</markdown></description>
<example>
<config>
modules_path "/home/source/lighttpd2/autobuild/src/modules/.libs";
@ -132,12 +119,10 @@
<parameter name="wrappers">
<short>path to a wrapper command and its arguments</short>
</parameter>
<description>
<textile>
This item appends all given strings to the command prefix list (which starts as empty list). Before spawning the worker the binary path to the worker and its arguments (config, module path) are appended.
Wrappers can be used to run the worker with valgrind, strace and similar.
</textile>
</description>
<description><markdown>
This item appends all given strings to the command prefix list (which starts as empty list). Before spawning the worker the binary path to the worker and its arguments (config, module path) are appended.
Wrappers can be used to run the worker with valgrind, strace and similar.
</markdown></description>
<example>
<config>
# in multiple lines
@ -156,11 +141,9 @@
<parameter name="vars">
<short>list of environment variables to add for the worker to run with</short>
</parameter>
<description>
<textile><![CDATA[
Append the given list of environment variables (starts empty), which can be either strings of the form @"var=xyz"@ or key-value pairs @"var" => "xyz"@ (the keys must not contain any @=@).
]]></textile>
</description>
<description><markdown><![CDATA[
Append the given list of environment variables (starts empty), which can be either strings of the form `"var=xyz"` or key-value pairs `"var" => "xyz"` (the keys must not contain any `=`).
]]></markdown></description>
<example>
<config>
# helps debugging with valgrind:
@ -174,11 +157,9 @@
<parameter name="varnames">
<short>list of environment variable names to copy</short>
</parameter>
<description>
<textile>
Adds copies of variables from the current environment. By default all variables will be dropped.
</textile>
</description>
<description><markdown>
Adds copies of variables from the current environment. By default all variables will be dropped.
</markdown></description>
<example>
<config>
env_copy [ "PATH" ];
@ -191,10 +172,10 @@
<parameter name="limit">
<short>limit in bytes</short>
</parameter>
<description>
Maximum size of a core file, in bytes, that may be created by the worker. Core files are created when the worker crashes.
<description><markdown>
Maximum size of a core file, in bytes, that may be created by the worker. Core files are created when the worker crashes.
0 disables core files, and by default the limit is not changed.
</description>
</markdown></description>
</item>
<item name="max_open_files">
@ -202,10 +183,10 @@
<parameter name="limit">
<short>maximum number of open files</short>
</parameter>
<description>
The worker limits the maximum number of connection based on the maximum number of open files (max connections = max open files / 4).
<description><markdown>
The worker limits the maximum number of connection based on the maximum number of open files (max connections = max open files / 4).
By default the limit is not changed.
</description>
</markdown></description>
<example>
<config>
# max 4096 connections
@ -219,20 +200,19 @@
<parameter name="list">
<short>list of network mask (CIDR) + optional port or unix domain socket addresses</short>
</parameter>
<description>
<textile>
The worker uses the angel to bind TCP/unix sockets; the angel checks whether those binds are allowed. If no @allow_listen@ is specified, all TCP binds (IPv4 and IPv6) using port 80 or 443 are allowed.
IPv4 and IPv6 use different masks (no IPv4 to IPv6 mapping), the network length for the CIDR mask is optional (defaults to a host address), and the port is optional too (allowing both 80 and 443 if omitted).
Formats:
* TCP on IPv4: @ipv4@, @ipv4:port@, @ipv4/net@, @ipv4/net:port@
* TCP on IPv6: @ipv6@, @ipv6/net@, @[ipv6]@, @[ipv6/net]@, @[ipv6]:port@, @[ipv6/net]:port@
* Unix domain: @unix:/wildcard/path/to/*.socket@
</textile>
</description>
<description><markdown>
The worker uses the angel to bind TCP/unix sockets; the angel checks whether those binds are allowed. If no `allow_listen` is specified, all TCP binds (IPv4 and IPv6) using port 80 or 443 are allowed.
IPv4 and IPv6 use different masks (no IPv4 to IPv6 mapping), the network length for the CIDR mask is optional (defaults to a host address), and the port is optional too (allowing both 80 and 443 if omitted).
Formats:
* TCP on IPv4: `ipv4`, `ipv4:port`, `ipv4/net`, `ipv4/net:port`
* TCP on IPv6: `ipv6`, `ipv6/net`, `[ipv6]`, `[ipv6/net]`, `[ipv6]:port`, `[ipv6/net]:port`
* Unix domain: `unix:/wildcard/path/to/*.socket`
</markdown></description>
<example>
<description>
Only allow TCP port 8080 for IPv4 and IPv6 and unix domain socket @/run/lighttpd/internal.sock@.
</description>
<description><markdown>
Only allow TCP port 8080 for IPv4 and IPv6 and unix domain socket `/run/lighttpd/internal.sock`.
</markdown></description>
<config>
allow_listen [ "0.0.0.0/0:8080", "[::/0]:8080" ];
allow_listen "unix:/run/lighttpd/internal.sock";

View File

@ -1,10 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Fetch API" order="core_regex_after_01_fetch">
<description>
<textile>
The Fetch API provides a common interface between lighttpd modules to lookup entries in a database. Both lookup key and data are simple (binary) strings.
<description><markdown>
The Fetch API provides a common interface between lighttpd modules to lookup entries in a database. Both lookup key and data are simple (binary) strings.
So far only a "fetch.files_static":plugin_core.html#plugin_core__setup_fetch-files_static is providing a database, and only "gnutls":mod_gnutls.html#mod_gnutls__setup_gnutls is using it to lookup SNI certificates.
</textile>
</description>
So far only a [fetch.files_static](plugin_core.html#plugin_core__setup_fetch-files_static) is providing a database, and only [gnutls](mod_gnutls.html#mod_gnutls__setup_gnutls) is using it to lookup SNI certificates.
</markdown></description>
</chapter>

View File

@ -2,21 +2,23 @@
<chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Introduction" order="a01_introduction">
<section title="Running lighttpd2">
<textile><![CDATA[
<markdown><![CDATA[
You need two config files for lighttpd, which are usually in the following two locations:
* "@/etc/lighttpd2/lighttpd.conf@":http://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/lighttpd.conf: the main config, see "Main Configuration":core_config.html#core_config. It can be split into multiple files, see "Includes":core_config.html#core_config__includes.
* "@/etc/lighttpd2/angel.conf@":http://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/angel.conf: the angel config, see "Angel Configuration":core_config_angel.html#core_config_angel.
* [`/etc/lighttpd2/lighttpd.conf`](https://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/lighttpd.conf): the main config, see [Main Configuration](core_config.html#core_config). It can be split into multiple files, see [Includes](core_config.html#core_config__includes).
* [`/etc/lighttpd2/angel.conf`](https://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/angel.conf): the angel config, see [Angel Configuration](core_config_angel.html#core_config_angel).
The "@contrib/@":http://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib directory in the sources includes example config files.
The [`contrib/`](https://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib) directory in the sources includes example config files.
Then start lighttpd2 with:
<pre>/usr/sbin/lighttpd2 -c /etc/lighttpd2/angel.conf</pre>
```
/usr/sbin/lighttpd2 -c /etc/lighttpd2/angel.conf
```
The process will not fork into background, you need to do that yourself if you want that.
Our recommended way to run lighttpd2 is "runit":http://smarden.org/runit/useinit.html (have a look at the "@contrib/service@":http://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/service directory).
]]></textile>
The process will not fork into background, you need to do that yourself if you want that.
Our recommended way to run lighttpd2 is [runit](http://smarden.org/runit/useinit.html) (have a look at the [`contrib/service`](https://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/service) directory).
]]></markdown>
</section>
</chapter>

View File

@ -1,26 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Lua API" order="core_regex_after_02_lua">
<description>
<textile>
Lua can be used to generate configs (like a shortcut to "@include_shell@":core_config.html#core_config__includes) or to write actual response handlers.
<description><markdown>
Lua can be used to generate configs (like a shortcut to [`include_shell`](core_config.html#core_config__includes)) or to write actual response handlers.
Using Lua to generate configs doesn't have any performance impact; in this case Lua is only run at startup to generate the config, and there is no Lua involved for processing requests.
Using Lua to generate configs doesn't have any performance impact; in this case Lua is only run at startup to generate the config, and there is no Lua involved for processing requests.
As a @lua_State@ itself is not thread-safe, you have two ways to use Lua configs:
* "@include_lua@":core_config.html#core_config__includes and "@lua.plugin@":mod_lua.html#mod_lua__setup_lua-plugin : using a global server lock, but with sharing the same @lua_State@ in all workers
* "@lua_handler@":mod_lua.html#mod_lua__action_lua-handler: without locking, and every worker has its own @lua_State@ (and they cannot share their global context).
</textile>
</description>
As a `lua_State` itself is not thread-safe, you have two ways to use Lua configs:
* [`include_lua`](core_config.html#core_config__includes) and [`lua.plugin`](mod_lua.html#mod_lua__setup_lua-plugin): using a global server lock, but with sharing the same `lua_State` in all workers
* [`lua_handler`](mod_lua.html#mod_lua__action_lua-handler): without locking, and every worker has its own `lua_State` (and they cannot share their global context).
</markdown></description>
<section title="Lua Config">
<textile>
This section describe how to translate concepts from the main config to Lua. You can write the whole config in Lua or only parts and include them (for example with "@include_lua@":core_config.html#core_config__includes).
</textile>
<markdown>
This section describe how to translate concepts from the main config to Lua. You can write the whole config in Lua or only parts and include them (for example with [`include_lua`](core_config.html#core_config__includes)).
</markdown>
<example title="Example - debug.lua">
<description><textile><![CDATA[
The following Lua snippet saved as "debug.lua" could for example be included with @include_lua "debug.lua"@.
]]></textile></description>
<description><markdown><![CDATA[
The following Lua snippet saved as "debug.lua" could for example be included with `include_lua "debug.lua"`.
]]></markdown></description>
<config><![CDATA[
function mydebug(vr)
@ -55,62 +54,63 @@
</example>
<section title="Values">
<textile><![CDATA[
* Boolean: Lua supports @true@ and @false@ directly
* Integers: Lua has its own number type (usually a "@double@":http://en.wikipedia.org/wiki/Double-precision_floating-point_format), and doesn't know any of the suffixes.
<markdown><![CDATA[
* Boolean: Lua supports `true` and `false` directly
* Integers: Lua has its own number type (usually a [`double`](https://en.wikipedia.org/wiki/Double-precision_floating-point_format)), and doesn't know any of the suffixes.
* Strings: Lua supports strings directly. Check the Lua reference for the various quoting styles.
* Lists and Key-Value-Lists: Lua has a "table" type; it can contain sequential lists and associative mappings. Use @{1, 2, 3}@ to create simple lists, @{a=1, b=2}@ to create unique mappings (which get converted to Key-Value-Lists) or @{{"a",1},{"a",2}}@ to explicitly create Key-Value-Lists (where a key can be used more than once and the order matters).
Don't mix sequential lists and associative mappings.
If you get a List (possible a Key-Value-List) value from lighttpd it is represented as sequential list but has a special @__index@ meta-table method supporting strings and @nil@ as lookup parameter, i.e. you can treat a Key-Value-List like an associative mapping in Lua (see for example the options handling in "contrib/secdownload.lua":http://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/secdownload.lua).
* Lists and Key-Value-Lists: Lua has a "table" type; it can contain sequential lists and associative mappings. Use `{1, 2, 3}` to create simple lists, `{a=1, b=2}` to create unique mappings (which get converted to Key-Value-Lists) or `{{"a",1},{"a",2}}` to explicitly create Key-Value-Lists (where a key can be used more than once and the order matters).
Don't mix sequential lists and associative mappings.
If you get a List (possible a Key-Value-List) value from lighttpd it is represented as sequential list but has a special `__index` meta-table method supporting strings and `nil` as lookup parameter, i.e. you can treat a Key-Value-List like an associative mapping in Lua (see for example the options handling in [contrib/secdownload.lua](https://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/secdownload.lua)).
* Expressions and variables just are the usual Lua things; there is no direct access to the lighttpd config variables (yet).
* Action blocks: you can make an action from a list of actions using the "list action":plugin_core.html#plugin_core__action_list (@act = action.list(act1, act2)@)
]]></textile>
* Action blocks: you can make an action from a list of actions using the [list action](plugin_core.html#plugin_core__action_list) (`act = action.list(act1, act2)`)
]]></markdown>
</section>
<section title="Function calls">
<textile><![CDATA[
Action context is given by prefixing the function name with @action.@, and setup context by prefixing with @setup.@. Don't try to call setups in request handling.
<markdown><![CDATA[
Action context is given by prefixing the function name with `action.`, and setup context by prefixing with `setup.`. Don't try to call setups in request handling.
Also each Lua function can act as an action (see the debug.lua example above), taking a virtual request object as parameter.
Includes are not supported, neither is the debug @__print@ (there are other logging methods available).
]]></textile>
Includes are not supported, neither is the debug `__print` (there are other logging methods available).
]]></markdown>
</section>
<section title="Conditions">
<textile><![CDATA[
<markdown><![CDATA[
Conditions are the ugliest part: there is no way translating native Lua if statements into the lighttpd config, so they need to be constructed manually.
Only the long names of the condition variables are available in Lua. The condition operators are all given names and appended to the condition variable, and then called with the value to compare with.
table(table table-striped).
|_. op |_. Lua name |_. op |_. Lua name |
| <notextile>==</notextile> | @:eq@ | != | @:ne@ |
| <= | @:le@ | < | @:lt@ |
| >= | @:ge@ | > | @:gt@ |
| =~ | @:match@ | !~ | @:nomatch@ |
| =^ | @:prefix@ | !^ | @:notprefix@ |
| =$ | @:suffix@ | !$ | @:notsuffix@ |
| =/ | @:ip@ | !/ | @:notip@ |
| op | Lua name | op | Lua name |
|----|-----------|----|----------|
| == | `:eq` | != | `:ne` |
| <= | `:le` | < | `:lt` |
| >= | `:ge` | > | `:gt` |
| =~ | `:match` | !~ | `:nomatch` |
| =^ | `:prefix` | !^ | `:notprefix` |
| =$ | `:suffix` | !$ | `:notsuffix` |
| =/ | `:ip` | !/ | `:notip` |
{:.table .table-striped }
Boolean condition variables are called with @:is()@ or @:isnot()@.
Boolean condition variables are called with `:is()` or `:isnot()`.
The result of such call (a "condition") is then passed as first parameter to "@action.when@":plugin_core#plugin_core__action_when.
]]></textile>
The result of such call (a "condition") is then passed as first parameter to [`action.when`](plugin_core#plugin_core__action_when).
]]></markdown>
<example title="Example - admin only">
<description><textile>
Translating @if req.env["REMOTE_USER"] != "admin" { auth.deny; }@ to Lua:
</textile></description>
<description><markdown>
Translating `if req.env["REMOTE_USER"] != "admin" { auth.deny; }` to Lua:
</markdown></description>
<config><![CDATA[
actions = action.when(request.environment["REMOTE_USER"]:ne("admin"), action.auth.deny())
]]></config>
</example>
<example title="Example - physical files only">
<description><textile>
Translating @if !phys.exists { auth.deny; }@ to Lua:
</textile></description>
<description><markdown>
Translating `if !phys.exists { auth.deny; }` to Lua:
</markdown></description>
<config><![CDATA[
actions = action.when(physical.exists:isnot(), action.auth.deny())
]]></config>
@ -119,67 +119,67 @@
</section>
<section title="API">
<textile><![CDATA[
<markdown><![CDATA[
This section documents the object types you need to handle requests; you will probably start from the Virtual Request object you get as parameter in your handler.
Object fields should be accessed with @.field@ or @["field"]@, for example:
Object fields should be accessed with `.field` or `["field"]`, for example:
<pre>
```
e = vr.env
e["XXX"] = "abc"
</pre>
```
Fields tagged with (ro) are read only; that does not mean the fields value can't be modified, you only cannot overwrite the field with another object. Readonly string / number properties are really read only though.
Call object methods with @:method(...)@:
Call object methods with `:method(...)`:
<pre>
```
vr:print("Hello World")
</pre>
```
*Note*:
The @obj:method(par1, par2, ...)@ syntax is just another way to say @obj["method"](obj, par1, par2, ...)@ (but @obj@ is only evaluated once), so field and method names live in the same namespace.
This means that our container types cannot provide access to fields which have the same names as the methods (and the methods starting with "__" are not listed here), so you have to use explicit access methods to read generic fields in such containers (write is not a problem as we don't allow writing methods).
All container types should provide a @get@ and a @set@ method to provide "clean" access to the container contents.
**Note**:
The `obj:method(par1, par2, ...)` syntax is just another way to say `obj["method"](obj, par1, par2, ...)` (but `obj` is only evaluated once), so field and method names live in the same namespace.
This means that our container types cannot provide access to fields which have the same names as the methods (and the methods starting with "__" are not listed here), so you have to use explicit access methods to read generic fields in such containers (write is not a problem as we don't allow writing methods).
All container types should provide a `get` and a `set` method to provide "clean" access to the container contents.
h3. pairs()
### pairs()
Some objects may provide a @:pairs()@ method to loop through the fields (not the methods); this works for simple things like
Some objects may provide a `:pairs()` method to loop through the fields (not the methods); this works for simple things like
<pre>
```
for k, v in vr.env:pairs() do
vr:print("env['" .. k .. "'] = '" .. v .. "'")
end
</pre>
```
lua expects that the @:pairs@ method returns a @next, obj, startkey@ tuple and loops through the list with @k = startkey; while k, v = next(obj, k) do ... end@; but the @next()@ method is supposed to use @k@ as previous key and to return the next one.
Our @next@ methods will keep the current position in an internal object (associated with the @next@ function as upvalue), and will advance on every call ignoring the @obj@ and @k@ parameter.
]]></textile>
lua expects that the `:pairs` method returns a `next, obj, startkey` tuple and loops through the list with `k = startkey; while k, v = next(obj, k) do ... end`; but the `next()` method is supposed to use `k` as previous key and to return the next one.
Our `next` methods will keep the current position in an internal object (associated with the `next` function as upvalue), and will advance on every call ignoring the `obj` and `k` parameter.
]]></markdown>
<section title="Global constants">
<textile><![CDATA[
@liHandlerResult@ enumeration values:
<markdown><![CDATA[
`liHandlerResult` enumeration values:
* @lighty.HANDLER_GO_ON@
* @lighty.HANDLER_COMEBACK@
* @lighty.HANDLER_WAIT_FOR_EVENT@
* @lighty.HANDLER_ERROR@
]]></textile>
* `lighty.HANDLER_GO_ON`
* `lighty.HANDLER_COMEBACK`
* `lighty.HANDLER_WAIT_FOR_EVENT`
* `lighty.HANDLER_ERROR`
]]></markdown>
</section>
<section title="Global methods">
<textile><![CDATA[
* @lighty.print@ (and @lighty.error@ and @print@): print parameters via lua "tostring" method as ERROR in global server context
* @lighty.warning@: print parameters via lua "tostring" method as WARNING in global server context
* @lighty.info@: print parameters via lua "tostring" method as INFO in global server context
* @lighty.debug@: print parameters via lua "tostring" method as DEBUG in global server context
* @lighty.filter_in(class)@: creates a new action, which adds a incoming filter from @class:new(vr)@ if called at runtime
* @lighty.filter_out(class)@: creates a new action, which adds a outgoing filter from @class:new(vr)@ if called at runtime
* @lighty.md5(str)@: calculates the md5 checksum of the string @str@ (returns the digest as string in hexadecimal)
* @lighty.sha1(str)@: calculates the sha1 checksum of the string @str@ (returns the digest as string in hexadecimal)
* @lighty.sha256(str)@: calculates the sha256 checksum of the string @str@ (returns the digest as string in hexadecimal)
* @lighty.path_simplify(str)@: return simplified path
]]></textile>
<markdown><![CDATA[
* `lighty.print` (and `lighty.error` and `print`): print parameters via lua "tostring" method as ERROR in global server context
* `lighty.warning`: print parameters via lua "tostring" method as WARNING in global server context
* `lighty.info`: print parameters via lua "tostring" method as INFO in global server context
* `lighty.debug`: print parameters via lua "tostring" method as DEBUG in global server context
* `lighty.filter_in(class)`: creates a new action, which adds a incoming filter from `class:new(vr)` if called at runtime
* `lighty.filter_out(class)`: creates a new action, which adds a outgoing filter from `class:new(vr)` if called at runtime
* `lighty.md5(str)`: calculates the md5 checksum of the string `str` (returns the digest as string in hexadecimal)
* `lighty.sha1(str)`: calculates the sha1 checksum of the string `str` (returns the digest as string in hexadecimal)
* `lighty.sha256(str)`: calculates the sha256 checksum of the string `str` (returns the digest as string in hexadecimal)
* `lighty.path_simplify(str)`: return simplified path
]]></markdown>
<example>
<config><![CDATA[
@ -206,167 +206,177 @@
</section>
<section title="Virtual Request">
<textile><![CDATA[
<markdown><![CDATA[
Fields:
* @con@(ro): Connection
* @in@(ro): Chunk Queue, read request post content
* @out@(ro): Chunk Queue, write response content
* @env@(ro): Environment, (fast)cgi environment
* @req@(ro): Request, data from request header
* @resp@(ro): Response, response header data
* @phys@(ro): Physical, paths and filenames
* @is_handled@(ro): whether vrequest is already handled
* @has_response@(ro): whether the response headers (and status) is available
* `con`(ro): Connection
* `in`(ro): Chunk Queue, read request post content
* `out`(ro): Chunk Queue, write response content
* `env`(ro): Environment, (fast)cgi environment
* `req`(ro): Request, data from request header
* `resp`(ro): Response, response header data
* `phys`(ro): Physical, paths and filenames
* `is_handled`(ro): whether vrequest is already handled
* `has_response`(ro): whether the response headers (and status) is available
Methods:
* @print(...)@: print parameters via lua @tostring@ method as ERROR in Virtual Request context
* @warning(...)@: print parameters via lua @tostring@ method as WARNING in Virtual Request context
* @info(...)@: print parameters via lua @tostring@ method as INFO in Virtual Request context
* @debug(...)@: print parameters via lua @tostring@ method as DEBUG in Virtual Request context
* @handle_direct()@: handle vrequest (i.e. provide headers and body); returns true if not already handled.
* @enter_action(act)@: push a new action on the action stack (return HANDLER_WAIT_FOR_EVENT to rerun after the pushed actions are done, HANDLER_GO_ON if you are done)
* @st, res, errno, msg = stat(filename)@: async stat(filename). Following results are possible
** st is the stat result, res == HANDLER_GO_ON, if the file was found. errno and msg are NIL. In all other cases st is NIL and res != HANDLER_GO_ON.
** res == HANDLER_WAIT_FOR_EVENT: stat() is in progress, just try again later (and return HANDLER_WAIT_FOR_EVENT in the meantime)
** res == HANDLER_ERROR: if stat() failed, errno contains the errno and msg the error message for the errno code.
* @add_filter_in(obj)@: adds @obj@ as lua incoming filter (needs to respond to @obj:handle(vr, outq, inq)@ and optionally @obj:finished()@); returns a Filter object
* @add_filter_out(obj)@: adds @obj@ as lua outgoing filter (needs to respond to @obj:handle(vr, outq, inq)@ and optionally @obj:finished()@); returns a Filter object
]]></textile>
* `print(...)`: print parameters via lua `tostring` method as ERROR in Virtual Request context
* `warning(...)`: print parameters via lua `tostring` method as WARNING in Virtual Request context
* `info(...)`: print parameters via lua `tostring` method as INFO in Virtual Request context
* `debug(...)`: print parameters via lua `tostring` method as DEBUG in Virtual Request context
* `handle_direct()`: handle vrequest (i.e. provide headers and body); returns true if not already handled.
* `enter_action(act)`: push a new action on the action stack (return HANDLER_WAIT_FOR_EVENT to rerun after the pushed actions are done, HANDLER_GO_ON if you are done)
* `st, res, errno, msg = stat(filename)`: async stat(filename). Following results are possible
* st is the stat result, res == HANDLER_GO_ON, if the file was found. errno and msg are NIL. In all other cases st is NIL and res != HANDLER_GO_ON.
* res == HANDLER_WAIT_FOR_EVENT: stat() is in progress, just try again later (and return HANDLER_WAIT_FOR_EVENT in the meantime)
* res == HANDLER_ERROR: if stat() failed, errno contains the errno and msg the error message for the errno code.
* `add_filter_in(obj)`: adds `obj` as lua incoming filter (needs to respond to `obj:handle(vr, outq, inq)` and optionally `obj:finished()`); returns a Filter object
* `add_filter_out(obj)`: adds `obj` as lua outgoing filter (needs to respond to `obj:handle(vr, outq, inq)` and optionally `obj:finished()`); returns a Filter object
]]></markdown>
</section>
<section title="Connection">
<textile><![CDATA[
* @local@: address of local socket
* @remote@: address of remote host
]]></textile>
<markdown><![CDATA[
* `local`: address of local socket
* `remote`: address of remote host
]]></markdown>
</section>
<section title="Environment">
<textile><![CDATA[
Fields are the keys in the environment, so it behaves like a lua table; if you use keys starting with "__" or keys with the name of one of the methods below, you have to use the @get@ method to read them, for example:
<markdown><![CDATA[
Fields are the keys in the environment, so it behaves like a lua table; if you use keys starting with "__" or keys with the name of one of the methods below, you have to use the `get` method to read them, for example:
<pre>
x = env["set"] -- doesn't work, returns the set method instead
x = env:get("set") -- use this instead
x = env["set"] -- doesn't work, returns the set method instead
x = env:get("set") -- use this instead
x = env[y] -- don't do this, as y may be a special key like "set"
x = env:get(y) -- just do it the safe way if you are not sure
</pre>
x = env[y] -- don't do this, as y may be a special key like "set"
x = env:get(y) -- just do it the safe way if you are not sure
Methods:
* @get(k)@: safe way for @env[k]@
* @set(k, v)@: safe way for @env[k] = v@
* @unset(k)@: safe way for @env[k] = nil@
* @weak_set(k, v)@: don't override old value, safe way for @env[k] = env[k] or v@
* @pairs()@: use to loop through keys: @for k, v in env:pairs() do ... end@
* @clear()@: remove all entries
]]></textile>
* `get(k)`: safe way for `env[k]`
* `set(k, v)`: safe way for `env[k] = v`
* `unset(k)`: safe way for `env[k] = nil`
* `weak_set(k, v)`: don't override old value, safe way for `env[k] = env[k] or v`
* `pairs()`: use to loop through keys: `for k, v in env:pairs() do ... end`
* `clear()`: remove all entries
]]></markdown>
</section>
<section title="Chunk Queue">
<textile><![CDATA[
<markdown><![CDATA[
Fields:
* @is_closed@: whether the ChunkQueue is closed
* `is_closed`: whether the ChunkQueue is closed
Methods:
* @add(s)@: appends a string to the queue
* @add({filename="/..."})@: appends a file to the queue (only regular files allowed)
* @reset()@: removes all chunks, resets counters
* @steal_all(from)@: steal all chunks from another queue (useful in a filter if you decide to pass all data through it)
* @skip_all()@: skips all chunks (removes all chunks but does *not* reset counters)
]]></textile>
* `add(s)`: appends a string to the queue
* `add({filename="/..."})`: appends a file to the queue (only regular files allowed)
* `reset()`: removes all chunks, resets counters
* `steal_all(from)`: steal all chunks from another queue (useful in a filter if you decide to pass all data through it)
* `skip_all()`: skips all chunks (removes all chunks but does **not** reset counters)
]]></markdown>
</section>
<section title="Request">
<textile><![CDATA[
<markdown><![CDATA[
Fields:
* @headers@(ro): HTTP Headers
* @http_method@(ro): HTTP method string ("GET", "POST", "HEAD", ...)
* @http_version@(ro): HTTP version string ("HTTP/1.0", "HTTP/1.1")
* @content_length@(ro): Numeric value of Content-Length header (not updated automatically if someone changes the header value), -1 if not specified
* @uri@: Request URI
]]></textile>
* `headers`(ro): HTTP Headers
* `http_method`(ro): HTTP method string ("GET", "POST", "HEAD", ...)
* `http_version`(ro): HTTP version string ("HTTP/1.0", "HTTP/1.1")
* `content_length`(ro): Numeric value of Content-Length header (not updated automatically if someone changes the header value), -1 if not specified
* `uri`: Request URI
]]></markdown>
</section>
<section title="Request URI">
<textile><![CDATA[
<markdown><![CDATA[
Fields:
* @raw@: Request uri as it was in the HTTP Request Line (or a rewrite result)
* @raw_path@: not decoded path with querystring (will be the same as @raw@ for most requests, unless someone does something like @GET http://example.com/test?abc HTTP/1.1@)
* @raw_orig_path@: same as raw_path, but saved before any rewrite happened
* @scheme@: "http" or "https"
* @authority@: complete host name header (or authority in an absolute url), e.g. "user@www.example.com.:8080"
* @path@: decoded and simplified path name, without authority, scheme, query-string; e.g. "/index.php"
* @host@: simple hostname, without auth information, without port, without trailing dot; e.g. "www.example.com"
* @query@: The querystring, e.g. "a=1&b=2"
]]></textile>
* `raw`: Request uri as it was in the HTTP Request Line (or a rewrite result)
* `raw_path`: not decoded path with querystring (will be the same as `raw` for most requests, unless someone does something like `GET http://example.com/test?abc HTTP/1.1`)
* `raw_orig_path`: same as raw_path, but saved before any rewrite happened
* `scheme`: "http" or "https"
* `authority`: complete host name header (or authority in an absolute url), e.g. "user@www.example.com.:8080"
* `path`: decoded and simplified path name, without authority, scheme, query-string; e.g. "/index.php"
* `host`: simple hostname, without auth information, without port, without trailing dot; e.g. "www.example.com"
* `query`: The querystring, e.g. "a=1&b=2"
]]></markdown>
</section>
<section title="Response">
<textile><![CDATA[
<markdown><![CDATA[
Fields:
* @headers@(ro): HTTP Headers
* @status@: HTTP status code
]]></textile>
* `headers`(ro): HTTP Headers
* `status`: HTTP status code
]]></markdown>
</section>
<section title="Physical">
<textile><![CDATA[
<markdown><![CDATA[
Fields:
* @path@: physical path
* @doc_root@: document root
* @pathinfo@: pathinfo
]]></textile>
* `path`: physical path
* `doc_root`: document root
* `pathinfo`: pathinfo
]]></markdown>
</section>
<section title="HTTP Headers">
<textile><![CDATA[
<markdown><![CDATA[
Same restriction as Environment for fields.
Methods:
* @get(k)@: joins all header values for the key @k@ with ", " (as the rfc allows it)
* @set(k, v)@: removes all headers with key @k@ and, if v is not nil, appends new "k: v" header
* @append(k, v)@: appends ", v" to last header value with key k if it already exists, @insert(k, v)@ otherwise
* @insert(k, v)@: appends new "k: v" header to list
* @unset(k)@: removes all headers with key @k@
* @pairs()@: loops through all headers. Please note that the keys are not unique!
* @list(k)@: loops through all headers with key @k@
* @clear()@: remove all headers
]]></textile>
* `get(k)`: joins all header values for the key `k` with ", " (as the rfc allows it)
* `set(k, v)`: removes all headers with key `k` and, if v is not nil, appends new "k: v" header
* `append(k, v)`: appends ", v" to last header value with key k if it already exists, `insert(k, v)` otherwise
* `insert(k, v)`: appends new "k: v" header to list
* `unset(k)`: removes all headers with key `k`
* `pairs()`: loops through all headers. Please note that the keys are not unique!
* `list(k)`: loops through all headers with key `k`
* `clear()`: remove all headers
]]></markdown>
</section>
<section title="Filter">
<textile><![CDATA[
<markdown><![CDATA[
Represents a "liFilter".
Fields:
* @in@(ro): Chunk Queue, incoming stream
* @out@(ro): Chunk Queue, outgoing stream
]]></textile>
* `in`(ro): Chunk Queue, incoming stream
* `out`(ro): Chunk Queue, outgoing stream
]]></markdown>
</section>
<section title="Stat struct">
<textile><![CDATA[
Represents "struct stat". Most fields should be self explaining (@man 2 stat@ ("debian manpage":https://manpages.debian.org/stat.2.en.html) if you don't know them).
<markdown><![CDATA[
Represents "struct stat". Most fields should be self explaining (`man 2 stat` ([debian manpage](https://manpages.debian.org/stat.2.en.html)) if you don't know them).
Fields:
* @is_file@(ro): S_ISREG(mode)
* @is_dir@(ro): S_ISDIR(mode)
* @is_char@(ro): S_ISCHR(mode)
* @is_block@(ro): S_ISBLK(mode)
* @is_socket@(ro): S_ISSOCK(mode)
* @is_link@(ro): S_ISLNK(mode)
* @is_fifo@(ro): S_ISFIFO(mode)
* @mode@(ro)
* @mtime@(ro)
* @ctime@(ro)
* @atime@(ro)
* @uid@(ro)
* @gid@(ro)
* @size@(ro)
* @ino@(ro)
* @dev@(ro)
]]></textile>
* `is_file`(ro): S_ISREG(mode)
* `is_dir`(ro): S_ISDIR(mode)
* `is_char`(ro): S_ISCHR(mode)
* `is_block`(ro): S_ISBLK(mode)
* `is_socket`(ro): S_ISSOCK(mode)
* `is_link`(ro): S_ISLNK(mode)
* `is_fifo`(ro): S_ISFIFO(mode)
* `mode`(ro)
* `mtime`(ro)
* `ctime`(ro)
* `atime`(ro)
* `uid`(ro)
* `gid`(ro)
* `size`(ro)
* `ino`(ro)
* `dev`(ro)
]]></markdown>
</section>
</section>

View File

@ -1,32 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Patterns">
<description>
<textile>
The lighttpd config supports "patterns" in various places (docroot, redirect, rewrite, env.set, ...); and they share the following structure.
<description><markdown>
The lighttpd config supports "patterns" in various places (docroot, redirect, rewrite, env.set, ...); and they share the following structure.
There are two kinds of "captures" available; one from the action itself (like captures from a regular expression in redirect/rewrite, or the labels from the hostname in docroot), and the captures from the previous matching regular expression conditional in the action stack. If there was no capture of the selected kind the values will be empty strings.
</textile>
</description>
There are two kinds of "captures" available; one from the action itself (like captures from a regular expression in redirect/rewrite, or the labels from the hostname in docroot), and the captures from the previous matching regular expression conditional in the action stack. If there was no capture of the selected kind the values will be empty strings.
</markdown></description>
<section title="Syntax">
<textile>
<markdown>
A pattern is a string consisting of the following parts:
* simple text. can contain special characters $ and % only when they are escaped with \ - remember, that the \ has to be escaped too for the config, so you'll probably have to use \\ to escape. You are allowed to escape ? too (used for special "split" in rewrite).
* simple text. can contain special characters $ and % only when they are escaped with `\` remember, that the `\` has to be escaped too for the config, so you'll probably have to use `\\` to escape. You are allowed to escape `?` too (used for special "split" in rewrite).
* "%" capture references (previous matching regular expression conditional); either followed by a single digit, or a range (see below for range syntax)
* "$" capture references (depends on action); either followed by a single digit, or a range (see below for range syntax)
* "%" references to "condition variables":core_config.html#core_config__condition_vars, for example: @%{req.path}@; the conditional can be prefixed with "enc:" (@%{enc:req.path}@), in which case the value will be urlencoded.
</textile>
* "%" references to [condition variables](core_config.html#core_config__condition_vars), for example: `%{req.path}`; the conditional can be prefixed with "enc:" (`%{enc:req.path}`), in which case the value will be urlencoded.
</markdown>
</section>
<section title="Ranges">
<textile><![CDATA[
Ranges can either be a single element @[n]@ (@n@ can have more than one digit), a closed range @[n-m]@ or an open range @[n-]@ or @[-m]@;
the open end is always replaced with "G_MAXUINT" (a very big positive integer). ranges can be "reversed", i.e. @n > m@.
<markdown><![CDATA[
Ranges can either be a single element `[n]` (`n` can have more than one digit), a closed range `[n-m]` or an open range `[n-]` or `[-m]`;
the open end is always replaced with "G_MAXUINT" (a very big positive integer). ranges can be "reversed", i.e. `n > m`.
There are now two different ways ranges are used:
* ranges of regular expression captures: the captures are just inserted for all values in the range; if the range is reversed, it starts with the highest index in the range.
* ranges of labels in a hostname: similar to the first range, but the inserted labels are separated by a "."; the index 0 stands for "complete hostname", and ranges including 0 are reduced to the complete hostname; the labels are numbered from top-level, and the range is interpreted reversed (just have a look at the examples, and it will be clear).
]]></textile>
]]></markdown>
</section>
<example title="Example: simple redirect">
@ -36,12 +36,10 @@
</example>
<example title="Example: docroot">
<description>
<textile>
* a request to "http://example.com/project/trunk" would lead to docroot "/var/www/project/trunk/htdocs"
* a request to "http://sub.example.com/" would lead to docroot "/var/www/vhosts/com/sub.example"
</textile>
</description>
<description><markdown>
* a request to "http://example.com/project/trunk" would lead to docroot "/var/www/project/trunk/htdocs"
* a request to "http://sub.example.com/" would lead to docroot "/var/www/vhosts/com/sub.example"
</markdown></description>
<config>
if req.path =~ "^/project/([^/]*)" {
docroot "/var/www/projects/%1/htdocs";

View File

@ -1,21 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Regular expressions">
<description>
<textile>
lighttpd2 uses the "Perl-compatible regular expressions" implementation from GLib, see their "Regular expression syntax":https://developer.gnome.org/glib/stable/glib-regex-syntax.html documentation.
<description><markdown>
lighttpd2 uses the "Perl-compatible regular expressions" implementation from GLib, see their [Regular expression syntax](https://developer.gnome.org/glib/stable/glib-regex-syntax.html) documentation.
The config format has different ways to provide strings (you can quote with either @'@ or @"@; the character used to quote has to be escaped with @\@ if used inside the string).
The simple (standard) way @"text"@ has the following escape rules:
* @"\n"@ is a newline, @"\r"@ a carriage return, @"\t"@ a tab stop
* @"\\"@ is one @\@, @"\""@ is one double quote @"@ and @"\'"@ a single quote @'@
* escaping single/double quote is optional if the symbol is not used to terminate the string, i.e. @'\"'@ = @'"'@ and @"\'"@ = @"'"@
* @"\xNN"@: NN must be hexadecimal characters, and the string is replaced with the decoded 8-bit value as a single byte
* All other @\@ occurences are *not* removed from the string.
The config format has different ways to provide strings (you can quote with either `'` or `"`; the character used to quote has to be escaped with `\` if used inside the string).
The simple (standard) way `"text"` has the following escape rules:
This way is the preferred one for regular expressions; only to actually match a @\@ you have to do additional escaping (@"\\\\"@; @"\x5C"@ = @"\\"@ is not working), and @\\@ is usually not doing what you wanted (matching a digit: @"\\d"@ = @"\d"@). All other escape rules are compatible with what pcre is doing.
* `"\n"` is a newline, `"\r"` a carriage return, `"\t"` a tab stop
* `"\\"` is one `\`, `"\""` is one double quote `"` and `"\'"` a single quote `'`
* escaping single/double quote is optional if the symbol is not used to terminate the string, i.e. `'\"'` = `'"'` and `"\'"` = `"'"`
* `"\xNN"`: NN must be hexadecimal characters, and the string is replaced with the decoded 8-bit value as a single byte
* All other `\` occurences are **not** removed from the string.
The second way is to place an @e@ before the string like this: @e"text"@. It has the same rules like the normal string, but does not allow unknown escape sequences (the last rule above).
To match a digit with pcre this way you'd have to write @e"\\d"@ instead of @"\d"@.
</textile>
</description>
This way is the preferred one for regular expressions; only to actually match a `\` you have to do additional escaping (`"\\\\"`; `"\x5C"` = `"\\"` is not working), and `\\` is usually not doing what you wanted (matching a digit: `"\\d"` = `"\d"`). All other escape rules are compatible with what pcre is doing.
The second way is to place an `e` before the string like this: `e"text"`. It has the same rules like the normal string, but does not allow unknown escape sequences (the last rule above).
To match a digit with pcre this way you'd have to write `e"\\d"` instead of `"\d"`.
</markdown></description>
</chapter>

View File

@ -91,11 +91,11 @@
<attribute name="name" type="Name" use="required" />
</complexType>
<complexType name="DescriptionType" mixed="true">
<complexType name="DescriptionType">
<sequence>
<choice minOccurs="0" maxOccurs="unbounded">
<element name="html" type="anyType" />
<element name="textile" type="anyType" />
<element name="markdown" type="anyType" />
</choice>
</sequence>
</complexType>
@ -111,7 +111,7 @@
<attribute name="anchor" type="token" use="optional" />
</complexType>
<complexType name="ModuleSectionType" mixed="true">
<complexType name="ModuleSectionType">
<sequence>
<choice minOccurs="0" maxOccurs="unbounded">
<element name="action" type="d:ActionSetupType" />
@ -119,7 +119,7 @@
<element name="option" type="d:OptionType" />
<element name="html" type="anyType" />
<element name="textile" type="anyType" />
<element name="markdown" type="anyType" />
<element name="example" type="d:ExampleType" />
<element name="section" type="d:ModuleSectionType" />
</choice>
@ -150,11 +150,11 @@
<attribute name="order" type="Name" use="optional" />
</complexType>
<complexType name="ChapterSectionType" mixed="true">
<complexType name="ChapterSectionType">
<sequence>
<choice minOccurs="0" maxOccurs="unbounded">
<element name="html" type="anyType" />
<element name="textile" type="anyType" />
<element name="markdown" type="anyType" />
<element name="example" type="d:ExampleType" />
<element name="section" type="d:ChapterSectionType" />
</choice>
@ -198,13 +198,13 @@
<attribute name="name" type="Name" use="required" />
</complexType>
<complexType name="AngelModuleSectionType" mixed="true">
<complexType name="AngelModuleSectionType">
<sequence>
<choice minOccurs="0" maxOccurs="unbounded">
<element name="item" type="d:AngelItemType" />
<element name="html" type="anyType" />
<element name="textile" type="anyType" />
<element name="markdown" type="anyType" />
<element name="example" type="d:ExampleType" />
<element name="section" type="d:AngelModuleSectionType" />
</choice>

View File

@ -14,7 +14,7 @@ CGI, basic and digest HTTP authentication, output compression, URL rewriting.
.PP
This manual page only lists the command line arguments. For details
on how to configure \fBlighttpd\fP and its modules see the online documentation:
http://redmine.lighttpd.net/projects/lighttpd2/wiki
https://redmine.lighttpd.net/projects/lighttpd2/wiki
.PP
You probably want to use the angel instead of this application: lighttpd2(8)
.
@ -42,13 +42,13 @@ Show version and exit.
Show a brief help message and exit.
.
.SH SEE ALSO
Online Documentation: http://redmine.lighttpd.net/projects/lighttpd2/wiki
Online Documentation: https://redmine.lighttpd.net/projects/lighttpd2/wiki
.PP
spawn-fcgi(1), lighttpd2(8)
.
.SH AUTHOR
Jan Kneschke <jan@kneschke.de>
.PP
Stefan Buehler <stbuehler@web.de>
Stefan Buehler <souce@stbuehler.de>
.PP
Thomas Porzelt <tp@cryosphere.de>

View File

@ -17,7 +17,7 @@ permissions are needed (opening network sockets, ...)
.PP
This manual page only lists the command line arguments. For details
on how to configure \fBlighttpd\fP and its modules see the online documentation:
http://redmine.lighttpd.net/projects/lighttpd2/wiki
https://redmine.lighttpd.net/projects/lighttpd2/wiki
.
.SH OPTIONS
The following options are supported:
@ -40,13 +40,13 @@ Show version and exit.
Show a brief help message and exit.
.
.SH SEE ALSO
Online Documentation: http://redmine.lighttpd.net/projects/lighttpd2/wiki
Online Documentation: https://redmine.lighttpd.net/projects/lighttpd2/wiki
.PP
lighttpd2-worker(8)
.
.SH AUTHOR
Jan Kneschke <jan@kneschke.de>
.PP
Stefan Buehler <stbuehler@web.de>
Stefan Buehler <souce@stbuehler.de>
.PP
Thomas Porzelt <tp@cryosphere.de>

View File

@ -13,13 +13,13 @@
<parameter name="rules">
<short>A key value list mapping "access" and/or "deny" keys to a list of CIDR addresses or "all".</short>
</parameter>
<description>
<description><markdown>
Checks the client IP address against the rules. Default is to deny all addresses. The most precise matching rule defines the result ("192.168.100.0/24" takes precedence over "192.168.0.0/16"; similar to routing tables); if the same CIDR is in both lists the second action is taken. "all" is a synonym for "0.0.0.0/0" and "::/0", matching all IPv4 and IPv6 addresses.
</description>
</markdown></description>
<example title="Example: restrict access to local network" anchor="#">
<description>
<description><markdown>
Limit access to clients from the local network. The deny rule isn't strictly required, as the default is to deny anyway. The smaller CIDR strings for the local networks override the global deny rule.
</description>
</markdown></description>
<config>
setup {
module_load "mod_access";
@ -32,9 +32,9 @@
</config>
</example>
<example title="Example: restrict access to subnet with exception" anchor="#">
<description>
<description><markdown>
Limit access to clients from "192.168.10.0/24", but deny access to "192.168.10.1". As "192.168.10.1" (equivalent to "192.168.10.1/32") is a more precise match it overwrites the allow rule for the subnet "192.168.10.0/24" containing it.
</description>
</markdown></description>
<config>
setup {
module_load "mod_access";
@ -52,11 +52,9 @@
<short>url to redirect to if access was denied (not implemented yet)</short>
<parameter name="url" />
<default><text>not set</text></default>
<description>
<textile>
*NOT IMPLEMENTED YET*
</textile>
</description>
<description><markdown>
**NOT IMPLEMENTED YET**
</markdown></description>
</option>
<option name="access.log_blocked">

View File

@ -6,42 +6,41 @@
<short>defines the log format</short>
<parameter name="format" />
<default><value>"%h %V %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""</value></default>
<description>
<textile><![CDATA[
Some format specifiers take a mandatory key, enclosed in curly braces between percent sign and the actual specifier. CLF means "common log format", if a value is zero, a '-' is used instead.
<description><markdown><![CDATA[
Some format specifiers take a mandatory key, enclosed in curly braces between percent sign and the actual specifier. CLF means "common log format", if a value is zero, a '-' is used instead.
table(table table-striped).
|_. specifier |_. description |
| %% | Percent sign itself |
| %a | Remote IP-address |
| %A | Local IP-address|
| %b | Size of response in bytes, excluding HTTP headers (CLF) |
| %B | Size of response in bytes, excluding HTTP headers |
| %{foobar}C | (*not implemented yet*) Contents of cookie @foobar@ of the request |
| %D | Time taken to serve the request in microseconds |
| %{foobar}e | Contents of the request environment variable @foobar@ |
| %f | Path to physical file |
| %h | Remote IP-address (same as @%a@) |
| %{foobar}i | Contents of request header @foobar@ |
| %m | Request method (GET, POST, etc) |
| %{foobar}o | Contents of response header @foobar@ |
| %p | Local port |
| %q | Querystring |
| %r | First line of request (GET /foo.html?bar HTTP/1.1) |
| %s | Response status code |
| %t | Time/date the request was received in standard english format |
| %T | Time taken to serve the request in seconds |
| %u | Authed user (from mod_auth). Same as @%{REMOTE_USER}e@ |
| %U | Request path (not including querystring) |
| %v | Server name as set through the @server.name@ option or the request hostname of @server.name@ is not set |
| %V | Request hostname |
| %X | Connection status after response: "X" if aborted before completed, "+" if keepalive, "-" if no keepalive |
| %I | Bytes received including HTTP headers and request body |
| %O | Bytes sent including HTTP headers and response body |
| specifier | description |
|--|--|
| %% | Percent sign itself |
| %a | Remote IP-address |
| %A | Local IP-address|
| %b | Size of response in bytes, excluding HTTP headers (CLF) |
| %B | Size of response in bytes, excluding HTTP headers |
| %{foobar}C | (**not implemented yet**) Contents of cookie `foobar` of the request |
| %D | Time taken to serve the request in microseconds |
| %{foobar}e | Contents of the request environment variable `foobar` |
| %f | Path to physical file |
| %h | Remote IP-address (same as `%a`) |
| %{foobar}i | Contents of request header `foobar` |
| %m | Request method (GET, POST, etc) |
| %{foobar}o | Contents of response header `foobar` |
| %p | Local port |
| %q | Querystring |
| %r | First line of request (GET /foo.html?bar HTTP/1.1) |
| %s | Response status code |
| %t | Time/date the request was received in standard english format |
| %T | Time taken to serve the request in seconds |
| %u | Authed user (from mod_auth). Same as `%{REMOTE_USER}e` |
| %U | Request path (not including querystring) |
| %v | Server name as set through the `server.name` option or the request hostname of `server.name` is not set |
| %V | Request hostname |
| %X | Connection status after response: "X" if aborted before completed, "+" if keepalive, "-" if no keepalive |
| %I | Bytes received including HTTP headers and request body |
| %O | Bytes sent including HTTP headers and response body |
{:.table .table-striped}
Modifiers right after the percent sign like Apache provides them, are not supported. "<" or ">" are ignored, everything else results in a parse error. Specifiers supported by Apache but not lighty: %l, %n, %P
]]></textile>
</description>
Modifiers right after the percent sign like Apache provides them, are not supported. "<" or ">" are ignored, everything else results in a parse error. Specifiers supported by Apache but not lighty: %l, %n, %P
]]></markdown></description>
<example>
<config>
accesslog.format "%h %V %u %t \"%r\" %>s %b";
@ -53,9 +52,9 @@
<short>defines the log target</short>
<parameter name="target" />
<default><text>logging disabled</text></default>
<description>
<html>Enable logging by setting a log target. Supports the same log targets as <a href="plugin_core.html#plugin_core__action_log">log</a>.</html>
</description>
<description><markdown>
Enable logging by setting a log target. Supports the same log targets as [log](plugin_core.html#plugin_core__action_log).
</markdown></description>
<example>
<config>
setup {

View File

@ -2,22 +2,18 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>requires authentication from clients using a username and password. It supports the basic (digest not yet) authentication method as well as plaintext, htpasswd and htdigest backends.</short>
<description>
<textile>
*IMPORTANT NOTE*: You need to put the auth actions before generating content! If a content handler is already active (like php or static or dirlist), auth will be ignored!
<description><markdown>
**IMPORTANT NOTE**: You need to put the auth actions before generating content! If a content handler is already active (like php or static or dirlist), auth will be ignored!
* Basic:
The "basic" method transfers the username and the password in cleartext over the network (base64 encoded) and might result in security problems if not used in conjunction with an encrypted communication channel between client and server.
It is recommend to use https in conjunction with basic authentication.
* Digest (not supported yet):
The "digest" method only transfers a hashed value over the network which performs a lot of work to harden the authentication process in insecure networks (like the internet).
The "digest" method doesn't work with the htpasswd backend, only with plaintext and htdigest.
*NOTE*: The digest method is broken in Internet Explorer &lt; 7. Use basic instead if this is a problem for you. (not supported for now anyway)
</textile>
</description>
* Basic:
The "basic" method transfers the username and the password in cleartext over the network (base64 encoded) and might result in security problems if not used in conjunction with an encrypted communication channel between client and server.
It is recommend to use https in conjunction with basic authentication.
* Digest (not supported yet):
The "digest" method only transfers a hashed value over the network which performs a lot of work to harden the authentication process in insecure networks (like the internet).
The "digest" method doesn't work with the htpasswd backend, only with plaintext and htdigest.
**NOTE**: The digest method is broken in Internet Explorer &lt; 7. Use basic instead if this is a problem for you. (not supported for now anyway)
</markdown></description>
<action name="auth.plain">
<short>requires authentication using a plaintext file</short>
@ -37,9 +33,9 @@
</entry>
</table>
</parameter>
<description>
<description><markdown>
requires authentication using a plaintext file containing user:password pairs separated by newlines (\n).
</description>
</markdown></description>
</action>
<action name="auth.htpasswd">
@ -60,14 +56,12 @@
</entry>
</table>
</parameter>
<description>
<textile>
* requires authentication using a htpasswd file containing user:encrypted_password pairs separated by newlines (\n)
* passwords are encrypted using crypt(3), use the htpasswd binary from apache to manage the file
** hashes starting with "$apr1$" ARE supported (htpasswd -m)
** hashes starting with "{SHA}" ARE supported (followed by sha1_base64(password), htpasswd -s)
</textile>
</description>
<description><markdown>
* requires authentication using a htpasswd file containing user:encrypted_password pairs separated by newlines (\n)
* passwords are encrypted using crypt(3), use the htpasswd binary from apache to manage the file
* hashes starting with "$apr1$" ARE supported (htpasswd -m)
* hashes starting with "{SHA}" ARE supported (followed by sha1_base64(password), htpasswd -s)
</markdown></description>
</action>
<action name="auth.htdigest">
@ -88,14 +82,12 @@
</entry>
</table>
</parameter>
<description>
<textile>
* requires authentication using a htdigest file containing user:realm:hashed_password tuples separated by newlines (\n)
* the hashes are bound to the realm, so you can't change the realm without resetting the passwords
* passwords are saved as (modified) md5 hashes:
@md5hex(username + ":" + realm + ":" + password)@
</textile>
</description>
<description><markdown>
* requires authentication using a htdigest file containing user:realm:hashed_password tuples separated by newlines (\n)
* the hashes are bound to the realm, so you can't change the realm without resetting the passwords
* passwords are saved as (modified) md5 hashes:
`md5hex(username + ":" + realm + ":" + password)`
</markdown></description>
</action>
<action name="auth.deny">
@ -122,11 +114,9 @@
</example>
<example>
<description>
<textile>
You can use @auth.require_user@ from the mod_lua plugin "contrib/core.lua":http://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/core.lua for the REMOTE_USER check too:
</textile>
</description>
<description><markdown>
You can use `auth.require_user` from the mod_lua plugin [contrib/core.lua](https://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/core.lua) for the REMOTE_USER check too:
</markdown></description>
<config>
setup {

View File

@ -2,20 +2,20 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>balances between different backends.</short>
<description>
<description><markdown>
Using an action from mod_balance also activates a backlog: lighttpd2 will then put requests in a backlog if no backend is available and try again later.
Be careful: the referenced actions may get executed more than once (until one is successful!), so don't loop rewrites in them or something similar.
</description>
</markdown></description>
<action name="balance.rr">
<short>balance between actions (list or single action) with Round-Robin</short>
<parameter name="actions">
<short>the actions to balance between</short>
</parameter>
<description>
<description><markdown>
Round-Robin (rr) the requests are distributed equally over all backends.
</description>
</markdown></description>
<example>
<config>
balance.rr { fastcgi "127.0.0.1:9090"; };
@ -33,9 +33,9 @@
<parameter name="actions">
<short>the actions to balance between</short>
</parameter>
<description>
<description><markdown>
Shortest-Queue-First (sqf) is similar to Round-Robin and prefers the backend with the shortest wait-queue.
</description>
</markdown></description>
<example>
<config>
balance.sqf { fastcgi "127.0.0.1:9090"; };

View File

@ -2,31 +2,29 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>caches generated content on disk if an etag response header is set; if the backend sends an already cached etag, the backend is closed and the file is sent directly.</short>
<description>
<textile>
Please note: This will not skip the backend, as it will need at least the response headers.
<description><markdown>
Please note: This will not skip the backend, as it will need at least the response headers.
*Hint:*
Use a cron-job like the following to remove old cached data, e.g. in crontab daily:
**Hint:**
Use a cron-job like the following to remove old cached data, e.g. in crontab daily:
<pre>
find /var/cache/lighttpd/cache_etag/ -type f -mtime +2 -exec rm -r {} \;
</pre>
```
find /var/cache/lighttpd/cache_etag/ -type f -mtime +2 -exec rm -r {} \;
```
*Hint:*
Have a look at "mod_deflate":mod_deflate.html#mod_deflate to see this module in action.
</textile>
</description>
**Hint:**
Have a look at [mod_deflate](mod_deflate.html#mod_deflate) to see this module in action.
</markdown></description>
<action name="cache.disk.etag">
<short>cache responses based on the ETag response header</short>
<parameter name="path">
<short>directory to store the cached results in</short>
</parameter>
<description>
<description><markdown>
This blocks action progress until the response headers are done (i.e. there has to be a content generator before it (like fastcgi/dirlist/static file).
You could insert it multiple times of course (e.g. before and after deflate).
</description>
</markdown></description>
<example>
<config>

View File

@ -3,16 +3,17 @@
<short>provides some useful helpers written in lua</short>
<section title="Install">
<textile>
By default distributions (and @make install@) should provide the necessary files; but you can always find them in the "contrib":http://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib folder:
* @core.lua@
* @core__cached_html.lua@
* @core__xsendfile.lua@
<markdown>
By default distributions (and `make install`) should provide the necessary files; but you can always find them in the [contrib](https://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib) folder:
* `core.lua`
* `core__cached_html.lua`
* `core__xsendfile.lua`
That way you can modify them for your own needs if you have to (although it is recommended to change the names of the files and the actions, so you don't get conflicts).
lighttpd should search for @core.lua@ in the correct (install) locations, so you don't need the absolute path here.
</textile>
lighttpd should search for `core.lua` in the correct (install) locations, so you don't need the absolute path here.
</markdown>
</section>
<action name="core.wsgi">
@ -23,23 +24,19 @@
<parameter name="action">
<short>action block connecting to the wsgi backend</short>
</parameter>
<description>
<textile>
See "Howto WSGI":https://redmine.lighttpd.net/projects/lighttpd2/wiki/Howto_WSGI for an example.
<description><markdown>
See [Howto WSGI](https://redmine.lighttpd.net/projects/lighttpd2/wiki/Howto_WSGI) for an example.
WSGI applications expect the url to be split into @SCRIPT_NAME@ and @PATH_INFO@ (CGI environment variables); @SCRIPT_NAME@ is their "application root", and @PATH_INFO@ the requested resource in the application.
By default, lighttpd uses an empty @PATH_INFO@ (unless you used the "pathinfo;" action, but this doesn't help as we're not dealing with static files here).
WSGI applications expect the url to be split into `SCRIPT_NAME` and `PATH_INFO` (CGI environment variables); `SCRIPT_NAME` is their "application root", and `PATH_INFO` the requested resource in the application.
By default, lighttpd uses an empty `PATH_INFO` (unless you used the "pathinfo;" action, but this doesn't help as we're not dealing with static files here).
*Important*: WSGI is an "extension" of CGI; it doesn't specify a transport protocol, you can use it with plain CGI, FastCGI or SCGI (or anything else that supports the basic CGI protocol)
</textile>
</description>
**Important**: WSGI is an "extension" of CGI; it doesn't specify a transport protocol, you can use it with plain CGI, FastCGI or SCGI (or anything else that supports the basic CGI protocol)
</markdown></description>
<example>
<description>
<textile>
Example: Trac in @/trac@, listening via FastCGI on @unix:/var/run/lighttpd/trac.socket@.
</textile>
</description>
<description><markdown>
Example: Trac in `/trac`, listening via FastCGI on `unix:/var/run/lighttpd/trac.socket`.
</markdown></description>
<config>
setup {
module_load ("mod_lua", "mod_fastcgi");
@ -92,20 +89,18 @@
<parameter name="userlist">
<short>list of usernames to allow</short>
</parameter>
<description>
<textile>
This helper constructs a regular expression to match against request.environment["REMOTE_USER"], so the example below is the same as:
<description><markdown>
This helper constructs a regular expression to match against request.environment["REMOTE_USER"], so the example below is the same as:
<pre>
auth.plain [ "method" => "basic", "realm" => "test", "file" => "/etc/lighttpd2/test.plain" ];
if req.env["REMOTE_USER"] !~ "^(foo1|foo2)$" { auth.deny; }
</pre>
```
auth.plain [ "method" => "basic", "realm" => "test", "file" => "/etc/lighttpd2/test.plain" ];
if req.env["REMOTE_USER"] !~ "^(foo1|foo2)$" { auth.deny; }
```
This action uses lua only to create the action, no lua is executed to handle requests in this case.
This action uses lua only to create the action, no lua is executed to handle requests in this case.
Be careful: the empty username matches unauthenticated users.
</textile>
</description>
Be careful: the empty username matches unauthenticated users.
</markdown></description>
<example>
<config>
setup {

View File

@ -6,9 +6,9 @@
<action name="debug.show_connections">
<short>shows a page similar to the one from mod_status, listing all active connections</short>
<description>
<description><markdown>
By specifying one or more "connection ids" via querystring (parameter "con"), one can request additional debug output for specific connections.
</description>
</markdown></description>
<example>
<config>
if req.path == "/debug/connections" { debug.show_connections; }
@ -19,18 +19,16 @@
<action name="debug.profiler_dump">
<short>dumps all allocated memory to the profiler output file if profiling enabled</short>
<description>
<textile>
lighttpd2 needs to be compiled with profiler support, and profiling has to be enabled by setting the environment variable @LIGHTY_PROFILE_MEM@ to the path of a target log file.
</textile>
</description>
<description><markdown>
lighttpd2 needs to be compiled with profiler support, and profiling has to be enabled by setting the environment variable `LIGHTY_PROFILE_MEM` to the path of a target log file.
</markdown></description>
</action>
<action name="debug.show_events">
<short>shows a plain text list of all events</short>
<description>
<description><markdown>
this is a very low level debug tool for developers.
</description>
</markdown></description>
<example>
<config>
if req.path == "/debug/events" { debug.show_events; }
@ -47,9 +45,9 @@
<short>timeout after which to repeat displaying events (default: disabled)</short>
</parameter>
<description>
<description><markdown>
this is a very low level debug tool for developers; it shows which event listeners keep lighttpd2 alive when it should stop.
</description>
</markdown></description>
<example>
<config>

View File

@ -38,24 +38,28 @@
</option>
<section title="Notes">
<textile>
*Important*: As @deflate;@ waits for the response headers, you must handle the request before it (see below how to check whether the request is handled).
<markdown>
**Important**: As `deflate;` waits for the response headers, you must handle the request before it (see below how to check whether the request is handled).
If the request is not handled, you will get a "500 - Internal error" and a message in the error.log.
Does not compress:
* response status: 100, 101, 204, 205, 206, 304
* already compressed content
* if more than one etag response header is sent
* if no common encoding is found
Supported encodings
* gzip, deflate (needs zlib)
* bzip2 (needs bzip2)
* Modifies etag response header (if present)
* Adds "Vary: Accept-Encoding" response header
* Resets Content-Length header
</textile>
`deflate` also:
* modifies etag response header (if present)
* adds "Vary: Accept-Encoding" response header
* resets Content-Length header
</markdown>
</section>
<example title="Simple config" anchor="#">

View File

@ -52,9 +52,9 @@
</parameter>
<example>
<description>
<description><markdown>
shows a directory listing including the content of HEADER.txt above the list and hiding itself from it; also hides all files ending in ".bak"
</description>
</markdown></description>
<config>
setup {
module_load ("mod_dirlist");

View File

@ -2,47 +2,41 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>add "Expires" and "Cache-Control" headers to the response</short>
<description>
<textile><![CDATA[
This allows you to control client-side caching of responses based on a simple rule/formula.
If a response is cached using an "Expires" and "Cache-Control" header, then the client will not issue a new request for it until the date specified by the header is reached.
<description><markdown><![CDATA[
This allows you to control client-side caching of responses based on a simple rule/formula.
If a response is cached using an "Expires" and "Cache-Control" header, then the client will not issue a new request for it until the date specified by the header is reached.
Adding expire headers to static content like css, javascript, images or similar, can greatly reduce the amount of requests you get and therefor save resources.
Use "modification" as @<base>@ if your content changes in specific intervals like every 15 minutes.
]]></textile>
</description>
Adding expire headers to static content like css, javascript, images or similar, can greatly reduce the amount of requests you get and therefor save resources.
Use "modification" as `<base>` if your content changes in specific intervals like every 15 minutes.
]]></markdown></description>
<action name="expire">
<short>adds an "Expires" header to the response</short>
<parameter name="rule">
<short>the rule to calculate the "Expires" header value with</short>
</parameter>
<description>
<textile><![CDATA[
The rule/formula used here, complies with the one mod_expire for Apache uses:
<description><markdown><![CDATA[
The rule/formula used here, complies with the one mod_expire for Apache uses:
<pre>
<base> [plus] (<num> <type>)+
</pre>
* @<base>@ is one of "access", "now" or "modification"; "now" being equivalent to "access".
* "@plus@" is optional and does nothing.
* @<num>@ is any positive integer.
* @<type>@ is one of "seconds, "minutes", "hours", "days", "weeks", "months" or "years".
* `<base>` is one of "access", "now" or "modification"; "now" being equivalent to "access".
* "`plus`" is optional and does nothing.
* `<num>` is any positive integer.
* `<type>` is one of "seconds", "minutes", "hours", "days", "weeks", "months" or "years".
The trailing "s" in @<type>@ is optional.
The trailing "s" in `<type>` is optional.
If you use "modification" as @<base>@ and the file does not exist or cannot be accessed, mod_expire will do nothing and request processing will go on.
If you use "modification" as `<base>` and the file does not exist or cannot be accessed, mod_expire will do nothing and request processing will go on.
The expire action will overwrite any existing "Expires" header.
It will append the max-age value to any existing "Cache-Control" header.
]]></textile>
</description>
The expire action will overwrite any existing "Expires" header.
It will append the max-age value to any existing "Cache-Control" header.
]]></markdown></description>
<example>
<description>
<description><markdown>
Cache image, css, txt and js files for 1 week.
</description>
</markdown></description>
<config>
setup {
module_load "mod_expire";

View File

@ -7,22 +7,18 @@
<parameter name="socket">
<short>socket to connect to, either "ip:port" or "unix:/path"</short>
</parameter>
<description>
<textile>
Don't confuse FastCGI with CGI! Not all CGI backends can be used as FastCGI backends (but you can use "fcgi-cgi":https://redmine.lighttpd.net/projects/fcgi-cgi/wiki to run CGI backends with lighttpd2).
</textile>
</description>
<description><markdown>
Don't confuse FastCGI with CGI! Not all CGI backends can be used as FastCGI backends (but you can use [fcgi-cgi](https://redmine.lighttpd.net/projects/fcgi-cgi/wiki) to run CGI backends with lighttpd2).
</markdown></description>
<example>
<config>
fastcgi "127.0.0.1:9090"
</config>
</example>
<example>
<description>
<textile>
Start php for example with spawn-fcgi: @spawn-fcgi -n -s /var/run/lighttpd2/php.sock -- /usr/bin/php5-cgi@
</textile>
</description>
<description><markdown>
Start php for example with spawn-fcgi: `spawn-fcgi -n -s /var/run/lighttpd2/php.sock -- /usr/bin/php5-cgi`
</markdown></description>
<config>
setup {
module_load "mod_fastcgi";

View File

@ -4,13 +4,11 @@
<action name="flv">
<short>pseudo stream the current file as flash</short>
<description>
<textile>
Lets flash players seek with the "start" query string parameter to an (byte) offset in the file, and prepends a simple flash header before streaming the file from that offset.
<description><markdown>
Lets flash players seek with the "start" query string parameter to an (byte) offset in the file, and prepends a simple flash header before streaming the file from that offset.
Uses "video/x-flv" as hard-coded content type.
</textile>
</description>
Uses "video/x-flv" as hard-coded content type.
</markdown></description>
<example>
<config>
if phys.path =$ ".flv" {
@ -19,13 +17,11 @@
</config>
</example>
<example>
<description>
<textile>
Use caching and bandwidth throttling to save traffic. Use a small burst threshold to prevent the player from buffering at the beginning.
<description><markdown>
Use caching and bandwidth throttling to save traffic. Use a small burst threshold to prevent the player from buffering at the beginning.
This config will make browsers cache videos for 1 month and limit bandwidth to 150 kilobyte/s after 500 kilobytes.
</textile>
</description>
This config will make browsers cache videos for 1 month and limit bandwidth to 150 kilobyte/s after 500 kilobytes.
</markdown></description>
<config>
if phys.path =$ ".flv" {
expire "access 1 month";

View File

@ -67,11 +67,9 @@
</example>
<example title="TLS with SNI from fetch backend">
<description>
<textile>
For a SNI hostname @example.com@ lighttpd2 will try to find the private key and certificate(s) in @/etc/certs/lighttpd_sni_example.com.pem@.
</textile>
</description>
<description><markdown>
For a SNI hostname `example.com` lighttpd2 will try to find the private key and certificate(s) in `/etc/certs/lighttpd_sni_example.com.pem`.
</markdown></description>
<config>
setup {
fetch.files_static "sni" => "/etc/certs/lighttpd_sni_*.pem";
@ -144,48 +142,51 @@
</setup>
<section title="Server Name Indication (SNI)">
<textile>
"TLS SNI":http://en.wikipedia.org/wiki/Server_Name_Indication means that a client can send the hostname of the server it tries to connect to *unencrypted* in the TLS handshake.
<markdown>
[TLS SNI](https://en.wikipedia.org/wiki/Server_Name_Indication) means that a client can send the hostname of the server it tries to connect to **unencrypted** in the TLS handshake.
If you want to host multiple hostnames on the same IP address (quite common) there are some options how to do it (they can be combined):
* Use a wildcard as "CommonName" (CN) in the certificate like @*.example.com@ (although this usually doesn't match @example.com@)
* Use a wildcard as "CommonName" (CN) in the certificate like `*.example.com` (although this usually doesn't match `example.com`)
* Use "Subject Alternative Names" in the certificate
* Provide different certificates based on the SNI hostname in the TLS handshake.
Clients supporting SNI usually support the other options too, but not all clients support SNI.
GnuTLS has some basic SNI support built in; if you specify multiple @pemfile@ s in the options, it will pick the first with a certificate that matches the SNI hostname.
GnuTLS has some basic SNI support built in; if you specify multiple `pemfile` s in the options, it will pick the first with a certificate that matches the SNI hostname.
lighttpd2 has an optional extended SNI support (which has to be enabled at compile time, and is required for the @sni-*@ options to be available). It is designed to load certificates asynchronously from backends (files, SQL, ...) on demand, using the "fetch API":core_fetch.html#core_fetch.
In this case lighttpd2 will fetch the certificate based on the SNI hostname from the given @sni-backend@ before GnuTLS is started for a connection.
If a SNI hostname was given by the client, but no certificate was found in the backend, it will use @sni-fallback-pemfile@ (if set) instead of @pemfile@.
lighttpd2 has an optional extended SNI support (which has to be enabled at compile time, and is required for the `sni-*` options to be available). It is designed to load certificates asynchronously from backends (files, SQL, ...) on demand, using the [fetch API](core_fetch.html#core_fetch).
In this case lighttpd2 will fetch the certificate based on the SNI hostname from the given `sni-backend` before GnuTLS is started for a connection.
If a SNI hostname was given by the client, but no certificate was found in the backend, it will use `sni-fallback-pemfile` (if set) instead of `pemfile`.
Combining @sni-backend@, @sni-fallback-pemfile@ and multiple @pemfile@ s won't work - it will only use the first configured @pemfile@ (if no SNI hostname was given by the client, otherwise @sni-*@ certificates are used).
Combining `sni-backend`, `sni-fallback-pemfile` and multiple `pemfile` s won't work - it will only use the first configured `pemfile` (if no SNI hostname was given by the client, otherwise `sni-*` certificates are used).
Also note that lighttpd2 does NOT verify whether the SNI hostname matches the hostname in the HTTP request. SNI is only used by the client to tell the server for which hostname it should send the certificate (i.e. what the client is using to verify it).
</textile>
</markdown>
</section>
<section title="GnuTLS priority string">
<textile>
<markdown>
The GnuTLS priority string configures which ciphers and protocol versions are available, and also a small set of options (workarounds to activate and so on).
Example: @"SECURE:-VERS-SSL3.0:-SHA1:+SHA1:-RSA:+RSA:%SERVER_PRECEDENCE"@
* @SECURE@: starts with @SECURE@ level: only secure ciphers and secure curves
* @-VERS-SSL3.0@: disables SSL3.0 support (all clients should support at least TLS1.0 now)
* @-SHA1:SHA1@ puts SHA1 back at the list for MAC algorithms (preferring the other SHA variants)
* @-RSA:+RSA@: prefer (RSA) DHE/ECDHE key exchanges over simple RSA
* @%SERVER_PRECEDENCE@ a flag telling GnuTLS to use its own order of preference instead of the order provided by the client.
Example: `"SECURE:-VERS-SSL3.0:-SHA1:+SHA1:-RSA:+RSA:%SERVER_PRECEDENCE"`
* `SECURE`: starts with `SECURE` level: only secure ciphers and secure curves
* `-VERS-SSL3.0`: disables SSL3.0 support (all clients should support at least TLS1.0 now)
* `-SHA1:SHA1` puts SHA1 back at the list for MAC algorithms (preferring the other SHA variants)
* `-RSA:+RSA`: prefer (RSA) DHE/ECDHE key exchanges over simple RSA
* `%SERVER_PRECEDENCE` a flag telling GnuTLS to use its own order of preference instead of the order provided by the client.
See also:
* "Priority strings":http://gnutls.org/manual/html_node/Priority-Strings.html#Priority-Strings (GnuTLS manual)
* "GnuTLS Priority Strings":http://blog.lighttpd.net/gnutls-priority-strings.html
* @gnutls-cli -l --priority "SECURE:-VERS-SSL3.0:-SHA1:+SHA1:-RSA:+RSA:%SERVER_PRECEDENCE"@
</textile>
* [Priority strings](https://gnutls.org/manual/html_node/Priority-Strings.html#Priority-Strings) (GnuTLS manual)
* [GnuTLS Priority Strings](https://blog.lighttpd.net/gnutls-priority-strings.html)
* `gnutls-cli -l --priority "SECURE:-VERS-SSL3.0:-SHA1:+SHA1:-RSA:+RSA:%SERVER_PRECEDENCE"`
</markdown>
</section>
<section title="OCSP stapling">
<textile>
"OCSP stapling":https://en.wikipedia.org/wiki/OCSP_stapling is used to assure a client the certificate is still valid (i.e. not revoked); you can put an OCSP response into the certificate file in an "OCSP RESPONSE"-PEM block (there is probably no standard for this, just base64-encode the DER-response you have), or specify the (DER or PEM formatted) OCSP response as separate file using "ocsp" in a "pemfile" block.
<markdown>
[OCSP stapling](https://en.wikipedia.org/wiki/OCSP_stapling) is used to assure a client the certificate is still valid (i.e. not revoked); you can put an OCSP response into the certificate file in an "OCSP RESPONSE"-PEM block (there is probably no standard for this, just base64-encode the DER-response you have), or specify the (DER or PEM formatted) OCSP response as separate file using "ocsp" in a "pemfile" block.
Server Name Indication (SNI) should work fine, as an OCSP response is only used if it matches the certificate in use for the connection.
@ -195,60 +196,56 @@
If you have your certificate and the issuer-certificate (the one that signed yours) in separate files you can request an OCSP response like that (using the GnuTLS "ocsptool"):
<pre>
ocsptool --ask --load-issuer issuer.pem --load-cert cert.pem --outfile ocsp.der
</pre>
Converting into PEM format can be done like this:
<pre>
(echo "-----BEGIN OCSP RESPONSE-----"; base64 --wrap=64 ocsp.der; echo "-----END OCSP RESPONSE-----") > ocsp.pem
</pre>
If you have trouble identifying which certificates you need, here the more detailed explanation:
You usually have a list of certificates in the PEM file you pass to lighttpd. The first certificate usually has a "Subject" pointing to your server name (CN), like: "Subject: CN=lighttpd.net". It also has a "Issuer" attribute (like "C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3"). The issuer certificate needs a "Subject" matching that "Issuer", and should be the second certificate in the PEM file (unless it already is the root CA, in which case it is usually omitted).
@ocsptool@ will always use the first certificate in a file and ignore the others, so you can use the normal PEM file you pass to lighttpd as argument after @--load-cert@, but you need to extract the issuer certificate if you don't have it in a separate file. The following @awk@ script extracts the second PEM block from a file:
`ocsptool` will always use the first certificate in a file and ignore the others, so you can use the normal PEM file you pass to lighttpd as argument after `--load-cert`, but you need to extract the issuer certificate if you don't have it in a separate file. The following `awk` script extracts the second PEM block from a file:
<pre>
awk '
BEGIN { block = 0 }
/^-----BEGIN / { ++block; }
{ if (block > 1) print; }
' "certs.pem" > "issuer.pem"
</pre>
</textile>
</markdown>
</section>
<section title="protect-against-beast">
<textile>
"BEAST":http://en.wikipedia.org/wiki/Transport_Layer_Security#BEAST_attack is considered mitigated on clients by many now, so this workaround is no longer recommended and disabled by default.
<markdown>
[BEAST](https://en.wikipedia.org/wiki/Transport_Layer_Security#BEAST_attack) is considered mitigated on clients by many now, so this workaround is no longer recommended and disabled by default.
It enabled it will enforce the usage of RC4 on TLS1.0 and before (TLS1.1 and TLS1.2 are not vulnerable); but RC4 has issues on its own.
</textile>
</markdown>
</section>
<section title="DH parameters">
<textile>
The @DHE_RSA@ key exchange requires parameters (similar to the curves used for @ECDHE_RSA@); the parameters specify a prime @p@ and a group generator @g@ of the multiplicative group of integers modulo @p@ (i.e. for all @x@ in @1..p-1@ exists an @e@ with @g^e = x@); sometimes @g@ might only create a sufficiently large subgroup (for example of size @(p-1)/2@).
<markdown>
The `DHE_RSA` key exchange requires parameters (similar to the curves used for `ECDHE_RSA`); the parameters specify a prime `p` and a group generator `g` of the multiplicative group of integers modulo `p` (i.e. for all `x` in `1..p-1` exists an `e` with `g^e = x`); sometimes `g` might only create a sufficiently large subgroup (for example of size `(p-1)/2`).
The security of the DH key exchange depends (among other things) on the bit length of @p@; therefore lighttpd includes default 4096-bit parameters (provided by the GnuTLS certtool with @certtool --get-dh-params --bits=4096@ in version 3.0.22), and these should be safe to use (key lengths > 1024 are not supported by some older clients; if you need to support those you either have to disable DH key exchange or specify 1024-bit parameters).
The security of the DH key exchange depends (among other things) on the bit length of `p`; therefore lighttpd includes default 4096-bit parameters (provided by the GnuTLS certtool with `certtool --get-dh-params --bits=4096` in version 3.0.22), and these should be safe to use (key lengths > 1024 are not supported by some older clients; if you need to support those you either have to disable DH key exchange or specify 1024-bit parameters).
You can use either GnuTLS or openssl to generate your own parameters:
* @certtool --generate-dh-params --bits=2048@
* @openssl dhparam -dsaparam 2048@
* @openssl dhparam -2 2048@
* @openssl dhparam -5 2048@
The GnuTLS @certtool@ only generates "DSA" parameters (any prime with a large generator), while @openssl@ can generate "DH" parameters with a generator of 2 or 5 combined with a Sophie Germain prime @(p-1)/2@ (i.e. both @p@ and @(p-1)/2@ are primes) or "DSA" parameters using the @-dsaparam@ option.
* `certtool --generate-dh-params --bits=2048`
* `openssl dhparam -dsaparam 2048`
* `openssl dhparam -2 2048`
* `openssl dhparam -5 2048`
"DH" parameters take a lot more time to generate, but you can reuse keys for those (although it is not recommended, search for @SSL_OP_SINGLE_DH_USE@ in the openssl manual on @SSL_CTX_set_tmp_dh_callback@). Keys for "DSA" parameters should not be reused, i.e. one should generate a new private key for each connection, which is the case in mod_gnutls. The default parameters provided by lighttpd are "DH" parameters.
The GnuTLS `certtool` only generates "DSA" parameters (any prime with a large generator), while `openssl` can generate "DH" parameters with a generator of 2 or 5 combined with a Sophie Germain prime `(p-1)/2` (i.e. both `p` and `(p-1)/2` are primes) or "DSA" parameters using the `-dsaparam` option.
"DH" parameters take a lot more time to generate, but you can reuse keys for those (although it is not recommended, search for `SSL_OP_SINGLE_DH_USE` in the openssl manual on `SSL_CTX_set_tmp_dh_callback`). Keys for "DSA" parameters should not be reused, i.e. one should generate a new private key for each connection, which is the case in mod_gnutls. The default parameters provided by lighttpd are "DH" parameters.
See also:
* "Diffie-Hellman(-Merkle) key exchange":http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
* "OpenSSL: Documents, dhparam(1)":https://www.openssl.org/docs/apps/dhparam.html
* "OpenSSL: Documents, SSL_CTX_set_tmp_dh_callback(3)":https://www.openssl.org/docs/ssl/SSL_CTX_set_tmp_dh_callback.html#NOTES
</textile>
* [Diffie-Hellman(-Merkle) key exchange](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange)
* [OpenSSL: Documents, dhparam(1)](https://www.openssl.org/docs/apps/dhparam.html)
* [OpenSSL: Documents, SSL_CTX_set_tmp_dh_callback(3)](https://www.openssl.org/docs/ssl/SSL_CTX_set_tmp_dh_callback.html#NOTES)
</markdown>
</section>
</module>

View File

@ -2,10 +2,9 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>limits concurrent connections or requests per second.</short>
<description>
<description><markdown>
Both limits can be "in total" or per IP.
</description>
</markdown></description>
<action name="limit.con">
<short>limits the total amount of concurrent connections to the specified limit.</short>
@ -15,9 +14,9 @@
<parameter name="action">
<short>(optional) an action to be executed when the limit is reached</short>
</parameter>
<description>
<description><markdown>
If no action is defined a 503 error page will be returned. If it is specified there is no other special handling apart from running the specified action when the limit is reached.
</description>
</markdown></description>
<example>
<config>
limit.con 10;
@ -33,9 +32,9 @@
<parameter name="action">
<short>(optional) an action to be executed when the limit is reached</short>
</parameter>
<description>
<description><markdown>
If no action is defined a 503 error page will be returned. If it is specified there is no other special handling apart from running the specified action when the limit is reached.
</description>
</markdown></description>
<example>
<config>
limit.con_ip 2;
@ -51,9 +50,9 @@
<parameter name="action">
<short>(optional) an action to be executed when the limit is reached</short>
</parameter>
<description>
<description><markdown>
If no action is defined a 503 error page will be returned. If it is specified there is no other special handling apart from running the specified action when the limit is reached.
</description>
</markdown></description>
<example>
<config>
limit.req 100;
@ -69,9 +68,9 @@
<parameter name="action">
<short>(optional) an action to be executed when the limit is reached</short>
</parameter>
<description>
<description><markdown>
If no action is defined a 503 error page will be returned. If it is specified there is no other special handling apart from running the specified action when the limit is reached.
</description>
</markdown></description>
<example>
<config>
limit.req_ip 100;
@ -80,9 +79,9 @@
</action>
<example title="Limiting concurrent connections" anchor="#">
<description>
<description><markdown>
This config snippet will allow only 10 active downloads overall and 1 per IP. If the limit is exceeded, either because more than 10 people try to access this resource or one person tries a second time while having one download running already, they will be redirected to /connection_limit_reached.html.
</description>
</markdown></description>
<config>
setup {
module_load ("mod_limit","mod_redirect");
@ -100,10 +99,10 @@
</example>
<example title="Limiting requests per second" anchor="#">
<description>
<description><markdown>
This config snippet will write a message to the log containing the client IP address if the /login page is hit more than once in a second.
It will however also not do anything else. The client will be able to use the /login page as often as he wants.
</description>
</markdown></description>
<config>
setup {
module_load "mod_limit";

View File

@ -2,11 +2,9 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>load lua plugins and actions</short>
<description>
<textile><![CDATA[
Also see "Lua API":core_lua.html#core_lua.
]]></textile>
</description>
<description><markdown><![CDATA[
Also see [Lua API](core_lua.html#core_lua).
]]></markdown></description>
<setup name="lua.plugin">
<short>load file as lua plugin</short>
@ -19,13 +17,11 @@
<parameter name="lua-args">
<short>arguments forwarded to the lua plugin</short>
</parameter>
<description>
<textile>
A lua plugin can register setup and action callbacks (like any C module) by creating a setups / actions table in the global lua namespace.
<description><markdown>
A lua plugin can register setup and action callbacks (like any C module) by creating a setups / actions table in the global lua namespace.
The filename and the third argument @lua-args@ are available as parameters in @...@ in the lua script.
</textile>
</description>
The filename and the third argument `lua-args` are available as parameters in `...` in the lua script.
</markdown></description>
<example>
<config>
setup {
@ -37,9 +33,9 @@
</setup>
<example title="Example plugin" anchor="#">
<description><textile>
(see "contrib/core.lua":http://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/core.lua for a real example)
</textile></description>
<description><markdown>
(see [contrib/core.lua](https://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/core.lua) for a real example)
</markdown></description>
<config>
local filename, args = ...
@ -74,18 +70,17 @@
<parameter name="lua-args">
<short>arguments forwarded to the lua plugin</short>
</parameter>
<description>
<textile>
lua.handler is basically the same as "include_lua":core_config.html#core_config__includes with the following differences:
* each worker loads the lua file itself
* it isn't loaded before it is used, so you won't see errors in the script at load time
* it cannot call setup functions
* it supports arguments to the script (@local filename, args = ...@)
* doesn't lock the global lua lock, so it performs better when you use multiple workers
<description><markdown>
lua.handler is basically the same as [include_lua](core_config.html#core_config__includes) with the following differences:
See "contrib/core.lua":http://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/core.lua for how we load some external actions like "contrib/core__xsendfile.lua":http://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/core__xsendfile.lua
</textile>
</description>
* each worker loads the lua file itself
* it isn't loaded before it is used, so you won't see errors in the script at load time
* it cannot call setup functions
* it supports arguments to the script (`local filename, args = ...`)
* doesn't lock the global lua lock, so it performs better when you use multiple workers
See [contrib/core.lua](https://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/core.lua) for how we load some external actions like [contrib/core__xsendfile.lua](https://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/core__xsendfile.lua).
</markdown></description>
<example>
<config>
setup {

View File

@ -2,20 +2,18 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>caches content on memcached servers</short>
<description>
<textile><![CDATA[
@lookup@ tries to find data associated with the key, and returns it as http body with status 200 if it finds something.
@store@ stores a http body (generated by another backend) in memcached.
<description><markdown><![CDATA[
`lookup` tries to find data associated with the key, and returns it as http body with status 200 if it finds something.
`store` stores a http body (generated by another backend) in memcached.
Caching always requires you to think about what you want; you cannot cache content that changes with every request!
Caching always requires you to think about what you want; you cannot cache content that changes with every request!
So most of the time you probably want to set a TTL for the stored content in memcached; your users probably don't need new content to be available the next second, perhaps 60 seconds is still good (obviously not true for a chat...).
So most of the time you probably want to set a TTL for the stored content in memcached; your users probably don't need new content to be available the next second, perhaps 60 seconds is still good (obviously not true for a chat...).
The other way is to purge the keys in your dynamic backend; you can set the memcached content from your backend too, which probably is faster than @memcached.store@.
The other way is to purge the keys in your dynamic backend; you can set the memcached content from your backend too, which probably is faster than `memcached.store`.
If the key is longer than 255 bytes or contains characters outside the range 0x21 - 0x7e we will use a hash of it instead (for now sha1, but that may change).
]]></textile>
</description>
If the key is longer than 255 bytes or contains characters outside the range 0x21 - 0x7e we will use a hash of it instead (for now sha1, but that may change).
]]></markdown></description>
<action name="memcached.lookup">
<short>searches the content in a memcached database</short>
@ -85,24 +83,26 @@
</example>
<section title="Lua API" anchor="#">
<textile><![CDATA[
mod_memcached exports a Lua API to per-worker @luaState@s too (for use in lua.handler):
<markdown><![CDATA[
mod_memcached exports a Lua API to per-worker `luaState`s too (for use in lua.handler):
@memcached.new(address)@ creates a new connection; a connection provides:
* @req = con:get(key, cb | vr)@
* @req = con:set(key, value, cb | vr, [ttl])@
* @con:setq(key, value, [ttl])@
`memcached.new(address)` creates a new connection; a connection provides:
* `req = con:get(key, cb | vr)`
* `req = con:set(key, value, cb | vr, [ttl])`
* `con:setq(key, value, [ttl])`
If a callback was given, the callback gets called with a response object; otherwise the response will be in req.response when ready.
The response object has:
* @code@: 1 - Ok, 2 - Not stored, 3 - Exists, 4 - Not found, 5 - Error
* @error@: error message
* @key@: the lookup key
* @flags@
* @ttl@
* @cas@
* @data@
]]></textile>
* `code`: 1 Ok, 2 Not stored, 3 Exists, 4 Not found, 5 Error
* `error`: error message
* `key`: the lookup key
* `flags`
* `ttl`
* `cas`
* `data`
]]></markdown>
</section>
</module>

View File

@ -45,13 +45,11 @@
</table>
</parameter>
<description>
<textile>
For @ciphers@ see OpenSSL "ciphers":https://www.openssl.org/docs/manmaster/man1/ciphers.html string
<description><markdown>
For `ciphers` see OpenSSL [ciphers](https://www.openssl.org/docs/manmaster/man1/ciphers.html) string
For @options@ see "options":https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html. Explicitly specify the reverse flag by toggling the "NO_" prefix to override defaults.
</textile>
</description>
For `options` see [options](https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html). Explicitly specify the reverse flag by toggling the "NO_" prefix to override defaults.
</markdown></description>
<example title="Simple TLS on IPv4 and IPv6">
<config>
@ -106,14 +104,13 @@
<parameter name="list">
<short>list of subsets to export</short>
</parameter>
<description>
<textile>
Supported subsets:
* "client" - set @SSL_CLIENT_S_DN_@ short-named entries
* "client-cert" - set @SSL_CLIENT_CERT@ to client certificate PEM
* "server" - set @SSL_SERVER_S_DN_@ short-named entries
* "server-cert" - set @SSL_SERVER_CERT@ to server certificate PEM
</textile>
</description>
<description><markdown>
Supported subsets:
* "client" set `SSL_CLIENT_S_DN_` short-named entries
* "client-cert" set `SSL_CLIENT_CERT` to client certificate PEM
* "server" set `SSL_SERVER_S_DN_` short-named entries
* "server-cert" set `SSL_SERVER_CERT` to server certificate PEM
</markdown></description>
</action>
</module>

View File

@ -2,19 +2,16 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>track connection progress (state) via a unique identifier</short>
<description>
<textile><![CDATA[
mod_progress lets you track connection progress (or rather state) using a lookup table in which connections are registered via a random unique identifier specified with the request.
It is most commonly used to implement progress bars for file uploads.
<description><markdown><![CDATA[
mod_progress lets you track connection progress (or rather state) using a lookup table in which connections are registered via a random unique identifier specified with the request.
It is most commonly used to implement progress bars for file uploads.
A request to the webserver is registered using the @progress.track@ action and being tracked by a random unique identifier supplied with the @X-Progress-Id@ querystring parameter.
From that moment on, other requests can fetch the state of the first request through the @progress.show@ action specifying the @X-Progress-Id@ used earlier.
Even after a tracked request finished and the connection to the client is gone, requests can for a limited amount of time get the status of it to see it as "done".
A request to the webserver is registered using the `progress.track` action and being tracked by a random unique identifier supplied with the `X-Progress-Id` querystring parameter.
From that moment on, other requests can fetch the state of the first request through the `progress.show` action specifying the `X-Progress-Id` used earlier.
Even after a tracked request finished and the connection to the client is gone, requests can for a limited amount of time get the status of it to see it as "done".
A live demonstration of a progress bar implementation can be seen at http://demo.lighttpd.net/progress/
Check the source code there for further insight.
]]></textile>
</description>
Check the source code there for further insight.
]]></markdown></description>
<setup name="progress.ttl">
@ -47,26 +44,26 @@
<parameter name="format">
<short>(optional) output format, one of "legacy", "json" or "jsonp". Defaults to "json".</short>
</parameter>
<description>
<textile><![CDATA[
Output formats:
* legacy: @new Object({"state": "running"", "received": 123456, "sent": 0, "request_size": 200000, "response_size": 0})@
* json: @{"state": "running", "received": 123456, "sent": 0, "request_size": 200000, "response_size": 0}@
* jsonp: @progress({"state": "running", "received": 123456, "sent": 0, "request_size": 200000, "response_size": 0})@
The function name (default "progress") can be altered by supplying a X-Progress-Callback querystring parameter.
<description><markdown><![CDATA[
Output formats:
The JSON object can contain the following members:
* *state*: One of @"unknown"@, @"running"@, @"done"@ or @"error"@.
* *received*: Bytes received by lighty or uploaded by the client.
* *request_size*: Total size of request or uploaded file as specified via the Content-Length request header.
* *sent*: Bytes sent by lighty or downloaded by the client.
* *response_size*: Total size of response. Attention: this might grow over time in case of streaming from a backend.
* *status*: HTTP status code of response.
* legacy: `new Object({"state": "running"", "received": 123456, "sent": 0, "request_size": 200000, "response_size": 0})`
* json: `{"state": "running", "received": 123456, "sent": 0, "request_size": 200000, "response_size": 0}`
* jsonp: `progress({"state": "running", "received": 123456, "sent": 0, "request_size": 200000, "response_size": 0})`
The function name (default "progress") can be altered by supplying a X-Progress-Callback querystring parameter.
@received@, @request_size@, @sent@ and @response_size@ are only available if @state@ is @"running"@ or @"done"@.
@status@ is only available if @state@ is @"error"@.
]]></textile>
</description>
The JSON object can contain the following members:
* **state**: One of `"unknown"`, `"running"`, `"done"` or `"error"`.
* **received**: Bytes received by lighty or uploaded by the client.
* **request_size**: Total size of request or uploaded file as specified via the Content-Length request header.
* **sent**: Bytes sent by lighty or downloaded by the client.
* **response_size**: Total size of response. Attention: this might grow over time in case of streaming from a backend.
* **status**: HTTP status code of response.
`received`, `request_size`, `sent` and `response_size` are only available if `state` is `"running"` or `"done"`.
`status` is only available if `state` is `"error"`.
]]></markdown></description>
<example>
<config><![CDATA[

View File

@ -7,11 +7,9 @@
<parameter name="socket">
<short>socket to connect to, either "ip:port" or "unix:/path"</short>
</parameter>
<description>
<textile><![CDATA[
proxy uses @request.raw_path@ for the URL (including the query string) to send to the backend.
]]></textile>
</description>
<description><markdown><![CDATA[
proxy uses `request.raw_path` for the URL (including the query string) to send to the backend.
]]></markdown></description>
<example>
<config>
setup {

View File

@ -2,25 +2,21 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>redirect clients by sending a http status code 301 plus Location header</short>
<description>
<textile>
It supports matching "regular expressions":core_regex.html#core_regex and "substitution":core_pattern.html#core_pattern with captured substrings as well as other placeholders.
</textile>
</description>
<description><markdown>
It supports matching [regular expressions](core_regex.html#core_regex) and [substitution](core_pattern.html#core_pattern) with captured substrings as well as other placeholders.
</markdown></description>
<action name="redirect">
<short>redirect clients</short>
<parameter name="rule">
<short>a simple target string or one rule, mapping a regular expression to a target string, or a list of rules.</short>
</parameter>
<description>
<textile>
* The target string is a "pattern":core_pattern.html#core_pattern.
* The "regular expressions":core_regex.html#core_regex are used to match the request path (always starts with "/"!)
* If a list of rules is given, redirect stops on the first match.
* By default the target string is interpreted as absolute uri; if it starts with '?' it will replace the query string, if it starts with '/' it will replace the current path, and if it starts with './' it is interpreted relative to the current "directory" in the path.
</textile>
</description>
<description><markdown>
* The target string is a [pattern](core_pattern.html#core_pattern).
* The [regular expressions](core_regex.html#core_regex) are used to match the request path (always starts with "/"!)
* If a list of rules is given, redirect stops on the first match.
* By default the target string is interpreted as absolute uri; if it starts with '?' it will replace the query string, if it starts with '/' it will replace the current path, and if it starts with './' it is interpreted relative to the current "directory" in the path.
</markdown></description>
<example title="Example: redirect always (http to https)">
<config>
setup {
@ -59,9 +55,9 @@
</example>
<example>
<description>
<description><markdown>
redirect all non www. requests. for example: foo.tld/bar?x=y to www.foo.tld/bar?x=y
</description>
</markdown></description>
<config>
if request.host !~ "^www\.(.*)$" {
redirect "." => "http://www.%1/$0?%{request.query}";

View File

@ -2,31 +2,27 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>modifies request path and querystring</short>
<description>
<textile>
It supports matching "regular expressions":core_regex.html#core_regex and "substitution":core_pattern.html#core_pattern with captured substrings as well as other placeholders.
<description><markdown>
It supports matching [regular expressions](core_regex.html#core_regex) and [substitution](core_pattern.html#core_pattern) with captured substrings as well as other placeholders.
If your rewrite target does not contain any question mark (@?@), then the querystring will not be altered.
If it does contain @?@ the querystring will be overwritten with the part after the @?@. To append the original querystring, use @%{request.query}@.
If your rewrite target does not contain any question mark (`?`), then the querystring will not be altered.
If it does contain `?` the querystring will be overwritten with the part after the `?`. To append the original querystring, use `%{request.query}`.
*IMPORTANT*: rewrite only changes the url, not the physical filename that it got mapped to by docroot or alias actions. So you need your docroot and alias actions after the rewrite.
If you have conditional rewrites like @if !phys.is_file { rewrite ... }@ you need docroot/alias both before (so it can check for the physical file) *and* after it (to build the new physical path).
</textile>
</description>
**IMPORTANT**: rewrite only changes the url, not the physical filename that it got mapped to by docroot or alias actions. So you need your docroot and alias actions after the rewrite.
If you have conditional rewrites like `if !phys.is_file { rewrite ... }` you need docroot/alias both before (so it can check for the physical file) **and** after it (to build the new physical path).
</markdown></description>
<action name="rewrite">
<short>modify request path and querystring</short>
<parameter name="rule">
<short>a simple target string or one rule, mapping a regular expression to a target string, or a list of rules.</short>
</parameter>
<description>
<textile>
* The target string is a "pattern":core_pattern.html#core_pattern.
* The "regular expressions":core_regex.html#core_regex are used to match the request path (always starts with "/" and does *not* include the query string!)
* If a list of rules is given, rewrite stops on the first match.
* Replaces the query string iff the target string contains an @?@
</textile>
</description>
<description><markdown>
* The target string is a [pattern](core_pattern.html#core_pattern).
* The [regular expressions](core_regex.html#core_regex) are used to match the request path (always starts with "/" and does **not** include the query string!)
* If a list of rules is given, rewrite stops on the first match.
* Replaces the query string iff the target string contains an `?`
</markdown></description>
<example title="Example: rewrite always">
<config>
setup {
@ -52,11 +48,9 @@
</config>
</example>
<example title="Example: pretty urls">
<description>
<textile>
Note: you really should move the logic for such rewrites into your application, and just rewrite all pretty urls to your index.php without putting the actions into the querystring.
</textile>
</description>
<description><markdown>
Note: you really should move the logic for such rewrites into your application, and just rewrite all pretty urls to your index.php without putting the actions into the querystring.
</markdown></description>
<config><![CDATA[
setup {
module_load "mod_rewrite";
@ -80,15 +74,13 @@
<parameter name="rule">
<short>a simple target string or one rule, mapping a regular expression to a target string, or a list of rules.</short>
</parameter>
<description>
<textile>
Similar to "@rewrite@":mod_rewrite.html#mod_rewrite__action_rewrite, but matches the raw path (i.e. the path before URL decoding and sanitizing) and the result is decoded again.
<description><markdown>
Similar to [`rewrite`](mod_rewrite.html#mod_rewrite__action_rewrite), but matches the raw path (i.e. the path before URL decoding and sanitizing) and the result is decoded again.
"@rewrite@":mod_rewrite.html#mod_rewrite__action_rewrite writes the result to @request.path@ and possibly @request.query@ and uses URL encoding to generate @request.raw_path@ from those.
"@rewrite_raw@":mod_rewrite.html#mod_rewrite__action_rewrite_raw writes @request.raw_path@ and decodes it into @request.path@ and @request.query@; this means the query string is always overwritten.
In both cases @request.path@ gets simplified afterwards.
</textile>
</description>
[`rewrite`](mod_rewrite.html#mod_rewrite__action_rewrite) writes the result to `request.path` and possibly `request.query` and uses URL encoding to generate `request.raw_path` from those.
[`rewrite_raw`](mod_rewrite.html#mod_rewrite__action_rewrite_raw) writes `request.raw_path` and decodes it into `request.path` and `request.query`; this means the query string is always overwritten.
In both cases `request.path` gets simplified afterwards.
</markdown></description>
</action>
<option name="rewrite.debug">

View File

@ -3,13 +3,14 @@
<short>protects files with a time limited code</short>
<section title="Install">
<textile><![CDATA[
By default distributions (and @make install@) should provide the necessary files; but you can always find them in the "contrib":http://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib folder:
* @secdownload.lua@
* @secdownload__secdownload.lua@
<markdown><![CDATA[
By default distributions (and `make install`) should provide the necessary files; but you can always find them in the [contrib](https://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib) folder:
* `secdownload.lua`
* `secdownload__secdownload.lua`
That way you can modify them for your own needs if you have to (although it is recommended to change the names of the files and the actions, so you don't get conflicts).
]]></textile>
]]></markdown>
</section>
<action name="secdownload">
@ -30,12 +31,10 @@
</entry>
</table>
</parameter>
<description>
<textile><![CDATA[
The @prefix@ is not used to build the filename; include it manually in the @document-root@ (works like @alias "/prefix" => "/docroot"@, see "@alias@":plugin_core.html#plugin_core__action_alias).
secdownload doesn't actually handle the (valid) request, it just provides the mapping to a filename (and rejects invalid requests).
]]></textile>
</description>
<description><markdown><![CDATA[
The `prefix` is not used to build the filename; include it manually in the `document-root` (works like `alias "/prefix" => "/docroot"`, see [`alias`](plugin_core.html#plugin_core__action_alias)).
secdownload doesn't actually handle the (valid) request, it just provides the mapping to a filename (and rejects invalid requests).
]]></markdown></description>
<example>
<config><![CDATA[
setup {
@ -48,33 +47,31 @@
</action>
<section title="Generating URLs">
<textile><![CDATA[
To generate URLs that are valid for @secdownload@ you need the same secret.
The url takes the form @prefix + md5hex(secret + filepath + timestamp) + '/' + timestamp + filepath@; timestamp is the "Unix time":http://en.wikipedia.org/wiki/Unix_time formatted as hexadecimal number.
<markdown><![CDATA[
To generate URLs that are valid for `secdownload` you need the same secret.
The url takes the form `prefix + md5hex(secret + filepath + timestamp) + '/' + timestamp + filepath`; timestamp is the [Unix time](https://en.wikipedia.org/wiki/Unix_time) formatted as hexadecimal number.
For example with PHP:
<pre>
$secret = "abc";
$uri_prefix = "/sec/";
$secret = "abc";
$uri_prefix = "/sec/";
# filename; please note file name starts with "/"
$f = "/secret-file.txt";
# filename; please note file name starts with "/"
$f = "/secret-file.txt";
# current timestamp
$t = time();
# current timestamp
$t = time();
$t_hex = sprintf("%08x", $t);
$m = md5($secret.$f.$t_hex);
$t_hex = sprintf("%08x", $t);
$m = md5($secret.$f.$t_hex);
# generate link
printf('<a href="%s%s/%s%s">%s</a>', $uri_prefix, $m, $t_hex, $f, $f);
</pre>
# generate link
printf('<a href="%s%s/%s%s">%s</a>', $uri_prefix, $m, $t_hex, $f, $f);
The config example above would map this url to the file @/secret/path/secret-file.txt@.
The config example above would map this url to the file `/secret/path/secret-file.txt`.
For more examples see "mod_secdownload (lighttpd 1.4.x)":https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModSecDownload#Examples
]]></textile>
For more examples see [mod_secdownload (lighttpd 1.4.x)](https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModSecDownload#Examples).
]]></markdown>
</section>
</module>

View File

@ -18,19 +18,18 @@
<parameter name="mode">
<short>(optional) "short"</short>
</parameter>
<description>
<textile>
The "short" mode removes connection and runtime details (recommended for "public" status).
<description><markdown>
The "short" mode removes connection and runtime details (recommended for "public" status).
The status page accepts the following query-string parameters:
* @?mode=runtime@: shows the runtime details
* "@format=plain@: shows the "short" stats in plain text format
</textile>
</description>
The status page accepts the following query-string parameters:
* `?mode=runtime`: shows the runtime details
* `format=plain`: shows the "short" stats in plain text format
</markdown></description>
<example>
<description>
<description><markdown>
If /server-status is requested, a page with lighttpd statistics is displayed.
</description>
</markdown></description>
<config>
setup {
module_load "mod_status";

View File

@ -2,9 +2,9 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>limits outgoing bandwidth usage</short>
<description>
<description><markdown>
All rates are in bytes/sec. The magazines are filled up in fixed intervals (compile time constant; defaults to 200ms).
</description>
</markdown></description>
<action name="io.throttle">
<short>set the outgoing throttle limits for current connection</short>
@ -14,11 +14,9 @@
<parameter name="burst">
<short>optional, defaults to 2*rate</short>
</parameter>
<description>
<textile>
@burst@ is the initial and maximum value for the @magazine@; doing IO drains the @magazine@, which fills up again over time with the specified @rate@.
</textile>
</description>
<description><markdown>
`burst` is the initial and maximum value for the `magazine`; doing IO drains the `magazine`, which fills up again over time with the specified `rate`.
</markdown></description>
</action>
<action name="io.throttle_pool">
@ -26,15 +24,13 @@
<parameter name="rate">
<short>bytes/sec limit</short>
</parameter>
<description>
<textile>
all connections in the same pool are limited as whole. Each @io.throttle_pool@ action creates its own pool.
</textile>
</description>
<description><markdown>
all connections in the same pool are limited as whole. Each `io.throttle_pool` action creates its own pool.
</markdown></description>
<example>
<description>
<description><markdown>
Using the same pool in more than one place:
</description>
</markdown></description>
<config>
setup {
module_load "mod_throttle";
@ -53,15 +49,13 @@
<parameter name="rate">
<short>bytes/sec limit</short>
</parameter>
<description>
<textile>
all connections from the same IP address in the same pool are limited as whole. Each @io.throttle_ip@ action creates its own pool.
</textile>
</description>
<description><markdown>
all connections from the same IP address in the same pool are limited as whole. Each `io.throttle_ip` action creates its own pool.
</markdown></description>
<example>
<description>
<description><markdown>
Using the same pool in more than one place:
</description>
</markdown></description>
<config>
setup {
module_load "mod_throttle";

View File

@ -2,41 +2,39 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>allows you to have user-specific document roots being accessed through http://domain/~user/</short>
<description>
<textile><![CDATA[
The document root can be built by using the home directory of a user which is specified by /~username/ at the beginning of the request path.
Alternatively, mod_userdir can build the docroot from a pattern similar to @vhost.pattern@ but using the username instead of the hostname.
]]></textile>
</description>
<description><markdown><![CDATA[
The document root can be built by using the home directory of a user which is specified by /~username/ at the beginning of the request path.
Alternatively, mod_userdir can build the docroot from a pattern similar to `vhost.pattern` but using the username instead of the hostname.
]]></markdown></description>
<action name="userdir">
<short>builds the document root by replacing certain placeholders in path with (parts of) the username.</short>
<parameter name="path">
<short>the path to build the document root with</short>
</parameter>
<description>
<textile><![CDATA[
If @path@ does not start with a slash (/), then the document root is prepended with the home directory of the given user as specified in /etc/passwd.
Otherwise the @path@ specifies the absolute docroot to be used.
<description><markdown><![CDATA[
If `path` does not start with a slash (/), then the document root is prepended with the home directory of the given user as specified in /etc/passwd.
Otherwise the `path` specifies the absolute docroot to be used.
Placeholders are:
* @*@ is replaced by the complete username
* @$1@-@$9@ are replaced by the n-th letter of the username, e.g. @$2@ is the second letter
Placeholders are:
Examples:
* `*` is replaced by the complete username
* `$1`-`$9` are replaced by the n-th letter of the username, e.g. `$2` is the second letter
Request for http://host/~lighty/foo.html (assuming "/home/lighty" is the home of the "lighty" user):
Examples:
table(table table-striped).
|_. @path@ |_. docroot |_. physicalpath|
| "public_html" | /home/lighty/public_html/ | /home/lighty/public_html/foo.html |
| "/usr/web/*/" | /usr/web/lighty/ | /usr/web/lighty/foo.html |
| "/usr/web" | /usr/web/lighty/ | /usr/web/lighty/foo.html |
| "/www/users/$1/$1$2/*/" | /www/users/l/li/lighty/ | /www/users/l/li/lighty/foo.html |
Request for http://host/~lighty/foo.html (assuming "/home/lighty" is the home of the "lighty" user):
*Note*: username "root" is not allowed for security reasons.
]]></textile>
</description>
| `path` | docroot | physicalpath|
|-|-|-|
| "public_html" | /home/lighty/public_html/ | /home/lighty/public_html/foo.html |
| "/usr/web/*/" | /usr/web/lighty/ | /usr/web/lighty/foo.html |
| "/usr/web" | /usr/web/lighty/ | /usr/web/lighty/foo.html |
| "/www/users/$1/$1$2/*/" | /www/users/l/li/lighty/ | /www/users/l/li/lighty/foo.html |
{:.table .table-striped}
**Note**: username "root" is not allowed for security reasons.
]]></markdown></description>
<example>
<config><![CDATA[
setup {

View File

@ -2,23 +2,19 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>offers various ways to implement virtual webhosts</short>
<description>
<textile>
It can map hostnames to actions and offers multiple ways to do so.
These ways differ in the flexibility of mapping (what to map and what to map to) as well as performance.
</textile>
</description>
<description><markdown>
It can map hostnames to actions and offers multiple ways to do so.
These ways differ in the flexibility of mapping (what to map and what to map to) as well as performance.
</markdown></description>
<action name="vhost.map">
<short>maps given hostnames to action blocks</short>
<parameter name="mapping">
<short>key-value list with hostnames as keys and actions as values</short>
</parameter>
<description>
<textile>
@vhost.map@ offers a fast (lookup through hash-table) and flexible mapping, but maps only exact hostnames (no pattern/regex matching). The server port is never considered part of the hostname. Use the key @default@ (keyword, not as string) to specify a default action.
</textile>
</description>
<description><markdown>
`vhost.map` offers a fast (lookup through hash-table) and flexible mapping, but maps only exact hostnames (no pattern/regex matching). The server port is never considered part of the hostname. Use the key `default` (keyword, not as string) to specify a default action.
</markdown></description>
<example>
<config>
vhost.map ["host1" => actionblock1, "host2" => actionblock2, ..., "hostN" => actionblockN, default => actionblock0];
@ -31,11 +27,9 @@
<parameter name="mapping">
<short>key-value list with regular expressions for hostnames as keys and actions as values</short>
</parameter>
<description>
<textile>
@vhost.map_regex@ walks through the list in the given order and stops at the first match; if no regular expression matched it will use the @default@ action (if specified).
</textile>
</description>
<description><markdown>
`vhost.map_regex` walks through the list in the given order and stops at the first match; if no regular expression matched it will use the `default` action (if specified).
</markdown></description>
<example>
<config>
vhost.map_regex ["host1regex" => actionblock1, "host2regex" => actionblock2, ..., "hostNregex" => actionblockN, default => actionblock0];
@ -49,17 +43,16 @@
</option>
<example>
<description>
<textile>
Combining both actions is also possible.
<description><markdown>
Combining both actions is also possible.
What it does (for example):
* if @example.com@ or @www.example.com@ is requested, the block named "examplesite" will be executed
* if @mydomain.tld@ is requested, the block named "mydomain" will be executed
* if @mydomain.com@ or @www.mydomain.net@ is requested, the block named "mydomain" will be executed (through the regex matching)
* if @www.mydomain.tld@ or something entirely different is requested, the block named "defaultdom" will be executed
</textile>
</description>
What it does (for example):
* if `example.com` or `www.example.com` is requested, the block named "examplesite" will be executed
* if `mydomain.tld` is requested, the block named "mydomain" will be executed
* if `mydomain.com` or `www.mydomain.net` is requested, the block named "mydomain" will be executed (through the regex matching)
* if `www.mydomain.tld` or something entirely different is requested, the block named "defaultdom" will be executed
</markdown></description>
<config>
setup {
module_load "mod_vhost";

View File

@ -3,30 +3,32 @@
<short>contains the core features for generic request handling, static files, log files and buffer limits.</short>
<section title="Socket addresses">
The following address formats can be used:
<markdown>
The following address formats can be used:
</markdown>
<section title="IPv4">
<textile>
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.
</textile>
<markdown>
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.
</markdown>
</section>
<section title="IPv6">
<textile>
Similar to IPv4; just put the IPv6 between "[" and "]" like this: @[::1]:80@ (IPv6 localhost with port 80).
<markdown>
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).
</textile>
</markdown>
</section>
<section title="Unix domain sockets">
<textile>
A unix domain socket needs a filename where the socket is placed; use @unix:/path/to/socket@ as socket address.
<markdown>
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.
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.
</textile>
</markdown>
</section>
</section>
@ -82,32 +84,26 @@
<option name="stat.async">
<short>enables async stat() calls</short>
<default><value>true</value></default>
<description>
<textile>
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.
<description><markdown>
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.
</textile>
</description>
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.
</markdown></description>
</option>
<option name="buffer_request_body">
<short>enable buffering request body on disk</short>
<default><value>true</value></default>
<description>
<textile>
Some backends like to wait for the complete response before forwarding/handling it. For this they require this option to save some memory.
</textile>
</description>
<description><markdown>
Some backends like to wait for the complete response before forwarding/handling it. For this they require this option to save some memory.
</markdown></description>
</option>
<option name="strict.post_content_length">
<short>require Content-Length for POST requests</short>
<default><value>true</value></default>
<description>
<textile>
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.
</textile>
</description>
<description><markdown>
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.
</markdown></description>
</option>
<option name="static.exclude_extensions">
@ -124,12 +120,10 @@
<short>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</short>
<parameter name="hostname" />
<default><value>""</value></default>
<description>
<textile>
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.
</textile>
</description>
<description><markdown>
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.
</markdown></description>
<example>
<config>
server.name "lighttpd.net";
@ -140,21 +134,19 @@
<short>used to display server name + version in different places (HTTP response header, CGI environment, mod_dirlist footer, ...)</short>
<parameter name="tag" />
<default><value>"lighttpd/2.0.0"</value></default>
<description>
<description><markdown>
The default is "lighttpd/" + the current version.
</description>
</markdown></description>
</option>
<option name="mime_types">
<short>maps file extensions to MIME types</short>
<parameter name="mapping" />
<default><value>[]</value></default>
<description>
<textile>
Default MIME type is "application/octet-stream". The sources contain a "mimetypes example config":http://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/mimetypes.conf with many standard mappings.
<description><markdown>
Default MIME type is "application/octet-stream". The sources contain a [mimetypes example config](https://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/mimetypes.conf) 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.
</textile>
</description>
The longest matching suffix is used (`".tar.gz"` always wins over `".gz"`), and in case of duplicate entries the last one is used.
</markdown></description>
<example>
<config>
mime_types [ ".htm" => "text/html", ".txt" => "text/plain; charset=utf-8" ];
@ -164,7 +156,9 @@
</section>
<section title="Actions needed from lua">
These action are not needed (or usable) in non-lua configs.
<markdown>
These action are not needed (or usable) in non-lua configs.
</markdown>
<action name="list">
<short>(lua) combines a list of actions into one action, only needed in lua</short>
@ -192,13 +186,11 @@
<parameter name="patterns">
<short>One or more patterns to build docroot from</short>
</parameter>
<description>
<textile>
Uses "patterns":core_pattern.html#core_pattern 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!
</textile>
</description>
<description><markdown>
Uses [patterns](core_pattern.html#core_pattern) 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!
</markdown></description>
<example>
<config>
docroot ("/var/www/vhosts/$0/htdocs", "/var/www/default/htdocs");
@ -211,14 +203,12 @@
<parameter name="mapping">
<short>maps prefix to base location on disk</short>
</parameter>
<description>
<textile>
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!
<description><markdown>
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":core_pattern.html#core_pattern 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.
</textile>
</description>
[Patterns](core_pattern.html#core_pattern) 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.
</markdown></description>
<example>
<config>
docroot ("/var/www/vhosts/$0/htdocs", "/var/www/default/htdocs");
@ -236,19 +226,18 @@
<parameter name="filenames">
<short>filenames to look for</short>
</parameter>
<description>
<textile>
If the physical path is a directory search for the specified filenames; prefix a filename with '/' to search in the doc-root.
<description><markdown>
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
</textile>
</description>
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
</markdown></description>
<example>
<config>
setup {
@ -265,15 +254,13 @@
</action>
<action name="pathinfo">
<short>splits physical path into existing file/directory and the remaining PATH_INFO</short>
<description>
<textile>
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).
</textile>
</description>
<description><markdown>
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).
</markdown></description>
<example>
<description>
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).
</description>
<description><markdown>
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).
</markdown></description>
<config>
docroot "/var/www";
pathinfo;
@ -281,9 +268,9 @@
</config>
</example>
<example>
<description>
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).
</description>
<description><markdown>
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).
</markdown></description>
<config>
docroot "/var/www";
pathinfo;
@ -297,31 +284,29 @@
<section title="Generating responses">
<action name="static">
<short>handle GET and HEAD requests with a static file from disk</short>
<description>
<textile>
This action is automatically appended to the global config (unless a lua config is specified at the command line).
<description><markdown>
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
Does nothing if:
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)
* ...
</textile>
</description>
* 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)
* ...
</markdown></description>
</action>
<action name="static_no_fail">
<short>handle GET and HEAD requests with a static file from disk</short>
<description>
<textile>
same as @static@, but doesn't return any error pages; instead request handling continues.
</textile>
</description>
<description><markdown>
same as `static`, but doesn't return any error pages; instead request handling continues.
</markdown></description>
</action>
<action name="respond">
<short>returns a quick response with optional body</short>
@ -331,12 +316,10 @@
<parameter name="content">
<short>(optional) pattern for response body</short>
</parameter>
<description>
<textile>
Generates a simple response (our favorite benchmark handler).
The body is parsed as "pattern":core_pattern.html#core_pattern.
</textile>
</description>
<description><markdown>
Generates a simple response (our favorite benchmark handler).
The body is parsed as [pattern](core_pattern.html#core_pattern).
</markdown></description>
<example>
<config>
respond 403 => "Forbidden";
@ -351,30 +334,28 @@
</section>
<section title="Logging">
<section title="Log levels">
<textile>
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)
</textile>
</section>
<section title="Log levels"><markdown>
For standard logging ("error.log") lighttpd knows the following levels:
<section title="Log targets">
<textile>
The following log targets are known:
* not logging: empty string
* files: @file:/var/log/error.log@ or just @/var/log/error.log@
* stderr: @stderr:@ or @stderr@
* syslog: @syslog:@ (not supported yet)
* pipes: @pipe:command@ or @| command@ (not supported yet)
* `debug`
* `info`
* `warning`
* `error`
* `abort` (right before terminating the process)
* `backend` (for log data from backends, like FastCGI stderr stream)
</markdown></section>
Unknown strings are mapped to @stderr@.
</textile>
</section>
<section title="Log targets"><markdown>
The following log targets are known:
* not logging: empty string
* files: `file:/var/log/error.log` or just `/var/log/error.log`
* stderr: `stderr:` or `stderr`
* syslog: `syslog:` (not supported yet)
* pipes: `pipe:command` or `| command` (not supported yet)
Unknown strings are mapped to `stderr`.
</markdown></section>
<action name="log">
<short>overwrite log targets for all log levels</short>
@ -397,11 +378,9 @@
<parameter name="message">
<short>message pattern string</short>
</parameter>
<description>
<textile>
Writes the specified message to the log using level @info@; the message is parsed as "pattern":core_pattern.html#core_pattern.
</textile>
</description>
<description><markdown>
Writes the specified message to the log using level `info`; the message is parsed as [pattern](core_pattern.html#core_pattern).
</markdown></description>
<example>
<config>
log.write "hello world";
@ -431,21 +410,19 @@
<parameter name="format">
<short>a strftime format string</short>
</parameter>
<description>
<textile>
See "strftime":http://pubs.opengroup.org/onlinepubs/007904875/functions/strftime.html for the format string syntax.
<description><markdown>
See [strftime](https://pubs.opengroup.org/onlinepubs/007904875/functions/strftime.html) for the format string syntax.
The default format string is @"%d/%b/%Y %T %Z"@.
</textile>
</description>
The default format string is `"%d/%b/%Y %T %Z"`.
</markdown></description>
</setup>
</section>
<section title="Connection environment">
<textile>
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.
<markdown>
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.
</textile>
</markdown>
<action name="env.set">
<short>sets a connection environment variable</short>
@ -455,11 +432,9 @@
<parameter name="value">
<short>the pattern value to set</short>
</parameter>
<description>
<textile>
The value is parsed as "pattern":core_pattern.html#core_pattern.
</textile>
</description>
<description><markdown>
The value is parsed as [pattern](core_pattern.html#core_pattern).
</markdown></description>
<example>
<config>
env.set "INFO" => "%{req.path}";
@ -474,11 +449,9 @@
<parameter name="value">
<short>the pattern value to set</short>
</parameter>
<description>
<textile>
The value is parsed as "pattern":core_pattern.html#core_pattern. @env.add@ does not overwrite already existing values.
</textile>
</description>
<description><markdown>
The value is parsed as [pattern](core_pattern.html#core_pattern). `env.add` does not overwrite already existing values.
</markdown></description>
<example>
<config>
env.add "INFO" => "%{req.path}";
@ -507,7 +480,9 @@
</section>
<section title="Response header">
All header values that get set are parsed as "patterns":core_pattern.html#core_pattern.
<markdown>
All header values that get set are parsed as [patterns](core_pattern.html#core_pattern).
</markdown>
<action name="header.add">
<short>adds a new response header line</short>
@ -517,12 +492,10 @@
<parameter name="value">
<short>pattern header value</short>
</parameter>
<description>
<textile>
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.
</textile>
</description>
<description><markdown>
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.
</markdown></description>
<example>
<config>
header.add "Cache-Control" => "public";
@ -537,11 +510,9 @@
<parameter name="value">
<short>pattern header value</short>
</parameter>
<description>
<textile>
If header already exists appends new value separated by ", "; otherwise adds a new header line.
</textile>
</description>
<description><markdown>
If header already exists appends new value separated by ", "; otherwise adds a new header line.
</markdown></description>
</action>
<action name="header.overwrite">
<short>overwrite response header line or add new one</short>
@ -551,11 +522,9 @@
<parameter name="value">
<short>pattern header value</short>
</parameter>
<description>
<textile>
If header already exists overwrites the value; otherwise a new line gets added.
</textile>
</description>
<description><markdown>
If header already exists overwrites the value; otherwise a new line gets added.
</markdown></description>
</action>
<action name="header.remove">
<short>remove existing response header</short>
@ -575,15 +544,13 @@
<action name="set_status">
<short>modify HTTP status code</short>
<description>
<textile>
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.
<description><markdown>
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.
</textile>
</description>
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.
</markdown></description>
<example>
<config>
# hide all 404s at end of config by setting 403
@ -595,7 +562,9 @@
</section>
<section title="Request headers">
All header values that get set are parsed as "patterns":core_pattern.html#core_pattern.
<markdown>
All header values that get set are parsed as [patterns](core_pattern.html#core_pattern).
</markdown>
<action name="req_header.add">
<short>adds a new request header line</short>
@ -605,11 +574,9 @@
<parameter name="value">
<short>pattern header value</short>
</parameter>
<description>
<textile>
Same as "header.add":plugin_core.html#plugin_core__action_header-add for request headers.
</textile>
</description>
<description><markdown>
Same as [header.add](plugin_core.html#plugin_core__action_header-add) for request headers.
</markdown></description>
</action>
<action name="req_header.append">
<short>appends value to request header line</short>
@ -619,11 +586,9 @@
<parameter name="value">
<short>pattern header value</short>
</parameter>
<description>
<textile>
Same as "header.append":plugin_core.html#plugin_core__action_header-append for request headers.
</textile>
</description>
<description><markdown>
Same as [header.append](plugin_core.html#plugin_core__action_header-append) for request headers.
</markdown></description>
</action>
<action name="req_header.overwrite">
<short>overwrite request header line or add new one</short>
@ -633,28 +598,22 @@
<parameter name="value">
<short>pattern header value</short>
</parameter>
<description>
<textile>
Same as "header.overwrite":plugin_core.html#plugin_core__action_header-overwrite for request headers.
</textile>
</description>
<description><markdown>
Same as [header.overwrite](plugin_core.html#plugin_core__action_header-overwrite) for request headers.
</markdown></description>
</action>
<action name="req_header.remove">
<short>remove existing request header</short>
<parameter name="name">
<short>header name</short>
</parameter>
<description>
<textile>
Same as "header.remove":plugin_core.html#plugin_core__action_header-remove for request headers.
</textile>
</description>
<description><markdown>
Same as [header.remove](plugin_core.html#plugin_core__action_header-remove) for request headers.
</markdown></description>
<example>
<description>
<textile>
Remove @Accept-Encoding@ request header to workaround the "BREACH":http://en.wikipedia.org/wiki/BREACH_(security_exploit) vulnerability in https.
</textile>
</description>
<description><markdown>
Remove `Accept-Encoding` request header to workaround the [BREACH](https://en.wikipedia.org/wiki/BREACH_(security_exploit)) vulnerability in https.
</markdown></description>
<config>
if request.scheme == "https" {
# create a copy of the header value
@ -697,11 +656,9 @@
<parameter name="mapping">
<short>maps strings (or default) to actions</short>
</parameter>
<description>
<textile>
The pattern is parsed as "pattern":core_pattern.html#core_pattern. Have a look at "mod_vhost":mod_vhost.html#mod_vhost for special mappings on hostnames.
</textile>
</description>
<description><markdown>
The pattern is parsed as [pattern](core_pattern.html#core_pattern). Have a look at [mod_vhost](mod_vhost.html#mod_vhost) for special mappings on hostnames.
</markdown></description>
<example>
<config>
map "%{req.path}" => [
@ -763,9 +720,9 @@
<parameter name="names">
<short>string or list of strings with the module name(s)</short>
</parameter>
<description>
<description><markdown>
modules can be "loaded" more than once without error
</description>
</markdown></description>
<example>
<config>
setup {
@ -791,15 +748,13 @@
<parameter name="threads">
<short>number of threads</short>
</parameter>
<description>
<textile><![CDATA[
For example the stat cache uses such background threads.
<description><markdown><![CDATA[
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.
]]></textile>
</description>
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.
]]></markdown></description>
</setup>
<setup name="fetch.files_static">
<short>starts a Fetch API provider</short>
@ -809,9 +764,9 @@
<parameter name="filename-pattern">
<short>A filename pattern including exactly on *</short>
</parameter>
<description>
Loads all filenames matching the wildcard pattern (which must include exactly on @*@) into the fetch storage.
</description>
<description><markdown>
Loads all filenames matching the wildcard pattern (which must include exactly on `*`) into the fetch storage.
</markdown></description>
<example>
<config>
setup {

View File

@ -6,7 +6,7 @@
* the public domain worldwide. This software is distributed without
* any warranty.
*
* For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
* For details, see <https://creativecommons.org/publicdomain/zero/1.0/>.
* SPDX-License-Identifier: CC0-1.0
*/

View File

@ -6,7 +6,7 @@
SRCTEST=src/main/lighttpd_worker.c
PACKAGE=lighttpd
REV=${REV}
BASEDOWNLOADURL="http://download.lighttpd.net/lighttpd/snapshots-2.0.x"
BASEDOWNLOADURL="https://download.lighttpd.net/lighttpd/snapshots-2.0.x"
if [ ! -f ${SRCTEST} ]; then
echo "Current directory is not the source directory"

View File

@ -73,7 +73,7 @@ gsize li_memory_usage(void) {
#include <mach/mach_init.h>
gsize li_memory_usage(void) {
/* info from http://miknight.blogspot.com/2005/11/resident-set-size-in-mac-os-x.html */
/* info from https://miknight.blogspot.com/2005/11/resident-set-size-in-mac-os-x.html */
struct task_basic_info tbinfo;
mach_msg_type_number_t cnt = TASK_BASIC_INFO_COUNT;

View File

@ -2,7 +2,7 @@
* mod_gnutls - TLS listen support
*
* TODO:
* * support client certificate authentication: http://www.gnutls.org/manual/gnutls.html#Client-certificate-authentication
* * support client certificate authentication: https://www.gnutls.org/manual/gnutls.html#Client-certificate-authentication
* gnutls_certificate_set_x509_system_trust (available since 3.0 (docs) or 3.0.19 (weechat ??))
* gnutls_certificate_set_x509_trust_file
* * TLS session tickets are always activated with gnutls >= 2.10 - option to disable

1
tests/pylt/run.py Executable file → Normal file
View File

@ -196,6 +196,7 @@ def run_tests_in_env(env: Env) -> bool:
# run tests
tests = Tests(env=env)
tests.load_tests()
result = False
try:
tests.prepare_tests()
result = tests.run_tests()