diff --git a/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequest.java index 92ea05d32018..a82aebe38e76 100644 --- a/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequest.java @@ -24,8 +24,8 @@ import java.util.concurrent.ExecutionException; import io.netty.bootstrap.Bootstrap; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufOutputStream; -import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; @@ -51,9 +51,11 @@ * @since 4.1.2 */ class Netty4ClientHttpRequest extends AbstractAsyncClientHttpRequest implements ClientHttpRequest { + + public static final int INITIAL_REQUEST_BUFFER_SIZE = 512; private final Bootstrap bootstrap; - + private final URI uri; private final HttpMethod method; @@ -61,11 +63,11 @@ class Netty4ClientHttpRequest extends AbstractAsyncClientHttpRequest implements private final ByteBufOutputStream body; - public Netty4ClientHttpRequest(Bootstrap bootstrap, URI uri, HttpMethod method, int maxRequestSize) { + public Netty4ClientHttpRequest(Bootstrap bootstrap, ByteBufAllocator byteBufAllocator, URI uri, HttpMethod method, int maxRequestSize) { this.bootstrap = bootstrap; this.uri = uri; this.method = method; - this.body = new ByteBufOutputStream(Unpooled.buffer(maxRequestSize)); + this.body = new ByteBufOutputStream(byteBufAllocator.buffer(INITIAL_REQUEST_BUFFER_SIZE, maxRequestSize)); } diff --git a/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequestFactory.java index fc3f5783ec45..5436dbbb8c2c 100644 --- a/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/Netty4ClientHttpRequestFactory.java @@ -20,7 +20,10 @@ import java.net.URI; import io.netty.bootstrap.Bootstrap; +import io.netty.buffer.ByteBufAllocator; +import io.netty.buffer.UnpooledByteBufAllocator; import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; @@ -54,14 +57,48 @@ public class Netty4ClientHttpRequestFactory implements ClientHttpRequestFactory, */ public static final int DEFAULT_MAX_REQUEST_SIZE = 1024 * 1024 * 10; + /** + * The default maximum header size + * @see #setMaxHeaderSize(int) + * @see HttpClientCodec#HttpClientCodec() + */ + public static final int DEFAULT_MAX_HEADER_SIZE = 8192; + + /** + * The default initial line length. + * @see #setInitialLineLength(int) + * @see HttpClientCodec#HttpClientCodec() + */ + public static final int DEFAULT_INITIAL_LINE_LENGTH = 4096; + + /** + * The default max chunk size. + * @see #setMaxChunkSize(int) + * @see HttpClientCodec#HttpClientCodec() + */ + public static final int DEFAULT_MAX_CHUNK_SIZE = 8192; + + /** + * The default byte-buf allocator. + * @see UnpooledByteBufAllocator#DEFAULT + */ + public static final ByteBufAllocator DEFAULT_BYTE_BUF_ALLOCATOR = UnpooledByteBufAllocator.DEFAULT; private final EventLoopGroup eventLoopGroup; private final boolean defaultEventLoopGroup; private int maxRequestSize = DEFAULT_MAX_REQUEST_SIZE; + + private int maxHeaderSize = DEFAULT_MAX_HEADER_SIZE; + + private int initialLineLength = DEFAULT_INITIAL_LINE_LENGTH; + + private int maxChunkSize = DEFAULT_MAX_CHUNK_SIZE; private SslContext sslContext; + + private ByteBufAllocator byteBufAllocator = DEFAULT_BYTE_BUF_ALLOCATOR; private volatile Bootstrap bootstrap; @@ -91,13 +128,53 @@ public Netty4ClientHttpRequestFactory(EventLoopGroup eventLoopGroup) { /** - * Set the default maximum request size. + * Set the maximum request size. *
By default this is set to {@link #DEFAULT_MAX_REQUEST_SIZE}. * @see HttpObjectAggregator#HttpObjectAggregator(int) */ public void setMaxRequestSize(int maxRequestSize) { this.maxRequestSize = maxRequestSize; } + + /** + * Set the maximum header size. + *
By default this is set to {@link #DEFAULT_MAX_HEADER_SIZE}. + * @see HttpClientCodec#HttpClientCodec(int, int, int) + */ + public void setMaxHeaderSize(int maxHeaderSize) { + this.maxHeaderSize = maxHeaderSize; + } + + /** + * Set the initial line length. + *
By default this is set to {@link #DEFAULT_INITIAL_LINE_LENGTH}. + * @see HttpClientCodec#HttpClientCodec(int, int, int) + */ + public void setInitialLineLength(int initialLineLength) { + this.initialLineLength = initialLineLength; + } + + /** + * Set the maximum chunk size. + *
By default this is set to {@link #DEFAULT_MAX_CHUNK_SIZE}.
+ * @see HttpClientCodec#HttpClientCodec(int, int, int)
+ */
+ public void setMaxChunkSize(int maxChunkSize) {
+ this.maxChunkSize = maxChunkSize;
+ }
+
+ /**
+ * Set the ByteBuf allocator used by the requests.
+ * @see ByteBufAllocator
+ */
+ public void setByteBufAllocator(ByteBufAllocator byteBufAllocator) {
+ if(byteBufAllocator==null) {
+ this.byteBufAllocator = DEFAULT_BYTE_BUF_ALLOCATOR;
+ }
+ else {
+ this.byteBufAllocator = byteBufAllocator;
+ }
+ }
/**
* Set the SSL context. When configured it is used to create and insert an
@@ -111,6 +188,7 @@ public void setSslContext(SslContext sslContext) {
private Bootstrap getBootstrap() {
if (this.bootstrap == null) {
Bootstrap bootstrap = new Bootstrap();
+ bootstrap.option(ChannelOption.ALLOCATOR, byteBufAllocator);
bootstrap.group(this.eventLoopGroup).channel(NioSocketChannel.class)
.handler(new ChannelInitializer