Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/2.x' into 'origin/3.0'
Browse files Browse the repository at this point in the history
Signed-off-by: Maxim Nesen <maxim.nesen@oracle.com>
  • Loading branch information
senivam committed May 22, 2024
2 parents 47716d0 + e2994ff commit 23f6080
Show file tree
Hide file tree
Showing 31 changed files with 932 additions and 62 deletions.
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 @@ -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 23f6080

Please sign in to comment.