[PR #2524] [MERGED] fix: path-based routing broken due to key collisions in sanitize() #7814

Closed
opened 2026-04-25 16:26:24 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/fosrl/pangolin/pull/2524
Author: @shreyaspapi
Created: 2/23/2026
Status: Merged
Merged: 3/8/2026
Merged by: @oschwartz10612

Base: devHead: fix/2294-path-based-routing


📝 Commits (4)

  • 5f18c06 fix: use collision-free path encoding for Traefik router key generation
  • e58f0c9 fix: preserve backward-compatible router names while fixing path collisions
  • 244f497 test: add comprehensive backward compatibility tests for path routing fix
  • 75a9097 fix: simplify path encoding per review — inline utils, use single key scheme

📊 Changes

4 files changed (+364 additions, -13 deletions)

View changed files

📝 server/lib/traefik/getTraefikConfig.ts (+9 -7)
server/lib/traefik/pathEncoding.test.ts (+323 -0)
📝 server/lib/traefik/utils.ts (+20 -0)
📝 server/private/lib/traefik/getTraefikConfig.ts (+12 -6)

📄 Description

Community Contribution License Agreement

By creating this pull request, I grant the project maintainers an unlimited,
perpetual license to use, modify, and redistribute these contributions under any terms they
choose, including both the AGPLv3 and the Fossorial Commercial license terms. I
represent that I have the right to grant this license for all contributed content.

Description

Fixes #2294

What this fixes

The sanitize() function used to generate internal map keys for grouping targets in getTraefikConfig can cause path collisions. It replaces all non-alphanumeric characters (including /, ., _) with dashes and collapses them, so structurally different paths can produce the same key:

  • sanitize("/a/b") = "a-b"
  • sanitize("/a-b") = "a-b" (same!)

When two targets get the same key, they're grouped into one loadbalancer service and Traefik round-robins between them instead of routing by path.

Note: this specific collision doesn't affect the / vs /api scenario reported in the issue (those already produce different keys), but it would affect setups with paths like /api/v1 vs /api-v1 or /app.v2 vs /app/v2.

How to test?

  1. Create two resources with paths that would collide under old sanitization (e.g., /api/v1 and /api-v1)
  2. Verify they route to their correct backends independently (no round-robin)
  3. Verify existing resources with simple paths still work with the same router names

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/fosrl/pangolin/pull/2524 **Author:** [@shreyaspapi](https://github.com/shreyaspapi) **Created:** 2/23/2026 **Status:** ✅ Merged **Merged:** 3/8/2026 **Merged by:** [@oschwartz10612](https://github.com/oschwartz10612) **Base:** `dev` ← **Head:** `fix/2294-path-based-routing` --- ### 📝 Commits (4) - [`5f18c06`](https://github.com/fosrl/pangolin/commit/5f18c06e03695b2567ccd802c830d6533d825773) fix: use collision-free path encoding for Traefik router key generation - [`e58f0c9`](https://github.com/fosrl/pangolin/commit/e58f0c9f07cafe58b33e2f2b718709f528d1900c) fix: preserve backward-compatible router names while fixing path collisions - [`244f497`](https://github.com/fosrl/pangolin/commit/244f497a9c0c0cbdd99ac6ae2336e65c51a3a88b) test: add comprehensive backward compatibility tests for path routing fix - [`75a9097`](https://github.com/fosrl/pangolin/commit/75a909784af857e27de2de69af74aa4fdd4e80cd) fix: simplify path encoding per review — inline utils, use single key scheme ### 📊 Changes **4 files changed** (+364 additions, -13 deletions) <details> <summary>View changed files</summary> 📝 `server/lib/traefik/getTraefikConfig.ts` (+9 -7) ➕ `server/lib/traefik/pathEncoding.test.ts` (+323 -0) 📝 `server/lib/traefik/utils.ts` (+20 -0) 📝 `server/private/lib/traefik/getTraefikConfig.ts` (+12 -6) </details> ### 📄 Description ## Community Contribution License Agreement By creating this pull request, I grant the project maintainers an unlimited, perpetual license to use, modify, and redistribute these contributions under any terms they choose, including both the AGPLv3 and the Fossorial Commercial license terms. I represent that I have the right to grant this license for all contributed content. ## Description Fixes #2294 ## What this fixes The `sanitize()` function used to generate internal map keys for grouping targets in `getTraefikConfig` can cause path collisions. It replaces all non-alphanumeric characters (including `/`, `.`, `_`) with dashes and collapses them, so structurally different paths can produce the same key: - `sanitize("/a/b")` = `"a-b"` - `sanitize("/a-b")` = `"a-b"` (same!) When two targets get the same key, they're grouped into one loadbalancer service and Traefik round-robins between them instead of routing by path. Note: this specific collision doesn't affect the `/` vs `/api` scenario reported in the issue (those already produce different keys), but it would affect setups with paths like `/api/v1` vs `/api-v1` or `/app.v2` vs `/app/v2`. ## How to test? 1. Create two resources with paths that would collide under old sanitization (e.g., `/api/v1` and `/api-v1`) 2. Verify they route to their correct backends independently (no round-robin) 3. Verify existing resources with simple paths still work with the same router names --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-25 16:26:24 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/pangolin#7814