@@ -202,16 +202,17 @@ public boolean remove(Object o) {
202202 };
203203private final ConnectionsPool <String ,Channel >connectionsPool ;
204204private Semaphore freeConnections =null ;
205- private final NettyAsyncHttpProviderConfig asyncHttpProviderConfig ;
205+ private final NettyAsyncHttpProviderConfig providerConfig ;
206206private boolean executeConnectAsync =true ;
207207public static final ThreadLocal <Boolean >IN_IO_THREAD =new ThreadLocalBoolean ();
208208private final boolean trackConnections ;
209209private final boolean useRawUrl ;
210+ private final boolean disableZeroCopy ;
210211private final static NTLMEngine ntlmEngine =new NTLMEngine ();
211212private static SpnegoEngine spnegoEngine =null ;
212213private final Protocol httpProtocol =new HttpProtocol ();
213214private final Protocol webSocketProtocol =new WebSocketProtocol ();
214- private HashedWheelTimer hashedWheelTimer ;
215+ private final HashedWheelTimer hashedWheelTimer ;
215216
216217private static boolean isNTLM (List <String >auth ) {
217218return isNonEmpty (auth ) &&auth .get (0 ).startsWith ("NTLM" );
@@ -220,29 +221,29 @@ private static boolean isNTLM(List<String> auth) {
220221public NettyAsyncHttpProvider (AsyncHttpClientConfig config ) {
221222
222223if (config .getAsyncHttpProviderConfig ()instanceof NettyAsyncHttpProviderConfig ) {
223- asyncHttpProviderConfig =NettyAsyncHttpProviderConfig .class .cast (config .getAsyncHttpProviderConfig ());
224+ providerConfig =NettyAsyncHttpProviderConfig .class .cast (config .getAsyncHttpProviderConfig ());
224225 }else {
225- asyncHttpProviderConfig =new NettyAsyncHttpProviderConfig ();
226+ providerConfig =new NettyAsyncHttpProviderConfig ();
226227 }
227228
228229if (config .getRequestCompressionLevel () >0 ) {
229230LOGGER .warn ("Request was enabled but Netty actually doesn't support this feature" );
230231 }
231232
232- if (asyncHttpProviderConfig .getProperty (USE_BLOCKING_IO ) !=null ) {
233+ if (providerConfig .getProperty (USE_BLOCKING_IO ) !=null ) {
233234socketChannelFactory =new OioClientSocketChannelFactory (config .executorService ());
234235this .allowReleaseSocketChannelFactory =true ;
235236 }else {
236237// check if external NioClientSocketChannelFactory is defined
237- Object oo =asyncHttpProviderConfig .getProperty (SOCKET_CHANNEL_FACTORY );
238+ Object oo =providerConfig .getProperty (SOCKET_CHANNEL_FACTORY );
238239if (oo instanceof NioClientSocketChannelFactory ) {
239240this .socketChannelFactory =NioClientSocketChannelFactory .class .cast (oo );
240241
241242// cannot allow releasing shared channel factory
242243this .allowReleaseSocketChannelFactory =false ;
243244 }else {
244245ExecutorService e ;
245- Object o =asyncHttpProviderConfig .getProperty (BOSS_EXECUTOR_SERVICE );
246+ Object o =providerConfig .getProperty (BOSS_EXECUTOR_SERVICE );
246247if (o instanceof ExecutorService ) {
247248e =ExecutorService .class .cast (o );
248249 }else {
@@ -279,7 +280,7 @@ public NettyAsyncHttpProvider(AsyncHttpClientConfig config) {
279280 }
280281
281282useRawUrl =config .isUseRawUrl ();
282-
283+ disableZeroCopy = providerConfig . isDisableZeroCopy ();
283284hashedWheelTimer =new HashedWheelTimer ();
284285hashedWheelTimer .start ();
285286 }
@@ -294,8 +295,8 @@ public String toString() {
294295 }
295296
296297void configureNetty () {
297- if (asyncHttpProviderConfig !=null ) {
298- for (Entry <String ,Object >entry :asyncHttpProviderConfig .propertiesSet ()) {
298+ if (providerConfig !=null ) {
299+ for (Entry <String ,Object >entry :providerConfig .propertiesSet ()) {
299300plainBootstrap .setOption (entry .getKey (),entry .getValue ());
300301 }
301302configureHttpClientCodec ();
@@ -304,7 +305,6 @@ void configureNetty() {
304305
305306plainBootstrap .setPipelineFactory (new ChannelPipelineFactory () {
306307
307- /* @Override */
308308public ChannelPipeline getPipeline ()throws Exception {
309309ChannelPipeline pipeline =pipeline ();
310310
@@ -320,11 +320,11 @@ public ChannelPipeline getPipeline() throws Exception {
320320 });
321321DefaultChannelFuture .setUseDeadLockChecker (false );
322322
323- if (asyncHttpProviderConfig !=null ) {
324- Object value =asyncHttpProviderConfig .getProperty (EXECUTE_ASYNC_CONNECT );
323+ if (providerConfig !=null ) {
324+ Object value =providerConfig .getProperty (EXECUTE_ASYNC_CONNECT );
325325if (value instanceof Boolean ) {
326326executeConnectAsync =Boolean .class .cast (value );
327- }else if (asyncHttpProviderConfig .getProperty (DISABLE_NESTED_REQUEST ) !=null ) {
327+ }else if (providerConfig .getProperty (DISABLE_NESTED_REQUEST ) !=null ) {
328328DefaultChannelFuture .setUseDeadLockChecker (true );
329329 }
330330 }
@@ -343,15 +343,15 @@ public ChannelPipeline getPipeline() throws Exception {
343343 }
344344
345345protected void configureHttpClientCodec () {
346- httpClientCodecMaxInitialLineLength =asyncHttpProviderConfig .getProperty (HTTP_CLIENT_CODEC_MAX_INITIAL_LINE_LENGTH ,Integer .class ,httpClientCodecMaxInitialLineLength );
347- httpClientCodecMaxHeaderSize =asyncHttpProviderConfig .getProperty (HTTP_CLIENT_CODEC_MAX_HEADER_SIZE ,Integer .class ,httpClientCodecMaxHeaderSize );
348- httpClientCodecMaxChunkSize =asyncHttpProviderConfig .getProperty (HTTP_CLIENT_CODEC_MAX_CHUNK_SIZE ,Integer .class ,httpClientCodecMaxChunkSize );
346+ httpClientCodecMaxInitialLineLength =providerConfig .getProperty (HTTP_CLIENT_CODEC_MAX_INITIAL_LINE_LENGTH ,Integer .class ,httpClientCodecMaxInitialLineLength );
347+ httpClientCodecMaxHeaderSize =providerConfig .getProperty (HTTP_CLIENT_CODEC_MAX_HEADER_SIZE ,Integer .class ,httpClientCodecMaxHeaderSize );
348+ httpClientCodecMaxChunkSize =providerConfig .getProperty (HTTP_CLIENT_CODEC_MAX_CHUNK_SIZE ,Integer .class ,httpClientCodecMaxChunkSize );
349349 }
350350
351351protected void configureHttpsClientCodec () {
352- httpsClientCodecMaxInitialLineLength =asyncHttpProviderConfig .getProperty (HTTPS_CLIENT_CODEC_MAX_INITIAL_LINE_LENGTH ,Integer .class ,httpsClientCodecMaxInitialLineLength );
353- httpsClientCodecMaxHeaderSize =asyncHttpProviderConfig .getProperty (HTTPS_CLIENT_CODEC_MAX_HEADER_SIZE ,Integer .class ,httpsClientCodecMaxHeaderSize );
354- httpsClientCodecMaxChunkSize =asyncHttpProviderConfig .getProperty (HTTPS_CLIENT_CODEC_MAX_CHUNK_SIZE ,Integer .class ,httpsClientCodecMaxChunkSize );
352+ httpsClientCodecMaxInitialLineLength =providerConfig .getProperty (HTTPS_CLIENT_CODEC_MAX_INITIAL_LINE_LENGTH ,Integer .class ,httpsClientCodecMaxInitialLineLength );
353+ httpsClientCodecMaxHeaderSize =providerConfig .getProperty (HTTPS_CLIENT_CODEC_MAX_HEADER_SIZE ,Integer .class ,httpsClientCodecMaxHeaderSize );
354+ httpsClientCodecMaxChunkSize =providerConfig .getProperty (HTTPS_CLIENT_CODEC_MAX_CHUNK_SIZE ,Integer .class ,httpsClientCodecMaxChunkSize );
355355 }
356356
357357void constructSSLPipeline (final NettyConnectListener <?>cl ) {
@@ -399,8 +399,8 @@ public ChannelPipeline getPipeline() throws Exception {
399399 }
400400 });
401401
402- if (asyncHttpProviderConfig !=null ) {
403- for (Entry <String ,Object >entry :asyncHttpProviderConfig .propertiesSet ()) {
402+ if (providerConfig !=null ) {
403+ for (Entry <String ,Object >entry :providerConfig .propertiesSet ()) {
404404secureBootstrap .setOption (entry .getKey (),entry .getValue ());
405405secureWebSocketBootstrap .setOption (entry .getKey (),entry .getValue ());
406406 }
@@ -544,7 +544,7 @@ protected final <T> void writeRequest(final Channel channel, final AsyncHttpClie
544544fileLength =raf .length ();
545545
546546ChannelFuture writeFuture ;
547- if (ssl ) {
547+ if (ssl || disableZeroCopy ) {
548548writeFuture =channel .write (new ChunkedFile (raf ,0 ,fileLength ,MAX_BUFFERED_BYTES ));
549549 }else {
550550final FileRegion region =new OptimizedFileRegion (raf ,0 ,fileLength );
@@ -572,7 +572,7 @@ public void operationComplete(ChannelFuture cf) {
572572 }else if (body !=null ) {
573573
574574ChannelFuture writeFuture ;
575- if (!ssl &&body instanceof RandomAccessBody ) {
575+ if (!ssl &&! disableZeroCopy && body instanceof RandomAccessBody ) {
576576BodyFileRegion bodyFileRegion =new BodyFileRegion ((RandomAccessBody )body );
577577writeFuture =channel .write (bodyFileRegion );
578578 }else {
@@ -1059,7 +1059,7 @@ private <T> ListenableFuture<T> doConnect(final Request request, final AsyncHand
10591059
10601060// Do no enable this with win.
10611061if (!System .getProperty ("os.name" ).toLowerCase (Locale .ENGLISH ).contains ("win" )) {
1062- bootstrap .setOption ("reuseAddress" ,asyncHttpProviderConfig .getProperty (REUSE_ADDRESS ));
1062+ bootstrap .setOption ("reuseAddress" ,providerConfig .getProperty (REUSE_ADDRESS ));
10631063 }
10641064
10651065try {