Skip to content

Documentation : behind a reverse proxy #705

@christopheblin

Description

@christopheblin

Here is a code snippet you could include in the documentation reltive to RootUrl https://github.com/domaindrivendev/Swashbuckle#rooturl

I think I am facing a common problem (2 chained reverse proxies) and many users can benefit from this...

    public static string ComputeHostAsSeenByOriginalClient(HttpRequestMessage req)
    {
        if (req.Headers.Contains("X-Forwarded-Host"))
        {
            //we are behind a reverse proxy, use the host that was used by the client
            var xForwardedHost = req.Headers.GetValues("X-Forwarded-Host").First();
            //when multiple apache httpd are chained, each proxy append to the header 
            //with a comma (see //https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#x-headers).
            //so we need to take only the first host because it is the host that was 
            //requested by the original client.
            //note that other reverse proxies may behave differently but 
            //we are not taking care of them...
            var firstForwardedHost = xForwardedHost.Split(',')[0];

            //now that we have the host, we also need to determine the protocol used by the 
            //original client.
            //if present, we are using the de facto standard header X-Forwarded-Proto, assuming 
            //that only the first reverse proxy in the chain added it.
            //otherwise, we fallback to http
            //note that this is extremely brittle, either because the first proxy 
            //can "forget" to set the header or because another proxy can rewrite it...
            var xForwardedProto = req.Headers.Contains("X-Forwarded-Proto")
                ? req.Headers.GetValues("X-Forwarded-Proto").First()
                : "http";
            return xForwardedProto + "://" + firstForwardedHost;
        }
        else
        {
            //no reverse proxy mean we can directly use the RequestUri
            return req.RequestUri.Scheme + "://" + req.RequestUri.Authority;
        }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions