-
Notifications
You must be signed in to change notification settings - Fork 1.4k
feat(http): add Lua script handler #856
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
b30b3d2
feat(http): add lua script handler
ithewei 0df28bc
fix(lua): detect Homebrew Lua 5.5
ithewei 74ea46b
refactor(http): add generic script handler entry
ithewei 4b6fc59
refactor(examples): fold lua routes into http_server_test
ithewei 3254032
refactor(http): simplify script path traversal check
ithewei e66be55
fix(http): make handler copy preserve callbacks
ithewei 5e4744e
refactor(cmake): simplify lua detection
ithewei e492437
feat(lua): dispatch handlers by http method
ithewei 1c161b7
test(lua): add method examples to hello script
ithewei c7fdb1a
refactor(http): rename lua handler type
ithewei a54c64e
chore: format
ithewei 3b4bddc
fix(http): address lua handler review comments
ithewei File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ | |
| - mqtt client | ||
| - redis client | ||
| - async DNS | ||
| - http lua handler | ||
|
|
||
| ## Plan | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,140 @@ | ||
| # Http Lua Handler | ||
|
|
||
| `HttpScriptHandler` 允许 `HttpService` 调用脚本里的 `handle(ctx)` 方法处理 HTTP 请求。当前支持 `.lua` 脚本,适合把少量业务逻辑从 C++ 编译周期里解耦出来:修改脚本后无需重新编译服务,下一次请求会自动加载新脚本。 | ||
|
|
||
| 该功能是可选模块,默认不编译。 | ||
|
|
||
| ## 编译 | ||
|
|
||
| 需要 Lua 5.3 或更新版本的开发库。 | ||
|
|
||
| Makefile: | ||
|
|
||
| ```bash | ||
| make libhv WITH_LUA=yes | ||
| make http_server_test WITH_LUA=yes | ||
| make unittest WITH_LUA=yes | ||
| ``` | ||
|
|
||
| 如果系统没有 `pkg-config`,或者 Lua 安装在自定义路径,可以显式指定: | ||
|
|
||
| ```bash | ||
| make libhv WITH_LUA=yes \ | ||
| LUA_CFLAGS="-I/usr/local/include/lua" \ | ||
| LUA_LIBS="-L/usr/local/lib -llua" | ||
| ``` | ||
|
|
||
| CMake: | ||
|
|
||
| ```bash | ||
| cmake -S . -B build -DWITH_LUA=ON -DBUILD_EXAMPLES=ON -DBUILD_UNITTEST=ON | ||
| cmake --build build | ||
| ``` | ||
|
|
||
| ## 基本用法 | ||
|
|
||
| C++: | ||
|
|
||
| ```cpp | ||
| #include "HttpServer.h" | ||
| #include "HttpScriptHandler.h" | ||
|
|
||
| using namespace hv; | ||
|
|
||
| int main() { | ||
| HttpService router; | ||
| router.GET("/hello", HttpScriptHandler("scripts/hello.lua")); | ||
|
|
||
| HttpServer server; | ||
| server.port = 8080; | ||
| server.service = &router; | ||
| server.run(); | ||
| return 0; | ||
| } | ||
| ``` | ||
|
|
||
| Lua: | ||
|
|
||
| ```lua | ||
| function handle(ctx) | ||
| local id = ctx:query("id", "") | ||
| return ctx:json({ | ||
| ok = true, | ||
| id = id, | ||
| path = ctx:path() | ||
| }) | ||
| end | ||
| ``` | ||
|
|
||
| 如果需要明确指定 Lua 引擎,也可以直接使用 `HttpLuaHandler("scripts/hello.lua")`。推荐用户代码优先使用 `HttpScriptHandler`,这样后续增加 JS/Python 等脚本引擎时不用改路由注册代码。 | ||
|
|
||
| ## 目录映射 | ||
|
|
||
| `HttpService::Script(path, script_dir)` 可以把 URL 前缀映射到脚本目录,内部同样使用 `HttpScriptHandler`: | ||
|
|
||
| ```cpp | ||
| router.Script("/script/", "scripts"); | ||
| ``` | ||
|
|
||
| 访问 `/script/user?id=42` 时会调用 `scripts/user.lua`。访问 `/script/` 时会调用 `scripts/index.lua`。当前目录映射只自动补 `.lua` 后缀。 | ||
|
|
||
| 目录映射默认支持 `GET`、`POST`、`PUT`、`DELETE`、`PATCH`。路径中包含 `..` 路径段时返回 `403`。 | ||
|
|
||
| ## ctx API | ||
|
|
||
| 首版只暴露 HTTP handler 必需的最小 API: | ||
|
|
||
| ```lua | ||
| ctx:method() -- GET/POST/... | ||
| ctx:path() -- URL path | ||
| ctx:param(name, default) -- query/restful params | ||
| ctx:query(name, default) -- alias of param | ||
| ctx:header(name, default) | ||
| ctx:body() | ||
|
|
||
| ctx:status(code) | ||
| ctx:set_header(name, value) | ||
| ctx:text(str) | ||
| ctx:json(table) | ||
| ``` | ||
|
|
||
| `handle(ctx)` 可以直接调用 `ctx:text` / `ctx:json` 返回,也可以返回字符串、数字状态码或 Lua table: | ||
|
|
||
| ```lua | ||
| function handle(ctx) | ||
| ctx:status(201) | ||
| ctx:set_header("X-From", "lua") | ||
| return ctx:text("created") | ||
| end | ||
| ``` | ||
|
|
||
| ## hv API | ||
|
|
||
| 首版只提供少量宿主能力: | ||
|
|
||
| ```lua | ||
| hv.log(...) | ||
| hv.now() | ||
| ``` | ||
|
|
||
| 暂不暴露 `hv.event_loop`、TCP/HTTP client、Redis 等能力,避免脚本直接操作底层事件循环。后续可以按业务需要增加受控的 `hv.redis`、`hv.http` 等模块。 | ||
|
|
||
| ## 热更新 | ||
|
|
||
| `HttpScriptHandler` 当前会把 `.lua` 文件转给 `HttpLuaHandler`。`HttpLuaHandler` 会记录脚本文件的 `mtime`。每次请求前,如果文件被修改,会重新加载脚本。 | ||
|
|
||
| 重新加载失败时: | ||
|
|
||
| - 如果已有旧版本脚本,继续使用旧版本。 | ||
| - 如果首次加载失败,返回 `500`。 | ||
|
|
||
| 这能避免线上脚本语法错误直接打断已有服务。 | ||
|
|
||
| ## 示例 | ||
|
|
||
| ```bash | ||
| make http_server_test WITH_LUA=yes | ||
| bin/http_server_test 8080 | ||
| curl "http://127.0.0.1:8080/lua/hello?id=42" | ||
| curl "http://127.0.0.1:8080/script/hello?id=42" | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| function get(ctx) | ||
| hv.log("lua get", ctx:path()) | ||
| return ctx:json({ | ||
| ok = true, | ||
| method = "GET", | ||
| path = ctx:path(), | ||
| id = ctx:query("id", "") | ||
| }) | ||
| end | ||
|
|
||
| function post(ctx) | ||
| hv.log("lua post", ctx:path()) | ||
| return ctx:text("POST " .. ctx:body()) | ||
| end | ||
|
|
||
| function handle(ctx) | ||
| hv.log("lua fallback", ctx:method(), ctx:path()) | ||
| return ctx:json({ | ||
| ok = true, | ||
| method = ctx:method(), | ||
| path = ctx:path() | ||
| }) | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -100,4 +100,6 @@ | |
| #cmakedefine WITH_KCP 1 | ||
| #cmakedefine WITH_IO_URING 1 | ||
|
|
||
| #cmakedefine WITH_LUA 1 | ||
|
|
||
| #endif // HV_CONFIG_H_ | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.