Skip to content

Whitespace (any uri escapable char) in virtual path root results in NoRouteFound in an WebApi/Owin setup #203

Closed
@adzhiljano

Description

@adzhiljano

Hello,

First of all, thank you very much for the Asp.Net and Katana!!!

I'm not entirely sure if this is an issue with WebApi or Katana or with the integration bits.

The environment is the following:

Packages (should be latest possible versions):

  <package id="Microsoft.AspNet.WebApi" version="5.2.6" targetFramework="net461" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.6" targetFramework="net461" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.6" targetFramework="net461" />
  <package id="Microsoft.AspNet.WebApi.Cors" version="5.2.6" targetFramework="net461" />
  <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.6" targetFramework="net461" />
  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.6" targetFramework="net461" />
  <package id="Microsoft.Owin" version="4.0.0" targetFramework="net461" />
  <package id="Microsoft.Owin.Cors" version="4.0.0" targetFramework="net461" />
  <package id="Microsoft.Owin.Host.SystemWeb" version="4.0.0" targetFramework="net461" />
  <package id="Microsoft.Owin.Security" version="3.1.0" targetFramework="net461" />
  <package id="Microsoft.Owin.Security.OAuth" version="3.1.0" targetFramework="net461" />
  <package id="Owin" version="1.0" targetFramework="net461" />

Hosting: IIS 10
OS: Win 10
Site/App: 'Virtual' application under the Default Web Site (localhost:80) with the name test api

But can be reproduced with the following minimal setup:

public void Configuration(IAppBuilder app)
{
	HttpConfiguration config = new HttpConfiguration();

	config.MapHttpAttributeRoutes();

	app.UseWebApi(config);
}

When I try to send a request to http://localhost/test%20api/ I get a 404 and this is what I managed to trace:

  1. The Uri related contents of the OwinRrequest (got it from a fake first middleware in the pipeline)
    1
    2

  2. The processing gets to a point where the the virtual path root is needed

    string virtualPathRoot = GetVirtualPathRoot(request.GetRequestContext());

and this is the current context:
3

  1. Further a RoutingContext is needed
    private static RoutingContext CreateRoutingContext(string virtualPathRoot, HttpRequestMessage request)

and this is where the actual problem can be seen:
4
It's trying to do
"/test api/".StartsWith("/test%20api", StringComparison.Ordinal) which results in a return RoutingContext.Invalid(); and then in a NoRouteFound.

I'll just share some additional info and my toughts:

An escapable character in the virtual path in a pure (no Owin) WebApi setup is NOT a problem, it works as expected (I haven't debugged it though).

Please, keep in mind that I haven't gone that deep into the source codes so I might be missing something!

The way the virtual path root is retrieved maybe is the problem:

string requestPathBase = _context.Request.PathBase.ToString();

the PathBase.ToString() is actually ToUriComponent() which escapes the string.

https://github.com/aspnet/AspNetKatana/blob/e2b18ec84ceab7ffa29d80d89429c9988ab40144/src/Microsoft.Owin/PathString.cs#L60

and later on the HttpRoute.CreateRoutingContext() is doing (notice the UriFormat.Unescaped)

string requestPath = "/" + request.RequestUri.GetComponents(UriComponents.Path, UriFormat.Unescaped);

and then those two are compared.

The only workaround that I found out was to use a custom HttpRouteCollection with an override of the
public virtual IHttpRouteData GetRouteData(HttpRequestMessage request) method so that I can unescape the virtual path root. Is there another way of doing this?

Thank you!

Metadata

Metadata

Assignees

Labels

3 - Donebugcost: XSWill take up to half a day to complete

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions