Skip to content
This repository has been archived by the owner on Nov 20, 2018. It is now read-only.

UsePathBase does not disable root path #893

Closed
ben-foster-cko opened this issue Jul 9, 2017 · 3 comments
Closed

UsePathBase does not disable root path #893

ben-foster-cko opened this issue Jul 9, 2017 · 3 comments

Comments

@ben-foster-cko
Copy link

When configuring the base path of the application, the root path continues to work, for example:

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            app.UsePathBase("/basepath");

            app.Map("/ping", map => map.Run(async 
                ctx => await ctx.Response.WriteAsync("pong")));

            app.UseMvc();
        }

With this configuration both /basepath/ping and /ping work. I would expect /ping to return a 404.

This is the same behavior demonstrated by setting ASPNETCORE_URLS to http://+:5000/basepath though I believe setting the base path this way has been depreciated.

@andrewlock
Copy link

It doesn't feel right, but it looks like it probably is to me.

For every request there's two paths, the Path and the PathBase. AFAIK, most middleware just uses the Path to determine whether it should execute.

Both the PathBaseMiddleware and MapMiddleware operate in a similar way - they move segments that match an expected value from the Path to the PathBase. The main difference is that the MapMidddleware runs the inner pipeline if the segment matches, whereas the PathBaseMiddleware always just runs the rest of the pipeline as normal.

So imagine you have a request for /basepath/ping. With the pipeline you defined, you get the following sequence of events:

  1. At the start of pipeline, Path = "/basepath/ping", PathBase = ""
  2. PathBaseMiddleware sees the /basepath prefix on Path so moves it from Path to PathBase.
    (Path = "/ping", PathBase = "/basepath")
  3. MapMiddleware sees the /basepath prefix so moves it from Path to PathBase.
    (Path = "", PathBase = "basepath/ping")
  4. As the MapMiddleware matched the provided segment, it runs the inner "pong" pipeline.

That's the behaviour you expect I believe. So now lets look at a request for /ping.

  1. At the start of pipeline, Path = "/ping", PathBase = ""
  2. PathBaseMiddleware sees that the Path variable is not prefixed with /basepath, so it doesn't modify Path or PathBase
    (Path = "/ping", PathBase = "")
  3. MapMiddleware sees the /ping prefix so moves it from Path to PathBase.
    (Path = "", PathBase = "basepath/ping")
  4. As the MapMiddleware matched the provided segment, it runs the inner "pong" pipeline.

I believe, what you really want is to have the first scenario only, and for the second scenario to return a 404. In which case, you probably want something closer to this, with a nested MapMiddleware:

public void Configure(IApplicationBuilder app)
{
    app.Map("/basepath", mainapp =>
    {
        mainapp.Map("/ping", map => map.Run(async
            ctx => await ctx.Response.WriteAsync("pong")));

        mainapp.UseMvc();
    });
}

This ensures that if the initial /basepath doesn't match, then the pipeline is skipped.

@Tratcher
Copy link
Member

I understand the expectation, but it is working as intended. UsePathBase is primarily about getting those segments out of your way because they're a deployment detail, and if they stayed it would mess up your routing.

Consider the alternative. If it were to disable the root path, how would it do so? A 404 isn't really appropriate, presumably that path is available on a separate instance of your site hosting the root. You could use Map as shown above if you really wanted the 404.

IIS/Http.Sys uses a 503 for this scenario, which we could do, but you wouldn't have an opportunity to provide content that fit the theme of your site. The IIS/Http.Sys 503 page is pretty stark. If you wanted a 503 you could use Map and then put a proper error page on the other branch.

@aspnet-hello
Copy link

This issue was moved to dotnet/aspnetcore#2698

@aspnet aspnet locked and limited conversation to collaborators Jan 2, 2018
@aspnet-hello aspnet-hello removed this from the Discussions milestone Jan 2, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants