- 新增 lua-embed-analysis.md 技术分析文档 - 新增 lua-nginx-module 文档目录 - 更新 gitignore 允许跟踪 docs/lua-nginx-module/ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
454 lines
9.8 KiB
Markdown
454 lines
9.8 KiB
Markdown
# lua-nginx-module ngx.* Lua API 参考
|
||
|
||
本文档详细列出 lua-nginx-module 暴露给 Lua 的所有 API。
|
||
|
||
## API 注入点
|
||
|
||
所有 API 通过 `ngx_http_lua_inject_ngx_api` 函数注入到 `ngx` 全局表。
|
||
|
||
**源文件**: `src/ngx_http_lua_util.c:835`
|
||
|
||
### 注入函数列表
|
||
|
||
| 注入函数 | 文件 | 说明 |
|
||
|---------|------|------|
|
||
| `ngx_http_lua_inject_arg_api` | ngx_http_lua_util.c | 命令行参数 |
|
||
| `ngx_http_lua_inject_http_consts` | ngx_http_lua_consts.c | HTTP 方法/状态码常量 |
|
||
| `ngx_http_lua_inject_core_consts` | ngx_http_lua_consts.c | 核心常量 |
|
||
| `ngx_http_lua_inject_log_api` | ngx_http_lua_log.c | 日志 API |
|
||
| `ngx_http_lua_inject_output_api` | ngx_http_lua_output.c | 输出控制 |
|
||
| `ngx_http_lua_inject_control_api` | ngx_http_lua_control.c | 控制流 |
|
||
| `ngx_http_lua_inject_subrequest_api` | ngx_http_lua_subrequest.c | 子请求 |
|
||
| `ngx_http_lua_inject_req_api` | ngx_http_lua_util.c | 请求 API |
|
||
| `ngx_http_lua_inject_resp_header_api` | ngx_http_lua_headers.c | 响应头 |
|
||
| `ngx_http_lua_inject_shdict_api` | ngx_http_lua_shdict.c | 共享字典 |
|
||
| `ngx_http_lua_inject_socket_tcp_api` | ngx_http_lua_socket_tcp.c | TCP socket |
|
||
| `ngx_http_lua_inject_socket_udp_api` | ngx_http_lua_socket_udp.c | UDP socket |
|
||
| `ngx_http_lua_inject_uthread_api` | ngx_http_lua_uthread.c | 用户线程 |
|
||
| `ngx_http_lua_inject_timer_api` | ngx_http_lua_timer.c | 定时器 |
|
||
| `ngx_http_lua_inject_coroutine_api` | ngx_http_lua_coroutine.c | 协程 |
|
||
|
||
---
|
||
|
||
## 一、ngx.req.* - 请求操作 API
|
||
|
||
### 1.1 URI 操作
|
||
|
||
#### `ngx.req.set_uri(uri, jump?, binary?)`
|
||
|
||
设置请求 URI。
|
||
|
||
- **参数**:
|
||
- `uri` (string): 新的 URI
|
||
- `jump` (boolean, 可选): 是否执行内部跳转
|
||
- `binary` (boolean, 可选): 是否二进制安全
|
||
- **返回值**: 无或 yield
|
||
- **适用阶段**: rewrite, server_rewrite
|
||
- **示例**:
|
||
```lua
|
||
ngx.req.set_uri("/new/path", true) -- 内部跳转
|
||
ngx.req.set_uri("/api/v2" .. ngx.var.request_uri) -- 重写
|
||
```
|
||
|
||
### 1.2 参数操作
|
||
|
||
#### `ngx.req.get_uri_args(max_args?)`
|
||
|
||
获取 URL 查询参数。
|
||
|
||
- **参数**: `max_args` (number, 可选, 默认 100)
|
||
- **返回值**: table (参数键值对,多值参数为数组)
|
||
- **示例**:
|
||
```lua
|
||
local args = ngx.req.get_uri_args()
|
||
-- URL: /test?foo=bar&foo=baz&name=john
|
||
-- args.foo = {"bar", "baz"}
|
||
-- args.name = "john"
|
||
```
|
||
|
||
#### `ngx.req.get_post_args(max_args?)`
|
||
|
||
获取 POST 表单参数。
|
||
|
||
- **参数**: `max_args` (number, 可选, 默认 100)
|
||
- **返回值**: table
|
||
- **前提**: 需要 `lua_need_request_body on` 或先调用 `ngx.req.read_body()`
|
||
|
||
#### `ngx.req.set_uri_args(args)`
|
||
|
||
设置 URL 查询参数。
|
||
|
||
- **参数**: `args` (string/number/table)
|
||
- **示例**:
|
||
```lua
|
||
ngx.req.set_uri_args({foo = "bar", page = 1})
|
||
ngx.req.set_uri_args("foo=bar&page=1")
|
||
```
|
||
|
||
### 1.3 请求头操作
|
||
|
||
#### `ngx.req.get_headers(max_headers?, raw?)`
|
||
|
||
获取请求头。
|
||
|
||
- **参数**:
|
||
- `max_headers` (number, 可选)
|
||
- `raw` (boolean, 可选): 是否保留原始大小写
|
||
- **返回值**: table
|
||
- **示例**:
|
||
```lua
|
||
local headers = ngx.req.get_headers()
|
||
local content_type = headers["Content-Type"]
|
||
local host = headers.host or headers.Host
|
||
```
|
||
|
||
#### `ngx.req.set_header(header_name, header_value)`
|
||
|
||
设置请求头。
|
||
|
||
- **参数**:
|
||
- `header_name` (string)
|
||
- `header_value` (string/table/nil)
|
||
- **示例**:
|
||
```lua
|
||
ngx.req.set_header("X-Custom", "value")
|
||
ngx.req.set_header("X-Multi", {"val1", "val2"})
|
||
ngx.req.set_header("X-Remove", nil) -- 删除
|
||
```
|
||
|
||
#### `ngx.req.clear_header(header_name)`
|
||
|
||
清除请求头。
|
||
|
||
### 1.4 请求体操作
|
||
|
||
#### `ngx.req.read_body()`
|
||
|
||
异步读取请求体。
|
||
|
||
- **返回值**: 无或 yield
|
||
- **适用阶段**: rewrite, access, content
|
||
|
||
#### `ngx.req.get_body_data(max?)`
|
||
|
||
获取请求体数据。
|
||
|
||
- **参数**: `max` (number, 可选)
|
||
- **返回值**: string 或 nil
|
||
|
||
#### `ngx.req.get_body_file()`
|
||
|
||
获取请求体临时文件路径。
|
||
|
||
- **返回值**: string 或 nil
|
||
|
||
#### `ngx.req.discard_body()`
|
||
|
||
丢弃请求体。
|
||
|
||
#### `ngx.req.set_body_data(data)`
|
||
|
||
设置请求体数据。
|
||
|
||
#### `ngx.req.set_body_file(file_path, auto_clean?)`
|
||
|
||
设置请求体文件。
|
||
|
||
### 1.5 其他请求信息
|
||
|
||
#### `ngx.req.http_version()`
|
||
|
||
获取 HTTP 版本。
|
||
|
||
- **返回值**: number (0.9, 1.0, 1.1, 2.0, 3.0) 或 nil
|
||
|
||
#### `ngx.req.raw_header(no_request_line?)`
|
||
|
||
获取原始请求头字符串。
|
||
|
||
- **参数**: `no_request_line` (boolean)
|
||
- **返回值**: string
|
||
|
||
#### `ngx.req.get_method()`
|
||
|
||
获取请求方法。
|
||
|
||
- **返回值**: string ("GET", "POST", etc.)
|
||
|
||
#### `ngx.req.set_method(method)`
|
||
|
||
设置请求方法。
|
||
|
||
#### `ngx.req.is_internal()`
|
||
|
||
判断是否内部请求。
|
||
|
||
- **返回值**: boolean
|
||
|
||
---
|
||
|
||
## 二、ngx.resp.* - 响应操作 API
|
||
|
||
#### `ngx.resp.get_headers(max_headers?, raw?)`
|
||
|
||
获取响应头。
|
||
|
||
- **参数**:
|
||
- `max_headers` (number, 可选)
|
||
- `raw` (boolean, 可选)
|
||
- **返回值**: table
|
||
|
||
---
|
||
|
||
## 三、输出控制 API
|
||
|
||
### `ngx.say(...)`
|
||
|
||
输出内容并附加换行符。
|
||
|
||
- **参数**: 可变参数 (string/number/boolean/table/nil)
|
||
- **返回值**: 1 (成功) 或 nil, err
|
||
- **适用阶段**: rewrite, access, content, precontent
|
||
- **示例**:
|
||
```lua
|
||
ngx.say("Hello, ", "World!")
|
||
ngx.say({name = "test", value = 123}) -- 输出 table
|
||
```
|
||
|
||
### `ngx.print(...)`
|
||
|
||
输出内容,不附加换行符。
|
||
|
||
### `ngx.flush(wait?)`
|
||
|
||
刷新输出缓冲区。
|
||
|
||
- **参数**: `wait` (boolean, 可选)
|
||
- **返回值**: 1, nil+err, 或 yield
|
||
|
||
### `ngx.eof()`
|
||
|
||
发送 EOF,结束响应。
|
||
|
||
### `ngx.send_headers()`
|
||
|
||
显式发送响应头。
|
||
|
||
### `ngx.exit(status)`
|
||
|
||
结束请求处理。
|
||
|
||
- **参数**: `status` (number) - HTTP 状态码或 ngx.ERROR 等
|
||
- **示例**:
|
||
```lua
|
||
ngx.exit(ngx.HTTP_NOT_FOUND) -- 404
|
||
ngx.exit(ngx.HTTP_OK) -- 正常结束
|
||
ngx.exit(ngx.ERROR) -- 错误
|
||
```
|
||
|
||
---
|
||
|
||
## 四、日志 API
|
||
|
||
### `ngx.log(level, ...)`
|
||
|
||
记录日志。
|
||
|
||
- **参数**:
|
||
- `level`: 日志级别常量
|
||
- `...`: 可变参数
|
||
- **示例**:
|
||
```lua
|
||
ngx.log(ngx.ERR, "error message: ", err)
|
||
ngx.log(ngx.INFO, "request from: ", ngx.var.remote_addr)
|
||
```
|
||
|
||
### 日志级别常量
|
||
|
||
| 常量 | 值 | 说明 |
|
||
|------|---|------|
|
||
| `ngx.STDERR` | 0 | 标准错误 |
|
||
| `ngx.EMERG` | 1 | 紧急 |
|
||
| `ngx.ALERT` | 2 | 警报 |
|
||
| `ngx.CRIT` | 3 | 严重 |
|
||
| `ngx.ERR` | 4 | 错误 |
|
||
| `ngx.WARN` | 5 | 警告 |
|
||
| `ngx.NOTICE` | 6 | 通知 |
|
||
| `ngx.INFO` | 7 | 信息 |
|
||
| `ngx.DEBUG` | 8 | 调试 |
|
||
|
||
### `print(...)`
|
||
|
||
全局函数,等效于 `ngx.log(ngx.NOTICE, ...)`
|
||
|
||
---
|
||
|
||
## 五、控制流 API
|
||
|
||
### `ngx.exec(uri, args?)`
|
||
|
||
内部重定向。
|
||
|
||
- **参数**:
|
||
- `uri` (string): 目标 URI
|
||
- `args` (string/table/nil): 参数
|
||
- **示例**:
|
||
```lua
|
||
ngx.exec("/internal/api", {foo = "bar"})
|
||
```
|
||
|
||
### `ngx.redirect(uri, status?)`
|
||
|
||
HTTP 重定向。
|
||
|
||
- **参数**:
|
||
- `uri` (string): 目标 URL
|
||
- `status` (number): HTTP 状态码 (默认 302)
|
||
- **可选状态**: 301, 302, 303, 307, 308
|
||
- **示例**:
|
||
```lua
|
||
ngx.redirect("https://example.com/new")
|
||
ngx.redirect("/login", ngx.HTTP_MOVED_TEMPORARILY)
|
||
```
|
||
|
||
### `ngx.on_abort(callback)`
|
||
|
||
注册客户端断开连接回调。
|
||
|
||
---
|
||
|
||
## 六、子请求 API
|
||
|
||
### `ngx.location.capture(uri, options?)`
|
||
|
||
发起单个子请求。
|
||
|
||
- **参数**:
|
||
- `uri` (string): 内部 URI
|
||
- `options` (table, 可选):
|
||
- `method`: HTTP 方法常量
|
||
- `args`: 参数字符串/table
|
||
- `body`: 请求体
|
||
- `headers`: 请求头 table
|
||
- `vars`: 变量 table
|
||
- `share_all_vars`: boolean
|
||
- `copy_all_vars`: boolean
|
||
- `always_forward_body`: boolean
|
||
- `ctx`: Lua table
|
||
- **返回值**: table {status, header, body, truncated}
|
||
- **适用阶段**: rewrite, access, content
|
||
- **示例**:
|
||
```lua
|
||
local res = ngx.location.capture("/api/users", {
|
||
method = ngx.HTTP_POST,
|
||
body = '{"name":"john"}',
|
||
headers = {["Content-Type"] = "application/json"}
|
||
})
|
||
ngx.say("Status: ", res.status)
|
||
ngx.say("Body: ", res.body)
|
||
```
|
||
|
||
### `ngx.location.capture_multi(requests)`
|
||
|
||
并发发起多个子请求。
|
||
|
||
- **参数**: `requests` (array of {uri, options?})
|
||
- **返回值**: array of response tables
|
||
- **示例**:
|
||
```lua
|
||
local res1, res2 = ngx.location.capture_multi({
|
||
{"/api/users"},
|
||
{"/api/products", {method = ngx.HTTP_GET}}
|
||
})
|
||
```
|
||
|
||
---
|
||
|
||
## 七、变量访问 API
|
||
|
||
### `ngx.var.VARIABLE_NAME`
|
||
|
||
读写 nginx 变量。
|
||
|
||
- **读取**: `local value = ngx.var.host`
|
||
- **写入**: `ngx.var.my_var = "value"`
|
||
- **删除**: `ngx.var.my_var = nil`
|
||
|
||
**内部实现**: 通过 FFI 函数 `ngx_http_lua_ffi_var_get` 和 `ngx_http_lua_ffi_var_set`
|
||
|
||
---
|
||
|
||
## 八、请求上下文 API
|
||
|
||
### `ngx.ctx`
|
||
|
||
当前请求的 Lua 表,可在请求各阶段共享数据。
|
||
|
||
- **特点**:
|
||
- 每个请求独立
|
||
- 子请求有独立的 ctx(除非显式传递)
|
||
- 请求结束时自动清理
|
||
- **示例**:
|
||
```lua
|
||
-- access_by_lua
|
||
ngx.ctx.user_id = 123
|
||
|
||
-- content_by_lua (同一请求)
|
||
ngx.say("User: ", ngx.ctx.user_id)
|
||
```
|
||
|
||
---
|
||
|
||
## 九、睡眠 API
|
||
|
||
### `ngx.sleep(seconds)`
|
||
|
||
非阻塞睡眠。
|
||
|
||
- **参数**: `seconds` (number) - 睡眠秒数,支持小数
|
||
- **返回值**: yield
|
||
- **示例**:
|
||
```lua
|
||
ngx.sleep(0.1) -- 睡眠 100ms
|
||
ngx.sleep(1) -- 睡眠 1s
|
||
```
|
||
|
||
---
|
||
|
||
## 十、常量定义
|
||
|
||
### 核心常量
|
||
|
||
| 常量 | 值 | 说明 |
|
||
|------|---|------|
|
||
| `ngx.OK` | 0 | 成功 |
|
||
| `ngx.ERROR` | -1 | 错误 |
|
||
| `ngx.AGAIN` | -2 | 再次 |
|
||
| `ngx.DONE` | -4 | 完成 |
|
||
| `ngx.DECLINED` | -5 | 拒绝 |
|
||
| `ngx.null` | lightuserdata | NULL 值 |
|
||
|
||
### HTTP 状态码常量
|
||
|
||
| 常量 | 值 |
|
||
|------|---|
|
||
| `ngx.HTTP_OK` | 200 |
|
||
| `ngx.HTTP_CREATED` | 201 |
|
||
| `ngx.HTTP_NO_CONTENT` | 204 |
|
||
| `ngx.HTTP_BAD_REQUEST` | 400 |
|
||
| `ngx.HTTP_UNAUTHORIZED` | 401 |
|
||
| `ngx.HTTP_FORBIDDEN` | 403 |
|
||
| `ngx.HTTP_NOT_FOUND` | 404 |
|
||
| `ngx.HTTP_INTERNAL_SERVER_ERROR` | 500 |
|
||
| `ngx.HTTP_SERVICE_UNAVAILABLE` | 503 |
|
||
|
||
### HTTP 方法常量
|
||
|
||
| 常量 | 值 |
|
||
|------|---|
|
||
| `ngx.HTTP_GET` | 2 |
|
||
| `ngx.HTTP_POST` | 8 |
|
||
| `ngx.HTTP_PUT` | 16 |
|
||
| `ngx.HTTP_DELETE` | 32 |
|
||
| `ngx.HTTP_HEAD` | 4 |
|
||
| `ngx.HTTP_PATCH` | 2048 | |