Mark,
On 6/6/23 06:42, Mark Thomas wrote:
devOn 02/06/2023 18:55, Christopher Schultz wrote:
Mark,
On 6/2/23 11:00, Mark Thomas wrote:
On 02/06/2023 15:35, Christopher Schultz wrote:
All,
I've built a Filter for use with a client who has many environments,
many reverse proxies, and many application servers and were getting
confused about what was what.
Basically, it just adds a "Via" header as appropriate and has some
configurability to choose the header name, override the protocol and
server-name if requested, and to limit the number of IP-segments
reported in the value.
Would this be something useful to add to Tomcat?
That implies that Tomcat is acting as a reverse proxy. Given that
functionality isn't built into Tomcat, I'd expect whatever component
is providing the reverse proxy functionality to provide the Via
header and any other appropriate debug tools. It seems a little odd
to provide a debug tool with Tomcat for a feature that Tomcat doesn't
implement.
I was thinking that Tomcat here was an origin server and reporting its
own identity, etc. to the reverse-proxy, which would then add its own
"Via" header.
I'm a little confused about how this all works.
Sorry, I think I didn't give enough explanation.
Shouldn't the reverse proxy add the Via header before forwarding the
request?
Is the Filter adding a Via header? I read the original post as it was.
But Via headers are for proxy's not origin servers.
Maybe an example would help. Or a link to the Filter's source.
It's possible that I may be abusing the HTTP Via header, but I don't
think so.
The idea was to provide information to the *client* about which servers
are handling the request. The HTTP Via header seems to fit the billing,
as a response-header and not a request-header. I'm not worried about
request-headers at all, here.
My Filter basically says 'add "Via: protocol/version myself" header to
the response' and that's it. The reverse-proxy can augment the Via
response header with its own. So for a simple setup where we have two
web servers and two Tomcat servers cross-linked, the client might see a
response header looking like this:
Via: HTTP/1.1 web1, HTTP/1.1 tomcat2
I am generally in favour of adding Filters that are generally useful but
wary of things that appear to behave in unexpected ways.
As you should be.
I created this Filter to be used in a situation with multiple
environments and where there are multiple reverse proxies between the
client and the Tomcat server. We were tracking-down what we believed was
a misconfiguration of one or more of the reverse-proxies that
cross-linked environments and we needed to figure out which pair of
reverse-proxy servers were being used in a simple way e.g. using curl.
(Automation wasn't going to solve this one, unfortunately, given the way
things had been deployed).
So we configured the Tomcat servers to announce themselves and the httpd
servers to do the same, using the Via header in this way.
I suppose the httpd instance could set the header to include BOTH
servers, since it really ought to know its own identity as well as the
identity of the origin server it's connecting to, but ... I chose this
way instead since upstream could be more complicated than httpd knows.
Here is the code of the doFilter function without the source of the
supporting functions:
StringBuilder serverIdentifier = new StringBuilder(64); // 64
characters ought to be enough for anybody
String protocol = getProtocol();
if(null == protocol) {
protocol = httpRequest.getProtocol();
if(null != protocol) {
if(!getIncludeProtocolName()) {
int pos = protocol.indexOf('/');
if(0 <= pos) {
protocol = protocol.substring(pos + 1);
}
}
serverIdentifier.append(protocol);
}
} else {
serverIdentifier.append(protocol);
}
String serverName = getServerName();
if(null == serverName) {
serverName = getTrimmedIPAddress(httpRequest.getLocalAddr());
}
serverIdentifier.append(' ').append(serverName);
if(getIncludePort()) {
serverIdentifier.append(':').append(httpRequest.getLocalPort());
}
httpResponse.addHeader(getHeaderName(),
serverIdentifier.toString());
Most of the stuff has reasonable defaults. If you installed this on
localhost IPv4 and didn't override anything, you'd get "Via: HTTP/1.1 1"
i the response header because the IP address 127.0.0.1 would have all
but the last octet of the address removed, leaving just the "1". This is
pretty useless for localhost, but in a subnet with multiple backends,
you'd get e.g. "Via: HTTP/1.1 42" and "Via HTTP/1.1 43" for servers on
x.x.x.42 and x.x.x.43 respectively.
You can override everything, including which header to use, the "name"
of the server (to get "Via: HTTP/1.1 gandalf" if that's what you want it
to say) and the protocol (including the version number).
Let me know if you have any more questions. I'm happy to share full
source if it would be helpful.
Re-reading the code (after already providing for some caching of certain
things), I can see that it could benefit from even more caching. The
common case will be that the Via header will always be set to the same
thing for every single request. Sure, it's possible that some requests
are served via HTTP and some via AJP, but I think usually the response
header will always be the same, so it's probably worth adding a little
bit of "quick checking" to avoid StringBuilder churn. Using shared
structures e.g. ConcurrentHashMap may be a wash, though, so I'd be happy
to get some feedback on whether this optimization won't really be effective.
-chris
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org