Ocelot: Upstream route templates that end in a slash are not 'found'.

Created on 2 Oct 2018  路  2Comments  路  Source: ThreeMammals/Ocelot

Expected Behavior / New Feature

When I map a specific route and it ends with a / I expect it to match to the same route if there was no ending /.

Actual Behavior / Motivation for New Feature

Given two upstream routes where one differ's only with the last character being an / then the Router fails to map to the route and returns a 404.

Steps to Reproduce the Problem

First, lets define a sample route configuration:

{
    "ReRoutes": [
        {
            "UpstreamPathTemplate": "/account/authenticate/",  <-- Notice the ENDING slash
            "DownstreamPathTemplate": "/authenticate",
            "DownstreamScheme": "http",
            "DownstreamHostAndPorts": [
                {
                    "Host": "accounts.api",
                    "Port": 80
                }
            ]
        }
    ],
    "GlobalConfiguration": {
        "BaseUrl": "http://localhost:5002"
    }
}

When using Postman, try to hit the following routes:

  • HTTP POST http://localhost:5002/account/authenticate <--- Succeeds
  • HTTP POST http://localhost:5002/account/authenticate/ <-- FAILS but expected to succeed.

There's no documentation about this, if this is a 'by design' feature.

Specifications

  • Version: 11.0.3
C:\Users\PK>dotnet --info
.NET Core SDK (reflecting any global.json):
 Version:   2.1.402
 Commit:    3599f217f4

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.17134
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\2.1.402\

Host (useful for support):
  Version: 2.1.4
  Commit:  85255dde3e

.NET Core SDKs installed:
  2.1.202 [C:\Program Files\dotnet\sdk]
  2.1.301 [C:\Program Files\dotnet\sdk]
  2.1.400 [C:\Program Files\dotnet\sdk]
  2.1.401 [C:\Program Files\dotnet\sdk]
  2.1.402 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.3-servicing-26724-03 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
enhancement help wanted medium effort

Most helpful comment

This is not great.. and I don't think the suggestion above is good enough.

For example with this re-route:

{
  "Description": "My service",
  "UpstreamHttpMethod": [ "GET", "POST", "PUT" ],
  "UpstreamPathTemplate": "/services/tags/{everything}",
  "DownstreamPathTemplate": "api/{version}/tags/{everything}",
  "DownstreamScheme": "http",
  "DownstreamHostAndPorts": [
    {
        "Host": "localhost",
        "Port": 5014
    }
  ]
}

This works:
GET: https://localhost:44321/services/v1/tags/id

This doesn't (because of the /{everything})
POST: https://localhost:44321/services/v1/tags

All 2 comments

@PureKrome thanks for your interest in Ocelot, we can take a look at making this work but for now I would suggest just adding the same ReRoute with a / at the end!

This is not great.. and I don't think the suggestion above is good enough.

For example with this re-route:

{
  "Description": "My service",
  "UpstreamHttpMethod": [ "GET", "POST", "PUT" ],
  "UpstreamPathTemplate": "/services/tags/{everything}",
  "DownstreamPathTemplate": "api/{version}/tags/{everything}",
  "DownstreamScheme": "http",
  "DownstreamHostAndPorts": [
    {
        "Host": "localhost",
        "Port": 5014
    }
  ]
}

This works:
GET: https://localhost:44321/services/v1/tags/id

This doesn't (because of the /{everything})
POST: https://localhost:44321/services/v1/tags

Was this page helpful?
0 / 5 - 0 ratings

Related issues

TomPallister picture TomPallister  路  4Comments

Ehrys picture Ehrys  路  5Comments

mogliang picture mogliang  路  3Comments

jefferson picture jefferson  路  3Comments

LuketaD2 picture LuketaD2  路  3Comments