11/*
2- * Copyright 2002-2015 the original author or authors.
2+ * Copyright 2002-2016 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
1818
1919import java .io .ByteArrayOutputStream ;
2020import java .io .IOException ;
21- import java .lang .reflect .Method ;
2221import java .net .URI ;
2322import java .nio .ByteBuffer ;
2423import java .util .List ;
4140import io .undertow .util .StringReadChannelListener ;
4241import org .xnio .ChannelListener ;
4342import org .xnio .ChannelListeners ;
44- import org .xnio .IoFuture ;
4543import org .xnio .IoUtils ;
4644import org .xnio .OptionMap ;
4745import org .xnio .Options ;
48- import org .xnio .Pool ;
4946import org .xnio .Xnio ;
5047import org .xnio .XnioWorker ;
5148import org .xnio .channels .StreamSinkChannel ;
5552import org .springframework .http .HttpStatus ;
5653import org .springframework .http .ResponseEntity ;
5754import org .springframework .util .Assert ;
58- import org .springframework .util .ClassUtils ;
59- import org .springframework .util .ReflectionUtils ;
6055import org .springframework .util .concurrent .SettableListenableFuture ;
6156import org .springframework .web .client .HttpServerErrorException ;
6257import org .springframework .web .socket .CloseStatus ;
6964
7065/**
7166 * An XHR transport based on Undertow's {@link io.undertow.client.UndertowClient}.
72- * Compatible with Undertow 1.0 to 1.3 , as of Spring Framework 4.2.2 .
67+ * Requires Undertow 1.3 or higher , as of Spring Framework 5.0 .
7368 *
7469 * <p>When used for testing purposes (e.g. load testing) or for specific use cases
7570 * (like HTTPS configuration), a custom OptionMap should be provided:
@@ -94,17 +89,14 @@ public class UndertowXhrTransport extends AbstractXhrTransport {
9489
9590 private static final AttachmentKey <String > RESPONSE_BODY = AttachmentKey .create (String .class );
9691
97- private static final boolean undertow13Present = ClassUtils .isPresent (
98- "io.undertow.connector.ByteBufferPool" , UndertowXhrTransport .class .getClassLoader ());
99-
10092
10193 private final OptionMap optionMap ;
10294
10395 private final UndertowClient httpClient ;
10496
10597 private final XnioWorker worker ;
10698
107- private final UndertowBufferSupport undertowBufferSupport ;
99+ private final ByteBufferPool bufferPool ;
108100
109101
110102 public UndertowXhrTransport () throws IOException {
@@ -116,8 +108,7 @@ public UndertowXhrTransport(OptionMap optionMap) throws IOException {
116108 this .optionMap = optionMap ;
117109 this .httpClient = UndertowClient .getInstance ();
118110 this .worker = Xnio .getInstance ().createWorker (optionMap );
119- this .undertowBufferSupport =
120- (undertow13Present ? new Undertow13BufferSupport () : new UndertowXnioBufferSupport ());
111+ this .bufferPool = new DefaultByteBufferPool (false , 1024 , -1 , 2 );
121112 }
122113
123114
@@ -172,7 +163,7 @@ public void failed(IOException ex) {
172163 }
173164 };
174165
175- this .undertowBufferSupport . httpClientConnect ( this . httpClient , clientCallback , url , worker , this .optionMap );
166+ this .httpClient . connect ( clientCallback , url , this . worker , this . bufferPool , this .optionMap );
176167 }
177168
178169 private static void addHttpHeaders (ClientRequest request , HttpHeaders headers ) {
@@ -276,8 +267,8 @@ protected ResponseEntity<String> executeRequest(URI url, HttpString method, Http
276267 List <ClientResponse > responses = new CopyOnWriteArrayList <ClientResponse >();
277268
278269 try {
279- ClientConnection connection = this . undertowBufferSupport
280- . httpClientConnect ( this .httpClient , url , this .worker , this .optionMap ).get ();
270+ ClientConnection connection =
271+ this .httpClient . connect ( url , this .worker , this . bufferPool , this .optionMap ).get ();
281272 try {
282273 ClientRequest request = new ClientRequest ().setMethod (method ).setPath (url .getPath ());
283274 request .getRequestHeaders ().add (HttpString .tryFromString (HttpHeaders .HOST ), url .getHost ());
@@ -317,7 +308,6 @@ private ClientCallback<ClientExchange> createRequestCallback(final String body,
317308 public void completed (ClientExchange result ) {
318309 result .setResponseListener (new ClientCallback <ClientExchange >() {
319310 @ Override
320- @ SuppressWarnings ("deprecation" )
321311 public void completed (final ClientExchange result ) {
322312 responses .add (result .getResponse ());
323313 new StringReadChannelListener (result .getConnection ().getBufferPool ()) {
@@ -326,14 +316,12 @@ protected void stringDone(String string) {
326316 result .getResponse ().putAttachment (RESPONSE_BODY , string );
327317 latch .countDown ();
328318 }
329-
330319 @ Override
331320 protected void error (IOException ex ) {
332321 onFailure (latch , ex );
333322 }
334323 }.setup (result .getResponseChannel ());
335324 }
336-
337325 @ Override
338326 public void failed (IOException ex ) {
339327 onFailure (latch , ex );
@@ -412,11 +400,11 @@ public void handleEvent(StreamSourceChannel channel) {
412400 throw new SockJsException ("Session closed." , this .session .getId (), null );
413401 }
414402
415- Object pooled = undertowBufferSupport . allocatePooledResource ();
403+ PooledByteBuffer pooled = bufferPool . allocate ();
416404 try {
417405 int r ;
418406 do {
419- ByteBuffer buffer = undertowBufferSupport . getByteBuffer ( pooled );
407+ ByteBuffer buffer = pooled . getBuffer ( );
420408 buffer .clear ();
421409 r = channel .read (buffer );
422410 buffer .flip ();
@@ -444,7 +432,7 @@ else if (r == -1) {
444432 onFailure (exc );
445433 }
446434 finally {
447- undertowBufferSupport . closePooledResource ( pooled );
435+ pooled . close ( );
448436 }
449437 }
450438
@@ -486,118 +474,4 @@ public void onFailure(Throwable failure) {
486474 }
487475 }
488476
489-
490- private interface UndertowBufferSupport {
491-
492- Object allocatePooledResource ();
493-
494- ByteBuffer getByteBuffer (Object pooled );
495-
496- void closePooledResource (Object pooled );
497-
498- void httpClientConnect (UndertowClient httpClient , final ClientCallback <ClientConnection > listener ,
499- final URI uri , final XnioWorker worker , OptionMap options );
500-
501- IoFuture <ClientConnection > httpClientConnect (UndertowClient httpClient , final URI uri ,
502- final XnioWorker worker , OptionMap options );
503- }
504-
505-
506- private class UndertowXnioBufferSupport implements UndertowBufferSupport {
507-
508- private final org .xnio .Pool <ByteBuffer > xnioBufferPool ;
509-
510- private final Method httpClientConnectCallbackMethod ;
511-
512- private final Method httpClientConnectMethod ;
513-
514- public UndertowXnioBufferSupport () {
515- this .xnioBufferPool = new org .xnio .ByteBufferSlicePool (1048 , 1048 );
516- this .httpClientConnectCallbackMethod = ReflectionUtils .findMethod (UndertowClient .class , "connect" ,
517- ClientCallback .class , URI .class , XnioWorker .class , Pool .class , OptionMap .class );
518- this .httpClientConnectMethod = ReflectionUtils .findMethod (UndertowClient .class , "connect" ,
519- URI .class , XnioWorker .class , Pool .class , OptionMap .class );
520- }
521-
522- @ Override
523- public Object allocatePooledResource () {
524- return this .xnioBufferPool .allocate ();
525- }
526-
527- @ Override
528- @ SuppressWarnings ("unchecked" )
529- public ByteBuffer getByteBuffer (Object pooled ) {
530- return ((org .xnio .Pooled <ByteBuffer >) pooled ).getResource ();
531- }
532-
533- @ Override
534- @ SuppressWarnings ("unchecked" )
535- public void closePooledResource (Object pooled ) {
536- ((org .xnio .Pooled <ByteBuffer >) pooled ).close ();
537- }
538-
539- @ Override
540- public void httpClientConnect (UndertowClient httpClient , ClientCallback <ClientConnection > listener , URI uri ,
541- XnioWorker worker , OptionMap options ) {
542- ReflectionUtils .invokeMethod (httpClientConnectCallbackMethod , httpClient , listener , uri , worker ,
543- this .xnioBufferPool , options );
544- }
545-
546- @ Override
547- @ SuppressWarnings ("unchecked" )
548- public IoFuture <ClientConnection > httpClientConnect (UndertowClient httpClient , URI uri ,
549- XnioWorker worker , OptionMap options ) {
550- return (IoFuture <ClientConnection >) ReflectionUtils .invokeMethod (httpClientConnectMethod , httpClient , uri ,
551- worker , this .xnioBufferPool , options );
552- }
553- }
554-
555-
556- private class Undertow13BufferSupport implements UndertowBufferSupport {
557-
558- private final ByteBufferPool undertowBufferPool ;
559-
560- private final Method httpClientConnectCallbackMethod ;
561-
562- private final Method httpClientConnectMethod ;
563-
564- public Undertow13BufferSupport () {
565- this .undertowBufferPool = new DefaultByteBufferPool (false , 1024 , -1 , 2 );
566- this .httpClientConnectCallbackMethod = ReflectionUtils .findMethod (UndertowClient .class , "connect" ,
567- ClientCallback .class , URI .class , XnioWorker .class , ByteBufferPool .class , OptionMap .class );
568- this .httpClientConnectMethod = ReflectionUtils .findMethod (UndertowClient .class , "connect" ,
569- URI .class , XnioWorker .class , ByteBufferPool .class , OptionMap .class );
570- }
571-
572- @ Override
573- public Object allocatePooledResource () {
574- return this .undertowBufferPool .allocate ();
575- }
576-
577- @ Override
578- public ByteBuffer getByteBuffer (Object pooled ) {
579- return ((PooledByteBuffer ) pooled ).getBuffer ();
580- }
581-
582- @ Override
583- public void closePooledResource (Object pooled ) {
584- ((PooledByteBuffer ) pooled ).close ();
585- }
586-
587- @ Override
588- public void httpClientConnect (UndertowClient httpClient , ClientCallback <ClientConnection > listener , URI uri ,
589- XnioWorker worker , OptionMap options ) {
590- ReflectionUtils .invokeMethod (httpClientConnectCallbackMethod , httpClient , listener , uri ,
591- worker , this .undertowBufferPool , options );
592- }
593-
594- @ Override
595- @ SuppressWarnings ("unchecked" )
596- public IoFuture <ClientConnection > httpClientConnect (UndertowClient httpClient , URI uri ,
597- XnioWorker worker , OptionMap options ) {
598- return (IoFuture <ClientConnection >) ReflectionUtils .invokeMethod (httpClientConnectMethod , httpClient , uri ,
599- worker , this .undertowBufferPool , options );
600- }
601- }
602-
603477}
0 commit comments