From 4b1a074c95a674f2da154ee627e053db550cdd9d Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Thu, 3 Nov 2022 11:13:30 +0100 Subject: [PATCH] luci-base: dispatcher.uc: only flush HTTP headers after rendering output Ensure to first completely render the action function before flushing HTTP headers since the invoked action logic might modify the HTTP headers itself. Fixes: e7afd0d327 ("luci-base: fix luci.http.close()") Ref: https://github.com/openwrt/luci/commit/e7afd0d327bb35c502ca41a3c5e3ea098898fbd7#commitcomment-88736854 Signed-off-by: Jo-Philipp Wich --- modules/luci-base/ucode/dispatcher.uc | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/modules/luci-base/ucode/dispatcher.uc b/modules/luci-base/ucode/dispatcher.uc index 8ac32c3d1d..89ff391939 100644 --- a/modules/luci-base/ucode/dispatcher.uc +++ b/modules/luci-base/ucode/dispatcher.uc @@ -764,6 +764,13 @@ function rollback_pending() { let dispatch; +function render_action(fn) { + const data = render(fn); + + http.write_headers(); + http.output(data); +} + function run_action(request_path, lang, tree, resolved, action) { switch (action?.type) { case 'template': @@ -775,13 +782,12 @@ function run_action(request_path, lang, tree, resolved, action) { break; case 'call': - http.write_headers(); - http.output(render(() => { + render_action(() => { runtime.call(action.module, action.function, ...(action.parameters ?? []), ...resolved.ctx.request_args ); - })); + }); break; case 'function': @@ -790,33 +796,30 @@ 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_headers(); - http.output(render(() => { + render_action(() => { call(mod[action.function], mod, runtime.env, ...(action.parameters ?? []), ...resolved.ctx.request_args ); - })); + }); break; case 'cbi': - http.write_headers(); - http.output(render(() => { + render_action(() => { runtime.call('luci.dispatcher', 'invoke_cbi_action', action.path, null, ...resolved.ctx.request_args ); - })); + }); break; case 'form': - http.write_headers(); - http.output(render(() => { + render_action(() => { runtime.call('luci.dispatcher', 'invoke_form_action', action.path, ...resolved.ctx.request_args ); - })); + }); break; case 'alias': -- 2.30.2