1

I have these settings:

    CustomHttpHandlers = {
        {HttpStatusCode.NotFound, new RazorHandler("/notfound")},
        {HttpStatusCode.Unauthorized, new RazorHandler("/unauthorized")},
    }

When I visit something inside a /stars folder that doesn't exist:

/stars/asdf/xyz

It first checks for /stars/asdf/default.cshtml. Then goes to stars/default.cshtml and loads whichever level that has default page. So, only if /stars root folder doesn't exist at all, then /notfound would be loaded.

Is it possible to ask it to load /notfound when /asdf/xyz doesn't exist?

This is the behaviour under root directory:

http://localhost:2000/asdf will take you to /notfound. However, it doesn't do so under folders.

Tnank you.

EDIT ------------------------------------------------------

I noticed actually if I go to bad url /stars/asdf where /stars doesn't have a default but root /default.cshtml actually exists, in that case, both /notfound -> /default are loaded up one after other?!?

My settings are wrong? SS glitched?

Tom
  • 15,781
  • 14
  • 69
  • 111

1 Answers1

1

ServiceStack's routing priority, is as follows. ServiceStack calls ServiceStackHttpHandlerFactory.GetHandler to get the handler for the current route.

ServiceStackHttpHandlerFactory.GetHandler returns:

  1. A matching RawHttpHandler, if any.
  2. If the domain root, the handler returned by GetCatchAllHandlerIfAny(...), if any.
  3. If the route matches a metadata uri, the relevant handler, if any.
  4. The handler returned by ServiceStackHttpHandlerFactory.GetHandlerForPathInfo if any.
  5. NotFoundHandler.

ServiceStackHttpHandlerFactory.GetHandlerForPathInfo returns:

  1. If the url matches a valid REST route, a new RestHandler.
  2. If the url matches an existing file or directory, it returns
    • the handler returned by GetCatchAllHandlerIfAny(...), if any.
    • If it's a supported filetype, a StaticFileHandler,
    • If it's not a supported filetype, the ForbiddenHttpHandler.
  3. The handler returned by GetCatchAllHandlerIfAny(...), if any.
  4. null.

The CatchAllHandlers array contains functions that evaluate the url and either return a handler, or null. The functions in the array are called in sequence and the first one that doesn't return null handles the route.

The code that controls whether the default file is served is part of the StaticFileHandler. It's only called for existing files and directories.

Here's the relevent fragement:

foreach (var defaultDoc in EndpointHost.Config.DefaultDocuments)
{
    var defaultFileName = Path.Combine(fi.FullName, defaultDoc);
    if (!File.Exists(defaultFileName)) continue;
    r.Redirect(request.GetPathUrl() + '/' + defaultDoc);
    return;
}

As you can see, if the default file isn't found at the requested directory, it redirects up the directory chain until it finds a default file to serve. If you need to change this behavior, you can override it by adding a CatchAllHander you code. More details about writing a CatchAllHandler can be found in my answer to a related question, here: https://stackoverflow.com/a/17618851/149060

Community
  • 1
  • 1
Pauli Price
  • 4,187
  • 3
  • 34
  • 62