Skip to content

mod_lua: Various cleanups. - #1022

Open
notroj wants to merge 18 commits into
apache:trunkfrom
notroj:lua-wsread-mem
Open

notroj wants to merge 18 commits into
apache:trunkfrom
notroj:lua-wsread-mem

Conversation

@notroj

@notroj notroj commented Nov 13, 2026

Copy link
Copy Markdown
Collaborator

Caps the memory used by mod_lua request methods within a request. r:wsread() and many other methods allocated their results from r->pool, so memory use scaled with the number of calls a script made; r:requestbody() allocated the declared Content-Length up front rather than as the body arrived.

Request methods are now dispatched through a wrapper, req_call(), which destroys the temporary pool returned by lua_temp_pool() when the method returns, and methods allocate their scratch memory from that instead of r->pool. The wrapper restores any outer call's pool afterwards, since a method can run filters which call back into Lua for the same request. r:base64_encode() and r:base64_decode() now refuse strings over 8MB (MODLUA_MAX_BASE64, overridable at build time).

Also included: r:wsread() handling of partial, empty and control frames; r:wspeek() no longer consumes input; r:regex() returns all 25 capture groups it accepts; r:scoreboard_worker() and r.mpm_query() return nil for invalid arguments; r:set_document_root() and r:set_context_info() copy their strings; r:requestbody() applies its size limit when writing to a file; and r.limit_req_body and r.started are no longer truncated to int. Each change is its own commit, covered by the new test/modules/lua suite.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* modules/lua/lua_request.c (lua_temp_ctx_t, lua_temp_ctx,
  lua_temp_pool, req_call): New.
  (req_dispatch): Push request methods as a req_call closure.
  (lua_websocket_read): Allocate from the temporary pool, and the mask
  on the stack.

* changes-entries/lua-wsread-memory.txt: Add.

Fixes: 731d18d (SVN r1522030)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  the requested length has been read.

* changes-entries/lua-fixes.txt: Add.

Fixes: 11a3fcb (SVN r1901502)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  frames; answer a ping with its payload; skip a pong; stop at a close
  frame, an unmasked frame or an oversized control frame; check the
  64-bit length before narrowing it.

* changes-entries/lua-fixes.txt: Update.

Fixes: 731d18d (SVN r1522030)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  the matches array to ap_regexec().

* changes-entries/lua-fixes.txt: Update.

Fixes: 49fcd96 (SVN r1433967)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* modules/lua/lua_request.c (lua_ap_regex): Free the compiled
  pattern, push captures without copying them into r->pool, and use
  a stack buffer for error messages.

* changes-entries/lua-wsread-memory.txt: Update.

Fixes: 3b6cdb0 (SVN r1420377)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  lua_ap_set_context_info): Copy the strings into r->pool.

* changes-entries/lua-fixes.txt: Update.

Fixes: 3b6cdb0 (SVN r1420377)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* modules/lua/lua_request.c (req_construct_url, req_escape_html,
  lua_apr_b64encode, lua_apr_b64decode, lua_ap_unescape,
  lua_ap_escape, lua_apr_htpassword, lua_ap_expr,
  lua_ap_runtime_dir_relative, lua_ap_getdir, lua_ap_os_escape_path,
  lua_ap_escape_logitem, lua_ivm_get, lua_ivm_set): Allocate from the
  temporary pool.

* changes-entries/lua-wsread-memory.txt: Update.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* modules/lua/lua_request.c (lua_apr_md5): Hash with apr_md5_update()
  into a stack buffer.
  (lua_apr_sha1, lua_ap_scoreboard_worker): Use stack buffers.
  (read_cfg_tree): Drop the request_rec argument; build the directive
  string with lua_pushfstring().
  (lua_ap_get_config, lua_ap_get_active_config): Adjust.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* modules/lua/lua_request.c (req_table): New function.
  (req_headers_in, req_headers_out, req_err_headers_out,
  req_subprocess_env, req_notes): Use it.
  (req_flags_string): New function.
  (lua_ap_options, lua_ap_allowoverrides): Rebuild the string only
  when the flags change.

* test/modules/lua/test_003_request.py (test_lua_003_04_fields): New
  test.

* test/modules/lua/htdocs/test1/lua/fields.lua: New file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  test_lua_001_08_wspeek_read): New tests.

* test/modules/lua/htdocs/test1/lua/wsread.lua (handle): Answer "peek"
  and "peekread".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  read, return false for an empty brigade, and allocate from the
  temporary pool.

* changes-entries/lua-fixes.txt: Update.

Fixes: c92f2cf (SVN r1570208)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* modules/lua/lua_request.c (lua_ap_sendfile): Allocate the file and
  brigade from the temporary pool in place of ap_send_fd(); fail if
  apr_stat() fails.

* test/modules/lua/test_003_request.py (test_lua_003_05_sendfile):
  New test.

* test/modules/lua/htdocs/test1/lua/sendfile.lua,
  test/modules/lua/htdocs/test1/lua/file.txt: New files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test/modules/lua/test_003_request.py (test_lua_003_06_limit_req_body,
  test_lua_003_07_mpm_query_unknown,
  test_lua_003_08_scoreboard_worker_range): New tests.

* test/modules/lua/htdocs/test1/lua/body.lua,
  test/modules/lua/htdocs/test1/lua/info.lua: New files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* modules/lua/lua_request.c (lua_read_body): Collect the body as it
  arrives rather than allocating the Content-Length up front; refuse
  a length which does not fit in an apr_size_t; return only OK, DONE
  or an HTTP status.
  (lua_write_body): Take the filename and open the file, truncating
  it, after checking the length against a new maxsize argument; drop
  the apr_size_t cast; fail on a short read; return only OK, DONE or
  an HTTP status; set *size to the bytes written.
  (lua_ap_requestbody): Return nil and a message for a body over the
  limit when storing it to a file too.
  (req_parsebody): Terminate the buffer at the flattened length.

* changes-entries/lua-wsread-memory.txt,
  changes-entries/lua-fixes.txt: Update.

Fixes: 1a50285 (SVN r1420286)
Fixes: 49fcd96 (SVN r1433967)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  for indexes outside the scoreboard.
  (lua_ap_mpm_query): Return nothing if the query fails.

Fixes: b2605d2 (SVN r1610491)
Fixes: 49fcd96 (SVN r1433967)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* modules/lua/lua_request.c (req_dispatch): Handle it.
  (lua_ap_started, lua_ap_limit_req_body): Return apr_int64_t, and
  register as APL_REQ_FUNTYPE_INT64.

* test/modules/lua/test_003_request.py (test_lua_003_09_started): New
  test.

Fixes: 2e9e74f (SVN r1370158)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  (lua_apr_b64encode, lua_apr_b64decode): Refuse a string longer than
  MODLUA_MAX_BASE64.
  (lua_apr_sha1): Pass the string to apr_sha1_update() in pieces which
  fit its length argument.

* test/modules/lua/test_003_request.py (test_lua_003_10_digests,
  test_lua_003_11_base64_max): New tests.

* test/modules/lua/htdocs/test1/lua/info.lua: Add md5, sha1 and
  base64_max.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant