[jsr369-experts] Re: [servlet-spec users] RFC7239 support

From: Greg Wilkins <gregw_at_webtide.com>
Date: Wed, 14 Sep 2016 14:32:22 +1000

On 14 September 2016 at 12:15, Edward Burns <edward.burns_at_oracle.com> wrote:

> Can someone please give us the TLDR on RFC7239?

Application servers are often deployed behing proxies/load
balancer/caches/TLS offloaders and other intermediaries. Such
intermediaries can hide important information about a connection such as
originating IP, original protocol etc. which an App Server often needs for
implementing features (eg. geolocating the client).

Various intermediaries came up with proprietary headers to communicate
connection information to the appserver, but the ones that became a popular
were those implemented by the squid cache:

   - X-Forwarded-Host
   - X-Forwarded-Server
   - X-Forwarded-For
   - X-Forwarded-Proto
   - X-Proxied-Https (not sure if this one is actually from squid, but it
   is used sometimes, but proto is more frequent).

These headers are considered a defacto standard and are widely supported.
However they were never codified into an RFC as they are. Instead
 RFC7239 was developed that allowed the same information to be communicated
in with a single Forwarded header.

> How about a sketch of what methods we would like to see?

I've not given this a great deal of thought regarding API, but I have
thought about some issues. Implementations of either X-Forwarded or
Forwarded headers typically override some or all of the local connection
values provided by:

   - getProtocol()
   - isSecure()
   - getRemoteAddr()
   - getRemoteHost()
   - getRemotePort()
   - getLocalName()
   - getLocalAddr()
   - getLocalPort()

However, even for something as seemingly simple as getRemoteAddr(), there
are needs to differently interpret the headers. If you want to geolocate
then using the left-most "for" value is likely to give you the most
accurate location of the client (and not the location of a proxy), but it
can be client supplied data so it cannot really be trusted. So if you
want the remote addr to defend against a DOS attack, then you want the
right-most value, which is the "for" value from the last intermediary - ie
the one in your data center that you trust.

So an API that lets you get the left most or right most Forwarded instance
would be good.

You then may want to aggregate Forwarded entries leftwards or rightwards,
as each intermediary does not necessarily set all the Forwarded fields. So
sometimes you might want the value from the right hand proxy, or null if it
was not set, other times you may want just the right-most value of a field.

The reason to standardize handling of this is that it is one of those
things were it is easy to get handling of these headers working, but it is
hard to get such handling robust in the face of clients that lie and
complex intermediaries with value parameters etc. etc.

If there is interest in standardizing this, I'll give some more thought to
an API.


Greg Wilkins <gregw@webtide.com> CTO http://webtide.com