Warm tip: This article is reproduced from serverfault.com, please click

REST API generating absolute URLs behind reverse proxy

发布于 2020-12-07 13:23:43

Situation

I have a REST API in place that returns JSON objects to its clients. Part of said JSON responses are absolute URLs to other "linked" resources/objects of the form "http://myservice.com/servicePath/apiVersionA/123". In the example URL "servicePath" is the web root of my service, "apiVersionA" is the specific version of the REST API being used, and "123" is the identifier of the actual resource. The fact that my API is returning absolute resource URLs in the response body is prescribed by the protocol I'm using, I am not at liberty to change that.

Problem The problem I'm facing now are reverse proxies, and more specifically how I assume they handle request patterns like the following:

  1. Client sends request "GET http://myproxy.com/rest/apiVersionA/123" to the Reverse Proxy.
  2. Reverse Proxy forwards the request to its final destination: "GET http://myservice.com/servicePath/apiVersionA/123". Please note that the proxy modifies both the host name and the URL path ("rest" is changed to "servicePath") of the request.

AFAIK, the usual suspects (i.e. HTTP headers "Forwarded", "X-Forwarded-For", "X-Forwarded-Host" etc.) only contain either IP addresses or domain names, but not the entire URL path. So right now in the best case scenario I can generate URLs like "http://myproxy.com/apiVersionA/123" - notice the missing "rest" URL path element that is required by the proxy. This URLs will thus not be accepted by the proxy in a subsequent request made by the client, e.g. to retrieve a resource that is referenced in the response message.

Questions

  1. Is there an obvious proxy-safe HTTP header I am missing that would deliver the original request URL to the actual REST API service?
  2. If not, is there another way how I can generate correct absolute URLs in my service?

So far I have thought about using a custom HTTP header (which might get removed by an intermediate proxy), or by using something like https://httpd.apache.org/docs/2.4/mod/mod_substitute.html on the reverse proxy (which I'd say is not possible as I do not control the networking infrastructure of my customers or any intermediaries). Another "non-solution" that I came up with is to document this as part of my API: "do not use custom URL path elements on your HTTP proxies". This would allow me to generate URLs using just X-Forwarded-Host and X-Forwarded-Proto.

Any help is appreciated!

Questioner
Michael Schmid
Viewed
0
Michael Schmid 2020-12-11 03:19:38

After some more research it became apparent that there is indeed no standard HTTP header that can do the job. I have thus proceeded with implementing a combination of "Forwarded/X-Forwarded-For" and Microsoft's proprietary "X-Forwarded-PathBase" (https://microsoft.github.io/reverse-proxy/articles/transforms.html) header. This works as intended - customers that cannot or do not want to use the proprietary header still get back valid absolute URLs via the reverse proxy, as long as they do not implement request path mapping in their proxy configuration.