Support HTTP/1.1 and HTTP/2 with a JAX-RS client
Asked Answered
H

5

24

I want to implement a JAX-RS client that support HTTP/1.1 and HTTP/2 for a JAX-RS client.

The idea is to use HTTP/2 if the server supports ALPN with HTTP/2 and uses HTTP/1.1 if the server does not provide any information.

I have read some articles about ALPN and it seems to be possible but I don't find anything supporting these protocol at the same time. I did not manage to plug these together.

I am currently using the Jetty HTTP/1.1 transport connector for Jersey and a custom implementation for HTTP/2 transport connector.

Hypogastrium answered 20/2, 2017 at 15:10 Comment(4)
You want to open an issue to Jetty to support dynamic selection of the transport to use based on ALPN. That way, you will only write one Jersey transport that works with both protocols. Thanks !Yawp
@Yawp I have just created the issueHypogastrium
Are you trying to use any async calls in your applicationCastaway
@SaurabhJhunjhunwala Just sync for the momentHypogastrium
H
4

Java HTTP client provided with Java 11 is supporting HTTP/1.1 and HTTP/2 (see Introduction to the Java HTTP Client).

I have built a connector using it Jersey Connector using java.net.http.HttpClient. You can use it adding the following dependency.

<dependency>
  <groupId>com.github.nhenneaux.jersey.connector.httpclient</groupId>
  <artifactId>jersey-httpclient-connector</artifactId>
  <version>0.2.2</version>
</dependency>

Maven Central

Hypogastrium answered 5/8, 2019 at 6:5 Comment(1)
Fantastic! Thank you. Question remains why this is not the default for Jersey.Peckham
C
-1

In fact ALPN is only support by jdk starting at JDK9 http://unrestful.io/2015/10/09/alpn-java.html.

That's is not handle by JAX-RS client api

Cutback answered 24/5, 2018 at 10:50 Comment(3)
It can be supported using a library (Jetty ALPN) with the TLS client of the JVM or using another TLS client (e.g. conscrypt). It can be handled through JAX-RS if the underlying transport handle it. For the moment there is none but the Jetty project would like to implement it github.com/eclipse/jetty.project/issues/1350.Hypogastrium
OK but to implement JAX-RS you use an existing http client implementation i suppose Jetty's HttpClient that handle ANPL for you ?Cutback
I use Jersey implementation of JAX-RS that uses under the hood Java HttpUrlConnectionHTTP1 client. Jetty HTTP/1.1 client can also be configured. I have also written an HTTP/2 client based on Jetty. However, there is no underlying transport supporting HTTP/1.1 and HTTP/2 by using ALPN.Hypogastrium
C
-2

A solution could be to use nginx (or apache2) as revers proxy to handle that requirement.

Nginx can proxy your jetty server (using http/1.1 or http/2 only protcol) and server http/2 with alpn (with the latest version) to the clients.

Cutback answered 22/5, 2018 at 21:0 Comment(1)
Indeed it could be a solution. However there are several drawback, i.e. you need to break the TLS encryption in the reverse proxy, you have to change the server whereas it could be an external party and you have to choose one protocol in your client while the point of the question is having a client supporting both protocols.Hypogastrium
S
-2

If this question is still open to contribute, then there is one way of implementing client with < JDK 9 version.

As you know, HTTP/2 requires ALPN support if using TLSv1.2 (h2).

netty package has some support for HTTP/2 provided that you have openssl (version 1.0.2 or later) installed on platform.

Netty package will use OpenSSL for ALPN support by invoking native libraries.

We implemented a client with JDK8 and manage to generate http2 request for operation where server only accepts http2 request. We used below mentioned dependency

    <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-all</artifactId>
        <!--<version>5.0.0.Alpha2</version> -->
        <version>4.1.29.Final</version>
    </dependency>
Sarre answered 20/11, 2018 at 11:41 Comment(5)
Actually I'm looking for a client being able to do both and I don't think your client is doing HTTP/1 and HTTP/2 ?Hypogastrium
My client is doing both HTTP/1.1 & HTTP/2. By default, it is using HTTP/1.1 & for specific service where only HTTP/2 is accepted, we create HTTP/2 requestSarre
can it select dynamically from ALPN output the protocol?Hypogastrium
application is already aware of specific service which only support HTTP/2 and if this service is being invoked, then we build ssl context and a request required for HTTP/2 .Sarre
ok I already got this working (I have an individual client for HTTP/1 and HTTP/2, see links in the question) but not dynamically which is my question actually.Hypogastrium
S
-2

It sounds like your question, in abstract, is you want a Java servlet than can negotiate and terminate a single REST endpoint, so avoiding one interface for HTTP/1 and another for HTTP/2, and avoiding termination externally, like via a proxy that can handle multiple protocols. So an all-in-one servlet.

This was already implemented in Undertow by Stuart (& JBoss folks) at least as late as 2017 when Steve Hu added test cases and PR. 1

You need to pass in the ENABLE_HTTP2 option in the OptionsMap. For http URI's this means that the client will attempt an upgrade on the first request, for https URI's ALPN will be used to try and negotiate HTTP/2. This is how browsers behave, and will work even if the target does not support HTTP/2. 2

It looks like Simone is pushing changes to implement this in Jetty. 3 So if you want this now, switch from Jetty to Undertow, or change the question to "Support ... in Jetty".

Stability answered 20/2, 2019 at 20:4 Comment(4)
This seems promising but actually I have not found so far a way to integrate JAX-RS and an HTTP client supporting both HTTP/1 and HTTP/2 depending on the target server. As far as I know there is no Undertown client connector with a JAX-RS implementation? The implementation of Simone is related to the issue I have created in Jetty. However, if there is another connector being able to connect HTTP/1 and HTTP/2 I can switch ;-)Hypogastrium
Undertow is already integrated as the servlet for Wildfly and Wildfly has JAX-RS, it's implemented as RESTEasy b/c ... well it's a JBoss project not an Apache project, but you can get both. I'm just as curious to try out your scenario on it to verify it works, so do you have a test case somewhere public?Stability
Actually I don't want the Servlet implementation but the HTTP JAX-RS client implementation side which does not seem to be implemented by Undertown unless I have missed something?Hypogastrium
Ah, I misunderstood then.Stability

© 2022 - 2024 — McMap. All rights reserved.