项目

通用

个人资料

操作

使用 Lua 进行 lighttpd 请求操作

模块:mod_magnet

概述

mod_magnet 通过 Lua(编程语言)脚本实现对 lighttpd 请求处理的程序化操作。

mod_magnet Lua 示例展示了少量 Lua 代码与 lighttpd 结合的强大功能和灵活性。mod_magnet 允许您执行比在 lighttpd.conf 中更复杂的 URL 重写和缓存,包括 lighttpd 中的 .htaccess 类功能

虽然 Lua 是一种非常强大的编程语言,但对于任何具有其他脚本语言(Python、PHP、Ruby 等)基本脚本经验的人来说,学习基本的字符串操作并将 Lua 脚本插入 lighttpd 应该相对简单。请查看此处的 Lua 示例并尝试一下!有问题?请在 lighttpd 论坛发帖。

请注意:mod_magnet 旨在进行请求操作,例如 URL 重写,并非旨在完全替代您的整个脚本环境。mod_magnet 在 lighttpd 核心中执行 Lua 脚本,这使得 Lua 脚本在 lighttpd 中运行非常快,但任何阻塞操作(例如对外部数据库的 I/O)都会暂停 lighttpd 服务器的所有其他请求。对于耗时或阻塞的 Lua 脚本,请使用 mod_fastcgimod_proxy 或其他动态后端,在 lighttpd 外部运行您的脚本。对于有兴趣运行耗时或阻塞的 Lua 脚本的人,一个选项是第三方 FastCGI 守护程序,例如 luafcgid

要求

lighttpd 1.4.12 或更高版本,使用 --with-lua 构建
Lua >= 5.1
lighttpd.conf server.modules += ("mod_magnet") # 注意:如果希望 mod_magnet 在其他模块生成响应之前操作请求,则 mod_magnet 必须在 server.modules 中列在其他可能处理请求的模块(例如 mod_fastcgimod_webdav 等)之前

选项

mod_magnet 可以在请求处理的一个或多个阶段“吸引”请求。您可以为每个阶段定义多个脚本,用逗号分隔。脚本按指定顺序执行。如果脚本返回除 0 或 1xx 之外的值,则后续脚本将不会执行。请参阅下面的 返回码。出于性能原因,mod_magnet 会缓存每个编译好的脚本。对于每个请求,都会检查脚本,如果脚本已修改,则重新加载并重新编译。脚本更改会在下一个请求时生效,无需重新启动 lighttpd。

magnet.attract-raw-url-to = (...) - 收到 HTTP 请求头之后(以及 mod_rewrite 之后)的 URL 处理
magnet.attract-physical-path-to = (...) - 文档根目录和物理路径设置为初始值之后的文件系统处理
magnet.attract-response-start-to = (...) - HTTP 状态设置之后且响应头最终确定之前(自 1.4.56 起)的响应开始

例如 magnet.attract-physical-path-to = ( "/absolute/path/to/script.lua" )

返回码

  • 如果脚本 return 0,或不返回任何内容(或 nil),则请求处理继续。
  • 如果脚本 return lighty.RESTART_REQUEST(当前等于 99),则请求将重新启动,重新处理请求 URI。这通常与在重写中更改 ["request.uri"] 属性结合使用。
  • 如果脚本返回 1xx,则发送 1xx 中间响应,请求处理继续。
  • 如果脚本返回 >= 200,则该值用作最终 HTTP 状态码,并最终确定响应。不再执行其他模块。

将“http”重定向到“https”的示例:(lighty.* 访问器将在下面进一步描述)
(例如 如何使用 mod_redirect 将 HTTP 请求重定向到 HTTPS)

  local r = lighty.r
  local req_attr = r.req_attr
  if (req_attr["uri.scheme"] == "http") then
    r.resp_header["Location"] = "https://" .. req_attr["uri.authority"] .. req_attr["request.uri"]
    return 308
  end

检测请求阶段

如果同一个 Lua 脚本被配置为在多个请求阶段运行,Lua 脚本可以使用 lighty.* 检测请求阶段(lighty.* 访问器将在下面进一步描述)

magnet.attract-raw-url-to
  • lighty.r.req_attr["physical.path"] == nil
  • (自 lighttpd 1.4.65 起)lighty.r.req_item.http_status == 0
  • (lighttpd 1.4.65 之前)lighty.r.req_attr["response.http-status"] == "0"
magnet.attract-physical-path-to
  • lighty.r.req_attr["physical.path"] ~= nil
  • (自 lighttpd 1.4.65 起)lighty.r.req_item.http_status == 0
  • (lighttpd 1.4.65 之前)lighty.r.req_attr["response.http-status"] == "0"
magnet.attract-response-start-to(自 1.4.56 起)
  • (自 lighttpd 1.4.65 起)lighty.r.req_item.http_status > 0
  • (lighttpd 1.4.65 之前)lighty.r.req_attr["response.http-status"] > 0

示例

 

 

库函数

mod_magnet 向脚本导出了一些附加函数
  • pairs() - 扩展默认的 pairs() 函数(适用于 Lua 5.1)
  • print() - 写入 lighttpd 错误日志;用于调试很有用
    • 例如 print("Host: " .. lighty.r.req_header["Host"])
    • 例如 print("Request-URI: " .. lighty.r.req_attr["request.uri"])
  • lighty.stat() - stat() 文件信息(推荐:lighty.c.stat()

 

mod_magnet API (lighttpd 1.4.60 及更高版本)

已弃用lighttpd 1.4.60 之前的 mod_magnet API 仍然受支持,但应优先使用此较新的 mod_magnet API。)

lighty.r 请求对象

(自 lighttpd 1.4.60 起)

lighty.r 描述
lighty.r.req_header[] HTTP 请求头
lighty.r.req_attr[] HTTP 请求属性/组件
lighty.r.req_item[] HTTP 请求选择内部成员(自 1.4.65 起)
lighty.r.req_env[] HTTP 请求环境变量
lighty.r.req_body.* HTTP 请求体属性和访问器(自 1.4.65 起)
lighty.r.resp_header[] HTTP 响应头
lighty.r.resp_body.* HTTP 响应体属性和访问器
lighty.r 请求对象修改
  • lighty.r.req_header[] 允许获取/设置请求头
    如果修改会影响配置处理,脚本应返回
    lighty.RESTART_REQUEST 以使 lighttpd 重新启动修改后的请求。
    lighty.r.req_header[] 与旧版 API lighty.env[] 表不同,
    后者(以前)不允许修改请求头。
    注意:头策略不适用于在 lighty.r.req_header[] 中设置的值;
    不要设置未经验证、不信任或未标准化的值。
    注意:如果使用 pairs() 迭代,请不要在迭代期间将请求头设置为空白值,
    否则迭代可能会跳过请求头。
  • lighty.r.req_attr[] 允许获取/设置请求属性,并将在下面详细介绍。
    lighty.r.req_attr[] 与(命名不太清晰的)旧版 API lighty.env[] 相同
  • lighty.r.req_item[] 允许(主要是)对选定的内部请求成员进行只读访问
    并将在下面详细介绍。(自 1.4.65 起)
  • lighty.r.req_env[] 允许获取/设置请求环境变量
    lighty.r.req_env[] 与旧版 API lighty.req_env[] 相同
    注意:对标准 CGI 环境变量的修改
    将被重新创建 CGI 环境的后端覆盖。
    但是,新变量将保留到传递给后端脚本的环境中。
  • lighty.r.req_body.* 添加/设置请求体内容(自 1.4.65 起)
    lighty.r.req_body 描述
    lighty.r.req_body.len HTTP 请求体长度
    (如果没有则为 0;如果未知则为 -1;如果客户端发送 Content-Length 或请求体完成则 >= 0)
    lighty.r.req_body.collect HTTP 请求体安排收集(之后请求将重新启动并重新运行脚本)
    (注意:请求体卸载会禁用向后端流式传输请求;延迟连接到后端)
    - 如果请求体完成,则返回 1(然后脚本可以调用 r.req_body.get
    - 如果请求体不完整,则返回 0(然后脚本应返回 0,以便脚本稍后可以重新运行)
    lighty.r.req_body.get 获取 HTTP 请求体(注意:将整个请求读入内存;检查 r.req_body.len 以确保合理性)
    (如果请求体不完整则为 nil(请参阅 r.req_body.collect))
    lighty.r.req_body.add() 添加 HTTP 请求体(字符串或字符串表)
    (如果使用,也应 r.req_header["Content-Length"] = nil(或设置为实际值))
    lighty.r.req_body.set() 设置 HTTP 请求体(字符串或字符串表)
    (如果使用,也应 r.req_header["Content-Length"] = nil(或设置为实际值))
    lighty.r.req_body.bytes_in 从客户端接收的 HTTP 请求体字节数(由 r.req_body.set() 重置)
    lighty.r.req_body.bytes_out 发送到后端的 HTTP 请求体字节数(由 r.req_body.set() 重置)
    lighty.r.req_body.unspecified_len HTTP/1.0 请求体字节数未指定(不是 0 长度)(仅可为 HTTP/1.0 请求设置)(自 1.4.74 起)
  • lighty.r.resp_header[] 允许获取/设置响应头
    (某些连接级头,如 Connection 和
    Transfer-Encoding 被限制修改)
    lighty.r.resp_headers[] 与旧版 API lighty.header[] 表不同,
    后者被收集和延迟,在脚本退出后才应用。
    注意:头策略不适用于在 lighty.r.resp_header[] 中设置的值;
    不要设置未经验证、不信任或未标准化的值。
    对于重复的头名称,例如 Set-Cookie 或 Link,使用 "\r\nNAME:" 连接
    lighty.r.resp_header["Link"] = "http://a.com/a.css\r\nLink: http:/b.com/b.js"
  • lighty.r.resp_body.* 添加/设置响应体内容
    lighty.r.resp_body.* 与旧版 API lighty.content[] 表不同,
    后者被收集和延迟,在脚本退出后才应用。
    lighty.r.resp_body 描述
    lighty.r.resp_body.len HTTP 响应体长度
    lighty.r.resp_body.get 获取 HTTP 响应体(注意:将整个响应读入内存;检查 r.resp_body.len 以确保合理性)(自 1.4.65 起)
    lighty.r.resp_body.add() 添加 HTTP 响应体(字符串或表)
    lighty.r.resp_body.set() 设置 HTTP 响应体(字符串或表)
    lighty.r.resp_body.bytes_in 排队发送的 HTTP 响应体字节数(自 1.4.65 起)
    lighty.r.resp_body.bytes_out 发送到客户端的 HTTP 响应体字节数(自 1.4.65 起)
-- examples
local r = lighty.r
local resp_header = r.resp_header
resp_header["Content-Type"] = "text/html" 
resp_header["Cache-Control"] = "max-age=0" 
r.resp_body:set({'bar\n'})  -- equivalent to below 'set'
-- (suggested if script run via magnet.attract-response-start-to)
resp_header["Content-Length"] = nil
-- alternatives
r.resp_body.set({'bar\n'})  -- equivalent to above 'set'
lighty.r.resp_header["Content-Type"] = "text/html" 
-- deprecated older syntax (API before lighttpd 1.4.60) (less clearly named)
lighty.header["Content-Type"] = "text/html" 
lighty.content = {'bar\n'}
lighty.r.req_attr[] 可读属性
lighty.r.req_attr[] 描述
["uri.scheme"] ("http", "https")
["uri.authority"] URI 权限或 Host 请求头
["uri.path"] 不带查询字符串的 url-path;url-path 已进行 URL 解码
["uri.path-raw"] 不带查询字符串的 url-path;url-path 未进行 URL 解码
(来自 ["request.uri"] 的 url-path 组件,即不带查询字符串)
["uri.query"] 查询字符串;'?' 后面的 URL 部分;查询字符串未进行 URL 解码
["request.method"] 请求方法(例如 GET)
["request.protocol"] 请求协议("HTTP/1.0", "HTTP/1.1", "HTTP/2.0")
["request.uri"] mod_rewrite 规则(如果有)后的 URI,否则与 request.orig-uri 相同
["request.orig-uri"] mod_rewrite 之前的 URI;客户端发送的原始请求 URI
["request.path-info"] url-path 后面的 path-info
["request.server-addr"] 服务器地址
["request.server-port"] 服务器端口
["request.remote-addr"] 远程地址
["request.remote-port"] 远程端口
["request.server-name"] 通常与 ["uri.authority"] 相同,除非在 lighttpd.conf 中配置了 server.name
["request.stage"] 内部请求阶段的字符串标签(例如用于显示;类似于 mod_status)
["physical.doc-root"] 文件系统文档根目录(原始)
["physical.basedir"] 文件系统文档根目录(与 physical.doc-root 相同,除非 mod_alias、mod_userdir 等调整)
["physical.path"] 请求的文件系统路径(以 physical.basedir 开头)
["physical.rel-path"] 请求的文件系统路径(附加到 physical.basedir 的部分)
["response.http-status"] HTTP 响应状态(如果尚未设置则为 0)
(已弃用;自 lighttpd 1.4.65 起替换为 lighty.r.req_item.http_status
(在 lighttpd 1.4.68 中已移除)
["response.body-length"] HTTP 响应体长度
(已弃用;自 lighttpd 1.4.60 起替换为 lighty.r.resp_body.len
(在 lighttpd 1.4.68 中已移除)
(除非响应体完成,否则为 nil)
["response.body"] HTTP 响应体
(已弃用;自 lighttpd 1.4.65 起替换为 lighty.r.resp_body.get
(在 lighttpd 1.4.68 中已移除)
(除非响应体完成,否则为 nil)
(将响应复制到内存中;不应在非常大的响应上使用)

可以使用组件重新构建完整的 URI

local req_attr = lighty.r.req_attr
local query_string = req_attr["uri.query"]
local url = req_attr["uri.scheme"]
         .. "://" 
         .. req_attr["uri.authority"]
         .. req_attr["uri.path-raw"]
         .. (query_string and ("?" .. query_string) or "")

更多示例
-- curl "https://example.org/search.php?q=lighty" 
-- results in a request like:
--   GET /search.php?q=lighty HTTP/1.1
--   Host: example.org

local r = lighty.r
local req_attr = r.req_attr
local req_header = r.req_header

-- scripts run via magnet.attract-raw-url-to can access the following variables:

-- parts of the request-line
req_attr["request.uri"] == "/search.php?q=lighty" 
-- HTTP request-headers
req_header["Host"] == "example.org" 
-- parts of the URI
req_attr["uri.path"] == "/search.php" 
req_attr["uri.path-raw"] == "/search.php" 
req_attr["uri.scheme"] == "https" 
req_attr["uri.authority"] == "example.org" 
req_attr["uri.query"] == "q=lighty" 

-- Later in the request-handling, the URL is split, cleaned up, and turned into a physical path name
-- scripts run via magnet.attract-physical-path-to can access the following variables:

-- filenames, pathnames
req_attr["physical.path"] == "/my-docroot/search.php" 
req_attr["physical.rel-path"] == "/search.php" 
req_attr["physical.doc-root"] == "/my-docroot" 
req_attr["physical.basedir"] == "/my-docroot"  -- same as doc-root unless changed, e.g. by mod_alias

-- All of them are readable, but not all of them are writable (or have no effect if you write to them).  Some examples writing changes:

-- change physical-path
req_attr["physical.path"] = ...

-- change query-string
req_attr["uri.query"] = ...

-- simple rewrite
req_attr["request.uri"] = ...
return lighty.RESTART_REQUEST

一些 lighty.r.req_attr[] 属性提供与标准 CGI/1.1 环境中相似的值
lighty.r.req_attr[] CGI/1.1 环境变量
["uri.scheme"] REQUEST_SCHEME
["uri.authority"] SERVER_NAME
["uri.path"] SCRIPT_NAME
["uri.query"] QUERY_STRING
["request.method"] REQUEST_METHOD
["request.protocol"] SERVER_PROTOCOL
["request.path-info"] PATH_INFO
["request.remote-addr"] REMOTE_ADDR
["request.remote-port"] REMOTE_PORT
["request.server-addr"] SERVER_ADDR
["request.server-port"] SERVER_PORT
["request.server-name"] SERVER_NAME
["physical.doc-root"] DOCUMENT_ROOT
["physical.basedir"] DOCUMENT_ROOT
["physical.path"] SCRIPT_FILENAME
["physical.rel-path"] SCRIPT_NAME
lighty.r.req_attr[] 可写属性

对特定属性或组件的修改是相当直接的接口
到 lighttpd 内部,并且不影响其他相关属性,包括
完整请求,从中可能派生出属性或组件。

这意味着什么?
这意味着:仔细测试您的脚本并验证所需行为。

如果任何修改后需要完整的请求重新处理,
例如,如果修改会影响配置处理,脚本应
返回 lighty.RESTART_REQUEST

lighty.r.req_attr[] 描述
["uri.scheme"] 修改具有与 mod_extforward 中更改方案类似的效果
如果需要重新处理请求,则 return lighty.RESTART_REQUEST
["uri.authority"] 修改通常应重复到 lighty.r.req_header["Host"]
如果需要重新处理请求,则 return lighty.RESTART_REQUEST
["uri.path"] 不鼓励修改;
源自 ["request.uri"],URL 解码并简化路径;
优先修改 ["request.uri"]return lighty.RESTART_REQUEST
["uri.query"] 修改影响其他模块后续对查询字符串的使用
如果需要重新处理请求,优先修改 ["request.uri"]return lighty.RESTART_REQUEST
["request.uri"] 修改具有与使用 mod_rewrite 类似的效果,之后应紧跟 return lighty.RESTART_REQUEST
以便 lighttpd 重新处理请求并将其 URI 重新解析为组件。
"request.uri" 可以使用组件重新构建:["request.uri"] = ["uri.path-raw"] "?" ["uri.query"]
["request.orig-uri"] 不鼓励修改
["request.path-info"] 修改影响其他模块后续对 path-info 的使用
如果需要重新处理请求,优先修改 ["request.uri"]return lighty.RESTART_REQUEST
["request.protocol"] 修改更改请求协议,并且只能将 "HTTP/1.1" 降级为 = "HTTP/1.0"
(例如,对于发送 HTTP/1.1 请求但无法处理 Transfer-Encoding: chunked 响应的客户端)
["request.remote-addr"] 修改更改连接上所有后续请求的 remote_addr (!!!)
修改具有与使用 mod_extforward 类似的效果
(尽管 mod_extforward 还会额外更新转发头)
如果需要重新处理请求,则 return lighty.RESTART_REQUEST
(优先使用 lighttpd 1.4.70+ 中按请求管理远程地址的 mod_extforward)
["request.remote-port"] 修改更改连接上所有后续请求的 remote_addr 端口
["physical.doc-root"] 修改影响其他模块后续对 doc_root 的使用
(例如 mod_ssi mod_webdav(有限用作回退))
["physical.basedir"] 修改影响其他模块后续对 basedir 的使用
(例如作为传递给后端脚本的 DOCUMENT_ROOT,除非在其他地方修改)
["physical.path"] 修改影响其他模块后续对 path 的使用
(例如 mod_staticfile 和许多其他基于文件系统的模块)
修改具有与使用 mod_alias 类似的效果
(当脚本从 magnet.attract-physical-path-to 钩子调用时)
["physical.rel-path"] 修改影响其他模块后续对相对路径的使用
(例如 mod_ssi mod_userdir mod_webdav)

["physical.*"] 属性对于从 magnet.attract-physical-path-to 钩子调用的脚本是有效的。这些属性在更早的 magnet 钩子中未定义,在更晚的 magnet 钩子中几乎没有效果。

lighty.r.req_item[] 可读属性(自 1.4.65 起)
  • req_item 提供对选定的 lighttpd 内部请求成员的原始只读访问
  • req_item 值通常是整数;req_attr 值通常是字符串
  • req_item 不可迭代;req_attr 可以使用 pairs() 迭代
  • 取决于 Lua 脚本运行的 magnet 钩子,
    req_item 值可能未设置或可能不是最终值。
lighty.r.req_item[] (备选) 描述
["http_status"] req_item.http_status 请求 HTTP 状态(如果尚未设置则为 0)
["req_header_len"] req_item.req_header_len 请求头长度
["resp_header_len"] req_item.resp_header_len 响应头长度(如果尚未设置则为 0)
["bytes_in"] req_item.bytes_in 请求读取的字节数
["bytes_out"] req_item.bytes_out 请求发送的字节数
["stream_id"] req_item.stream_id HTTP/2 流 ID
["start_time"]() req_item.start_time() 请求开始时间(秒,纳秒)
(注意:函数需要括号 ()
["req_count"] req_item.req_count 连接上启动的请求数
(注意:HTTP/2 流可以并行启动)
["keep_alive"] req_item.keep_alive 请求 keep-alive 状态
(1 keep-alive;0 关闭(或 HTTP/2);-1 关闭,goaway)
lighty.r.req_item[] 可写属性(自 1.4.65 起)
lighty.r.req_item[] (备选) 描述
["keep_alive"] req_item.keep_alive 请求 keep-alive 状态(可设置为 0 或 -1)
(1 keep-alive;0 关闭(或 HTTP/2);-1 关闭,goaway)

.

lighty.server 对象

(自 lighttpd 1.4.65 起)

lighty.r 描述
lighty.server.irequests() 遍历客户端请求
lighty.server.plugin_stats[] 后端模块的统计信息(等同于旧版 API lighty.status
lighty.server.stats[] 服务器统计信息
lighty.server.irequests()(自 1.4.65 起)
  • 遍历客户端请求
  • 注意:迭代器对象在每次迭代时都会重用
    (在迭代之前复制所需的叶节点信息;只保存字符串或数字)
    (迭代器对象在迭代循环外部无效;不要保存迭代器对象)
  • 示例:Lua mod_statusLua mod_evasiveLua mod_uploadprogress
lighty.server.plugin_stats[](自 1.4.65 起)
  • 后端模块的统计信息
    (等同于 lighty.status
    (类似于 mod_status status.statistics-url 的输出)
  • 示例:mod_magnet 可以将统计信息添加到 mod_status 全局统计页面。
    • lighttpd.conf
      server.modules += ("mod_magnet", "mod_status")
      status.statistics-url = "/server-counters"
      magnet.attract-raw-url-to = (server.docroot + "/counter.lua")
    • counter.lua
      local plugin_stats = lighty.server.plugin_stats
      plugin_stats["magnet.connections"] = plugin_stats["magnet.connections"] + 1
    • 访问 /server-counters 的结果
      magnet.connections: 7
      fastcgi.backend.php-foo.0...
      fastcgi.backend.php-foo.1...
      fastcgi.backend.php-foo.load: 0
lighty.server.stats[](自 1.4.65 起)
lighty.server.stats[] 描述
clients_open 打开的客户端连接数
uptime 运行时间(秒)
version 版本字符串

.

lighty.c.* 库函数

(自 lighttpd 1.4.60 起)

-- digests and passwords

lighty.c.time()             -- seconds since 1 Jan 1970 00:00:00 (cached; faster than os.time())
lighty.c.hrtime()           -- (seconds, nanoseconds) since 1 Jan 1970 00:00:00 (high resolution) (since 1.4.65)
lighty.c.rand()             -- generate pseudo-random number
lighty.c.md()               -- calculate message digest (md5,sha1,sha256,sha512)
lighty.c.hmac()             -- calculate HMAC           (md5,sha1,sha256,sha512)
lighty.c.digest_eq()        -- timing-safe comparison of two hex digests
lighty.c.secret_eq()        -- timing-safe comparison of two strings

-- decode/encode

lighty.c.b64urldec()        -- base64url decode (validate and decode)
lighty.c.b64urlenc()        -- base64url encode, no padding
lighty.c.b64dec()           -- base64 decode (validate and decode)
lighty.c.b64enc()           -- base64 encode, no padding
lighty.c.hexdec()           -- hex decode (validate and decode)
lighty.c.hexenc()           -- hex encode uc; lc w/ lua s = s:lower()
lighty.c.xmlenc()           -- xml-encode/html-encode: <>&'\"`
lighty.c.urldec()           -- url-decode
lighty.c.urlenc()           -- url-encode
lighty.c.urldec_query()     -- url-decode query-string into table (since 1.4.65)
lighty.c.urlenc_query()     -- url-encode query-string from table (since 1.4.65)
lighty.c.urlenc_normalize() -- url-encode normalization
lighty.c.fspath_simplify()  -- simplify fspath (remove "/." "/.." "/../" "//")
lighty.c.quoteddec()        -- decode MIME quoted-string (since 1.4.65)
lighty.c.quotedenc()        -- encode input as MIME quoted-string (since 1.4.65)
lighty.c.bsdec()            -- decode backspace-escaped string (since 1.4.65)
lighty.c.bsenc()            -- encode CTLs and non-ASCII input as hex (\xFF) backspace-escaped string (since 1.4.65)
lighty.c.bsenc_json()       -- encode CTLs and non-ASCII input as json (\uFFFF) backspace-escaped string (since 1.4.66)

-- misc

lighty.c.cookie_tokens()    -- parse HTTP Cookie header into table (since 1.4.65)
lighty.c.header_tokens()    -- parse HTTP header into sequence table (since 1.4.65)
lighty.c.readdir()          -- dir walk
lighty.c.readlink()         -- contents of symbolic link (since 1.4.72)
lighty.c.stat()             -- stat() path
消息摘要 (md) 和基于哈希的消息认证码 (HMAC)
(MD5, SHA1, SHA256, SHA512)
lighty.c.md("algo", "data")
lighty.c.hmac("algo", "secret", "data")
  • "algo" 可以是以下之一:"md5", "sha1", "sha256", "sha512"
    (只要 lighttpd 编译时包含支持这些算法的加密库)
  • 返回摘要的大写十六进制字符串
lighty.c.digest_eq("digest1", "digest2")
  • 对两个十六进制摘要执行时间安全、不区分大小写的比较
    (时间安全比较比 digest1 == digest2 稍安全)
  • "digest1" 和 "digest2" 是十六进制字符串(二进制摘要)
  • 返回布尔值 true 或 false
lighty.c.secret_eq("data1", "data2")
  • 对两个字符串执行时间安全比较
    (并尝试隐藏字符串长度的差异)
    (时间安全比较比 data1 == data2 稍安全)
  • "data1" 和 "data2" 是字符串
  • 返回布尔值 true 或 false
解码/编码
lighty.c.b64urldec("base64url-string")
lighty.c.b64urlenc("string") lighty.c.b64dec("base64-string")
lighty.c.b64enc("string") lighty.c.urldec_query("query-string")(自 1.4.65 起)
lighty.c.urlenc_query("query-string")(自 1.4.65 起)
  • 将查询字符串 URL 解码为表,或将表 URL 编码为查询字符串
  • 如果“key”后面没有“=”,则解码后的键的表值为 “”
  • 如果“key=”后面有空白值,则解码后的键的表值为 “”
  • 如果值为 “” ,则编码结果为 "key="
lighty.c.quoteddec("quoted-string")(自 1.4.65 起)
quoteddec:解码输入带引号的字符串
  • (移除周围的双引号,反转义带引号的对 (string.gsub(str, '\\(["\\])?', '%1')))
    (简单的便捷函数;有关更彻底的反斜杠转义解码,请参阅 lighty.c.bsdec
    quotedenc:将输入编码为带引号的字符串
  • (反斜杠转义 "\ 为带引号的对 (string.gsub(str, '(["\\])', '\\%1')),然后用双引号括起来)
    (简单的便捷函数;有关更彻底的反斜杠转义编码,请参阅 lighty.c.bsenc
    lighty.c.bsdec("escaped-string")(自 1.4.65 起)
解码反斜杠转义的字符串
  • (解码 \", \\, \n(以及其他知名 CTL \-转义),八进制 \000, 十六进制 \xFF, json \uFFFF)(json 自 1.4.66 起)
    (如果存在,移除输入周围的双引号)
    lighty.c.bsenc("string")(自 1.4.65 起)
将控制字符或非 ASCII 输入编码为十六进制 (\xFF) 反斜杠转义字符串(或知名 CTL \-转义,例如 \n
  • 输入中的双引号 (") 和反斜杠 (\) 也会被反斜杠转义
  • 结果不包含周围的双引号;调用者应酌情添加
  • lighty.c.bsenc_json("string")(自 1.4.66 起)
将控制字符或非 ASCII 输入编码为 json (\uFFFF) 反斜杠转义字符串(或知名 CTL \-转义,例如 \n
  • 杂项
  • 结果不包含周围的双引号;调用者应酌情添加
  • lighty.c.bsenc_json("string")(自 1.4.66 起)
lighty.c.cookie_tokens("cookie-string")(自 1.4.65 起)
将 HTTP Cookie 头解析为表(注意:带引号的字符串原样保留;不解码)
  • local cookies = lighty.c.cookie_tokens(lighty.r.req_header['Cookie'])
  • local identity = lighty.c.urldec(cookies["ident"])
    lighty.c.header_tokens("header-string")(自 1.4.65 起)
将 HTTP 头解析为序列表(注意:带引号的字符串原样保留;不解码)
  • 序列表包含单词/标记和分隔符(, ; =)作为单独的元素
  • (可选空白 (OWS) 和错误空白 (BWS) 已移除)
    local tokens = lighty.c.header_tokens(lighty.r.req_header['Accept-Encoding'])
  • for i = 1, #tokens do tok = lighty.c.quoteddec(tokens[i]) ......... end
  • Accept-Encoding 的情况下,每个编码可能可选地包含 ;q=0.x 质量,
    这将在 tokens 表中显示为多个元素(; q = 0.x
    lighty.c.readdir("/path/to/dir")
目录遍历
  • 为方便起见跳过 "." 或 ".."
  • for name in lighty.c.readdir("/tmp") do r.resp_body:add({name, "\n"}) end
  • lighty.c.readlink("/path/to/softlink")(自 1.4.72 起)
返回 readlink 调用中的软链接内容,未缓存
  • lighty.c.stat("/path")
检查文件/目录/套接字是否存在并返回其 stat() 信息
  • 使用 lighttpd 内部 stat-cache
  • path: (字符串) 绝对路径
  • 返回:包含以下字段的表,或错误时返回 nil
  • is_file
    • is_dir
    • is_char
    • is_block
    • is_socket
    • is_link
    • is_fifo
    • st_mode
    • st_mtime
    • st_ctime
    • st_atime
    • st_uid
    • st_gid
    • st_size
    • st_ino
    • etag
    • content-type
    • http-response-send-file(类似于 mod_staticfile)(自 1.4.64 起)
    • st_mtim()(返回秒数,纳秒)(自 1.4.65 起)
    • st_ctim()(返回秒数,纳秒)(自 1.4.65 起)
    • st_atim()(返回秒数,纳秒)(自 1.4.65 起)
    • lighttpd.conf 配置条件等价物

lighttpd.conf 配置条件 mod_magnet lua 等价物

lighttpd.conf 配置条件

mod_magnet lua 等价物 $HTTP["request-method"]
lighty.r.req_attr["request.method"] $HTTP["scheme"]
lighty.r.req_attr["uri.scheme"] $HTTP["host"]
lighty.r.req_attr["uri.authority"] $HTTP["url"]
lighty.r.req_attr["uri.path"] lighty.r.req_attr["uri.path-raw"]
$HTTP["querystring"]
lighty.r.req_attr["uri.query"] $HTTP["remoteip"]
lighty.r.req_attr["request.remote-addr"] lighty.r.req_attr["request.remote-port"]
$SERVER["socket"]
lighty.r.req_attr["request.server-addr"] lighty.r.req_attr["request.server-port"]
$REQUEST_HEADER["..."]
lighty.r.req_header["..."] $HTTP["cookie"]
lighty.r.req_header["Cookie"] $HTTP["useragent"]
lighty.r.req_header["User-Agent"] $HTTP["language"]
lighty.r.req_header["Accept-Language"] $HTTP["referer"]
lighty.r.req_header["Referer"] 在 mod_magnet 阶段 magnet.attract-physical-path-to
物理路径
lighty.r.req_attr["physical.path"] 物理路径存在
lighty.c.stat(...) 已弃用

 

mod_magnet API (lighttpd 1.4.60 以前版本)

 

(注意:此旧版 API 已弃用。请优先使用 lighty.r 请求对象

lighty.*

mod_magnet 和 lighttpd 之间的大部分交互都是通过表完成的。Lua 中的表类似于哈希(Perl、Ruby)、字典(Java、Python)、关联数组(PHP)等。以下表支持 pairs() 来迭代其条目。

lighty.request[] - 某些请求头如 Host、Cookie 或 User-Agent 可用(推荐:lighty.r.req_header[]
  • lighty.req_env[] - 请求环境变量(推荐:lighty.r.req_env[]
  • lighty.env[] - 请求属性(推荐:lighty.r.req_attr[])(请参阅 lighty.r 请求对象
  • lighty.header[] - 某些响应头如 Location 可用(推荐:lighty.r.resp_header[]
  • lighty.content[] - 响应体(推荐:lighty.r.resp_body.set()
  • lighty.status[] - 统计信息(推荐:lighty.server.plugin_stats[]
  • lighty.header[](推荐:lighty.r.resp_header[]
如果要为请求设置响应头,可以向 lighty.header[] 表添加字段

lighty.header["Content-Type"] = "text/html"
lighty.content[](推荐:lighty.r.resp_body.set()

您可以生成自己的内容并将其作为响应发送。lighty.content[] 表可以包含字符串或文件信息表。脚本完成后,响应将通过按顺序连接所有表元素来生成。

字符串 - 复制到响应中

  • 表 - 表示响应的文件信息
  • filename = "<absolute-path>" 是必需的
    • offset = <number> [默认值: 0]
    • length = <number> [默认值: 文件大小]
    • 这将发送文件的范围 [offset, length-1]。
      (“length”参数命名不当,实际上表示范围偏移量 + 1;为了与现有脚本的历史兼容性而保持不变)
      移植 mod_cml 脚本
lighty.content = { "<pre>", { filename = "/etc/motd" }, "</pre>" }
lighty.header["Content-Type"] = "text/html" 
return 200

mod_cml 已被 mod_magnet 取代。

mod_cml 函数 memcache_get_string() memcache_get_long() memcache_exists()(以及 lighttpd.conf cml.memcache-hosts)应替换为仅限 Lua 的解决方案
  • mod_cml 中的 CACHE_HIT
  • output_include = { "file1", "file2" }
    return CACHE_HIT
    在 mod_magnet 中变为
    lighty.r.resp_body.set({ { filename = "/path/to/file1" }, { filename = "/path/to/file2"} })
    return 200
    mod_cml 中的 CACHE_MISS
  • trigger_handler = "/index.php"
    return CACHE_MISS
    lighty.r.req_attr["request.uri"] = "/index.php"
    lighty.r.resp_body.set({ { filename = "/path/to/file1" }, { filename = "/path/to/file2"} })
    return lighty.RESTART_REQUEST
    有问题?请在 lighttpd 论坛发帖

文件 (0)

Redmine © 2006-2025 Jean-Philippe Lang 提供技术支持