cleanup, error pages
This commit is contained in:
parent
f2a3503ac3
commit
dff1959341
@ -85,3 +85,12 @@ ARCHIVE_MAX_ZIP_ENTRIES=4096
|
||||
|
||||
# LIFETIME OF SESSION COOKIES IN SECONDS
|
||||
SESSION_TIME=2592000
|
||||
|
||||
# DEVELOPER-DEFINED ERROR PAGES (see /doc/index.uce?p=error_pages and
|
||||
# /doc/index.uce?p=3_blocked_functions). The unit receives the error details in
|
||||
# context.call["error"]; comment out for the plain-text fallback instead.
|
||||
page_runtime_error=site/errors/runtime-error.uce
|
||||
|
||||
# Comma-separated uce_host_* names to disable per server policy (empty = none).
|
||||
# A unit calling a blocked hostcall fails into the error page above.
|
||||
UCE_HOSTCALL_BLOCKLIST=
|
||||
|
||||
@ -172,6 +172,11 @@ void cli_run_http_smoke()
|
||||
cli_expect_http("uce_http_smoke:starter workspace ONCE assets reach head", "/examples/uce-starter/?workspace/projects", 200, "css/workspace.css");
|
||||
cli_expect_http("uce_http_smoke:starter ajax section", "/examples/uce-starter/?page2-section1", 200, "UCE starter AJAX fragment response");
|
||||
cli_expect_http("uce_http_smoke:starter route traversal blocked", "/examples/uce-starter/?../../../demo/index", 404, "The requested page does not exist.");
|
||||
// Configurable error page (page_runtime_error): a runtime fault must render the
|
||||
// developer-defined error-page unit with the real error info marshalled across
|
||||
// the membrane, at the error status. Asserts HTTP 500 AND that error["request_uri"]
|
||||
// reached the page (the "mode=trap" query is only shown if error_info crossed).
|
||||
cli_expect_http("uce_http_smoke:configurable error page 500 + error info", "/demo/error-reporting.uce?mode=trap", 500, "mode=trap");
|
||||
}
|
||||
|
||||
void cli_run_site_suite()
|
||||
|
||||
@ -497,35 +497,6 @@ void compiler_record_compile_result(SharedUnit* su, f64 duration, bool success,
|
||||
}
|
||||
}
|
||||
|
||||
void compiler_begin_render_result(SharedUnit* su, bool count_request)
|
||||
{
|
||||
su->invoke_count += 1;
|
||||
if(count_request)
|
||||
su->request_count += 1;
|
||||
su->last_rendered = time();
|
||||
}
|
||||
|
||||
void compiler_record_render_result(SharedUnit* su, f64 duration, bool success, String error_status = "")
|
||||
{
|
||||
su->last_render_duration = duration;
|
||||
su->total_render_duration += duration;
|
||||
if(su->best_render_duration == 0 || duration < su->best_render_duration)
|
||||
su->best_render_duration = duration;
|
||||
if(duration > su->worst_render_duration)
|
||||
su->worst_render_duration = duration;
|
||||
|
||||
if(success)
|
||||
{
|
||||
su->runtime_error_status = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
su->runtime_error_count += 1;
|
||||
su->runtime_error_status = error_status;
|
||||
su->last_error = time();
|
||||
}
|
||||
}
|
||||
|
||||
String compiler_error_status(SharedUnit* su)
|
||||
{
|
||||
if(!su)
|
||||
@ -591,24 +562,6 @@ void compiler_tree_set_bool(DValue& tree, String key, bool value)
|
||||
tree[key].set_bool(value);
|
||||
}
|
||||
|
||||
bool compiler_is_request_entry_unit(Request* context, SharedUnit* su)
|
||||
{
|
||||
if(!context || !su)
|
||||
return(false);
|
||||
auto request_file = compiler_normalize_unit_path(context, context->params["SCRIPT_FILENAME"]);
|
||||
return(request_file != "" && request_file == su->file_name);
|
||||
}
|
||||
|
||||
bool compiler_can_write_response(Request* context)
|
||||
{
|
||||
return(
|
||||
context &&
|
||||
context->params["REQUEST_METHOD"] != "" &&
|
||||
context->ob &&
|
||||
context->ob_stack.size() > 0
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
String preprocess_shared_unit(Request* context, SharedUnit* su)
|
||||
|
||||
@ -625,7 +625,7 @@ String trim(String raw)
|
||||
s64 len = raw.length();
|
||||
s64 start_pos = 0;
|
||||
s64 end_pos = len - 1;
|
||||
if(len == 0 || (len == 1 && isspace((unsigned char)raw[0])))
|
||||
if(len == 0)
|
||||
return("");
|
||||
while(start_pos < len && isspace((unsigned char)raw[start_pos]))
|
||||
start_pos++;
|
||||
@ -2308,7 +2308,7 @@ String json_decode_String(String s, u32& i, char termination_char)
|
||||
result.append(1, '\'');
|
||||
break;
|
||||
case('u'):
|
||||
if(i <= s.length() && s.length() - i >= 5 && json_decode_unicode_escape(s, i, result))
|
||||
if(s.length() - i >= 5 && json_decode_unicode_escape(s, i, result))
|
||||
break;
|
||||
return(result);
|
||||
default:
|
||||
|
||||
@ -112,6 +112,10 @@ bool render_wasm_error_page(Request& request, String config_key, s32 status_code
|
||||
request.call.remove("error");
|
||||
return(false);
|
||||
}
|
||||
// Rendering the error-page unit set the response to its own (200) status;
|
||||
// re-assert the error status + html content-type so the client sees e.g. 500.
|
||||
request.set_status(status_code, status_reason);
|
||||
request.header["Content-Type"] = first(request.server->config["CONTENT_TYPE"], "text/html; charset=utf-8");
|
||||
print(html);
|
||||
return(true);
|
||||
}
|
||||
|
||||
@ -375,18 +375,25 @@ static bool uce_header_name_safe(String name)
|
||||
static DValue uce_http_request_value(const DValue& req)
|
||||
{
|
||||
DValue r; r["status"]=(f64)0; r["headers"].set_array(); r["body"]=""; r["error"]="";
|
||||
String method = req.key("method") ? to_upper(req.key("method")->to_string()) : String("GET");
|
||||
String url = req.key("url") ? req.key("url")->to_string() : String("");
|
||||
const DValue* method_value = req.key("method");
|
||||
const DValue* url_value = req.key("url");
|
||||
const DValue* timeout_value = req.key("timeout_ms");
|
||||
const DValue* follow_redirects_value = req.key("follow_redirects");
|
||||
const DValue* headers_value = req.key("headers");
|
||||
const DValue* body_value = req.key("body");
|
||||
String method = method_value ? to_upper(method_value->to_string()) : String("GET");
|
||||
String url = url_value ? url_value->to_string() : String("");
|
||||
if(url=="" || url.find('\0')!=String::npos) { r["error"]="missing url"; return(r); }
|
||||
if(method=="") method="GET";
|
||||
std::vector<String> argv = {"curl", "-sS", "--http1.0", "-X", method, "-D", "-", "-w", "\nUCE_HTTP_STATUS:%{http_code}", "--max-time", std::to_string(std::max<u64>(1, (req.key("timeout_ms") ? req.key("timeout_ms")->to_u64(5000) : 5000) / 1000))};
|
||||
if(req.key("follow_redirects") && req.key("follow_redirects")->to_bool()) argv.push_back("-L");
|
||||
if(req.key("headers")) req.key("headers")->each([&](const DValue& v, String k){ if(uce_header_name_safe(k)) { argv.push_back("-H"); argv.push_back(k + ": " + replace(replace(v.to_string(), "\r", " "), "\n", " ")); } });
|
||||
String body = req.key("body") ? req.key("body")->to_string() : String("");
|
||||
if(req.key("body")) { argv.push_back("--data-binary"); argv.push_back("@-"); }
|
||||
u64 timeout_ms = timeout_value ? timeout_value->to_u64(5000) : 5000;
|
||||
std::vector<String> argv = {"curl", "-sS", "--http1.0", "-X", method, "-D", "-", "-w", "\nUCE_HTTP_STATUS:%{http_code}", "--max-time", std::to_string(std::max<u64>(1, timeout_ms / 1000))};
|
||||
if(follow_redirects_value && follow_redirects_value->to_bool()) argv.push_back("-L");
|
||||
if(headers_value) headers_value->each([&](const DValue& v, String k){ if(uce_header_name_safe(k)) { argv.push_back("-H"); argv.push_back(k + ": " + replace(replace(v.to_string(), "\r", " "), "\n", " ")); } });
|
||||
String body = body_value ? body_value->to_string() : String("");
|
||||
if(body_value) { argv.push_back("--data-binary"); argv.push_back("@-"); }
|
||||
argv.push_back(url);
|
||||
if(access("/usr/bin/curl", X_OK)!=0 && access("/bin/curl", X_OK)!=0) { r["error"]="curl binary not found in runtime PATH"; return(r); }
|
||||
DValue pr = uce_exec_argv_capture(argv, body, req.key("timeout_ms") ? req.key("timeout_ms")->to_u64(5000) : 5000);
|
||||
DValue pr = uce_exec_argv_capture(argv, body, timeout_ms);
|
||||
String out = pr["stdout"].to_string();
|
||||
String marker="\nUCE_HTTP_STATUS:"; size_t mp=out.rfind(marker);
|
||||
if(mp!=String::npos) { r["status"]=(f64)strtoull(out.c_str()+mp+marker.size(),0,10); out=out.substr(0,mp); }
|
||||
@ -989,11 +996,6 @@ public:
|
||||
return("");
|
||||
}
|
||||
|
||||
String render_entry(const String& entry_source_path)
|
||||
{
|
||||
return(invoke_entry(entry_source_path, "render"));
|
||||
}
|
||||
|
||||
String collect(WasmResponse& response)
|
||||
{
|
||||
String error = call_core("uce_wasm_finish_output", {}, 0);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user