Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jetty-users] Proxy from H2 to 1.1

Hi,

On Thu, Jul 30, 2020 at 5:54 PM Travis Spencer <travis.spencer@xxxxxxxxx> wrote:
>
> On Thu, Jul 30, 2020 at 4:33 PM Simone Bordet <sbordet@xxxxxxxxxxx> wrote:
> >
> > Hi,
>
> Hey, Simone. Thanks for bearing with me even though my message was so confusing. Let me try to clarify.
>
> > On Thu, Jul 30, 2020 at 11:47 AM Travis Spencer
> > <travis.spencer@xxxxxxxxx> wrote:
> > >
> > > We are trying to add H2 support to our server that embeds Jetty. This
> > > works perfectly except in the case where we proxy to downstream
> > > services. For a couple routes, we forward to an HTTP (not HTTPS)
> > > server and a server that doesn't support H2. In these cases, the proxy
> > > request fails since non-SSL with H2 isn't supported by the one origin
> > > server and the other only accepts 1.1.
> > >
> > > So, my question is, how in our AsyncProxyServlet subclass should we
> > > specify that the proxy requests should use HTTP 1.1 and not H2? ATM,
> > > the proxied request seems to always use whatever version the client
> > > used when communicating with the proxy servlet.
> >
> > I am not sure I understand.
>
> A picture's worth a 1000 words, so here's a diagram:
>
>                         +-----------------------------+
>                         |                             |
>                         |    +--------------------+   |
>        H2 for various   |    |                    |   |
>        non-proxied cases|    |                    |   |
>                +-------------+  Jetty Web server  |   |
>                         |    |                    |   |                   +-----------------+
>                         |    |                    |   |      HTTP 1.1     |                 |
>                         |    +--------------------+   |      without SSL  |     Origin      |
>        H2 that proxies  |                             |           +-------+     server      |
>        to an HTTP 1.1   |    +--------------------+   |           ^       |       1         |
>        server without   |    |                    |   |           |       +-----------------+
>        SSL     +-------------+                    +---------------+
>                         |    | Jetty Proxy Server |   |
>                         |    |                    |   |
>                +-------------+                    +---------------+       +-----------------+
>                         |    +--------------------+   |           v       |     Origin      |
>        H2 that proxies  |                             |           +-------+     server      |
>        to an HTTP 1.1   |           Our Server        |       HTTP 1.1    |        2        |
>        server with SSL  |                             |       with SSL    |                 |
>                         +-----------------------------+                   +-----------------+
>
>
>
> (In case the fonts get screwed up you can find a copy of that diagram here: https://drive.google.com/file/d/1Ks8AsjeKHcSUyL7qVtjenkputtsqJZPZ/view?usp=sharing)
>
> > You have a server that is both a server (i.e. it answers requests
> > directly) and a proxy (i.e. it uses AsyncProxyServlet to forward to
> > other servers that only support HTTP/1.1).
>
> Yes, exactly.
>
> > AsyncProxyServlet will create an instance of HttpClient with (by
> > default) the HTTP/1.1 transport.
> > So every proxied request will be sent as HTTP/1.1.
> >
> > Therefore it is already the case that all proxied requests use HTTP/1.1.
>
> That's not what I'm seeing, in the logs at least. I think the logged info is correct too because the origin servers (both of them) are giving me errors, and the only thing I've changed is H2 support on the proxy.
>
> > > When access the downstream HTTP 1.1 server, the client and proxy
> > > request looks like this:
> > >
> > > MyGoodTransparentProxyServlet:70 474713221 rewriting:
> > > https://localhost:5555/mygood-api ->
> > > https://remote.example.com:443/some-other-good-api
> >
> > Uh? You said the other server was not using HTTPS?
>
> One is HTTP and one is HTTPS.
>
> > > HttpRequest[GET /some-other-good-api HTTP/2.0]@8c22593
>
> See, Simone, how the proxy uses H2 as well and not 1.1?

That does not mean the request is sent using HTTP/2.
The HTTP version is copied from the incoming request, which in your
case is HTTP/2.
But it is sent as HTTP/1.1 on the wire and that may confuse your server.

Override AsyncProxyServlet.copyRequestHeaders() or addProxyHeaders()
to customize the proxy request, and force
version(HttpVersion.HTTP_1_1).

Please file an issue about this, we should do a bit better here.

> Here's an example of the default Via that's created when my subclass calls org.eclipse.jetty.proxy.AbstractProxyServlet#addProxyHeaders:
>
> Via: http/1.1 null
>
> The http/1.1 is hardcoded (which is wrong IINM, since I connected via H2) and the host is not a pseudonym and not the actual host.

I don't know where this comes from.
viaHost is configured in AbstractProxyServlet.init() and is never null
(see method viaHost()).
The "http/1.1" is hardcoded in addViaHeader(), but you can override the method.

Please file an issue about this as well, as we should remove the
hardcoded "http/1.1" from the Via header.

Thanks!

-- 
Simone Bordet
----
http://cometd.org
http://webtide.com
Developer advice, training, services and support
from the Jetty & CometD experts.


Back to the top