Skip to content

Commit d4f8943

Browse files
committed
Apply pull 158 to the proper branch
1 parent 92dc79a commit d4f8943

File tree

2 files changed

+86
-15
lines changed

2 files changed

+86
-15
lines changed

src/main/java/com/ning/http/client/providers/netty/NettyAsyncHttpProvider.java

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,12 @@ public class NettyAsyncHttpProvider extends SimpleChannelUpstreamHandler impleme
151151
private final AsyncHttpClientConfig config;
152152
private final AtomicBoolean isClose = new AtomicBoolean(false);
153153
private final ClientSocketChannelFactory socketChannelFactory;
154+
private int httpClientCodecMaxInitialLineLength = 4096;
155+
private int httpClientCodecMaxHeaderSize = 8192;
156+
private int httpClientCodecMaxChunkSize = 8192;
157+
private int httpsClientCodecMaxInitialLineLength = 4096;
158+
private int httpsClientCodecMaxHeaderSize = 8192;
159+
private int httpsClientCodecMaxChunkSize = 8192;
154160

155161
private final ChannelGroup openChannels = new
156162
CleanupChannelGroup("asyncHttpClient") {
@@ -238,6 +244,8 @@ void configureNetty() {
238244
for (Entry<String, Object> entry : asyncHttpProviderConfig.propertiesSet()) {
239245
plainBootstrap.setOption(entry.getKey(), entry.getValue());
240246
}
247+
configureHttpClientCodec();
248+
configureHttpsClientCodec();
241249
}
242250

243251
plainBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@@ -246,7 +254,7 @@ void configureNetty() {
246254
public ChannelPipeline getPipeline() throws Exception {
247255
ChannelPipeline pipeline = pipeline();
248256

249-
pipeline.addLast(HTTP_HANDLER, new HttpClientCodec());
257+
pipeline.addLast(HTTP_HANDLER, createHttpClientCodec());
250258

251259
if (config.getRequestCompressionLevel() > 0) {
252260
pipeline.addLast("deflater", new HttpContentCompressor(config.getRequestCompressionLevel()));
@@ -284,6 +292,42 @@ public ChannelPipeline getPipeline() throws Exception {
284292
});
285293
}
286294

295+
protected void configureHttpClientCodec() {
296+
httpClientCodecMaxInitialLineLength = asyncHttpProviderConfig.getProperty(
297+
NettyAsyncHttpProviderConfig.HTTP_CLIENT_CODEC_MAX_INITIAL_LINE_LENGTH,
298+
Integer.class,
299+
httpClientCodecMaxInitialLineLength
300+
);
301+
httpClientCodecMaxHeaderSize = asyncHttpProviderConfig.getProperty(
302+
NettyAsyncHttpProviderConfig.HTTP_CLIENT_CODEC_MAX_HEADER_SIZE,
303+
Integer.class,
304+
httpClientCodecMaxHeaderSize
305+
);
306+
httpClientCodecMaxChunkSize = asyncHttpProviderConfig.getProperty(
307+
NettyAsyncHttpProviderConfig.HTTP_CLIENT_CODEC_MAX_CHUNK_SIZE,
308+
Integer.class,
309+
httpClientCodecMaxChunkSize
310+
);
311+
}
312+
313+
protected void configureHttpsClientCodec() {
314+
httpsClientCodecMaxInitialLineLength = asyncHttpProviderConfig.getProperty(
315+
NettyAsyncHttpProviderConfig.HTTPS_CLIENT_CODEC_MAX_INITIAL_LINE_LENGTH,
316+
Integer.class,
317+
httpsClientCodecMaxInitialLineLength
318+
);
319+
httpsClientCodecMaxHeaderSize = asyncHttpProviderConfig.getProperty(
320+
NettyAsyncHttpProviderConfig.HTTPS_CLIENT_CODEC_MAX_HEADER_SIZE,
321+
Integer.class,
322+
httpsClientCodecMaxHeaderSize
323+
);
324+
httpsClientCodecMaxChunkSize = asyncHttpProviderConfig.getProperty(
325+
NettyAsyncHttpProviderConfig.HTTPS_CLIENT_CODEC_MAX_CHUNK_SIZE,
326+
Integer.class,
327+
httpsClientCodecMaxChunkSize
328+
);
329+
}
330+
287331
void constructSSLPipeline(final NettyConnectListener<?> cl) {
288332

289333
secureBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@@ -298,7 +342,7 @@ public ChannelPipeline getPipeline() throws Exception {
298342
abort(cl.future(), ex);
299343
}
300344

301-
pipeline.addLast(HTTP_HANDLER, new HttpClientCodec());
345+
pipeline.addLast(HTTP_HANDLER, createHttpsClientCodec());
302346

303347
if (config.isCompressionEnabled()) {
304348
pipeline.addLast("inflater", new HttpContentDecompressor());
@@ -363,6 +407,14 @@ private SSLEngine createSSLEngine() throws IOException, GeneralSecurityException
363407
return sslEngine;
364408
}
365409

410+
private HttpClientCodec createHttpClientCodec() {
411+
return new HttpClientCodec(httpClientCodecMaxInitialLineLength, httpClientCodecMaxHeaderSize, httpClientCodecMaxChunkSize);
412+
}
413+
414+
private HttpClientCodec createHttpsClientCodec() {
415+
return new HttpClientCodec(httpsClientCodecMaxInitialLineLength, httpsClientCodecMaxHeaderSize, httpsClientCodecMaxChunkSize);
416+
}
417+
366418
private Channel verifyChannelPipeline(Channel channel, String scheme) throws IOException, GeneralSecurityException {
367419

368420
if (channel.getPipeline().get(SSL_HANDLER) != null && HTTP.equalsIgnoreCase(scheme)) {
@@ -547,7 +599,6 @@ private static HttpRequest construct(AsyncHttpClientConfig config,
547599
ChannelBuffer buffer) throws IOException {
548600

549601
String host = AsyncHttpProviderUtils.getHost(uri);
550-
boolean webSocket = isWebSocket(uri);
551602

552603
if (request.getVirtualHost() != null) {
553604
host = request.getVirtualHost();
@@ -568,12 +619,11 @@ private static HttpRequest construct(AsyncHttpClientConfig config,
568619
}
569620
nettyRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, m, path.toString());
570621
}
571-
622+
boolean webSocket = isWebSocket(uri);
572623
if (webSocket) {
573624
nettyRequest.addHeader(HttpHeaders.Names.UPGRADE, HttpHeaders.Values.WEBSOCKET);
574625
nettyRequest.addHeader(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.UPGRADE);
575-
nettyRequest.addHeader("Origin", "http://" + uri.getHost() + ":"
576-
+ (uri.getPort() == -1 ? isSecure(uri.getScheme()) ? 443 : 80 : uri.getPort()));
626+
nettyRequest.addHeader("Origin", "http://" + uri.getHost() + ":" + uri.getPort());
577627
nettyRequest.addHeader(WEBSOCKET_KEY, WebSocketUtil.getKey());
578628
nettyRequest.addHeader("Sec-WebSocket-Version", "13");
579629
}
@@ -2346,13 +2396,7 @@ public void handle(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
23462396
s = new ResponseStatus(future.getURI(), response, NettyAsyncHttpProvider.this);
23472397
final boolean statusReceived = h.onStatusReceived(s) == STATE.UPGRADE;
23482398

2349-
if (!statusReceived) {
2350-
h.onClose(new NettyWebSocket(ctx.getChannel()), 1002, "Bad response status " + response.getStatus().getCode());
2351-
future.done(null);
2352-
return;
2353-
}
2354-
2355-
if (!validStatus || !validUpgrade || !validConnection) {
2399+
if (!validStatus || !validUpgrade || !validConnection || !statusReceived) {
23562400
throw new IOException("Invalid handshake response");
23572401
}
23582402

@@ -2463,4 +2507,3 @@ private static boolean isSecure(URI uri) {
24632507
return isSecure(uri.getScheme());
24642508
}
24652509
}
2466-

src/main/java/com/ning/http/client/providers/netty/NettyAsyncHttpProviderConfig.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,20 @@ public class NettyAsyncHttpProviderConfig implements AsyncHttpProviderConfig<Str
5757
*/
5858
public final static String REUSE_ADDRESS = "reuseAddress";
5959

60+
/**
61+
* Allow configuring the Netty's HttpClientCodec.
62+
*/
63+
public final static String HTTP_CLIENT_CODEC_MAX_INITIAL_LINE_LENGTH = "httpClientCodecMaxInitialLineLength";
64+
public final static String HTTP_CLIENT_CODEC_MAX_HEADER_SIZE = "httpClientCodecMaxHeaderSize";
65+
public final static String HTTP_CLIENT_CODEC_MAX_CHUNK_SIZE = "httpClientCodecMaxChunkSize";
66+
67+
/**
68+
* Allow configuring the Netty's HttpClientCodec.
69+
*/
70+
public final static String HTTPS_CLIENT_CODEC_MAX_INITIAL_LINE_LENGTH = "httpsClientCodecMaxInitialLineLength";
71+
public final static String HTTPS_CLIENT_CODEC_MAX_HEADER_SIZE = "httpsClientCodecMaxHeaderSize";
72+
public final static String HTTPS_CLIENT_CODEC_MAX_CHUNK_SIZE = "httpsClientCodecMaxChunkSize";
73+
6074
private final ConcurrentHashMap<String, Object> properties = new ConcurrentHashMap<String, Object>();
6175

6276
public NettyAsyncHttpProviderConfig() {
@@ -85,6 +99,20 @@ public Object getProperty(String name) {
8599
return properties.get(name);
86100
}
87101

102+
/**
103+
* Return the value associated with the property's name
104+
*
105+
* @param name
106+
* @return this instance of AsyncHttpProviderConfig
107+
*/
108+
public <T> T getProperty(String name, Class<T> type, T defaultValue) {
109+
Object value = properties.get(name);
110+
if (value != null && type.isAssignableFrom(value.getClass())) {
111+
return type.cast(value);
112+
}
113+
return defaultValue;
114+
}
115+
88116
/**
89117
* Remove the value associated with the property's name
90118
*
@@ -103,4 +131,4 @@ public Object removeProperty(String name) {
103131
public Set<Map.Entry<String, Object>> propertiesSet() {
104132
return properties.entrySet();
105133
}
106-
}
134+
}

0 commit comments

Comments
 (0)