Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/openwrt/luci.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2022-11-03 02:38:00 +0300
committerJo-Philipp Wich <jo@mein.io>2022-11-03 02:38:00 +0300
commite7afd0d327bb35c502ca41a3c5e3ea098898fbd7 (patch)
treec8d082a939d4184f83d588bf5d78164964f96920 /modules
parentf83e4a6c3602a8d840fc25d1a9299d6a941f2370 (diff)
luci-base: fix luci.http.close()
Ensure that `http.write()` or template rendering operations after a call to `http.close()` do not produce additional output. This is required for certain legacy Lua apps which invoke write and close operations in the middle of a server side cbi rendering process. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'modules')
-rw-r--r--modules/luci-base/ucode/dispatcher.uc12
-rw-r--r--modules/luci-base/ucode/http.uc2
-rw-r--r--modules/luci-base/ucode/runtime.uc10
3 files changed, 17 insertions, 7 deletions
diff --git a/modules/luci-base/ucode/dispatcher.uc b/modules/luci-base/ucode/dispatcher.uc
index 86cab9b88f..8ac32c3d1d 100644
--- a/modules/luci-base/ucode/dispatcher.uc
+++ b/modules/luci-base/ucode/dispatcher.uc
@@ -775,7 +775,8 @@ function run_action(request_path, lang, tree, resolved, action) {
break;
case 'call':
- http.write(render(() => {
+ http.write_headers();
+ http.output(render(() => {
runtime.call(action.module, action.function,
...(action.parameters ?? []),
...resolved.ctx.request_args
@@ -789,7 +790,8 @@ function run_action(request_path, lang, tree, resolved, action) {
assert(type(mod[action.function]) == 'function',
`Module '${action.module}' does not export function '${action.function}'`);
- http.write(render(() => {
+ http.write_headers();
+ http.output(render(() => {
call(mod[action.function], mod, runtime.env,
...(action.parameters ?? []),
...resolved.ctx.request_args
@@ -798,7 +800,8 @@ function run_action(request_path, lang, tree, resolved, action) {
break;
case 'cbi':
- http.write(render(() => {
+ http.write_headers();
+ http.output(render(() => {
runtime.call('luci.dispatcher', 'invoke_cbi_action',
action.path, null,
...resolved.ctx.request_args
@@ -807,7 +810,8 @@ function run_action(request_path, lang, tree, resolved, action) {
break;
case 'form':
- http.write(render(() => {
+ http.write_headers();
+ http.output(render(() => {
runtime.call('luci.dispatcher', 'invoke_form_action',
action.path,
...resolved.ctx.request_args
diff --git a/modules/luci-base/ucode/http.uc b/modules/luci-base/ucode/http.uc
index 4856c47a0d..e8982e77a0 100644
--- a/modules/luci-base/ucode/http.uc
+++ b/modules/luci-base/ucode/http.uc
@@ -524,7 +524,7 @@ const Class = {
// If the content chunk is nil this function will automatically invoke close.
write: function(content) {
- if (content != null) {
+ if (content != null && !this.closed) {
this.write_headers();
this.output(content);
diff --git a/modules/luci-base/ucode/runtime.uc b/modules/luci-base/ucode/runtime.uc
index ed330abcc1..da73d13fe4 100644
--- a/modules/luci-base/ucode/runtime.uc
+++ b/modules/luci-base/ucode/runtime.uc
@@ -48,8 +48,10 @@ const Class = {
let bridge = this.env.dispatcher.load_luabridge(optional);
if (bridge) {
+ let http = this.env.http;
+
this.L = bridge.create();
- this.L.set('L', proto({ write: print }, this.env));
+ this.L.set('L', proto({ write: (...args) => http.closed || print(...args) }, this.env));
this.L.invoke('require', 'luci.ucodebridge');
this.env.lua_active = true;
@@ -61,7 +63,11 @@ const Class = {
render_ucode: function(path, scope) {
let tmplfunc = loadfile(path, { raw_mode: false });
- call(tmplfunc, null, scope ?? {});
+
+ if (this.env.http.closed)
+ render(call, tmplfunc, null, scope ?? {});
+ else
+ call(tmplfunc, null, scope ?? {});
},
render_lua: function(path, scope) {