fix: keep the /api prefix when proxying /api/logs/* - #74
Conversation
The catch-all proxy strips its own /api before forwarding, on the assumption that mcpgateway mounts every router at the root. log_search declares prefix="/api/logs", so /api/logs/activity was forwarded to /logs/activity and 404d. It is the only router in mcpgateway mounted under /api; the other 29 sit at the root. No caller had exercised an /api/logs/* route through the BFF before — the other five log routes exist only as generated URL builders with no live callers — so this surfaced as soon as the activity feed asked for real data. Signed-off-by: Anna Effort <anna.effort@ibm.com>
f6f3c36 to
a2d00a3
Compare
marekdano
left a comment
There was a problem hiding this comment.
Blocking
server/src/routes/proxy/catch-all.ts:92
rewriteUpstreamLocation() unconditionally prepends /api to a redirect Location path, but the PR's new toUpstreamPath() now forwards /api/logs/* requests upstream with /api already in the path (unlike every other route, which strips it).
Failure scenario: If mcpgateway issues a 307 for a logs request — which it will for any trailing-slash mismatch, since Starlette's default redirect_slashes=True is active and none of log_search's six routes (search, trace/{id}, security-events, audit-trails, activity, performance-metrics) are declared with a trailing slash — the rewritten Location becomes a doubled /api/api/logs/..., which 404s.
Keeping /api on logs requests left rewriteUpstreamLocation() prepending /api to a Location that already carried it, so a 307 on a logs path resolved to /api/api/logs/*. toBrowserPath() mirrors toUpstreamPath() off the same constant. Signed-off-by: Anna Effort <anna.effort@ibm.com>
|
Good catch, @marekdano! Confirmed and fixed in 0fa007b. 🙌
One correction on the trigger. Because none of the six routes declare a trailing slash, Fix is a |
Problem
GET /api/logs/activityfails through the BFF. The catch-all proxy strips its own/apibefore forwarding, on the assumption (stated in the file) that mcpgateway mounts every router at the root:log_searchdeclaresprefix="/api/logs", so/api/logs/activitywas forwarded to/logs/activityupstream and 404d.Probed against a live gateway:
/api/logs/activity/logs/activity/api/definitely-not-a-real-routeWhy now
No caller had ever exercised an
/api/logs/*route through the BFF. The other five log routes exist only as generated URL builders incontextForge.tswith no live callers, so the root-mount assumption was never tested. It surfaced the moment the Recent Activity feed asked for real data.Fix
A
toUpstreamPath()helper that keeps the prefix forlogs/*and strips it for everything else, plus a correction to the now-false comment.The exception is deliberately narrow.
/api/logsis the only router in mcpgateway mounted under/api. The other 29 sit at the root or under root-relative prefixes (/v1/...,/admin/...,/observability/...) that already proxy correctly. That's recorded next to the constant so it doesn't get "simplified" back.Tests
Two additions to
server/test/proxy.test.ts:/api/logs/activityreaches upstream intact, and/api/logsearchstill strips. The second guards the prefix match, sincestartsWith("logs")without the trailing slash would wrongly catch it.BFF suite: 79 passed / 8 files. Server typecheck, eslint and prettier clean.