Is there a means to set the host & port for the Spring HATEOAS `ControllerLinkBuilder`?

落花浮王杯 提交于 2019-12-01 04:58:07

A pure answer to the question I originally posed seems to involve writing my own ControllerLinkBuilder implementation which has the option of building the URL based on environment variables that I set. I may do that.

However, the reason I was trying to force the URL is that there is a bug in the ControllerLinkBuilder. It's worth noting that this bug is a bug in code which was copied from ServletUriComponentsBuilder.

String scheme = request.getScheme();

// The port number retrieved here is the port set by server.port
int port = request.getServerPort();
String host = request.getServerName();

String header = request.getHeader("X-Forwarded-Host");

if (StringUtils.hasText(header)) {
    String[] hosts = StringUtils.commaDelimitedListToStringArray(header);
    String hostToUse = hosts[0];
    if (hostToUse.contains(":")) {
        String[] hostAndPort = StringUtils.split(hostToUse, ":");
        host  = hostAndPort[0];

        // Note that the port is set if there is a ":" in the address.
        port = Integer.parseInt(hostAndPort[1]);
    }
    else {
        host = hostToUse;
    }
}

ServletUriComponentsBuilder builder = new ServletUriComponentsBuilder();
builder.scheme(scheme);
builder.host(host);

// Here lies the bug...
if ((scheme.equals("http") && port != 80) || (scheme.equals("https") && port != 443)) {
    builder.port(port);
}

Basically, the port is only set when the server.port is not 80 or 443, rather than being based on the port used for the request. This means that if the X-Forwarded-Host is using a default port for the scheme (and therefore not having anything after the ":"), then the application port will be used instead of the default.

Spring-Boot uses an older version of Spring-HATEOAS, i think it was .11 that they added support for X-Forwarded-Port and X-Forwarded-Ssl headers, just add that explicit version to your POM and if your proxy is doing the right thing and adding those headers you should be good to go.

Also if your proxy can be configured to NOT rewrite the HOST header the built in controller link builder will work just fine.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!