2
0
Fork 0

[docs] fix links, add index page, add small introduction, add lua config / api

personal/stbuehler/wip
Stefan Bühler 2014-05-26 15:04:46 +02:00
parent 5c9a9bbaba
commit 4741120b74
8 changed files with 510 additions and 48 deletions

View File

@ -50,6 +50,8 @@ class Documentation
@actions = []
@setups = []
@options = []
@sub_pages = []
end
def render_main
@ -66,7 +68,7 @@ class Documentation
def title=(value)
@title = value
@html_doc.xpath('/html/head/title')[0].inner_html = value
@html_doc.xpath('/html/head/title')[0].inner_html = value ? 'lighttpd2 - ' + value : 'lighttpd2'
end
def to_html_fragment
@ -93,6 +95,10 @@ class Documentation
@options
end
def sub_pages
@sub_pages
end
def _store_toc(html, toc, rootToc = false)
return unless toc.length > 0
html.ul(:class => rootToc ? "nav bs-sidenav" : "nav" ) {
@ -601,6 +607,8 @@ class ModuleIndex < Documentation
def initialize(modules)
super('index_modules')
@sub_pages = modules
actions = []
setups = []
options = []
@ -611,7 +619,7 @@ class ModuleIndex < Documentation
end
render_main do
nest('Modules overview', '', 'index_modules') {
nest('Module index', '', 'index_modules') {
modules_table(modules)
aso_html_table('action', actions.sort)
aso_html_table('setup', setups.sort)
@ -619,7 +627,41 @@ class ModuleIndex < Documentation
}
end
self.title = "lighttpd2 - all in one"
self.title = "Module index"
store_toc
end
end
class IndexPage < Documentation
def list(pages)
return if pages.empty?
@html.ul do
pages.each do |page|
@html.li do
@html.a({:href => page.filename}, page.title)
list(page.sub_pages)
end
end
end
end
def initialize(pages)
super('index')
self.title = "Index"
render_main do
nest(self.title, '', 'index') do
@html.p do
@html << "The documentation is also available as a "
@html.a({:href => "all.html"}, "single HTML page")
@html << "."
end
list(pages)
end
end
store_toc
end
end
@ -632,26 +674,29 @@ class AllPage < Documentation
a['href'] = m[2] if m && @href_map[m[1]]
end
def append(pages)
pages.each do |page|
@href_map[page.filename] = true
@html << page.to_html_fragment
@toc += page.toc
append(page.sub_pages)
end
end
def initialize(pages)
super('all')
@href_map = {}
pages.each do |page|
@href_map[page.filename] = true
end
render_main do
pages.each do |page|
@html << page.to_html_fragment
@toc += page.toc
end
append(pages)
end
@html_doc.xpath('//a').each do |a|
fix_link(a)
end
self.title = "lighttpd2 - all in one"
self.title = "all in one"
store_toc
end
end
@ -688,11 +733,28 @@ if __FILE__ == $0
end
pages.sort!
pages << ModuleIndex.new(pages)
normal_pages = []
module_pages = []
pages.each do |page|
if page.is_a? ModuleDocumentation
module_pages << page
else
normal_pages << page
end
end
module_index_page = ModuleIndex.new(module_pages)
pages << module_index_page
normal_pages << module_index_page
pages.sort!
pages << AllPage.new(pages)
all_page = AllPage.new(normal_pages)
index_page = IndexPage.new(normal_pages)
pages << all_page << index_page
pages.sort!
pages.each { |page| page.write_disk(output_directory) }

View File

@ -225,14 +225,14 @@
The actions, setups and options are provided by the "modules":index_modules.html#index_modules.
]]></textile>
<section title="Includes">
<section title="Includes" anchor="includes">
<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.
There are three types of includes:
* @include "/etc/lighttpd/vhosts/*.conf";@: include files like the main config itself; the path can contain wildcards
* @include_shell "/etc/lighttpd/config_generator.sh";@: runs the specified command, and parses the output of it as config file
* @include_lua "/etc/lighttpd/complex.lua"@: includes a Lua config file
* @include_lua "/etc/lighttpd/complex.lua"@: includes a Lua config file. The single action to be executed must be returned in the global @actions@ variable (or leave it empty to do nothing). See also "@lua.handler@":mod_lua.html#mod_lua__action_lua-handler
Includes also create a new nested scope.
]]></textile>
@ -294,30 +294,30 @@
table(table table-striped).
|_. variable |_. description |
| req.localip | ip address of the listing socket, the client connected to (filename for unix sockets) |
| req.localport | port number of the listening socket, -1 for unix sockets |
| req.remoteip | ip address of the client |
| req.remoteport | port number of the client, -1 for unix sockets |
| req.path | the _path_ part of the requested url. not including the querystring. |
| req.host | requested hostname |
| req.scheme | scheme of the request. "http" or "https" |
| req.query | the _querystring_ of the requested url |
| req.method | method of the request. "GET", "POST", "HEAD" etc. |
| req.length | integer. length of the content for e.g. POST methods |
| req.header["name"] | request header _name_ e.g. req.header["referer"] |
| req.is_handled | boolean condition, does request already have a handler (static, fastcgi..) |
| req.env["name"] | (short for req.environment["name"]) CGI environment |
| request.localip | ip address of the listing socket, the client connected to (filename for unix sockets) |
| request.localport | port number of the listening socket, -1 for unix sockets |
| request.remoteip | ip address of the client |
| request.remoteport | port number of the client, -1 for unix sockets |
| request.path | the _path_ part of the requested url. not including the querystring. |
| request.host | requested hostname |
| request.scheme | scheme of the request. "http" or "https" |
| request.query | the _querystring_ of the requested url |
| request.method | method of the request. "GET", "POST", "HEAD" etc. |
| request.length | integer. length of the content for e.g. POST methods |
| request.header["name"] | request header _name_ e.g. request.header["referer"] |
| request.is_handled | boolean condition, does request already have a handler (static, fastcgi..) |
| request.environment["name"] | (or short request.env["name"]) CGI environment |
| | |
| phys.path | physical path of the file to be served. e.g. document root + path |
| phys.exists | boolean condition, indicates whether the requested file exist |
| phys.size | integer. size of the requested file. -1 if file doesn't exist |
| phys.is_dir | boolean condition, indicates whether the requested file is a directory |
| phys.is_file | boolean condition, indicates whether the requested file is a normal file (e.g. no unix socket etc) |
| phys.docroot | document root |
| phys.pathinfo | pathinfo |
| physical.path | physical path of the file to be served. e.g. document root + path |
| physical.exists | boolean condition, indicates whether the requested file exist |
| physical.size | integer. size of the requested file. -1 if file doesn't exist |
| physical.is_dir | boolean condition, indicates whether the requested file is a directory |
| physical.is_file | boolean condition, indicates whether the requested file is a normal file (e.g. no unix socket etc) |
| physical.docroot | document root |
| physical.pathinfo | pathinfo |
| | |
| resp.status | response status code (blocks request until response header is available) |
| resp.header["name"] | response header (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) |
]]></textile>
</section>

View File

@ -3,7 +3,7 @@
<description>
<textile>
lighttpd2 consists of two main binaries: the angel (@lighttpd2@) and the worker (@lighttpd2-worker@). The "main configuration":core_config.html#core_config is used by the worker, and this chapter describes the configuration for the angel.
A standard distribution should install a angel config with reasonable defaults which should work for most basic setups.
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>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Fetch API">
<chapter xmlns="urn:lighttpd.net:lighttpd2/doc1" title="Fetch API" order="core_regex_after_01_fetch">
<description>
<textile>
The Fetch API provides a common interface between lighttpd modules to lookup entries in a database. Both lookup key and data are simple (binary) strings.

22
doc/core_introduction.xml Normal file
View File

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

372
doc/core_lua.xml Normal file
View File

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

View File

@ -124,7 +124,7 @@
<example>
<description>
<textile>
You can use @auth.require_user@ from the mod_lua plugin "contrib/core.lua":http://git.lighttpd.net/lighttpd/lighttpd2/tree/contrib/core.lua for the REMOTE_USER check too:
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>

View File

@ -2,6 +2,12 @@
<module xmlns="urn:lighttpd.net:lighttpd2/doc1">
<short>load lua plugins and actions</short>
<description>
<textile><![CDATA[
Also see "Lua API":core_lua.html#core_lua.
]]></textile>
</description>
<setup name="lua.plugin">
<short>load file as lua plugin</short>
<parameter name="filename">
@ -30,11 +36,12 @@
</example>
</setup>
<section title="Example plugin" anchor="#">
<textile>
(see "contrib/core.lua":http://git.lighttpd.net/lighttpd/lighttpd2/tree/contrib/core.lua for a real example)
<example title="Example plugin" anchor="#">
<description><textile>
(see "contrib/core.lua":http://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/core.lua for a real example)
</textile></description>
<pre>
<config>
local filename, args = ...
-- args are from the lua.plugin line
@ -49,8 +56,7 @@
actions = {
["simple"] = simple,
}
</pre>
</textile>
</config>
</section>
<action name="lua.handler">
@ -70,14 +76,14 @@
</parameter>
<description>
<textile>
lua.handler is basically the same as "include_lua":plugin_core.html#plugin_core__action_include_lua with the following differences:
lua.handler is basically the same as "include_lua":core_config.html#core_config__includes with the following differences:
* each worker loads the lua file itself
* it isn't loaded before it is used, so you won't see errors in the script at load time
* it cannot call setup functions
* it supports arguments to the script (@local filename, args = ...@)
* doesn't lock the global lua lock, so it performs better when you use multiple workers
See "contrib/core.lua":http://git.lighttpd.net/lighttpd/lighttpd2/tree/contrib/core.lua for how we load some external actions like "contrib/core__xsendfile.lua":http://git.lighttpd.net/lighttpd/lighttpd2/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
</textile>
</description>
<example>