In httpcore 5.2 and in 5.3, if I follow the example and create a simple server
on say port 8000 like this:
SocketConfig socketConfig = SocketConfig.custom()
.setSoTimeout(15, TimeUnit.SECONDS)
.setTcpNoDelay(true)
.build();
server = ServerBootstrap.bootstrap()
//.setExceptionListener(new MyExceptionListener()) // nope
doesnt intercept err 421
.setListenerPort(port)
.setSocketConfig(socketConfig)
//.setCanonicalHostName(InetAddress.getLocalHost().getHostAddress())
//.setSslContext(null)
.register("*", handler)
.create();
It will start and listed on 8000 on all interfaces *.*.
The default behavior if one doesn’t setCanonicalHostName is that it does
exactly what my commented out line above does, which on a laptop or an EC2
instance finds the main ethernet interface and sets the IP address as the
canonical hostname.
The behavior I want is for the incoming request header Host: to be ignored,
regardless of what my http client (curl, another program, a loadbalancer)
thinkgs this machine is called, if the network routing got the request to this
machine I want it to serve it.
What actually happens however is that a curl to the IP works (because it
matches the default canonical hostname the code set).
But a curl to the DNS entry like this:
curl -v http://ip-192-168-17-74.us-west-2.compute.internal:8250/asdf/
results in a 421 Misdirected Request error which I cannot figure out how to
register any kind of error handler to ignore.
This is because the curl request set’s Host:
ip-192-168-17-74.us-west-2.compute.internal
Where this truly falls down is putting this code on an ec2 box and fronting it
with an ALB and TargetGroup.
The target group created just by IP address sends health checks, these have
Host: 10.1.2.3 set, for whatever the internal private vpc IP address is for
this host, and that works.
The load balancer however has it’s own DNS entry like
internal-Consumers-1234567.us-west-2.elb.amazonaws.com
and if one uses curl on that:
curl -v http://internal-Consumers-1234567.us-west-2.elb.amazonaws.com:8250/asdf
Then the Host: request header is set to
internal-Consumers-1234567.us-west-2.elb.amazonaws.com
<http://internal-consumers-1234567.us-west-2.elb.amazonaws.com/>,
and the ALB passes the Host: header along,
and the httpcore5 server rejects it with 421.
If I were to code that ALB dns name as the canonicalHostName, then the health
checks would fail.
I know it’s not that secure but that’s fine for this use-case, I’m trying to
get org.apache.hc.core5.http.impl.bootstrap.HttpServer
to just start a basic http server that responds regardless of what the incoming
Host: request header is.
Or, at least figure out how anyone else using this would deploy it to amazon on
ec2 and have both healthchecks and normal traffic actually work?
Thanks alot fo anyone’s time.