2
0

Compare commits

..

No commits in common. "698c1a54efd73c36cd1dcad2bfe04719df07fee2" and "77f9f06c2a73319cf7c02e8538f2d49bb6bb8e33" have entirely different histories.

47 changed files with 1238 additions and 1120 deletions

View File

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

View File

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

View File

@ -28,12 +28,12 @@
</div> </div>
<h3>About this page</h3> <h3>About this page</h3>
<p>This is a placeholder page installed by the Lighttpd2 package of this servers operating system.</p> <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="https://www.lighttpd.net">https://www.lighttpd.net</a></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>
<h3>If you are the administrator of this server</h3> <h3>If you are the administrator of this server</h3>
<ul> <ul>
<li>Configuration files are most likely located in /etc/lighttpd2/</li> <li>Configuration files are most likely located in /etc/lighttpd2/</li>
<li>Logs are usually stored in /var/log/lighttpd2/</li> <li>Logs are usually stored in /var/log/lighttpd2/</li>
<li>Please consult the documenation provided in the <a href="https://redmine.lighttpd.net/projects/lighttpd2/wiki">Lighttpd2 wiki</a></li> <li>Please consult the documenation provided in the <a href="http://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> <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> </ul>
<div id="logo" style="text-align: center;"> <div id="logo" style="text-align: center;">

View File

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

View File

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

View File

@ -1,187 +1,178 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Main Configuration"> <chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Main Configuration">
<description><markdown> <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. 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. 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> </textile>
</description>
<section title="Basic Syntax"> <section title="Basic Syntax">
<markdown><![CDATA[ <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 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). The basic blocks are "values":#core_config__values, "variables":#core_config__variables, "function calls":#core_config__funcalls and "conditions":#core_config__conditions.
]]></markdown> ]]></textile>
</section> </section>
<section title="Values" anchor="values"> <section title="Values" anchor="values">
<section title="Boolean"> <section title="Boolean">
<markdown><![CDATA[ <textile><![CDATA[
There are two boolean values: There are two boolean values:
* @true@
* `true` * @false@
* `false` ]]></textile>
]]></markdown>
</section> </section>
<section title="Integers"> <section title="Integers">
<markdown><![CDATA[ <textile><![CDATA[
Integers are stored as signed ints with 64 bits (max value around 9 * 10^18). There are three basic ways to use them: 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@
* decimal integers: starting with any non zero digit, like `128` * octal integers: starting with a zero, like @0644@
* octal integers: starting with a zero, like `0644` * hexadecimal integers: starting with @0x@ like @0xff@
* hexadecimal integers: starting with `0x` like `0xff`
All three can have a suffix representing a factor the number gets multiplied with: All three can have a suffix representing a factor the number gets multiplied with:
* @byte@: @1@
* `byte`: `1` * @kbyte@: @1024@
* `kbyte`: `1024` * @mbyte@: @1024*1024@
* `mbyte`: `1024*1024` * @gbyte@: @1024*1024*1024@
* `gbyte`: `1024*1024*1024` * @tbyte@: @1024*1024*1024*1024@
* `tbyte`: `1024*1024*1024*1024` * @pbyte@: @1024*1024*1024*1024*1024@
* `pbyte`: `1024*1024*1024*1024*1024` * @bit@: @1 / 8@
* `bit`: `1 / 8` * @kbit@: @1024 / 8@
* `kbit`: `1024 / 8` * @mbit@: @1024*1024 / 8@
* `mbit`: `1024*1024 / 8` * @gbit@: @1024*1024*1024 / 8@
* `gbit`: `1024*1024*1024 / 8` * @tbit@: @1024*1024*1024*1024 / 8@
* `tbit`: `1024*1024*1024*1024 / 8` * @pbit@: @1024*1024*1024*1024*1024 / 8@
* `pbit`: `1024*1024*1024*1024*1024 / 8` * @sec@: @1@
* `sec`: `1` * @min@: @60@
* `min`: `60` * @hours@: @3600@
* `hours`: `3600` * @days@: @24*3600@
* `days`: `24*3600`
For sizes the base unit is byte, and for intervals seconds. For sizes the base unit is byte, and for intervals seconds.
]]></markdown> ]]></textile>
</section> </section>
<section title="Strings"> <section title="Strings">
<markdown><![CDATA[ <textile><![CDATA[
There are 4 ways to specify a string: There are 4 ways to specify a string:
* @'hello world'@
* `'hello world'` * @"hello world"@
* `"hello world"` * @e'hello world'@
* `e'hello world'` * @e"hello world"@
* `e"hello world"`
The basic escape rules are the same for both: 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.
* `"\n"` is a newline, `"\r"` a carriage return, `"\t"` a tab stop The @e'..'@ and @e"..."@ variant do not allow any occurences of the last kind to happen.
* `"\\"` 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). All other characters are allowed (the strings are parsed as 8-bit binary; lighttpd2 usually doesn't care about the encoding).
]]></markdown> ]]></textile>
</section> </section>
<section title="Lists"> <section title="Lists">
<markdown><![CDATA[ <textile><![CDATA[
Lists are ordered collections of other values: 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)
* `[1, true, "foo"]` (simple list) 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.
* `[]` (empty list) ]]></textile>
* `[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>
<section title="Key-Value Lists"> <section title="Key-Value Lists">
<markdown><![CDATA[ <textile><![CDATA[
Key-value lists associates keys to values (both can be of any type); the syntax is: Key-value lists associates keys to values (both can be of any type); the syntax is:
* @[ "a" => 1, "b" => 10 ]@
* `[ "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).
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] ]@
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. This especially means that key-value lists are ordered too, although they can get converted to hash tables in certain function calls internally.
]]></markdown> ]]></textile>
</section> </section>
<section title="Expressions"> <section title="Expressions">
<markdown><![CDATA[ <textile><![CDATA[
There are operators available for some value types: There are operators available for some value types:
* for integers: @+@, @-@, @*@ and @/@
* for integers: `+`, `-`, `*` and `/` * for strings: @+@ (concatenate two strings)
* for strings: `+` (concatenate two strings) * for lists: @+@ (append lists)
* for lists: `+` (append lists)
Also you can cast strings and booleans to integers and any value to strings: 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) "256"` (only supports decimal representations and no suffix like above) * @cast(int) true@ (@true@ maps to @1@ and @false@ to @0@)
* `cast(int) true` (`true` maps to `1` and `false` to `0`) * @cast(string) 5@
* `cast(string) 5`
Expressions can be grouped to override default association: Expressions can be grouped to override default association:
* @3 * (1 + 2)@ vs. @3 * 1 + 2@ and so on
* `3 * (1 + 2)` vs. `3 * 1 + 2` and so on ]]></textile>
]]></markdown>
</section> </section>
<section title="Action Blocks"> <section title="Action Blocks">
<markdown><![CDATA[ <textile><![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. 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. 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: The syntax is:
``` <pre>
{ {
log "hello world"; log "hello world";
if req.path =$ ".hidden" { static; } 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. 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; Each action block that is not a condition branch starts a new nested variable scope;
]]></markdown> ]]></textile>
</section> </section>
<section title="Variables" anchor="variables"> <section title="Variables" anchor="variables">
<markdown><![CDATA[ <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. 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"]; my_types = [".txt" => "text/html"];
php = { php = {
if phys.path =$ ".php" { fastcgi "unix:/var/run/lighttpd/php.sock"; } 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). 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"; local wwwpath = "/var/www/example.com";
``` </pre>
You can also create variables in the global scope by prefixing the assignment with `global`. 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). 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. If a variable name is used in a context it will always use the definition from the nearest scope.
]]></markdown> ]]></textile>
<example> <example>
<description><markdown> <description>
This example illustrates that variables are evaluated while parsing the config. This example illustrates that variables are evaluated while parsing the config.
</markdown></description> </description>
<config> <config>
foo = "bar"; foo = "bar";
if req.path == "/somepath" { if req.path == "/somepath" {
@ -193,9 +184,9 @@
</example> </example>
<example> <example>
<description><markdown> <description>
This example illustrates scoping. This example illustrates scoping.
</markdown></description> </description>
<config> <config>
foo = "bar"; foo = "bar";
php = { php = {
@ -209,60 +200,57 @@
</section> </section>
<section title="Special Variables"> <section title="Special Variables">
<markdown><![CDATA[ <textile><![CDATA[
`sys.*` variables are readonly. right now the following `sys.*` variables are available: @sys.*@ variables are readonly. right now the following @sys.*@ variables are available:
* @sys.pid@: the process id of lighttpd
* `sys.pid`: the process id of lighttpd * @sys.cwd@: the current working directory
* `sys.cwd`: the current working directory * @sys.env.X@: the system environment variable with name @X@ (for any @X@)
* `sys.env.X`: the system environment variable with name `X` (for any `X`) ]]></textile>
]]></markdown>
</section> </section>
</section> </section>
<section title="Function calls" anchor="funcalls"> <section title="Function calls" anchor="funcalls">
<markdown><![CDATA[ <textile><![CDATA[
There are three types of function calls: There are three types of function calls:
* actions * actions
* setups * setups
* options * options
Actions can only be used in action (block) context, setups only in setup (block) context, and options can be used in both. 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). 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). The actions, setups and options are provided by the "modules":index_modules.html#index_modules.
]]></markdown> ]]></textile>
<section title="Includes" anchor="includes"> <section title="Includes" anchor="includes">
<markdown><![CDATA[ <textile><![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. 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: There are three types of includes:
* @include "/etc/lighttpd/vhosts/*.conf";@: include files like the main config itself; the path can contain wildcards
* `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_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_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. Includes also create a new nested scope.
]]></markdown> ]]></textile>
</section> </section>
<section title="Debug Print"> <section title="Debug Print">
<markdown><![CDATA[ <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". 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> ]]></textile>
</section> </section>
</section> </section>
<section title="Conditions" anchor="conditions"> <section title="Conditions" anchor="conditions">
<markdown><![CDATA[ <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. 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). 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. 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> ]]></textile>
<example> <example>
<config> <config>
@ -281,34 +269,31 @@
</example> </example>
<section title="Syntax"> <section title="Syntax">
<markdown><![CDATA[ <textile><![CDATA[
The basic syntax forms are: 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@)
* `if <expr> { ... }` A condition expression @<expr>@ is:
* `if <expr> { ... } else { ... }` * @(<expr>)@
* `if <expr> { ... } else if <expr2> { ... }` * @<expr1> and <expr2>@
* `if <expr> { ... } else if <expr2> { ... } ...` (continue with `else` or `else if`) * @<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.
A condition expression `<expr>` is: * @<condvar>@ or @!<condvar>@ for a boolean condition variable.
]]></textile>
* `(<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>
<section title="Condition variables" anchor="condition_vars"> <section title="Condition variables" anchor="condition_vars">
<markdown><![CDATA[ <textile><![CDATA[
There are three categories of condvars: There are three categories of condvars:
* request.xyz (can be abbreviated by req.xyz) * request.xyz (can be abbreviated by req.xyz)
* physical.xyz (can be abbreviated by phys.xyz) * physical.xyz (can be abbreviated by phys.xyz)
* response.xyz (can be abbreviated by resp.xyz) * response.xyz (can be abbreviated by resp.xyz)
| variable | description | table(table table-striped).
|----------|-------------| |_. variable |_. description |
| request.localip | ip address of the listing socket, the client connected to (filename for unix sockets) | | 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.localport | port number of the listening socket, -1 for unix sockets |
| request.remoteip | ip address of the client | | request.remoteip | ip address of the client |
@ -323,7 +308,7 @@
| request.header["name"] | request header _name_ e.g. request.header["referer"] | | 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.is_handled | boolean condition, does request already have a handler (static, fastcgi..) |
| request.environment["name"] | (or short request.env["name"]) CGI environment | | 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.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.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 | | physical.size | integer. size of the requested file. -1 if file doesn't exist |
@ -331,26 +316,24 @@
| physical.is_file | boolean condition, indicates whether the requested file is a normal file (e.g. no unix socket etc) | | 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.docroot | document root |
| physical.pathinfo | pathinfo | | physical.pathinfo | pathinfo |
|-|-| | | |
| response.status | response status code (blocks request until response header is available) | | response.status | response status code (blocks request until response header is available) |
| response.header["name"] | response header (blocks request until response header is available) | | response.header["name"] | response header (blocks request until response header is available) |
{:.table .table-striped} ]]></textile>
]]></markdown>
</section> </section>
<section title="Condition operators"> <section title="Condition operators">
<markdown><![CDATA[ <textile><![CDATA[
| op | description | op | description | table(table table-striped).
|----|-------------|----|-------------| |_. op |_. description |_. op |_. description |
| == | compares two values on equality | != | negative == | | <notextile>==</notextile> | compares two values on equality | != | negative == |
| <= | less than or equal | < | less than | | <= | less than or equal | < | less than |
| >= | greater than or equal | > | greater than | | >= | greater than or equal | > | greater than |
| =~ | regular expression match | !~ | negative =~ | | =~ | regular expression match | !~ | negative =~ |
| =^ | prefix match | !^ | negative =^ | | =^ | prefix match | !^ | negative =^ |
| =$ | suffix match | !$ | negative =$ | | =$ | suffix match | !$ | negative =$ |
| =/ | cidr match | !/ | negative =/ | | =/ | cidr match | !/ | negative =/ |
{:.table .table-striped} ]]></textile>
]]></markdown>
</section> </section>
</section> </section>

View File

@ -1,36 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<angel-module xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Angel Configuration"> <angel-module xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Angel Configuration">
<description><markdown> <description>
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. <textile>
A standard distribution should install a angel config in `/etc/lighttpd2/angel.conf` with reasonable defaults which should work for most basic setups. 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.
</markdown></description> 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>
<section title="Angel concept"> <section title="Angel concept">
<markdown> <textile>
You can start the worker without the angel, but the angel provides some useful features: 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 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. 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. * The angel also does a simple supervise: if the worker crashes the angel will respawn it.
</markdown> </textile>
</section> </section>
<section title="Config items"> <section title="Config items">
<markdown> <textile>
The config syntax is very similar to the [main configuration](core_config), although it has no action blocks, setup blocks, conditionals and scopes. The config syntax is very similar to the "main configuration":core_config, although it has no action blocks, setup blocks, conditionals and scopes.
</markdown> </textile>
<item name="user"> <item name="user">
<short>drops privileges for spawning the worker</short> <short>drops privileges for spawning the worker</short>
<parameter name="username"> <parameter name="username">
<short>username to drop privileges to for spawning the worker</short> <short>username to drop privileges to for spawning the worker</short>
</parameter> </parameter>
<description><markdown> <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. 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. The username is also used to find all groups the user is in.
</markdown></description> </textile>
</description>
<example> <example>
<config> <config>
user "www-data"; user "www-data";
@ -43,10 +46,12 @@
<parameter name="groupname"> <parameter name="groupname">
<short>groupname to drop privileges to for spawning the worker</short> <short>groupname to drop privileges to for spawning the worker</short>
</parameter> </parameter>
<description><markdown> <description>
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. <textile>
The default is the main group of the user specified by `user`, or not dropping privileges at all. 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.
</markdown></description> The default is the main group of the user specified by @user@, or not dropping privileges at all.
</textile>
</description>
<example> <example>
<config> <config>
group "www-data"; group "www-data";
@ -57,11 +62,13 @@
<item name="binary"> <item name="binary">
<short>specifies path to worker binary</short> <short>specifies path to worker binary</short>
<parameter name="path"> <parameter name="path">
<short>path to the lighttpd2-worker binary</short> <short>path to the @lighttpd2-worker@ binary</short>
</parameter> </parameter>
<description><markdown> <description>
<textile>
This item should only be needed if you didn't install the binaries at all (for testing). This item should only be needed if you didn't install the binaries at all (for testing).
</markdown></description> </textile>
</description>
<example> <example>
<config> <config>
binary "/home/source/lighttpd2/autobuild/src/main/lighttpd2-worker"; binary "/home/source/lighttpd2/autobuild/src/main/lighttpd2-worker";
@ -74,9 +81,11 @@
<parameter name="path"> <parameter name="path">
<short>path to the main config file</short> <short>path to the main config file</short>
</parameter> </parameter>
<description><markdown> <description>
By default `/etc/lighttpd2/lighttpd.conf` is used. <textile>
</markdown></description> By default @/etc/lighttpd2/lighttpd.conf@ is used.
</textile>
</description>
<example> <example>
<config> <config>
config "/etc/lighttpd2-test/lighttpd.conf"; config "/etc/lighttpd2-test/lighttpd.conf";
@ -89,9 +98,11 @@
<parameter name="path"> <parameter name="path">
<short>path to the lua config file</short> <short>path to the lua config file</short>
</parameter> </parameter>
<description><markdown> <description>
<textile>
By default a normal config file is used; you must use either a normal config file or a lua config file. By default a normal config file is used; you must use either a normal config file or a lua config file.
</markdown></description> </textile>
</description>
<example> <example>
<config> <config>
luaconfig "/etc/lighttpd2/lighttpd.lua"; luaconfig "/etc/lighttpd2/lighttpd.lua";
@ -104,9 +115,11 @@
<parameter name="path"> <parameter name="path">
<short>path to the directory containing modules for the worker</short> <short>path to the directory containing modules for the worker</short>
</parameter> </parameter>
<description><markdown> <description>
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>
</markdown></description> 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>
<example> <example>
<config> <config>
modules_path "/home/source/lighttpd2/autobuild/src/modules/.libs"; modules_path "/home/source/lighttpd2/autobuild/src/modules/.libs";
@ -119,10 +132,12 @@
<parameter name="wrappers"> <parameter name="wrappers">
<short>path to a wrapper command and its arguments</short> <short>path to a wrapper command and its arguments</short>
</parameter> </parameter>
<description><markdown> <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. 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. Wrappers can be used to run the worker with valgrind, strace and similar.
</markdown></description> </textile>
</description>
<example> <example>
<config> <config>
# in multiple lines # in multiple lines
@ -141,9 +156,11 @@
<parameter name="vars"> <parameter name="vars">
<short>list of environment variables to add for the worker to run with</short> <short>list of environment variables to add for the worker to run with</short>
</parameter> </parameter>
<description><markdown><![CDATA[ <description>
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><![CDATA[
]]></markdown></description> 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>
<example> <example>
<config> <config>
# helps debugging with valgrind: # helps debugging with valgrind:
@ -157,9 +174,11 @@
<parameter name="varnames"> <parameter name="varnames">
<short>list of environment variable names to copy</short> <short>list of environment variable names to copy</short>
</parameter> </parameter>
<description><markdown> <description>
<textile>
Adds copies of variables from the current environment. By default all variables will be dropped. Adds copies of variables from the current environment. By default all variables will be dropped.
</markdown></description> </textile>
</description>
<example> <example>
<config> <config>
env_copy [ "PATH" ]; env_copy [ "PATH" ];
@ -172,10 +191,10 @@
<parameter name="limit"> <parameter name="limit">
<short>limit in bytes</short> <short>limit in bytes</short>
</parameter> </parameter>
<description><markdown> <description>
Maximum size of a core file, in bytes, that may be created by the worker. Core files are created when the worker crashes. 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. 0 disables core files, and by default the limit is not changed.
</markdown></description> </description>
</item> </item>
<item name="max_open_files"> <item name="max_open_files">
@ -183,10 +202,10 @@
<parameter name="limit"> <parameter name="limit">
<short>maximum number of open files</short> <short>maximum number of open files</short>
</parameter> </parameter>
<description><markdown> <description>
The worker limits the maximum number of connection based on the maximum number of open files (max connections = max open files / 4). 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. By default the limit is not changed.
</markdown></description> </description>
<example> <example>
<config> <config>
# max 4096 connections # max 4096 connections
@ -200,19 +219,20 @@
<parameter name="list"> <parameter name="list">
<short>list of network mask (CIDR) + optional port or unix domain socket addresses</short> <short>list of network mask (CIDR) + optional port or unix domain socket addresses</short>
</parameter> </parameter>
<description><markdown> <description>
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. <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). 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: Formats:
* TCP on IPv4: @ipv4@, @ipv4:port@, @ipv4/net@, @ipv4/net:port@
* 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@
* TCP on IPv6: `ipv6`, `ipv6/net`, `[ipv6]`, `[ipv6/net]`, `[ipv6]:port`, `[ipv6/net]:port` * Unix domain: @unix:/wildcard/path/to/*.socket@
* Unix domain: `unix:/wildcard/path/to/*.socket` </textile>
</markdown></description> </description>
<example> <example>
<description><markdown> <description>
Only allow TCP port 8080 for IPv4 and IPv6 and unix domain socket `/run/lighttpd/internal.sock`. Only allow TCP port 8080 for IPv4 and IPv6 and unix domain socket @/run/lighttpd/internal.sock@.
</markdown></description> </description>
<config> <config>
allow_listen [ "0.0.0.0/0:8080", "[::/0]:8080" ]; allow_listen [ "0.0.0.0/0:8080", "[::/0]:8080" ];
allow_listen "unix:/run/lighttpd/internal.sock"; allow_listen "unix:/run/lighttpd/internal.sock";

View File

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Fetch API" order="core_regex_after_01_fetch"> <chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Fetch API" order="core_regex_after_01_fetch">
<description><markdown> <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. 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. 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> </textile>
</description>
</chapter> </chapter>

View File

@ -2,23 +2,21 @@
<chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Introduction" order="a01_introduction"> <chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Introduction" order="a01_introduction">
<section title="Running lighttpd2"> <section title="Running lighttpd2">
<markdown><![CDATA[ <textile><![CDATA[
You need two config files for lighttpd, which are usually in the following two locations: You need two config files for lighttpd, which are usually in the following two locations:
* [`/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/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`](https://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/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.
The [`contrib/`](https://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib) directory in the sources includes example config files. The "@contrib/@":http://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib directory in the sources includes example config files.
Then start lighttpd2 with: 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. 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). 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).
]]></markdown> ]]></textile>
</section> </section>
</chapter> </chapter>

View File

@ -1,25 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Lua API" order="core_regex_after_02_lua"> <chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Lua API" order="core_regex_after_02_lua">
<description><markdown> <description>
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. <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.
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: 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
* [`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).
* [`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>
</markdown></description> </description>
<section title="Lua Config"> <section title="Lua Config">
<markdown> <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)). 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> </textile>
<example title="Example - debug.lua"> <example title="Example - debug.lua">
<description><markdown><![CDATA[ <description><textile><![CDATA[
The following Lua snippet saved as "debug.lua" could for example be included with `include_lua "debug.lua"`. The following Lua snippet saved as "debug.lua" could for example be included with @include_lua "debug.lua"@.
]]></markdown></description> ]]></textile></description>
<config><![CDATA[ <config><![CDATA[
function mydebug(vr) function mydebug(vr)
@ -54,63 +55,62 @@
</example> </example>
<section title="Values"> <section title="Values">
<markdown><![CDATA[ <textile><![CDATA[
* Boolean: Lua supports `true` and `false` directly * 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. * 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.
* Strings: Lua supports strings directly. Check the Lua reference for the various quoting styles. * 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). * 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. 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)). 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).
* Expressions and variables just are the usual Lua things; there is no direct access to the lighttpd config variables (yet). * 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)`) * 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> ]]></textile>
</section> </section>
<section title="Function calls"> <section title="Function calls">
<markdown><![CDATA[ <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. 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. 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). Includes are not supported, neither is the debug @__print@ (there are other logging methods available).
]]></markdown> ]]></textile>
</section> </section>
<section title="Conditions"> <section title="Conditions">
<markdown><![CDATA[ <textile><![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. 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. 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.
| op | Lua name | op | Lua name | table(table table-striped).
|----|-----------|----|----------| |_. op |_. Lua name |_. op |_. Lua name |
| == | `:eq` | != | `:ne` | | <notextile>==</notextile> | @:eq@ | != | @:ne@ |
| <= | `:le` | < | `:lt` | | <= | @:le@ | < | @:lt@ |
| >= | `:ge` | > | `:gt` | | >= | @:ge@ | > | @:gt@ |
| =~ | `:match` | !~ | `:nomatch` | | =~ | @:match@ | !~ | @:nomatch@ |
| =^ | `:prefix` | !^ | `:notprefix` | | =^ | @:prefix@ | !^ | @:notprefix@ |
| =$ | `:suffix` | !$ | `:notsuffix` | | =$ | @:suffix@ | !$ | @:notsuffix@ |
| =/ | `:ip` | !/ | `:notip` | | =/ | @: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). The result of such call (a "condition") is then passed as first parameter to "@action.when@":plugin_core#plugin_core__action_when.
]]></markdown> ]]></textile>
<example title="Example - admin only"> <example title="Example - admin only">
<description><markdown> <description><textile>
Translating `if req.env["REMOTE_USER"] != "admin" { auth.deny; }` to Lua: Translating @if req.env["REMOTE_USER"] != "admin" { auth.deny; }@ to Lua:
</markdown></description> </textile></description>
<config><![CDATA[ <config><![CDATA[
actions = action.when(request.environment["REMOTE_USER"]:ne("admin"), action.auth.deny()) actions = action.when(request.environment["REMOTE_USER"]:ne("admin"), action.auth.deny())
]]></config> ]]></config>
</example> </example>
<example title="Example - physical files only"> <example title="Example - physical files only">
<description><markdown> <description><textile>
Translating `if !phys.exists { auth.deny; }` to Lua: Translating @if !phys.exists { auth.deny; }@ to Lua:
</markdown></description> </textile></description>
<config><![CDATA[ <config><![CDATA[
actions = action.when(physical.exists:isnot(), action.auth.deny()) actions = action.when(physical.exists:isnot(), action.auth.deny())
]]></config> ]]></config>
@ -119,67 +119,67 @@
</section> </section>
<section title="API"> <section title="API">
<markdown><![CDATA[ <textile><![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. 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 = vr.env
e["XXX"] = "abc" 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. 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") vr:print("Hello World")
``` </pre>
**Note**: *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. 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). 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. All container types should provide a @get@ and a @set@ method to provide "clean" access to the container contents.
### pairs() h3. 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 for k, v in vr.env:pairs() do
vr:print("env['" .. k .. "'] = '" .. v .. "'") vr:print("env['" .. k .. "'] = '" .. v .. "'")
end 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. 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. 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> ]]></textile>
<section title="Global constants"> <section title="Global constants">
<markdown><![CDATA[ <textile><![CDATA[
`liHandlerResult` enumeration values: @liHandlerResult@ enumeration values:
* `lighty.HANDLER_GO_ON` * @lighty.HANDLER_GO_ON@
* `lighty.HANDLER_COMEBACK` * @lighty.HANDLER_COMEBACK@
* `lighty.HANDLER_WAIT_FOR_EVENT` * @lighty.HANDLER_WAIT_FOR_EVENT@
* `lighty.HANDLER_ERROR` * @lighty.HANDLER_ERROR@
]]></markdown> ]]></textile>
</section> </section>
<section title="Global methods"> <section title="Global methods">
<markdown><![CDATA[ <textile><![CDATA[
* `lighty.print` (and `lighty.error` and `print`): print parameters via lua "tostring" method as ERROR in global server context * @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.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.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.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_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.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.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.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.sha256(str)@: calculates the sha256 checksum of the string @str@ (returns the digest as string in hexadecimal)
* `lighty.path_simplify(str)`: return simplified path * @lighty.path_simplify(str)@: return simplified path
]]></markdown> ]]></textile>
<example> <example>
<config><![CDATA[ <config><![CDATA[
@ -206,177 +206,167 @@
</section> </section>
<section title="Virtual Request"> <section title="Virtual Request">
<markdown><![CDATA[ <textile><![CDATA[
Fields: Fields:
* @con@(ro): Connection
* `con`(ro): Connection * @in@(ro): Chunk Queue, read request post content
* `in`(ro): Chunk Queue, read request post content * @out@(ro): Chunk Queue, write response content
* `out`(ro): Chunk Queue, write response content * @env@(ro): Environment, (fast)cgi environment
* `env`(ro): Environment, (fast)cgi environment * @req@(ro): Request, data from request header
* `req`(ro): Request, data from request header * @resp@(ro): Response, response header data
* `resp`(ro): Response, response header data * @phys@(ro): Physical, paths and filenames
* `phys`(ro): Physical, paths and filenames * @is_handled@(ro): whether vrequest is already handled
* `is_handled`(ro): whether vrequest is already handled * @has_response@(ro): whether the response headers (and status) is available
* `has_response`(ro): whether the response headers (and status) is available
Methods: Methods:
* @print(...)@: print parameters via lua @tostring@ method as ERROR in Virtual Request context
* `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
* `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
* `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
* `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.
* `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)
* `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, 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.
* 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_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.
* 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_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
* `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>
]]></markdown>
</section> </section>
<section title="Connection"> <section title="Connection">
<markdown><![CDATA[ <textile><![CDATA[
* `local`: address of local socket * @local@: address of local socket
* `remote`: address of remote host * @remote@: address of remote host
]]></markdown> ]]></textile>
</section> </section>
<section title="Environment"> <section title="Environment">
<markdown><![CDATA[ <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: 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["set"] -- doesn't work, returns the set method instead
x = env:get("set") -- use this 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[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 x = env:get(y) -- just do it the safe way if you are not sure
</pre>
Methods: Methods:
* @get(k)@: safe way for @env[k]@
* `get(k)`: safe way for `env[k]` * @set(k, v)@: safe way for @env[k] = v@
* `set(k, v)`: safe way for `env[k] = v` * @unset(k)@: safe way for @env[k] = nil@
* `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@
* `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@
* `pairs()`: use to loop through keys: `for k, v in env:pairs() do ... end` * @clear()@: remove all entries
* `clear()`: remove all entries ]]></textile>
]]></markdown>
</section> </section>
<section title="Chunk Queue"> <section title="Chunk Queue">
<markdown><![CDATA[ <textile><![CDATA[
Fields: Fields:
* @is_closed@: whether the ChunkQueue is closed
* `is_closed`: whether the ChunkQueue is closed
Methods: Methods:
* @add(s)@: appends a string to the queue
* `add(s)`: appends a string to the queue * @add({filename="/..."})@: appends a file to the queue (only regular files allowed)
* `add({filename="/..."})`: appends a file to the queue (only regular files allowed) * @reset()@: removes all chunks, resets counters
* `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)
* `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)
* `skip_all()`: skips all chunks (removes all chunks but does **not** reset counters) ]]></textile>
]]></markdown>
</section> </section>
<section title="Request"> <section title="Request">
<markdown><![CDATA[ <textile><![CDATA[
Fields: Fields:
* @headers@(ro): HTTP Headers
* `headers`(ro): HTTP Headers * @http_method@(ro): HTTP method string ("GET", "POST", "HEAD", ...)
* `http_method`(ro): HTTP method string ("GET", "POST", "HEAD", ...) * @http_version@(ro): HTTP version string ("HTTP/1.0", "HTTP/1.1")
* `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
* `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
* `uri`: Request URI ]]></textile>
]]></markdown>
</section> </section>
<section title="Request URI"> <section title="Request URI">
<markdown><![CDATA[ <textile><![CDATA[
Fields: Fields:
* @raw@: Request uri as it was in the HTTP Request Line (or a rewrite result)
* `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_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
* `raw_orig_path`: same as raw_path, but saved before any rewrite happened * @scheme@: "http" or "https"
* `scheme`: "http" or "https" * @authority@: complete host name header (or authority in an absolute url), e.g. "user@www.example.com.:8080"
* `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"
* `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"
* `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"
* `query`: The querystring, e.g. "a=1&b=2" ]]></textile>
]]></markdown>
</section> </section>
<section title="Response"> <section title="Response">
<markdown><![CDATA[ <textile><![CDATA[
Fields: Fields:
* @headers@(ro): HTTP Headers
* `headers`(ro): HTTP Headers * @status@: HTTP status code
* `status`: HTTP status code ]]></textile>
]]></markdown>
</section> </section>
<section title="Physical"> <section title="Physical">
<markdown><![CDATA[ <textile><![CDATA[
Fields: Fields:
* @path@: physical path
* `path`: physical path * @doc_root@: document root
* `doc_root`: document root * @pathinfo@: pathinfo
* `pathinfo`: pathinfo ]]></textile>
]]></markdown>
</section> </section>
<section title="HTTP Headers"> <section title="HTTP Headers">
<markdown><![CDATA[ <textile><![CDATA[
Same restriction as Environment for fields. Same restriction as Environment for fields.
Methods: Methods:
* @get(k)@: joins all header values for the key @k@ with ", " (as the rfc allows it)
* `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
* `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
* `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
* `insert(k, v)`: appends new "k: v" header to list * @unset(k)@: removes all headers with key @k@
* `unset(k)`: removes all headers with key `k` * @pairs()@: loops through all headers. Please note that the keys are not unique!
* `pairs()`: loops through all headers. Please note that the keys are not unique! * @list(k)@: loops through all headers with key @k@
* `list(k)`: loops through all headers with key `k` * @clear()@: remove all headers
* `clear()`: remove all headers ]]></textile>
]]></markdown>
</section> </section>
<section title="Filter"> <section title="Filter">
<markdown><![CDATA[ <textile><![CDATA[
Represents a "liFilter". Represents a "liFilter".
Fields: Fields:
* @in@(ro): Chunk Queue, incoming stream
* `in`(ro): Chunk Queue, incoming stream * @out@(ro): Chunk Queue, outgoing stream
* `out`(ro): Chunk Queue, outgoing stream ]]></textile>
]]></markdown>
</section> </section>
<section title="Stat struct"> <section title="Stat struct">
<markdown><![CDATA[ <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). 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: Fields:
* @is_file@(ro): S_ISREG(mode)
* `is_file`(ro): S_ISREG(mode) * @is_dir@(ro): S_ISDIR(mode)
* `is_dir`(ro): S_ISDIR(mode) * @is_char@(ro): S_ISCHR(mode)
* `is_char`(ro): S_ISCHR(mode) * @is_block@(ro): S_ISBLK(mode)
* `is_block`(ro): S_ISBLK(mode) * @is_socket@(ro): S_ISSOCK(mode)
* `is_socket`(ro): S_ISSOCK(mode) * @is_link@(ro): S_ISLNK(mode)
* `is_link`(ro): S_ISLNK(mode) * @is_fifo@(ro): S_ISFIFO(mode)
* `is_fifo`(ro): S_ISFIFO(mode) * @mode@(ro)
* `mode`(ro) * @mtime@(ro)
* `mtime`(ro) * @ctime@(ro)
* `ctime`(ro) * @atime@(ro)
* `atime`(ro) * @uid@(ro)
* `uid`(ro) * @gid@(ro)
* `gid`(ro) * @size@(ro)
* `size`(ro) * @ino@(ro)
* `ino`(ro) * @dev@(ro)
* `dev`(ro) ]]></textile>
]]></markdown>
</section> </section>
</section> </section>

View File

@ -1,32 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Patterns"> <chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Patterns">
<description><markdown> <description>
<textile>
The lighttpd config supports "patterns" in various places (docroot, redirect, rewrite, env.set, ...); and they share the following structure. 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. 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> </textile>
</description>
<section title="Syntax"> <section title="Syntax">
<markdown> <textile>
A pattern is a string consisting of the following parts: 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 (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) * "$" 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. * "%" 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> </textile>
</section> </section>
<section title="Ranges"> <section title="Ranges">
<markdown><![CDATA[ <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]`; 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`. 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: 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 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). * 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).
]]></markdown> ]]></textile>
</section> </section>
<example title="Example: simple redirect"> <example title="Example: simple redirect">
@ -36,10 +36,12 @@
</example> </example>
<example title="Example: docroot"> <example title="Example: docroot">
<description><markdown> <description>
<textile>
* a request to "http://example.com/project/trunk" would lead to docroot "/var/www/project/trunk/htdocs" * 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" * a request to "http://sub.example.com/" would lead to docroot "/var/www/vhosts/com/sub.example"
</markdown></description> </textile>
</description>
<config> <config>
if req.path =~ "^/project/([^/]*)" { if req.path =~ "^/project/([^/]*)" {
docroot "/var/www/projects/%1/htdocs"; docroot "/var/www/projects/%1/htdocs";

View File

@ -1,20 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Regular expressions"> <chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Regular expressions">
<description><markdown> <description>
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. <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.
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 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: 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.
* `"\n"` is a newline, `"\r"` a carriage return, `"\t"` a tab stop 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.
* `"\\"` 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.
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"@.
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). </textile>
To match a digit with pcre this way you'd have to write `e"\\d"` instead of `"\d"`. </description>
</markdown></description>
</chapter> </chapter>

View File

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

View File

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

View File

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

View File

@ -13,13 +13,13 @@
<parameter name="rules"> <parameter name="rules">
<short>A key value list mapping "access" and/or "deny" keys to a list of CIDR addresses or "all".</short> <short>A key value list mapping "access" and/or "deny" keys to a list of CIDR addresses or "all".</short>
</parameter> </parameter>
<description><markdown> <description>
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. 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.
</markdown></description> </description>
<example title="Example: restrict access to local network" anchor="#"> <example title="Example: restrict access to local network" anchor="#">
<description><markdown> <description>
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. 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.
</markdown></description> </description>
<config> <config>
setup { setup {
module_load "mod_access"; module_load "mod_access";
@ -32,9 +32,9 @@
</config> </config>
</example> </example>
<example title="Example: restrict access to subnet with exception" anchor="#"> <example title="Example: restrict access to subnet with exception" anchor="#">
<description><markdown> <description>
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. 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.
</markdown></description> </description>
<config> <config>
setup { setup {
module_load "mod_access"; module_load "mod_access";
@ -52,9 +52,11 @@
<short>url to redirect to if access was denied (not implemented yet)</short> <short>url to redirect to if access was denied (not implemented yet)</short>
<parameter name="url" /> <parameter name="url" />
<default><text>not set</text></default> <default><text>not set</text></default>
<description><markdown> <description>
**NOT IMPLEMENTED YET** <textile>
</markdown></description> *NOT IMPLEMENTED YET*
</textile>
</description>
</option> </option>
<option name="access.log_blocked"> <option name="access.log_blocked">

View File

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

View File

@ -2,18 +2,22 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1"> <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> <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><markdown> <description>
**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! <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!
* Basic: * 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. 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. It is recommend to use https in conjunction with basic authentication.
* Digest (not supported yet): * 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 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. 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) *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> </textile>
</description>
<action name="auth.plain"> <action name="auth.plain">
<short>requires authentication using a plaintext file</short> <short>requires authentication using a plaintext file</short>
@ -33,9 +37,9 @@
</entry> </entry>
</table> </table>
</parameter> </parameter>
<description><markdown> <description>
requires authentication using a plaintext file containing user:password pairs separated by newlines (\n). requires authentication using a plaintext file containing user:password pairs separated by newlines (\n).
</markdown></description> </description>
</action> </action>
<action name="auth.htpasswd"> <action name="auth.htpasswd">
@ -56,12 +60,14 @@
</entry> </entry>
</table> </table>
</parameter> </parameter>
<description><markdown> <description>
<textile>
* requires authentication using a htpasswd file containing user:encrypted_password pairs separated by newlines (\n) * 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 * 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 "$apr1$" ARE supported (htpasswd -m)
* hashes starting with "{SHA}" ARE supported (followed by sha1_base64(password), htpasswd -s) ** hashes starting with "{SHA}" ARE supported (followed by sha1_base64(password), htpasswd -s)
</markdown></description> </textile>
</description>
</action> </action>
<action name="auth.htdigest"> <action name="auth.htdigest">
@ -82,12 +88,14 @@
</entry> </entry>
</table> </table>
</parameter> </parameter>
<description><markdown> <description>
<textile>
* requires authentication using a htdigest file containing user:realm:hashed_password tuples separated by newlines (\n) * 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 * 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: * passwords are saved as (modified) md5 hashes:
`md5hex(username + ":" + realm + ":" + password)` @md5hex(username + ":" + realm + ":" + password)@
</markdown></description> </textile>
</description>
</action> </action>
<action name="auth.deny"> <action name="auth.deny">
@ -114,9 +122,11 @@
</example> </example>
<example> <example>
<description><markdown> <description>
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: <textile>
</markdown></description> 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>
<config> <config>
setup { setup {

View File

@ -2,20 +2,20 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1"> <module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>balances between different backends.</short> <short>balances between different backends.</short>
<description><markdown> <description>
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. 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. 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.
</markdown></description> </description>
<action name="balance.rr"> <action name="balance.rr">
<short>balance between actions (list or single action) with Round-Robin</short> <short>balance between actions (list or single action) with Round-Robin</short>
<parameter name="actions"> <parameter name="actions">
<short>the actions to balance between</short> <short>the actions to balance between</short>
</parameter> </parameter>
<description><markdown> <description>
Round-Robin (rr) the requests are distributed equally over all backends. Round-Robin (rr) the requests are distributed equally over all backends.
</markdown></description> </description>
<example> <example>
<config> <config>
balance.rr { fastcgi "127.0.0.1:9090"; }; balance.rr { fastcgi "127.0.0.1:9090"; };
@ -33,9 +33,9 @@
<parameter name="actions"> <parameter name="actions">
<short>the actions to balance between</short> <short>the actions to balance between</short>
</parameter> </parameter>
<description><markdown> <description>
Shortest-Queue-First (sqf) is similar to Round-Robin and prefers the backend with the shortest wait-queue. Shortest-Queue-First (sqf) is similar to Round-Robin and prefers the backend with the shortest wait-queue.
</markdown></description> </description>
<example> <example>
<config> <config>
balance.sqf { fastcgi "127.0.0.1:9090"; }; balance.sqf { fastcgi "127.0.0.1:9090"; };

View File

@ -2,29 +2,31 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1"> <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> <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><markdown> <description>
<textile>
Please note: This will not skip the backend, as it will need at least the response headers. Please note: This will not skip the backend, as it will need at least the response headers.
**Hint:** *Hint:*
Use a cron-job like the following to remove old cached data, e.g. in crontab daily: 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 {} \; find /var/cache/lighttpd/cache_etag/ -type f -mtime +2 -exec rm -r {} \;
``` </pre>
**Hint:** *Hint:*
Have a look at [mod_deflate](mod_deflate.html#mod_deflate) to see this module in action. Have a look at "mod_deflate":mod_deflate.html#mod_deflate to see this module in action.
</markdown></description> </textile>
</description>
<action name="cache.disk.etag"> <action name="cache.disk.etag">
<short>cache responses based on the ETag response header</short> <short>cache responses based on the ETag response header</short>
<parameter name="path"> <parameter name="path">
<short>directory to store the cached results in</short> <short>directory to store the cached results in</short>
</parameter> </parameter>
<description><markdown> <description>
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). 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). You could insert it multiple times of course (e.g. before and after deflate).
</markdown></description> </description>
<example> <example>
<config> <config>

View File

@ -3,17 +3,16 @@
<short>provides some useful helpers written in lua</short> <short>provides some useful helpers written in lua</short>
<section title="Install"> <section title="Install">
<markdown> <textile>
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: 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.lua` * @core__cached_html.lua@
* `core__cached_html.lua` * @core__xsendfile.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). 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. lighttpd should search for @core.lua@ in the correct (install) locations, so you don't need the absolute path here.
</markdown> </textile>
</section> </section>
<action name="core.wsgi"> <action name="core.wsgi">
@ -24,19 +23,23 @@
<parameter name="action"> <parameter name="action">
<short>action block connecting to the wsgi backend</short> <short>action block connecting to the wsgi backend</short>
</parameter> </parameter>
<description><markdown> <description>
See [Howto WSGI](https://redmine.lighttpd.net/projects/lighttpd2/wiki/Howto_WSGI) for an example. <textile>
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. 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). 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) *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> </textile>
</description>
<example> <example>
<description><markdown> <description>
Example: Trac in `/trac`, listening via FastCGI on `unix:/var/run/lighttpd/trac.socket`. <textile>
</markdown></description> Example: Trac in @/trac@, listening via FastCGI on @unix:/var/run/lighttpd/trac.socket@.
</textile>
</description>
<config> <config>
setup { setup {
module_load ("mod_lua", "mod_fastcgi"); module_load ("mod_lua", "mod_fastcgi");
@ -89,18 +92,20 @@
<parameter name="userlist"> <parameter name="userlist">
<short>list of usernames to allow</short> <short>list of usernames to allow</short>
</parameter> </parameter>
<description><markdown> <description>
<textile>
This helper constructs a regular expression to match against request.environment["REMOTE_USER"], so the example below is the same as: 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" ]; auth.plain [ "method" => "basic", "realm" => "test", "file" => "/etc/lighttpd2/test.plain" ];
if req.env["REMOTE_USER"] !~ "^(foo1|foo2)$" { auth.deny; } if req.env["REMOTE_USER"] !~ "^(foo1|foo2)$" { auth.deny; }
``` </pre>
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. Be careful: the empty username matches unauthenticated users.
</markdown></description> </textile>
</description>
<example> <example>
<config> <config>
setup { setup {

View File

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

View File

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

View File

@ -52,9 +52,9 @@
</parameter> </parameter>
<example> <example>
<description><markdown> <description>
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" 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"
</markdown></description> </description>
<config> <config>
setup { setup {
module_load ("mod_dirlist"); module_load ("mod_dirlist");

View File

@ -2,41 +2,47 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1"> <module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>add "Expires" and "Cache-Control" headers to the response</short> <short>add "Expires" and "Cache-Control" headers to the response</short>
<description><markdown><![CDATA[ <description>
<textile><![CDATA[
This allows you to control client-side caching of responses based on a simple rule/formula. 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. 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. 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. Use "modification" as @<base>@ if your content changes in specific intervals like every 15 minutes.
]]></markdown></description> ]]></textile>
</description>
<action name="expire"> <action name="expire">
<short>adds an "Expires" header to the response</short> <short>adds an "Expires" header to the response</short>
<parameter name="rule"> <parameter name="rule">
<short>the rule to calculate the "Expires" header value with</short> <short>the rule to calculate the "Expires" header value with</short>
</parameter> </parameter>
<description><markdown><![CDATA[ <description>
<textile><![CDATA[
The rule/formula used here, complies with the one mod_expire for Apache uses: The rule/formula used here, complies with the one mod_expire for Apache uses:
<pre>
<base> [plus] (<num> <type>)+ <base> [plus] (<num> <type>)+
</pre>
* `<base>` is one of "access", "now" or "modification"; "now" being equivalent to "access". * @<base>@ is one of "access", "now" or "modification"; "now" being equivalent to "access".
* "`plus`" is optional and does nothing. * "@plus@" is optional and does nothing.
* `<num>` is any positive integer. * @<num>@ is any positive integer.
* `<type>` is one of "seconds", "minutes", "hours", "days", "weeks", "months" or "years". * @<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. The expire action will overwrite any existing "Expires" header.
It will append the max-age value to any existing "Cache-Control" header. It will append the max-age value to any existing "Cache-Control" header.
]]></markdown></description> ]]></textile>
</description>
<example> <example>
<description><markdown> <description>
Cache image, css, txt and js files for 1 week. Cache image, css, txt and js files for 1 week.
</markdown></description> </description>
<config> <config>
setup { setup {
module_load "mod_expire"; module_load "mod_expire";

View File

@ -7,18 +7,22 @@
<parameter name="socket"> <parameter name="socket">
<short>socket to connect to, either "ip:port" or "unix:/path"</short> <short>socket to connect to, either "ip:port" or "unix:/path"</short>
</parameter> </parameter>
<description><markdown> <description>
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>
</markdown></description> 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>
<example> <example>
<config> <config>
fastcgi "127.0.0.1:9090" fastcgi "127.0.0.1:9090"
</config> </config>
</example> </example>
<example> <example>
<description><markdown> <description>
Start php for example with spawn-fcgi: `spawn-fcgi -n -s /var/run/lighttpd2/php.sock -- /usr/bin/php5-cgi` <textile>
</markdown></description> Start php for example with spawn-fcgi: @spawn-fcgi -n -s /var/run/lighttpd2/php.sock -- /usr/bin/php5-cgi@
</textile>
</description>
<config> <config>
setup { setup {
module_load "mod_fastcgi"; module_load "mod_fastcgi";

View File

@ -4,11 +4,13 @@
<action name="flv"> <action name="flv">
<short>pseudo stream the current file as flash</short> <short>pseudo stream the current file as flash</short>
<description><markdown> <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. 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. Uses "video/x-flv" as hard-coded content type.
</markdown></description> </textile>
</description>
<example> <example>
<config> <config>
if phys.path =$ ".flv" { if phys.path =$ ".flv" {
@ -17,11 +19,13 @@
</config> </config>
</example> </example>
<example> <example>
<description><markdown> <description>
<textile>
Use caching and bandwidth throttling to save traffic. Use a small burst threshold to prevent the player from buffering at the beginning. 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. This config will make browsers cache videos for 1 month and limit bandwidth to 150 kilobyte/s after 500 kilobytes.
</markdown></description> </textile>
</description>
<config> <config>
if phys.path =$ ".flv" { if phys.path =$ ".flv" {
expire "access 1 month"; expire "access 1 month";

View File

@ -67,9 +67,11 @@
</example> </example>
<example title="TLS with SNI from fetch backend"> <example title="TLS with SNI from fetch backend">
<description><markdown> <description>
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>
</markdown></description> 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>
<config> <config>
setup { setup {
fetch.files_static "sni" => "/etc/certs/lighttpd_sni_*.pem"; fetch.files_static "sni" => "/etc/certs/lighttpd_sni_*.pem";
@ -142,51 +144,48 @@
</setup> </setup>
<section title="Server Name Indication (SNI)"> <section title="Server Name Indication (SNI)">
<markdown> <textile>
[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. "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.
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): 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 * Use "Subject Alternative Names" in the certificate
* Provide different certificates based on the SNI hostname in the TLS handshake. * 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. 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). 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. 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`. 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). 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).
</markdown> </textile>
</section> </section>
<section title="GnuTLS priority string"> <section title="GnuTLS priority string">
<markdown> <textile>
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). 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"` Example: @"SECURE:-VERS-SSL3.0:-SHA1:+SHA1:-RSA:+RSA:%SERVER_PRECEDENCE"@
* @SECURE@: starts with @SECURE@ level: only secure ciphers and secure curves
* `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)
* `-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)
* `-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
* `-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.
* `%SERVER_PRECEDENCE` a flag telling GnuTLS to use its own order of preference instead of the order provided by the client.
See also: See also:
* "Priority strings":http://gnutls.org/manual/html_node/Priority-Strings.html#Priority-Strings (GnuTLS manual)
* [Priority strings](https://gnutls.org/manual/html_node/Priority-Strings.html#Priority-Strings) (GnuTLS manual) * "GnuTLS Priority Strings":http://blog.lighttpd.net/gnutls-priority-strings.html
* [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"@
* `gnutls-cli -l --priority "SECURE:-VERS-SSL3.0:-SHA1:+SHA1:-RSA:+RSA:%SERVER_PRECEDENCE"` </textile>
</markdown>
</section> </section>
<section title="OCSP stapling"> <section title="OCSP stapling">
<markdown> <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. "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. Server Name Indication (SNI) should work fine, as an OCSP response is only used if it matches the certificate in use for the connection.
@ -196,56 +195,60 @@
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"): 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 ocsptool --ask --load-issuer issuer.pem --load-cert cert.pem --outfile ocsp.der
</pre>
Converting into PEM format can be done like this: 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 (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: 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). 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 ' awk '
BEGIN { block = 0 } BEGIN { block = 0 }
/^-----BEGIN / { ++block; } /^-----BEGIN / { ++block; }
{ if (block > 1) print; } { if (block > 1) print; }
' "certs.pem" > "issuer.pem" ' "certs.pem" > "issuer.pem"
</markdown> </pre>
</textile>
</section> </section>
<section title="protect-against-beast"> <section title="protect-against-beast">
<markdown> <textile>
[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. "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.
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. 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.
</markdown> </textile>
</section> </section>
<section title="DH parameters"> <section title="DH parameters">
<markdown> <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`). 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: 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@
* `certtool --generate-dh-params --bits=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.
* `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. "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.
"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: See also:
* "Diffie-Hellman(-Merkle) key exchange":http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
* [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, 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
* [OpenSSL: Documents, SSL_CTX_set_tmp_dh_callback(3)](https://www.openssl.org/docs/ssl/SSL_CTX_set_tmp_dh_callback.html#NOTES) </textile>
</markdown>
</section> </section>
</module> </module>

View File

@ -2,9 +2,10 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1"> <module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>limits concurrent connections or requests per second.</short> <short>limits concurrent connections or requests per second.</short>
<description><markdown> <description>
Both limits can be "in total" or per IP. Both limits can be "in total" or per IP.
</markdown></description> </description>
<action name="limit.con"> <action name="limit.con">
<short>limits the total amount of concurrent connections to the specified limit.</short> <short>limits the total amount of concurrent connections to the specified limit.</short>
@ -14,9 +15,9 @@
<parameter name="action"> <parameter name="action">
<short>(optional) an action to be executed when the limit is reached</short> <short>(optional) an action to be executed when the limit is reached</short>
</parameter> </parameter>
<description><markdown> <description>
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. 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.
</markdown></description> </description>
<example> <example>
<config> <config>
limit.con 10; limit.con 10;
@ -32,9 +33,9 @@
<parameter name="action"> <parameter name="action">
<short>(optional) an action to be executed when the limit is reached</short> <short>(optional) an action to be executed when the limit is reached</short>
</parameter> </parameter>
<description><markdown> <description>
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. 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.
</markdown></description> </description>
<example> <example>
<config> <config>
limit.con_ip 2; limit.con_ip 2;
@ -50,9 +51,9 @@
<parameter name="action"> <parameter name="action">
<short>(optional) an action to be executed when the limit is reached</short> <short>(optional) an action to be executed when the limit is reached</short>
</parameter> </parameter>
<description><markdown> <description>
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. 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.
</markdown></description> </description>
<example> <example>
<config> <config>
limit.req 100; limit.req 100;
@ -68,9 +69,9 @@
<parameter name="action"> <parameter name="action">
<short>(optional) an action to be executed when the limit is reached</short> <short>(optional) an action to be executed when the limit is reached</short>
</parameter> </parameter>
<description><markdown> <description>
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. 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.
</markdown></description> </description>
<example> <example>
<config> <config>
limit.req_ip 100; limit.req_ip 100;
@ -79,9 +80,9 @@
</action> </action>
<example title="Limiting concurrent connections" anchor="#"> <example title="Limiting concurrent connections" anchor="#">
<description><markdown> <description>
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. 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.
</markdown></description> </description>
<config> <config>
setup { setup {
module_load ("mod_limit","mod_redirect"); module_load ("mod_limit","mod_redirect");
@ -99,10 +100,10 @@
</example> </example>
<example title="Limiting requests per second" anchor="#"> <example title="Limiting requests per second" anchor="#">
<description><markdown> <description>
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. 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. It will however also not do anything else. The client will be able to use the /login page as often as he wants.
</markdown></description> </description>
<config> <config>
setup { setup {
module_load "mod_limit"; module_load "mod_limit";

View File

@ -2,9 +2,11 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1"> <module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>load lua plugins and actions</short> <short>load lua plugins and actions</short>
<description><markdown><![CDATA[ <description>
Also see [Lua API](core_lua.html#core_lua). <textile><![CDATA[
]]></markdown></description> Also see "Lua API":core_lua.html#core_lua.
]]></textile>
</description>
<setup name="lua.plugin"> <setup name="lua.plugin">
<short>load file as lua plugin</short> <short>load file as lua plugin</short>
@ -17,11 +19,13 @@
<parameter name="lua-args"> <parameter name="lua-args">
<short>arguments forwarded to the lua plugin</short> <short>arguments forwarded to the lua plugin</short>
</parameter> </parameter>
<description><markdown> <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. 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. The filename and the third argument @lua-args@ are available as parameters in @...@ in the lua script.
</markdown></description> </textile>
</description>
<example> <example>
<config> <config>
setup { setup {
@ -33,9 +37,9 @@
</setup> </setup>
<example title="Example plugin" anchor="#"> <example title="Example plugin" anchor="#">
<description><markdown> <description><textile>
(see [contrib/core.lua](https://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/core.lua) for a real example) (see "contrib/core.lua":http://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/core.lua for a real example)
</markdown></description> </textile></description>
<config> <config>
local filename, args = ... local filename, args = ...
@ -70,17 +74,18 @@
<parameter name="lua-args"> <parameter name="lua-args">
<short>arguments forwarded to the lua plugin</short> <short>arguments forwarded to the lua plugin</short>
</parameter> </parameter>
<description><markdown> <description>
lua.handler is basically the same as [include_lua](core_config.html#core_config__includes) with the following differences: <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 * 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 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 cannot call setup functions
* it supports arguments to the script (`local filename, args = ...`) * 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 * 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). 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
</markdown></description> </textile>
</description>
<example> <example>
<config> <config>
setup { setup {

View File

@ -2,18 +2,20 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1"> <module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>caches content on memcached servers</short> <short>caches content on memcached servers</short>
<description><markdown><![CDATA[ <description>
`lookup` tries to find data associated with the key, and returns it as http body with status 200 if it finds something. <textile><![CDATA[
`store` stores a http body (generated by another backend) in memcached. @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). 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> ]]></textile>
</description>
<action name="memcached.lookup"> <action name="memcached.lookup">
<short>searches the content in a memcached database</short> <short>searches the content in a memcached database</short>
@ -83,26 +85,24 @@
</example> </example>
<section title="Lua API" anchor="#"> <section title="Lua API" anchor="#">
<markdown><![CDATA[ <textile><![CDATA[
mod_memcached exports a Lua API to per-worker `luaState`s too (for use in lua.handler): 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: @memcached.new(address)@ creates a new connection; a connection provides:
* @req = con:get(key, cb | vr)@
* `req = con:get(key, cb | vr)` * @req = con:set(key, value, cb | vr, [ttl])@
* `req = con:set(key, value, cb | vr, [ttl])` * @con:setq(key, value, [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. 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: The response object has:
* @code@: 1 - Ok, 2 - Not stored, 3 - Exists, 4 - Not found, 5 - Error
* `code`: 1 Ok, 2 Not stored, 3 Exists, 4 Not found, 5 Error * @error@: error message
* `error`: error message * @key@: the lookup key
* `key`: the lookup key * @flags@
* `flags` * @ttl@
* `ttl` * @cas@
* `cas` * @data@
* `data` ]]></textile>
]]></markdown>
</section> </section>
</module> </module>

View File

@ -45,11 +45,13 @@
</table> </table>
</parameter> </parameter>
<description><markdown> <description>
For `ciphers` see OpenSSL [ciphers](https://www.openssl.org/docs/manmaster/man1/ciphers.html) string <textile>
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. 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> </textile>
</description>
<example title="Simple TLS on IPv4 and IPv6"> <example title="Simple TLS on IPv4 and IPv6">
<config> <config>
@ -104,13 +106,14 @@
<parameter name="list"> <parameter name="list">
<short>list of subsets to export</short> <short>list of subsets to export</short>
</parameter> </parameter>
<description><markdown> <description>
<textile>
Supported subsets: Supported subsets:
* "client" - set @SSL_CLIENT_S_DN_@ short-named entries
* "client" set `SSL_CLIENT_S_DN_` short-named entries * "client-cert" - set @SSL_CLIENT_CERT@ to client certificate PEM
* "client-cert" set `SSL_CLIENT_CERT` to client certificate PEM * "server" - set @SSL_SERVER_S_DN_@ short-named entries
* "server" set `SSL_SERVER_S_DN_` short-named entries * "server-cert" - set @SSL_SERVER_CERT@ to server certificate PEM
* "server-cert" set `SSL_SERVER_CERT` to server certificate PEM </textile>
</markdown></description> </description>
</action> </action>
</module> </module>

View File

@ -2,16 +2,19 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1"> <module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>track connection progress (state) via a unique identifier</short> <short>track connection progress (state) via a unique identifier</short>
<description><markdown><![CDATA[ <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. 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. 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. 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. 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". 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. Check the source code there for further insight.
]]></markdown></description> ]]></textile>
</description>
<setup name="progress.ttl"> <setup name="progress.ttl">
@ -44,26 +47,26 @@
<parameter name="format"> <parameter name="format">
<short>(optional) output format, one of "legacy", "json" or "jsonp". Defaults to "json".</short> <short>(optional) output format, one of "legacy", "json" or "jsonp". Defaults to "json".</short>
</parameter> </parameter>
<description><markdown><![CDATA[ <description>
<textile><![CDATA[
Output formats: Output formats:
* legacy: @new Object({"state": "running"", "received": 123456, "sent": 0, "request_size": 200000, "response_size": 0})@
* 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}@
* 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})@
* 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. The function name (default "progress") can be altered by supplying a X-Progress-Callback querystring parameter.
The JSON object can contain the following members: 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.
* **state**: One of `"unknown"`, `"running"`, `"done"` or `"error"`. @received@, @request_size@, @sent@ and @response_size@ are only available if @state@ is @"running"@ or @"done"@.
* **received**: Bytes received by lighty or uploaded by the client. @status@ is only available if @state@ is @"error"@.
* **request_size**: Total size of request or uploaded file as specified via the Content-Length request header. ]]></textile>
* **sent**: Bytes sent by lighty or downloaded by the client. </description>
* **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> <example>
<config><![CDATA[ <config><![CDATA[

View File

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

View File

@ -2,21 +2,25 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1"> <module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>redirect clients by sending a http status code 301 plus Location header</short> <short>redirect clients by sending a http status code 301 plus Location header</short>
<description><markdown> <description>
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>
</markdown></description> 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>
<action name="redirect"> <action name="redirect">
<short>redirect clients</short> <short>redirect clients</short>
<parameter name="rule"> <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> <short>a simple target string or one rule, mapping a regular expression to a target string, or a list of rules.</short>
</parameter> </parameter>
<description><markdown> <description>
* The target string is a [pattern](core_pattern.html#core_pattern). <textile>
* The [regular expressions](core_regex.html#core_regex) are used to match the request path (always starts with "/"!) * 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. * 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. * 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> </textile>
</description>
<example title="Example: redirect always (http to https)"> <example title="Example: redirect always (http to https)">
<config> <config>
setup { setup {
@ -55,9 +59,9 @@
</example> </example>
<example> <example>
<description><markdown> <description>
redirect all non www. requests. for example: foo.tld/bar?x=y to www.foo.tld/bar?x=y redirect all non www. requests. for example: foo.tld/bar?x=y to www.foo.tld/bar?x=y
</markdown></description> </description>
<config> <config>
if request.host !~ "^www\.(.*)$" { if request.host !~ "^www\.(.*)$" {
redirect "." => "http://www.%1/$0?%{request.query}"; redirect "." => "http://www.%1/$0?%{request.query}";

View File

@ -2,27 +2,31 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1"> <module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>modifies request path and querystring</short> <short>modifies request path and querystring</short>
<description><markdown> <description>
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>
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 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 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. *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). 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> </textile>
</description>
<action name="rewrite"> <action name="rewrite">
<short>modify request path and querystring</short> <short>modify request path and querystring</short>
<parameter name="rule"> <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> <short>a simple target string or one rule, mapping a regular expression to a target string, or a list of rules.</short>
</parameter> </parameter>
<description><markdown> <description>
* The target string is a [pattern](core_pattern.html#core_pattern). <textile>
* 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!) * 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. * If a list of rules is given, rewrite stops on the first match.
* Replaces the query string iff the target string contains an `?` * Replaces the query string iff the target string contains an @?@
</markdown></description> </textile>
</description>
<example title="Example: rewrite always"> <example title="Example: rewrite always">
<config> <config>
setup { setup {
@ -48,9 +52,11 @@
</config> </config>
</example> </example>
<example title="Example: pretty urls"> <example title="Example: pretty urls">
<description><markdown> <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. 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> </textile>
</description>
<config><![CDATA[ <config><![CDATA[
setup { setup {
module_load "mod_rewrite"; module_load "mod_rewrite";
@ -74,13 +80,15 @@
<parameter name="rule"> <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> <short>a simple target string or one rule, mapping a regular expression to a target string, or a list of rules.</short>
</parameter> </parameter>
<description><markdown> <description>
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. <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.
[`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@":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. "@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. In both cases @request.path@ gets simplified afterwards.
</markdown></description> </textile>
</description>
</action> </action>
<option name="rewrite.debug"> <option name="rewrite.debug">

View File

@ -3,14 +3,13 @@
<short>protects files with a time limited code</short> <short>protects files with a time limited code</short>
<section title="Install"> <section title="Install">
<markdown><![CDATA[ <textile><![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: 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.lua` * @secdownload__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). 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).
]]></markdown> ]]></textile>
</section> </section>
<action name="secdownload"> <action name="secdownload">
@ -31,10 +30,12 @@
</entry> </entry>
</table> </table>
</parameter> </parameter>
<description><markdown><![CDATA[ <description>
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)). <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). secdownload doesn't actually handle the (valid) request, it just provides the mapping to a filename (and rejects invalid requests).
]]></markdown></description> ]]></textile>
</description>
<example> <example>
<config><![CDATA[ <config><![CDATA[
setup { setup {
@ -47,12 +48,13 @@
</action> </action>
<section title="Generating URLs"> <section title="Generating URLs">
<markdown><![CDATA[ <textile><![CDATA[
To generate URLs that are valid for `secdownload` you need the same secret. 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. 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.
For example with PHP: For example with PHP:
<pre>
$secret = "abc"; $secret = "abc";
$uri_prefix = "/sec/"; $uri_prefix = "/sec/";
@ -67,11 +69,12 @@
# generate link # generate link
printf('<a href="%s%s/%s%s">%s</a>', $uri_prefix, $m, $t_hex, $f, $f); printf('<a href="%s%s/%s%s">%s</a>', $uri_prefix, $m, $t_hex, $f, $f);
</pre>
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). For more examples see "mod_secdownload (lighttpd 1.4.x)":https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModSecDownload#Examples
]]></markdown> ]]></textile>
</section> </section>
</module> </module>

View File

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

View File

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

View File

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

View File

@ -2,19 +2,23 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1"> <module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>offers various ways to implement virtual webhosts</short> <short>offers various ways to implement virtual webhosts</short>
<description><markdown> <description>
<textile>
It can map hostnames to actions and offers multiple ways to do so. 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. These ways differ in the flexibility of mapping (what to map and what to map to) as well as performance.
</markdown></description> </textile>
</description>
<action name="vhost.map"> <action name="vhost.map">
<short>maps given hostnames to action blocks</short> <short>maps given hostnames to action blocks</short>
<parameter name="mapping"> <parameter name="mapping">
<short>key-value list with hostnames as keys and actions as values</short> <short>key-value list with hostnames as keys and actions as values</short>
</parameter> </parameter>
<description><markdown> <description>
`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>
</markdown></description> @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>
<example> <example>
<config> <config>
vhost.map ["host1" => actionblock1, "host2" => actionblock2, ..., "hostN" => actionblockN, default => actionblock0]; vhost.map ["host1" => actionblock1, "host2" => actionblock2, ..., "hostN" => actionblockN, default => actionblock0];
@ -27,9 +31,11 @@
<parameter name="mapping"> <parameter name="mapping">
<short>key-value list with regular expressions for hostnames as keys and actions as values</short> <short>key-value list with regular expressions for hostnames as keys and actions as values</short>
</parameter> </parameter>
<description><markdown> <description>
`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>
</markdown></description> @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>
<example> <example>
<config> <config>
vhost.map_regex ["host1regex" => actionblock1, "host2regex" => actionblock2, ..., "hostNregex" => actionblockN, default => actionblock0]; vhost.map_regex ["host1regex" => actionblock1, "host2regex" => actionblock2, ..., "hostNregex" => actionblockN, default => actionblock0];
@ -43,16 +49,17 @@
</option> </option>
<example> <example>
<description><markdown> <description>
<textile>
Combining both actions is also possible. Combining both actions is also possible.
What it does (for example): What it does (for example):
* if @example.com@ or @www.example.com@ is requested, the block named "examplesite" will be executed
* 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.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 `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
* if `www.mydomain.tld` or something entirely different is requested, the block named "defaultdom" will be executed </textile>
</markdown></description> </description>
<config> <config>
setup { setup {
module_load "mod_vhost"; module_load "mod_vhost";

View File

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

View File

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

View File

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

View File

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

View File

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

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

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