diff --git a/doc/compile.rb b/doc/compile.rb index f44f02a..398b0f8 100755 --- a/doc/compile.rb +++ b/doc/compile.rb @@ -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) } diff --git a/doc/core_config.xml b/doc/core_config.xml index 67adf07..7ec9836 100644 --- a/doc/core_config.xml +++ b/doc/core_config.xml @@ -225,14 +225,14 @@ The actions, setups and options are provided by the "modules":index_modules.html#index_modules. ]]> -
+
@@ -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) | ]]>
diff --git a/doc/core_config_angel.xml b/doc/core_config_angel.xml index b26c962..71b043b 100644 --- a/doc/core_config_angel.xml +++ b/doc/core_config_angel.xml @@ -3,7 +3,7 @@ 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. diff --git a/doc/core_fetch.xml b/doc/core_fetch.xml index 862c167..d46f5e7 100644 --- a/doc/core_fetch.xml +++ b/doc/core_fetch.xml @@ -1,5 +1,5 @@ - + 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. diff --git a/doc/core_introduction.xml b/doc/core_introduction.xml new file mode 100644 index 0000000..a0a7a6c --- /dev/null +++ b/doc/core_introduction.xml @@ -0,0 +1,22 @@ + + + +
+ /usr/sbin/lighttpd2 -c /etc/lighttpd2/angel.conf + + The process will not fork into background, you need to do that yourself if you want that. + Our recommended way to run lighttpd2 is "runit":http://smarden.org/runit/useinit.html (have a look at the "@contrib/service@":http://git.lighttpd.net/lighttpd/lighttpd2.git/tree/contrib/service directory). + ]]> +
+ +
diff --git a/doc/core_lua.xml b/doc/core_lua.xml new file mode 100644 index 0000000..10f79c6 --- /dev/null +++ b/doc/core_lua.xml @@ -0,0 +1,372 @@ + + + + + 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). + + + +
+ + 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). + + + + + + + + +
+ +
+ +
+ +
+ +
+ == | @: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. + ]]> + + + + Translating @if req.env["REMOTE_USER"] != "admin" { auth.deny; }@ to Lua: + + + + + + + Translating @if !phys.exists { auth.deny; }@ to Lua: + + + +
+
+ +
+ + e = vr.env + e["XXX"] = "abc" + + + 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(...)@: + +
+			vr:print("Hello World")
+			
+ + *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 + +
+			for k, v in vr.env:pairs() do
+			  vr:print("env['" .. k .. "'] = '" .. v .. "'")
+			end
+			
+ + 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. + ]]>
+ +
+ +
+ +
+ + + + + + + + + +
+ +
+ +
+ +
+ +
+ +
+ + 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 + + + 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 + ]]> +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ +
diff --git a/doc/mod_auth.xml b/doc/mod_auth.xml index 0c223b7..fcd9965 100644 --- a/doc/mod_auth.xml +++ b/doc/mod_auth.xml @@ -124,7 +124,7 @@ - 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: diff --git a/doc/mod_lua.xml b/doc/mod_lua.xml index 9f23a8a..e759d4b 100644 --- a/doc/mod_lua.xml +++ b/doc/mod_lua.xml @@ -2,6 +2,12 @@ load lua plugins and actions + + + + load file as lua plugin @@ -30,11 +36,12 @@ -
- - (see "contrib/core.lua":http://git.lighttpd.net/lighttpd/lighttpd2/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) + -
+		
 			local filename, args = ...
 
 			-- args are from the lua.plugin line
@@ -49,8 +56,7 @@
 			actions = {
 				["simple"] = simple,
 			}
-			
-
+
@@ -70,14 +76,14 @@ - 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