From 1f28ff5ac4a8a466113296d9510fe91f8cd13bc3 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Tue, 7 Jul 2026 14:53:53 +0300 Subject: ychat: redirect to login page on invalid session (not blank page) When a chat request carried an invalid/expired tmpid (no matching session), reqp::parse returned early with an empty response, leaving the browser with a blank page -- e.g. after a server restart (sessions are in-memory) or reloading a bookmarked frameset URL with a stale tmpid. Instead serve a small redirect.html page that does a top-level JS redirect (top.location.href) back to the login page (httpd.startsite, i.e. index.html). Using a *top-level* redirect matters because the chat UI is a frameset of iframes (stream/online/input) that each reload with ?tmpid=... ; a plain in-iframe redirect would render three stacked login forms inside the frameset, while top.location sends the whole chat window back to the login form. top === self when this page is loaded directly (no parent frameset), so one line covers both cases. A noscript link is included as a fallback. The redirect response is built in the p_sess==NULL branch (mirroring the header-wrapping at the end of parse()) and returned, so the normal template-render path -- which would re-render the originally-requested frame -- does not run. --- ychat/html/redirect.html | 26 ++++++++++++++++++++++++++ ychat/src/reqp.cpp | 22 ++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 ychat/html/redirect.html diff --git a/ychat/html/redirect.html b/ychat/html/redirect.html new file mode 100644 index 0000000..4a7f326 --- /dev/null +++ b/ychat/html/redirect.html @@ -0,0 +1,26 @@ + + + + + + Session expired + + + + +
Your chat session is no longer valid. + Return to the login page.
+ + \ No newline at end of file diff --git a/ychat/src/reqp.cpp b/ychat/src/reqp.cpp index 907161d..aa60078 100644 --- a/ychat/src/reqp.cpp +++ b/ychat/src/reqp.cpp @@ -78,7 +78,29 @@ reqp::parse(context *p_context) } else { + // The session is invalid/expired (no tmpid match). The old code + // returned here with an empty response, leaving the browser with a + // blank page. Instead serve a small redirect page (redirect.html) + // that does a *top-level* JS redirect back to the login page, so the + // whole chat window returns to the login form rather than rendering + // three stacked login forms inside the frameset's iframes. wrap::system_message(SESSERR); + map_params["request"] = "redirect.html"; + map_params["content-type"] = "text/html"; + + // Build the full HTTP response here (mirroring the header wrapping + // at the end of parse()) and return, so the normal template-render + // path below -- which would re-render the originally-requested frame + // (e.g. stream.html) -- doesn't run. + *p_response = wrap::HTML->parse( map_params ); + + string s_resp; + s_resp.append( s_http ); + s_resp.append( s_http_colength + tool::int2string(p_response->size()) + "\r\n" + + s_http_cotype + map_params["content-type"] + + s_http_cotype_add + "\r\n" ); + s_resp.append( *p_response ); + *p_response = s_resp; return; } -- cgit v1.2.3