Clone URL rewritten to browsing hostname by client-side JS, ignoring ROOT_URL setting #12419
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Does your problem still exist on the latest Forgejo version?
Unknown, I can't try it for some reason (please explain)
About your usage of Forgejo
Small architecture firm using Forgejo as a self-hosted git forge for open-source building design projects. We host large binary files (BIM models, PDFs, blender files) via Git LFS, some exceeding 100MB. We have a mix of technical and non-technical collaborators.
Problem description
We run Forgejo behind two domains pointing to the same instance:
hub.openingdesign.com— proxied through Cloudflare (web UI)git.openingdesign.com— DNS only, bypasses Cloudflare (needed for large LFS file transfers >100MB which exceed Cloudflare's request body limit)We set
ROOT_URL = https://git.openingdesign.com/inapp.iniso that clone URLs generated by Forgejo point togit.openingdesign.com, bypassing Cloudflare for git operations.This works correctly — the raw HTML served by Forgejo contains the correct
git.openingdesign.comclone URL. However, when a user browses viahub.openingdesign.com, Forgejo's client-side JavaScript rewrites the clone URL input field to match the current browsing hostname, overriding theROOT_URLsetting. The result is that users seehub.openingdesign.comin the clone URL box, which fails for large LFS pushes/pulls due to Cloudflare's 100MB limit.test url: https://hub.openingdesign.com/OpeningDesign/3_Season_Porch_URGC
it renders out as: https://hub.openingdesign.com/OpeningDesign/3_Season_Porch_URGC.git
the raw link is: https://git.openingdesign.com/OpeningDesign/3_Season_Porch_URGC.git
Potential workarounds
hub.openingdesign.com→git.openingdesign.comvia Caddy, but this loses Cloudflare bot protection on the web UIForgejo Version
Forgejo version 8.0.3+gitea-1.22.0 (release name 8.0.3) built with GNU Make 4.4.1, go1.22.7 : bindata, timetzdata, sqlite, sqlite_unlock_notify
Other details about your environment (software names and versions)
Solutions
Accepted solutions to address this problem will go here
Hi @theoryshaw. Unfortunately I can't offer you an easy solution -- from what I can tell, the client-side rewriting of the URL is automatic and there's no current option to disable it. Unless someone else has awareness of a configuration option that I don't, development work would be required to support this.
I have to warn you that Forgejo 8.0 is an end-of-life release which is missing critical security patches, with support having ended in October 2024. Even if this was fixed, you're going to need to manage upgrading 7 major software releases before a new feature or fix would be available to you.
AI helped with a possible solution...
Suggested Fix
Problem Summary
toOriginUrl()intemplates/repo/clone_script.tmplunconditionally rewrites all clone URLs to use the browser's current hostname (window.location.hostname), ignoring theROOT_URLset inapp.ini. This breaks setups where the administrator intentionally wants clone URLs to point to a different host than the one being browsed.Use Case
A common deployment scenario:
hub.example.com— proxied through Cloudflare (web UI, bot protection)git.example.com— DNS only, bypasses Cloudflare (git/LFS operations)ROOT_URL = https://git.example.com/is set inapp.iniso that clone URLs bypass Cloudflare's 100MB request body limit for large LFS file transfers. The raw HTML correctly reflects this —data-link="https://git.example.com/user/repo.git"— buttoOriginUrl()overwrites it withhub.example.comwhen the user browses via that domain.Current Behavior
js
This runs unconditionally for all absolute URLs, including ones where the server has explicitly set a different host via
ROOT_URL.Proposed Fix — Option 1 (Recommended)
Only rewrite relative URLs. If the URL is already absolute (has an explicit host), respect it and return it unchanged:
js
This preserves the original intent of the function (handling relative URLs and avoiding flicker) while respecting explicitly configured absolute URLs from
ROOT_URL.Proposed Fix — Option 2 (Opt-out attribute)
Add a
data-no-origin-rewriteattribute on the server side thattoOriginUrl()checks before rewriting. This gives administrators explicit control:Server side (
templates/repo/clone_script.tmpl):html
Client side:
js
Proposed Fix — Option 3 (Simplest)
Remove
toOriginUrl()entirely and usedata-linkdirectly:js
This is the simplest fix but removes the multi-hostname auto-adaptation feature entirely. Only appropriate if that feature is considered an edge case.
Recommendation
Option 1 is the least disruptive — it preserves the existing multi-hostname behavior for relative URLs and Forgejo instances that don't set an explicit
ROOT_URLhost, while respecting explicitly configured absolute URLs. It also requires changes to only one function in one file, and the same change would need to be applied toweb_src/js/webcomponents/origin-url.jswheretoOriginUrlis duplicated (the comment there already notes "Keep this function in sync").Files to Change
templates/repo/clone_script.tmpl—toOriginUrl()functionweb_src/js/webcomponents/origin-url.js— duplicatetoOriginUrl()(keep in sync per existing comment)There's no configuration to change this, because this was the behavior highly requested from people running a setup somewhat similar to yours. The domain always point to the domain from where the request originate from to make it possible to run Forgejo under multiple domains. I think adding a setting for this would add quite some complexity after quite a lot effort (over the years) went into not relying on the configured domain when possible.
Thanks for the context @Gusted. I understand the multi-domain auto-adaptation is intentional and valued.
To clarify, the proposed Option 1 fix (in AI's possible solution pasted above) wouldn't change that behavior at all. It would only affect cases where
ROOT_URLexplicitly points to a different host than the one being browsed. WhenROOT_URLand the browsing hostname match (the common case),toOriginUrl()would behave exactly as it does today.The admin setting
ROOT_URL = https://git.example.com/while serving the UI athub.example.comis an explicit signal that they want git operations routed differently. Respecting that seems consistent with Forgejo's philosophy of giving admins control over their deployment.Would a small, non-breaking change like this be considered?