hono icon indicating copy to clipboard operation
hono copied to clipboard

Handling empty slash slots in URL (Double slash)

Open movahhedi opened this issue 1 year ago • 4 comments

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: /

movahhedi avatar Jun 25 '24 06:06 movahhedi

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?

yusukebe avatar Jun 27 '24 01:06 yusukebe

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.

usualoma avatar Jun 27 '24 03:06 usualoma

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 avatar Jun 30 '24 07:06 movahhedi

@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

yusukebe avatar Jul 01 '24 08:07 yusukebe

I kinda fixed it, because above getPath doesn't work for normal requests

@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

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

rajatsandeepsen avatar Mar 14 '25 10:03 rajatsandeepsen

We can close this issue because the user can use getPath() to resolve the issue.

yusukebe avatar Mar 15 '25 08:03 yusukebe

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.

I still think supporting this out-of-the-box is better.

movahhedi avatar Mar 15 '25 08:03 movahhedi