Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ignoring trailing slashes in rest interfaces #2537

Open
CodeMyst opened this issue Feb 22, 2021 · 1 comment
Open

ignoring trailing slashes in rest interfaces #2537

CodeMyst opened this issue Feb 22, 2021 · 1 comment

Comments

@CodeMyst
Copy link
Contributor

the web interfaces have a setting to ignore trailing slashes (which is true by default).

[2021-02-22 21:18:39.278 main(----) dbg] add route GET /:id
[2021-02-22 21:18:39.278 main(----) dbg] add route GET /:id/

and if you disable it like so:

WebInterfaceSettings s = new WebInterfaceSettings();
s.ignoreTrailingSlash = false;

router.registerWebInterface(new RootWeb(), s);

then the logs show something like this (no trailing slash):

[2021-02-22 21:18:39.278 main(----) dbg] add route GET /:id

but the rest interface settings dont have such an option, and i couldnt manage to get the same effect without using redirects:

router.any("/*", (HTTPServerRequest req, HTTPServerResponse res) {
	import std.algorithm : startsWith;
	if (req.requestURI.startsWith("/api/") && req.requestURI[$-1] == '/')
	{
              // 307 needed so post requests get redirected correctly
		res.redirect(req.requestURI[0..$-1], 307);
	}
});

and looks like this is how web interface handles this option:

vibe.d/web/vibe/web/web.d

Lines 216 to 228 in fee3872

if (settings.ignoreTrailingSlash && !fullurl.endsWith("*") && fullurl != "/") {
auto m = fullurl.endsWith("/") ? fullurl[0 .. $-1] : fullurl ~ "/";
router.match(minfo.method, m, delegate void (HTTPServerRequest req, HTTPServerResponse res) @safe {
static if (minfo.method == HTTPMethod.GET) {
URL redurl = req.fullURL;
auto redpath = redurl.path;
redpath.endsWithSlash = !redpath.endsWithSlash;
redurl.path = redpath;
res.redirect(redurl);
} else {
() @trusted { handleRequest!(M, overload)(req, res, instance, settings); } ();
}
});

i could also try implementing this myself if the suggestion is accepted.

@lesderid
Copy link
Contributor

lesderid commented Feb 3, 2024

This is making it impossible for me to use vibe.d to re-implement an existing REST API without dirty hacks, rolling my own route generator, or changing vibe.d code.

Edit: I'm using the following workaround for now, but it's not ideal:

typeof(toDelegate(&Router.handleRequest))
getHandler(Router)(Router router)
{
    return (req, res) {
        req.requestPath.endsWithSlash = true;
        // or to disallow URLs with trailing slashes:
        //req.requestPath.endsWithSlash = !req.requestPath.endsWithSlash;
        (&router.handleRequest)(req, res);
    };
}

// ...

void main()
{
    auto router = new URLRouter;
    router.registerRestInterface(new MyAPI());

    listenHTTP(new HTTPServerSettings(), getHandler(router));
}

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

No branches or pull requests

2 participants