Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 12, 2026

PWAs treat /webapp/{appname} and /webapp/{appname}/ as different scopes, forcing developers to either duplicate assets or implement client-side redirects. This implements an unconditional 302 redirect to the trailing-slash form.

Changes

  • WebAppHandler: Added redirect logic when restPath is null (URL pattern /webapp/{appname})

    • Returns HTTP 302 with Location header to {url}/
    • Preserves query string parameters
    • Only affects direct webapp access; vhost-based deployments bypass this handler entirely
  • Tests: Added coverage for redirect with/without query strings and no-op when slash present

// Before: /webapp/myapp treated differently from /webapp/myapp/
// After: /webapp/myapp → 302 → /webapp/myapp/

if ( restPath == null )
{
    String redirectUrl = portalRequest.getRawPath() + "/";
    final String queryString = portalRequest.getRawRequest().getQueryString();
    if ( queryString != null )
    {
        redirectUrl = redirectUrl + "?" + queryString;
    }
    return WebResponse.create()
        .status( HttpStatus.FOUND )
        .header( "Location", redirectUrl )
        .build();
}

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • scans-in.gradle.com
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED -Xmx2048m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Redirect webapp url if it doesn't end with /</issue_title>
<issue_description>Something we talked about for a very long while but apparently have never implemented. If webapp url doesn't end with "/", we should redirect from webappUrl to webappUrl/. This now causes a lot of issues with PWAs where we have to implement client-side redirect to not have to store assets twice (webapp and webapp/are two different scopes).

Consider doing the same for site url without vhost.</issue_description>

<agent_instructions>implement unconditional "found" redirect for for any webapp</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@sigdestad NB! When using vhosts, this is not a problem, so this only relates to cases where the url is used directly. Test out carefully that this does not affect webapps deployed through vhosts.

NB! Also try out how this works for vhosts with subpath i.e. myapp.com/app etc.

The purpose is simply that we don't want webapp developers to build custom code to handle development specific problems.</comment_new>
<comment_new>@sigdestad
Also, would be nice with some considerations on how this might affect admin tools as well. i.e. what if content studio was a PWA.</comment_new>
<comment_new>@sigdestad
Thought this was already done? </comment_new>
<comment_new>@rymsha

  1. It would be breaking, because some may already use webapp without a slash.
  2. it is trivial for PWA developers to implement using lib-router 3.0.0 on XP 7.7.1
libRouter.get('/?', req => {
    if (!(req.rawPath || '').endsWith('/')) {
        return {
            redirect: req.path + '/'
        }
    }
    return {
        body: ...

So, I don't see a great demand for this anymore.</comment_new>
<comment_new>@sigdestad
I think this is already implemented for webapp root? But really nice to control this via app code anyway.

Are we able to run a filter that do such rewrites in the site engine as well? As in before pages are rendered? </comment_new>
<comment_new>@rymsha
No redirection happens right now (at least XP does not do it).

Next question is to @espen42 who gained quite a bit of knowledge (And it is out of topic in this issue) </comment_new>


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits January 12, 2026 08:49
Co-authored-by: rymsha <2891483+rymsha@users.noreply.github.com>
…ng whitespace

Co-authored-by: rymsha <2891483+rymsha@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement redirect for webapp URL if it doesn't end with / Redirect webapp URLs without trailing slash to canonical form Jan 12, 2026
Copilot AI requested a review from rymsha January 12, 2026 08:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Redirect webapp url if it doesn't end with /

2 participants