Skip to content

Commit

Permalink
Update Vert.x to 4.1.0.Beta1 and Netty to 4.1.65.Final
Browse files Browse the repository at this point in the history
This update introduces some changes.
First, when the HTTP compression is set to identity, the header is not written into the response anymore.
Then, the cookie interface has a new method (maxAge), so our implementations must be updated.

Finally, and that's the more significant change. Netty now depends on Brotli4J. Brotli is a compression algorithm.
The implementation uses a native dependency. At the moment, we won't support Brotli in native mode. This
commit adds a substitution to disable it. All decoders using Brotli related classes have been substituted to avoid having to depend on the Brotli4J dependency.
  • Loading branch information
cescoffier committed May 24, 2021
1 parent 31a6912 commit a8a239a
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 15 deletions.
4 changes: 2 additions & 2 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
<wildfly-elytron.version>1.15.4.Final</wildfly-elytron.version>
<jboss-modules.version>1.8.7.Final</jboss-modules.version>
<jboss-threads.version>3.2.0.Final</jboss-threads.version>
<vertx.version>4.1.0.Beta1</vertx.version>
<vertx.version>4.1.0.CR1</vertx.version>
<httpclient.version>4.5.13</httpclient.version>
<httpcore.version>4.4.14</httpcore.version>
<httpasync.version>4.1.4</httpasync.version>
Expand All @@ -137,7 +137,7 @@
<infinispan.version>12.1.1.Final</infinispan.version>
<infinispan.protostream.version>4.4.0.Final</infinispan.protostream.version>
<caffeine.version>2.9.1</caffeine.version>
<netty.version>4.1.60.Final</netty.version>
<netty.version>4.1.65.Final</netty.version>
<reactive-streams.version>1.0.3</reactive-streams.version>
<jboss-logging.version>3.4.1.Final</jboss-logging.version>
<mutiny.version>0.17.0</mutiny.version>
Expand Down
8 changes: 8 additions & 0 deletions extensions/netty/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@
<groupId>io.netty</groupId>
<artifactId>netty-codec</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-codec-http</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-codec-http2</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package io.quarkus.netty.runtime.graal;

import static io.netty.handler.codec.http.HttpHeaderValues.DEFLATE;
import static io.netty.handler.codec.http.HttpHeaderValues.GZIP;
import static io.netty.handler.codec.http.HttpHeaderValues.X_DEFLATE;
import static io.netty.handler.codec.http.HttpHeaderValues.X_GZIP;

import java.nio.ByteBuffer;
import java.security.PrivateKey;
import java.security.Provider;
Expand All @@ -17,6 +22,7 @@
import javax.net.ssl.TrustManagerFactory;

import com.oracle.svm.core.annotate.Alias;
import com.oracle.svm.core.annotate.Delete;
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.RecomputeFieldValue.Kind;
import com.oracle.svm.core.annotate.Substitute;
Expand All @@ -29,7 +35,14 @@
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.DefaultChannelPromise;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.compression.ZlibCodecFactory;
import io.netty.handler.codec.compression.ZlibWrapper;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http2.Http2Exception;
import io.netty.handler.ssl.ApplicationProtocolConfig;
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior;
import io.netty.handler.ssl.CipherSuiteFilter;
Expand Down Expand Up @@ -83,7 +96,9 @@ static boolean isAlpnSupported() {
}
}

/** Hardcode io.netty.handler.ssl.OpenSsl as non-available */
/**
* Hardcode io.netty.handler.ssl.OpenSsl as non-available
*/
@TargetClass(className = "io.netty.handler.ssl.OpenSsl")
final class Target_io_netty_handler_ssl_OpenSsl {

Expand Down Expand Up @@ -186,7 +201,8 @@ final class Target_io_netty_handler_ssl_JdkAlpnApplicationProtocolNegotiator_Alp
@Substitute
public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc,
JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) {
return (SSLEngine) (Object) new Target_io_netty_handler_ssl_JdkAlpnSslEngine(engine, applicationNegotiator, isServer);
return (SSLEngine) (Object) new Target_io_netty_handler_ssl_JdkAlpnSslEngine(engine, applicationNegotiator,
isServer);
}

}
Expand Down Expand Up @@ -242,7 +258,8 @@ final class Target_io_netty_handler_ssl_SslContext {

@Substitute
static SslContext newServerContextInternal(SslProvider provider, Provider sslContextProvider,
X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, X509Certificate[] keyCertChain,
X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
X509Certificate[] keyCertChain,
PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, Iterable<String> ciphers,
CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout,
ClientAuth clientAuth, String[] protocols, boolean startTls, boolean enableOcsp, String keyStoreType,
Expand All @@ -257,10 +274,12 @@ static SslContext newServerContextInternal(SslProvider provider, Provider sslCon
}

@Substitute
static SslContext newClientContextInternal(SslProvider provider, Provider sslContextProvider, X509Certificate[] trustCert,
static SslContext newClientContextInternal(SslProvider provider, Provider sslContextProvider,
X509Certificate[] trustCert,
TrustManagerFactory trustManagerFactory, X509Certificate[] keyCertChain, PrivateKey key, String keyPassword,
KeyManagerFactory keyManagerFactory, Iterable<String> ciphers, CipherSuiteFilter cipherFilter,
ApplicationProtocolConfig apn, String[] protocols, long sessionCacheSize, long sessionTimeout, boolean enableOcsp,
ApplicationProtocolConfig apn, String[] protocols, long sessionCacheSize, long sessionTimeout,
boolean enableOcsp,
String keyStoreType, Map.Entry<SslContextOption<?>, Object>... options) throws SSLException {
if (enableOcsp) {
throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider);
Expand Down Expand Up @@ -305,11 +324,11 @@ static JdkApplicationProtocolNegotiator toNegotiator(ApplicationProtocolConfig c
// .append(config.selectorFailureBehavior()).append(" failure behavior").toString());
// }
SelectorFailureBehavior behavior = config.selectorFailureBehavior();
if (behavior == SelectorFailureBehavior.FATAL_ALERT)
if (behavior == SelectorFailureBehavior.FATAL_ALERT) {
return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols());
else if (behavior == SelectorFailureBehavior.NO_ADVERTISE)
} else if (behavior == SelectorFailureBehavior.NO_ADVERTISE) {
return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols());
else {
} else {
throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ")
.append(config.selectorFailureBehavior()).append(" failure behavior").toString());
}
Expand All @@ -321,12 +340,14 @@ else if (behavior == SelectorFailureBehavior.NO_ADVERTISE)
return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols());
default:
throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ")
.append(config.selectedListenerFailureBehavior()).append(" failure behavior").toString());
.append(config.selectedListenerFailureBehavior()).append(" failure behavior")
.toString());
}
}
default:
throw new UnsupportedOperationException(
new StringBuilder("JDK provider does not support ").append(config.protocol()).append(" protocol")
new StringBuilder("JDK provider does not support ").append(config.protocol())
.append(" protocol")
.toString());
}
}
Expand Down Expand Up @@ -515,6 +536,67 @@ public long memoryAddress() {

}

@TargetClass(className = "io.netty.handler.codec.compression.BrotliDecoder")
@Delete
final class Target_BrotliDecoder {

}

@TargetClass(className = "io.netty.handler.codec.http.HttpContentDecompressor")
final class Target_io_netty_handler_codec_http_HttpContentDecompressor {

@Alias
private boolean strict;

@Alias
protected ChannelHandlerContext ctx;

@Substitute
protected EmbeddedChannel newContentDecoder(String contentEncoding) throws Exception {
if (GZIP.contentEqualsIgnoreCase(contentEncoding) ||
X_GZIP.contentEqualsIgnoreCase(contentEncoding)) {
return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(),
ctx.channel().config(), ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP));
}
if (DEFLATE.contentEqualsIgnoreCase(contentEncoding) ||
X_DEFLATE.contentEqualsIgnoreCase(contentEncoding)) {
final ZlibWrapper wrapper = strict ? ZlibWrapper.ZLIB : ZlibWrapper.ZLIB_OR_NONE;
// To be strict, 'deflate' means ZLIB, but some servers were not implemented correctly.
return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(),
ctx.channel().config(), ZlibCodecFactory.newZlibDecoder(wrapper));
}

// 'identity' or unsupported
return null;
}
}

@TargetClass(className = "io.netty.handler.codec.http2.DelegatingDecompressorFrameListener")
final class Target_io_netty_handler_codec_http2_DelegatingDecompressorFrameListener {

@Alias
boolean strict;

@Substitute
protected EmbeddedChannel newContentDecompressor(ChannelHandlerContext ctx, CharSequence contentEncoding)
throws Http2Exception {
if (!HttpHeaderValues.GZIP.contentEqualsIgnoreCase(contentEncoding)
&& !HttpHeaderValues.X_GZIP.contentEqualsIgnoreCase(contentEncoding)) {
if (!HttpHeaderValues.DEFLATE.contentEqualsIgnoreCase(contentEncoding)
&& !HttpHeaderValues.X_DEFLATE.contentEqualsIgnoreCase(contentEncoding)) {
return null;
} else {
ZlibWrapper wrapper = this.strict ? ZlibWrapper.ZLIB : ZlibWrapper.ZLIB_OR_NONE;
return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), ctx.channel().config(),
new ChannelHandler[] { ZlibCodecFactory.newZlibDecoder(wrapper) });
}
} else {
return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), ctx.channel().config(),
new ChannelHandler[] { ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP) });
}
}
}

class NettySubstitutions {

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package io.quarkus.vertx.http;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;

Expand Down Expand Up @@ -45,7 +48,7 @@ public void test() throws Exception {
.body(Matchers.equalTo(longString));

RestAssured.given().get("/nocompress").then().statusCode(200)
.header("content-encoding", "identity")
.header("content-encoding", is(nullValue()))
.header("content-length", Matchers.equalTo(Integer.toString(longString.length())))
.body(Matchers.equalTo(longString));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ public void testEditingBeanUsingVertx() {
.statusCode(200)
.body(containsString("hello"));

System.out.println("Modification");
TEST.modifySourceFile("VertxEventBusConsumer.java", s -> s.replace("hello", "bonjour"));
System.out.println("After");
RestAssured.get("/").then()
.statusCode(200)
.body(containsString("bonjour"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@ public Cookie setMaxAge(long maxAge) {
return null;
}

@Override
public long getMaxAge() {
return Long.MIN_VALUE;
}

@Override
public Cookie setSecure(boolean secure) {
return null;
Expand Down

0 comments on commit a8a239a

Please sign in to comment.