From: Jo-Philipp Wich Date: Thu, 3 Nov 2022 10:13:30 +0000 (+0100) Subject: luci-base: dispatcher.uc: only flush HTTP headers after rendering output X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=4b1a074c95a674f2da154ee627e053db550cdd9d;p=project%2Fluci.git 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 --- 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':