Skip to content

fix: preserve path when target includes path#139

Closed
chimurai wants to merge 1 commit into
unjs:mainfrom
chimurai:fix-path-regression
Closed

fix: preserve path when target includes path#139
chimurai wants to merge 1 commit into
unjs:mainfrom
chimurai:fix-path-regression

Conversation

@chimurai
Copy link
Copy Markdown

@chimurai chimurai commented May 19, 2026

regression introduced in #137

fixes #138

tested patch in chimurai/http-proxy-middleware#1234

When target is configured with path the outgoing path is not preserved:
(in 0.5.2 a trailing slash is added)

Reproduction:

const app = express()

app.use('/', createProxyMiddleware({
    changeOrigin: true,
    target: `http://localhost:9000/api`,        // <--- configure target with path
}));

app.listen(3000)
0.5.1
curl http://localhost:3000  -> http://localhost:9000/api

0.5.2
curl http://localhost:3000  -> http://localhost:9000/api/

PR
curl http://localhost:3000  -> http://localhost:9000/api

Summary by CodeRabbit

  • Bug Fixes
    • Fixed URL path resolution to correctly handle root path scenarios in path joining logic.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 978f9e9e-5482-4548-98da-8d2619119844

📥 Commits

Reviewing files that changed from the base of the PR and between c68013c and 1bd439c.

📒 Files selected for processing (2)
  • src/_utils.ts
  • test/_utils.test.ts

📝 Walkthrough

Walkthrough

This PR fixes a regression where joinURL incorrectly preserved a trailing slash when the incoming path was / and the base had a path component. The implementation now treats path === "/" as an absent path, returning the base unchanged. Test coverage is expanded to validate this behavior and adjacent edge cases.

Changes

Root Path Joining Fix

Layer / File(s) Summary
joinURL root-path handling fix
src/_utils.ts
Updated joinURL early-return condition to treat path === "/" the same as falsy path, returning base instead of continuing with slash-normalization logic.
Test coverage for path-joining edge cases
test/_utils.test.ts
Expanded test coverage for setupOutgoing (new assertion for root path with base) and joinURL (comprehensive cases for "/", "", and nested paths with/without trailing slashes on base).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

  • #138: Regression where trailing slash is added when target is used with a path; this PR fixes that by making joinURL return the base path unchanged when the incoming path is "/".

Possibly related PRs

  • unjs/httpxy#137: Prior PR that introduced the regression in joinURL handling of path === "/" that this PR corrects.

Suggested reviewers

  • pi0

Poem

🐰 A trailing slash caused quite a mess,
When "/" met a path, it made things less.
Now joinURL knows when to stay,
Base paths unchanged, no extra sway!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: fixing behavior when target includes a path, which is the core issue addressed by the regression fix.
Linked Issues check ✅ Passed The PR directly addresses issue #138 by fixing the trailing slash regression in joinURL when target includes a path, restoring the original behavior from version 0.5.1.
Out of Scope Changes check ✅ Passed All changes are focused on fixing the joinURL regression reported in issue #138; modifications to both implementation and tests are scoped to the specific path-joining behavior issue.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chimurai
Copy link
Copy Markdown
Author

Copilot shouldn't have modified existing tests.

@chimurai chimurai closed this May 19, 2026
@pi0
Copy link
Copy Markdown
Member

pi0 commented May 20, 2026

Thanks for PR. Do you prefer to revert last patch? behavior change was kinda known behavior change in #137

@chimurai
Copy link
Copy Markdown
Author

Hi @pi0

Think reverting the last patch makes sense, since some url paths are being changed after #137.

With http-proxy-middleware@4.0.0 released, httpxy is now getting around 10k+ daily new users.
Quite a large ecosystem will be impacted as projects are slowly adapting v4.

Some projects like @rspack/dev-server already migrated to v4
webpack-dev-server is currently upgrading as well: webpack/webpack-dev-server#5663

After reverting the patch. This missing unit test can be added to guard the specific proxy configuration/behaviour.

it("should not add trailing slash when target has base path and request path is root", () => {
  const outgoing = createOutgoing();
  common.setupOutgoing(
    outgoing,
    {
      target: URL.parse("http://localhost/api")!,
    },
    stubIncomingMessage({ url: "/" }),
  );

  expect(outgoing.path).to.eql("/api");
});

from: https://github.com/unjs/httpxy/pull/139/changes#diff-10beca856b0075affd0be8845cd175f88b977fc852ca7f23b4b96b23a1254e66R380-R391

@pi0
Copy link
Copy Markdown
Member

pi0 commented May 20, 2026

reverting now (3b5f8b0). Also added #141 to track adding better ecosystem CI testing.

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.

path regression (trailing slash is added in 0.5.2)

2 participants