4

We are using Nancy framework for our application which is self-hosted in console application. The problem appears when loading the URL without trailing slash.

Let's say we are hosting the page in

http://host.com:8081/module/

It then serves us am html page which has resources with a relative path like this:

content/scripts.js

Everything works well when you enter a url such as

// Generates a resource url 'http://host.com:8081/module/content/scripts.js' 
// which is good
http://host.com:8081/module/ 

But when we leave out a trailing slash, the resource url is

// Generates a resource url 'http://host.com:8081/content/scripts.js' 
// which is bad
http://host.com:8081/module

Is there any way to make redirection to trailing slash version? Or at least detect if trailing slash exists or not.

Thanks!

Drasius
  • 825
  • 1
  • 11
  • 26
  • You could probably hook into the Before application pipeline and add the trailing slash or do theredirecct – Christian Horsdal Nov 11 '14 at 09:56
  • Hooking to the Before doesn't work because I get the same URL when accessing URL with or without trailing slash. I can't detect when trailing slash is missing and when do the redirect. – Drasius Nov 11 '14 at 10:34
  • If I create two routes, `Get["/module"]` and `Get["/module/"]`, then requests for both _/module_ and _/module/_ get handled by the `Get["/module/"]` route - so there appears to be no way to distinguish between them? – rogersillito Dec 04 '15 at 14:35

1 Answers1

0

This feels a bit hacky but it works:

Get["/module/"] = o =>
{
    if (!Context.Request.Url.Path.EndsWith("/"))
        return Response.AsRedirect("/module/" + Context.Request.Url.Query, RedirectResponse.RedirectType.Permanent);
    return View["module"];
};

The Request accessible from Context lets you see whether the path has the trailing slash or not and redirect to a 'slashed' version. I wrapped this up as an extension method (which works for my very simple use case):

public static class NancyModuleExtensions
{
    public static void NewGetRouteForceTrailingSlash(this NancyModule module, string routeName)
    {
        var routeUrl = string.Concat("/", routeName, "/");
        module.Get[routeUrl] = o =>
        {
            if (!module.Context.Request.Url.Path.EndsWith("/"))
                return module.Response.AsRedirect(routeUrl + module.Request.Url.Query, RedirectResponse.RedirectType.Permanent);
            return module.View[routeName];
        };
    }
}

To use in a module:

// returns view "module" to client at "/module/" location
// for either "/module/" or "/module" requests
this.NewGetRouteForceTrailingSlash("module");

This is worth reading though before going with a solution such as this

Community
  • 1
  • 1
rogersillito
  • 869
  • 1
  • 10
  • 27