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: e7afd0d327 (commitcomment-88736854)
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
Jo-Philipp Wich 2022-11-03 11:13:30 +01:00
parent 86523709ef
commit 4b1a074c95

View file

@ -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':