Kong: trailing slashes appended to requests to root of a configured API

Created on 16 Mar 2017  ·  16Comments  ·  Source: Kong/kong

Summary

Requests to the root of an API registered with kong 0.10.0 append a trailing slash to the request when it's passed to the upstream API.

Steps To Reproduce

  1. register an API like
name: thing
attributes:
  upstream_url: 'http://upstream/path'
  uris: '/thing'
  strip_uri: true
  1. make a request to newly configured API
curl http://kong/thing
  1. note that a trailing slash is appended when the request reaches the upstream service
http://kong/thing/
  1. this is problematic in the case where I do not append any additional path to my request to the API, say for instance I use a querystring, like so:
curl http://kong/thing?foo=bar

the upstream service will receive a request like so:

http://upstream/path/?foo=bar

Additional Details & Logs

  • Kong version 0.10.0

It looks as if this bug existed previously and was fixed at one point, see the comments here and https://github.com/Mashape/kong/issues/675

tasbug

Most helpful comment

Here is what I would propose to handle upstream URLs trailing slashes:

Since 0.10.0, we know an API's upstream_url cannot contain a trailing slash value anymore. This is currently explicitly enforced by not accepting trailing slash values from the Admin API (HTTP 400 responses to the client). It could be handled differently, and stripped under the hood at insert time, sure. This is I feel, is not the main concern raised by this discussion. Just trying to make this point clearer after the talk with @pklingem on Gitter and the links provided in the issue.


Now on to the issue at hand: providing a way for the consumer to be able to chose whether the upstream URL will have a trailing slash or not. For this, I believe we can do the following:

The decision on whether or not to append a trailing slash to the upstream URI depends on the incoming request URI:

| upstream_url | request URI | strip_uris | upstream URI (call from Kong)
|-------------------------|------------------|------------------|---------------|
| /foo/bar | /foo/bar | false | /foo/bar |
| /foo/bar | /foo/bar/ | false | /foo/bar/ |
| /foo/bar | /foo/bar | true | /bar |
| /foo/bar | /foo/bar/ | true | /bar/ |
| /foo/bar | / | N/A | /foo/bar |
| /foo/bar/ | / | N/A | /foo/bar/ |

The last row in here seems to be the only way to control whether or not to append a trailing slash to the upstream URI (call from Kong) when the request URI simply is /, so would require that upstream_url needs to be able to handle trailing slashes again. In that case, the full table could become:

| upstream_url | request URI | strip_uris | upstream URI (call from Kong)
|-------------------------|------------------|------------------|---------------|
| /foo/bar | /foo/bar | false | /foo/bar |
| /foo/bar | /foo/bar/ | false | /foo/bar/ |
| /foo/bar | /foo/bar | true | /bar |
| /foo/bar | /foo/bar/ | true | /bar/ |
| /foo/bar | / | N/A | /foo/bar |
| /foo/bar/ | / | N/A | /foo/bar/ |
| /foo/bar/ | /foo/bar | false | /foo/bar |
| /foo/bar/ | /foo/bar/ | false | /foo/bar/ |
| /foo/bar/ | /foo/bar | true | /bar |
| /foo/bar/ | /foo/bar/ | true | /bar/ |

Explanation: we still ignore trailing slash in upstream_url, and only consider it when the request URI is / (rows 5 and 6).

This way, whenever the request URI is not /, then the user has control on whether the upstream URI will be with or without a trailing slash. Any thoughts?

All 16 comments

Hey,

Noticed your message on Gitter (I think?) but thanks for the report! Will investigate.

@thibaultcha yeah, that was me, figured it warranted an issue. Thanks for your help!

I have the same question. It didn't behave like this in 0.9.8. The extra slash is unexpected. How to avoid that?

Hi, just came across this issue too. Also looking for a workaround. This is a serious issue because some upstream behave differently with a trailing slash http://foo/bar can be different from http://foo/bar/ in my case http://foo/bar/ return a 404 while http://foo/bar does not.

Here is what I would propose to handle upstream URLs trailing slashes:

Since 0.10.0, we know an API's upstream_url cannot contain a trailing slash value anymore. This is currently explicitly enforced by not accepting trailing slash values from the Admin API (HTTP 400 responses to the client). It could be handled differently, and stripped under the hood at insert time, sure. This is I feel, is not the main concern raised by this discussion. Just trying to make this point clearer after the talk with @pklingem on Gitter and the links provided in the issue.


Now on to the issue at hand: providing a way for the consumer to be able to chose whether the upstream URL will have a trailing slash or not. For this, I believe we can do the following:

The decision on whether or not to append a trailing slash to the upstream URI depends on the incoming request URI:

| upstream_url | request URI | strip_uris | upstream URI (call from Kong)
|-------------------------|------------------|------------------|---------------|
| /foo/bar | /foo/bar | false | /foo/bar |
| /foo/bar | /foo/bar/ | false | /foo/bar/ |
| /foo/bar | /foo/bar | true | /bar |
| /foo/bar | /foo/bar/ | true | /bar/ |
| /foo/bar | / | N/A | /foo/bar |
| /foo/bar/ | / | N/A | /foo/bar/ |

The last row in here seems to be the only way to control whether or not to append a trailing slash to the upstream URI (call from Kong) when the request URI simply is /, so would require that upstream_url needs to be able to handle trailing slashes again. In that case, the full table could become:

| upstream_url | request URI | strip_uris | upstream URI (call from Kong)
|-------------------------|------------------|------------------|---------------|
| /foo/bar | /foo/bar | false | /foo/bar |
| /foo/bar | /foo/bar/ | false | /foo/bar/ |
| /foo/bar | /foo/bar | true | /bar |
| /foo/bar | /foo/bar/ | true | /bar/ |
| /foo/bar | / | N/A | /foo/bar |
| /foo/bar/ | / | N/A | /foo/bar/ |
| /foo/bar/ | /foo/bar | false | /foo/bar |
| /foo/bar/ | /foo/bar/ | false | /foo/bar/ |
| /foo/bar/ | /foo/bar | true | /bar |
| /foo/bar/ | /foo/bar/ | true | /bar/ |

Explanation: we still ignore trailing slash in upstream_url, and only consider it when the request URI is / (rows 5 and 6).

This way, whenever the request URI is not /, then the user has control on whether the upstream URI will be with or without a trailing slash. Any thoughts?

@thibaultcha thank you for the thorough explanation and prompt reply. I agree that this is the best path forward and provides the most flexibility for the Kong administrator and API clients.

@thibaultcha thanks a lot for your detailed explanation. My config is very similar to @pklingem 's case:

  • upstream_url: http://upstream/service-test
  • strip_uris: true
  • uris: /v1/test/service

Then when I send a request http://kong/v1/test/service?x=1&y=2, it will be converted by kong to http://upstream/service-test/?x=1&y=2 which will surely cause an error. Is it a normal behaviour in 0.10's routing strategy? If yes, how to avoid that extra unexpected slash before the query string?

According to your table, only the 2nd and 4th rows will append trailing slashes (notice that I don't have trailing slash configured in upstream_url), and only because there ARE slashes in the raw request uri. They look quite reasonable and straight forward. But I don't see how to solve @pklingem 's problem as well as mine. Would you please give me some more hints? Thanks a lot!

@thibaultcha I have the same question in the version of 0.10x. When I access one of my services like http:// example.com/service.controller through the browser, the browser give me the right data and return the HTTP status code 200 OK, but when I add a slash at the end of that url, that is to say the url is http:// example.com/service.controller/, the browser return the HTTP status code 404 NOT FOUND and I don't receive the right data which I want to get. If I want to get the right data from the service when I access the url, I should not add the slash at the end of that url.

when I register an API like

  • name: test1
  • upstream_url: 'http:// example.com/service.controller'
  • uris:'/test1'

Then access the API by curl:curl -X GET http://kong:8000/test1.
Unfortunately,It return HTTP status code 404 NOT FOUND. Why? Because KONG add a slash at the end of upstream_url, I can't get the right data.
When I use the vesion of 0.9x, I can get the right result, because KONG don't add a slash at the end.
So, how to fix that bug? Look forward to the next version or we can configure some parameters to avoid the slash at the end?

Hi folks,

My configuration is actually the opposite to this, that is, I do need a trailing slash for my backend to work.

I wanted to confirm with you folks that I understand this correctly. In 0.9.X, the trailing slash is deleted (at least if strip_request_path is enabled) whereas it is appended in 0.10.0 and 0.10.1.

In addition, the way it will be implemented in the future is as @thibaultcha described. Am I right?

Many thanks.

@mgiorgio, correct. I will be looking at this issue and implement this as @thibaultcha suggested above. Is that alright with you?

@bungle yes, that would be perfect! Thanks!

@bungle Thanks for your response.We also had the same problem.kong10.x appended slash on upstream url,and kong0.9.x did not act that. When will u release this change?

@deepshrift, I will keep you updated. I hope soon.

@deepshrift, @mgiorgio, @ssholder, @tumluliu, @pklingem, @mbugeia,

I just pushed a first try to fix this with PR #2315. It would be really helpful if you could try the patch, and report back any findings.

This fix is just what we need too

@rodrigo-garcia-engrande, I'm pretty sure we get this to next release, along with #2343.

Was this page helpful?
0 / 5 - 0 ratings