Handling empty slash slots in URL (Double slash)
What version of Hono are you using?
4.4.5
What runtime/platform is your app running on?
Node
What steps can reproduce the bug?
Opening a URL on Hono with a double slash, like http://localhost:3001/api//account. It doesn't find the route at /api/account.
What is the expected behavior?
I expect the // to be normalized to /.
What do you see instead?
No response
Additional information
It can be solved with a RegEx like:
Find: /\/+/g
Replace: /
OR
Find: /\/{2,}/g
Replace: /
Hi @movahhedi
The router separates paths with /, so supporting it on the routers will be hard. But you can use getPath() function:
https://hono.dev/docs/api/routing#routing-with-hostname
@usualoma Any thoughts?
I am aware that some frameworks treat consecutive "/" as a single "/", but others do not.
I, too, think that in Hono, users can deal with getPath(), so there is no need to change the functionality.
We may be able to remove the extra /s before reaching the routers.
We can also make this optional, which can be set like this:
const hono = new Hono<IHonoEnv>({
strict: true,
removeEmptySlots: true,
})
Nevertheless, It can be a functionality of strict: false. So if it's false, it removes the extra /s, and if it's true, it doesn't.
@movahhedi
As mentioned above, we don't have to add a new function. You can use getPath option. Try the following:
import { Hono } from 'hono'
import { getPath } from 'hono/utils/url'
const app = new Hono({
getPath: (request) => {
const path = getPath(request)
return path.replace(/\/+/g, '/')
},
})
app.get('/api/account', (c) => c.text('/api/account'))
const res = await app.request('/api//account')
console.log(res.status) // 200
I kinda fixed it, because above getPath doesn't work for normal requests
As mentioned above, we don't have to add a new function. You can use
getPathoption. Try the following:import { Hono } from 'hono' import { getPath } from 'hono/utils/url'
const app = new Hono({ getPath: (request) => { const path = getPath(request) return path.replace(//+/g, '/') }, })
app.get('/api/account', (c) => c.text('/api/account'))
const res = await app.request('/api//account') console.log(res.status) // 200
Solution
import { createMiddleware } from "hono/factory";
export const resolvePath = createMiddleware(async (c, next) => {
if (c.req.path.includes("//")) {
return c.redirect(c.req.path.replaceAll(/\/+/g, "/"));
}
await next();
});
const app = new Hono({
strict: false,
}).basePath("/");
app.use(resolvePath);
Now any type of double-triple slash issue will be resolved automatically by redirecting
We can close this issue because the user can use getPath() to resolve the issue.
We may be able to remove the extra
/s before reaching the routers.We can also make this optional, which can be set like this:
const hono = new Hono<IHonoEnv>({ strict: true, removeEmptySlots: true, }) Nevertheless, It can be a functionality of
strict: false. So if it'sfalse, it removes the extra/s, and if it'strue, it doesn't.
I still think supporting this out-of-the-box is better.