Skip to content

Commit

Permalink
Merge remote-tracking branch '3.0' into '3.1'
Browse files Browse the repository at this point in the history
Signed-off-by: jansupol <jan.supol@oracle.com>
  • Loading branch information
jansupol committed May 23, 2024
2 parents 95f2ec9 + 6d658b7 commit fa8b106
Show file tree
Hide file tree
Showing 36 changed files with 1,119 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,7 @@ protected void prepareSocket(SSLSocket socket) throws IOException {
if (objectRequest != null) {
ClientRequest clientRequest = (ClientRequest) objectRequest;
SSLParamConfigurator sniConfig = SSLParamConfigurator.builder().request(clientRequest)
.setSNIHostName(clientRequest.getConfiguration()).build();
.setSNIHostName(clientRequest).build();
sniConfig.setSNIServerName(socket);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,7 @@ protected void prepareSocket(SSLSocket socket) throws IOException {
if (objectRequest != null) {
ClientRequest clientRequest = (ClientRequest) objectRequest;
SSLParamConfigurator sniConfig = SSLParamConfigurator.builder().request(clientRequest)
.setSNIHostName(clientRequest.getConfiguration()).build();
.setSNIHostName(clientRequest).build();
sniConfig.setSNIServerName(socket);

final int socketTimeout = ((ClientRequest) objectRequest).resolveProperty(ClientProperties.READ_TIMEOUT, -1);
Expand Down
28 changes: 28 additions & 0 deletions connectors/netty-connector/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-jetty</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand All @@ -75,4 +81,26 @@
</plugins>
</build>

<profiles>
<profile>
<id>JettyExclude</id>
<activation>
<jdk>1.8</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<testExcludes>
<testExclude>org/glassfish/jersey/netty/connector/HugeHeaderTest.java</testExclude>
</testExcludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>

</project>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -129,4 +129,56 @@ public class NettyClientProperties {
public static final Integer
DEFAULT_EXPECT_100_CONTINUE_TIMEOUT_VALUE = 500;


/**
* Parameter which allows extending of the header size for the Netty connector
*
* @since 2.44
*/
public static final String
MAX_HEADER_SIZE = "jersey.config.client.netty.maxHeaderSize";

/**
* Default header size for Netty Connector.
* Taken from {@link io.netty.handler.codec.http.HttpClientCodec#HttpClientCodec(int, int, int)}
*
* @since 2.44
*/
public static final Integer
DEFAULT_HEADER_SIZE = 8192;

/**
* Parameter which allows extending of the initial line length for the Netty connector
*
* @since 2.44
*/
public static final String
MAX_INITIAL_LINE_LENGTH = "jersey.config.client.netty.maxInitialLineLength";

/**
* Default initial line length for Netty Connector.
* Taken from {@link io.netty.handler.codec.http.HttpClientCodec#HttpClientCodec(int, int, int)}
*
* @since 2.44
*/
public static final Integer
DEFAULT_INITIAL_LINE_LENGTH = 4096;

/**
* Parameter which allows extending of the chunk size for the Netty connector
*
* @since 2.44
*/
public static final String
MAX_CHUNK_SIZE = "jersey.config.client.netty.maxChunkSize";

/**
* Default chunk size for Netty Connector.
* Taken from {@link io.netty.handler.codec.http.HttpClientCodec#HttpClientCodec(int, int, int)}
*
* @since 2.44
*/
public static final Integer
DEFAULT_CHUNK_SIZE = 8192;

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
Expand Down Expand Up @@ -89,6 +88,7 @@
import org.glassfish.jersey.client.innate.http.SSLParamConfigurator;
import org.glassfish.jersey.client.spi.AsyncConnectorCallback;
import org.glassfish.jersey.client.spi.Connector;
import org.glassfish.jersey.innate.VirtualThreadUtil;
import org.glassfish.jersey.message.internal.OutboundMessageContext;
import org.glassfish.jersey.netty.connector.internal.NettyEntityWriter;

Expand Down Expand Up @@ -130,14 +130,15 @@ class NettyConnector implements Connector {

NettyConnector(Client client) {

final Map<String, Object> properties = client.getConfiguration().getProperties();
final Configuration configuration = client.getConfiguration();
final Map<String, Object> properties = configuration.getProperties();
final Object threadPoolSize = properties.get(ClientProperties.ASYNC_THREADPOOL_SIZE);

if (threadPoolSize != null && threadPoolSize instanceof Integer && (Integer) threadPoolSize > 0) {
executorService = Executors.newFixedThreadPool((Integer) threadPoolSize);
executorService = VirtualThreadUtil.withConfig(configuration).newFixedThreadPool((Integer) threadPoolSize);
this.group = new NioEventLoopGroup((Integer) threadPoolSize);
} else {
executorService = Executors.newCachedThreadPool();
executorService = VirtualThreadUtil.withConfig(configuration).newCachedThreadPool();
this.group = new NioEventLoopGroup();
}

Expand Down Expand Up @@ -208,7 +209,7 @@ protected void execute(final ClientRequest jerseyRequest, final Set<URI> redirec

try {
final SSLParamConfigurator sslConfig = SSLParamConfigurator.builder()
.request(jerseyRequest).setSNIAlways(true).setSNIHostName(jerseyRequest.getConfiguration()).build();
.request(jerseyRequest).setSNIAlways(true).setSNIHostName(jerseyRequest).build();

String key = requestUri.getScheme() + "://" + sslConfig.getSNIHostName() + ":" + port;
ArrayList<Channel> conns;
Expand Down Expand Up @@ -303,7 +304,17 @@ protected void initChannel(SocketChannel ch) throws Exception {
p.addLast(sslHandler);
}

p.addLast(new HttpClientCodec());
final Integer maxHeaderSize = ClientProperties.getValue(config.getProperties(),
NettyClientProperties.MAX_HEADER_SIZE,
NettyClientProperties.DEFAULT_HEADER_SIZE);
final Integer maxChunkSize = ClientProperties.getValue(config.getProperties(),
NettyClientProperties.MAX_CHUNK_SIZE,
NettyClientProperties.DEFAULT_CHUNK_SIZE);
final Integer maxInitialLineLength = ClientProperties.getValue(config.getProperties(),
NettyClientProperties.MAX_INITIAL_LINE_LENGTH,
NettyClientProperties.DEFAULT_INITIAL_LINE_LENGTH);

p.addLast(new HttpClientCodec(maxInitialLineLength, maxHeaderSize, maxChunkSize));
p.addLast(new ChunkedWriteHandler());
p.addLast(new HttpContentDecompressor());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package org.glassfish.jersey.netty.connector;

import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.jetty.JettyTestContainerFactory;
import org.glassfish.jersey.test.jetty.JettyTestContainerProperties;
import org.glassfish.jersey.test.spi.TestContainerException;
import org.glassfish.jersey.test.spi.TestContainerFactory;
import org.junit.jupiter.api.Test;

import jakarta.ws.rs.HeaderParam;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.core.Response;

import java.util.HashMap;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

public class HugeHeaderTest extends JerseyTest {

private static final int SERVER_HEADER_SIZE = 1234567;

private static final String hugeHeader =
"abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz";

@Path("/test")
public static class HttpMethodResource {
@POST
public Response post(
@HeaderParam("X-HUGE-HEADER") String hugeHeader,
String entity) {

return Response.noContent()
.header("X-HUGE-HEADER", hugeHeader)
.header("X-HUGE-HEADER-SIZE", hugeHeader.length())
.build();
}
}

@Override
protected Application configure() {
return new ResourceConfig(HugeHeaderTest.HttpMethodResource.class);
}

@Override
protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
final Map<String, Object> configurationProperties = new HashMap<>();
configurationProperties.put(JettyTestContainerProperties.HEADER_SIZE, SERVER_HEADER_SIZE);
return new JettyTestContainerFactory(configurationProperties);
}

@Override
protected void configureClient(ClientConfig config) {
config.connectorProvider(new NettyConnectorProvider());
}

@Test
public void testContentHeaderTrunked() {
final StringBuffer veryHugeHeader = new StringBuffer();
for (int i = 1; i < 33; i++) {
veryHugeHeader.append(hugeHeader);
}
final Response response = target("test").request()
.header("X-HUGE-HEADER", veryHugeHeader.toString())
.post(null);

assertNull(response.getHeaderString("X-HUGE-HEADER-SIZE"));
assertNull(response.getHeaderString("X-HUGE-HEADER"));
response.close();
}

@Test
public void testConnectorHeaderSize() {
final StringBuffer veryHugeHeader = new StringBuffer();
for (int i = 1; i < 35; i++) {
veryHugeHeader.append(hugeHeader);
}
int headerSize = veryHugeHeader.length();
Response response = target("test")
.property(NettyClientProperties.MAX_HEADER_SIZE, 77750)
.request()


.header("X-HUGE-HEADER", veryHugeHeader.toString())
.post(null);
assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());

assertEquals(String.valueOf(headerSize), response.getHeaderString("X-HUGE-HEADER-SIZE"));
assertEquals(veryHugeHeader.toString(), response.getHeaderString("X-HUGE-HEADER"));
response.close();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -18,10 +18,15 @@

import java.io.IOException;
import java.net.URI;
import java.util.concurrent.ThreadFactory;

import jakarta.ws.rs.ProcessingException;
import jakarta.ws.rs.core.Configuration;

import org.glassfish.jersey.grizzly2.httpserver.internal.LocalizationMessages;
import org.glassfish.jersey.innate.VirtualThreadSupport;
import org.glassfish.jersey.innate.VirtualThreadUtil;
import org.glassfish.jersey.innate.virtual.LoomishExecutors;
import org.glassfish.jersey.internal.guava.ThreadFactoryBuilder;
import org.glassfish.jersey.process.JerseyProcessingUncaughtExceptionHandler;
import org.glassfish.jersey.server.ApplicationHandler;
Expand Down Expand Up @@ -281,11 +286,20 @@ public static HttpServer createHttpServer(final URI uri,
: uri.getPort();

final NetworkListener listener = new NetworkListener("grizzly", host, port);
final Configuration configuration = handler != null ? handler.getConfiguration().getConfiguration() : null;

listener.getTransport().getWorkerThreadPoolConfig().setThreadFactory(new ThreadFactoryBuilder()
final LoomishExecutors executors = VirtualThreadUtil.withConfig(configuration, false);
final ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setNameFormat("grizzly-http-server-%d")
.setUncaughtExceptionHandler(new JerseyProcessingUncaughtExceptionHandler())
.build());
.setThreadFactory(executors.getThreadFactory())
.build();

if (executors.isVirtual()) {
listener.getTransport().setWorkerThreadPool(executors.newCachedThreadPool());
} else {
listener.getTransport().getWorkerThreadPoolConfig().setThreadFactory(threadFactory);
}

listener.setSecure(secure);
if (sslEngineConfigurator != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -23,6 +23,7 @@
import jakarta.servlet.Servlet;

import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.servlet.ServletContainer;
import org.glassfish.jersey.uri.UriComponent;

Expand Down Expand Up @@ -251,11 +252,13 @@ private static HttpServer create(URI u, Class<? extends Servlet> c, Servlet serv
}
}

ResourceConfig configuration = new ResourceConfig();
if (initParams != null) {
registration.setInitParameters(initParams);
configuration.addProperties((Map) initParams);
}

HttpServer server = GrizzlyHttpServerFactory.createHttpServer(u);
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(u, configuration);
context.deploy(server);
return server;
}
Expand Down
Loading

0 comments on commit fa8b106

Please sign in to comment.