Keep the relative URL root in streamed Rapid Diffs paths
What does this MR do and why?
This MR makes Rapid Diffs keep the relative URL root in every path it streams, such as the expand lines endpoint and the View file link.
On instances served under a relative URL root, every diff file streamed after the first one got paths without that root. Expanding lines failed with "Failed to expand lines, please try again." and View file returned 404. Files rendered with the page itself were not affected.
config.ru mounts GitLab at its relative URL root with Rack::URLMap, which restores SCRIPT_NAME as soon as the request thread returns through it. With ActionController::Live that happens once the response is committed, while the stream thread is still rendering, and Rails reads SCRIPT_NAME every time it builds URL options. The stream now resolves the URL options before anything is written, as it already does for the current user.
This surfaced in 19.4.3 and 19.5.0, when the Rack env started to outlive the committed response. Before that, the env was cleared at the same moment, so Rails fell back to the default script_name, which carries the relative URL root.
References
- #637180 (closed)
- !253635 (merged), which kept the Rack env until the response body closes
Screenshots or screen recordings
Not applicable: there are no UI changes, only the generated paths change.
How to set up and validate locally
- Serve GDK under a relative URL root: set
relative_url_root: /gitlabingdk.yml, then rungdk reconfigureandgdk restart. - Open a merge request with at least 10 changed files and select Changes.
- Scroll past the sixth file and select Next 20 lines or Previous 20 lines on any file there.
- Before this change, the request goes to
/<group>/<project>/-/blob/<sha>/<path>/diff_lineswithout/gitlaband fails. After it, the path starts with/gitlaband the lines expand.
Request specs cannot reproduce this race: Rails runs ActionController::Live inline in tests, and rack-test speaks HTTP/1.0, which gets a buffered response. The new specs restore SCRIPT_NAME by hand instead, like the existing specs for signed-out users drop Warden.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.