diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/UndertowXhrTransport.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/UndertowXhrTransport.java index 863059a4e5..d6a7c5efd8 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/UndertowXhrTransport.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/UndertowXhrTransport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ package org.springframework.web.socket.sockjs.client; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.lang.reflect.Method; import java.net.URI; import java.nio.ByteBuffer; import java.util.List; @@ -41,11 +40,9 @@ import io.undertow.util.Methods; import io.undertow.util.StringReadChannelListener; import org.xnio.ChannelListener; import org.xnio.ChannelListeners; -import org.xnio.IoFuture; import org.xnio.IoUtils; import org.xnio.OptionMap; import org.xnio.Options; -import org.xnio.Pool; import org.xnio.Xnio; import org.xnio.XnioWorker; import org.xnio.channels.StreamSinkChannel; @@ -55,8 +52,6 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; import org.springframework.util.concurrent.SettableListenableFuture; import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.socket.CloseStatus; @@ -69,7 +64,7 @@ import org.springframework.web.socket.sockjs.frame.SockJsFrame; /** * An XHR transport based on Undertow's {@link io.undertow.client.UndertowClient}. - * Compatible with Undertow 1.0 to 1.3, as of Spring Framework 4.2.2. + * Requires Undertow 1.3 or higher, as of Spring Framework 5.0. * *

When used for testing purposes (e.g. load testing) or for specific use cases * (like HTTPS configuration), a custom OptionMap should be provided: @@ -94,9 +89,6 @@ public class UndertowXhrTransport extends AbstractXhrTransport { private static final AttachmentKey RESPONSE_BODY = AttachmentKey.create(String.class); - private static final boolean undertow13Present = ClassUtils.isPresent( - "io.undertow.connector.ByteBufferPool", UndertowXhrTransport.class.getClassLoader()); - private final OptionMap optionMap; @@ -104,7 +96,7 @@ public class UndertowXhrTransport extends AbstractXhrTransport { private final XnioWorker worker; - private final UndertowBufferSupport undertowBufferSupport; + private final ByteBufferPool bufferPool; public UndertowXhrTransport() throws IOException { @@ -116,8 +108,7 @@ public class UndertowXhrTransport extends AbstractXhrTransport { this.optionMap = optionMap; this.httpClient = UndertowClient.getInstance(); this.worker = Xnio.getInstance().createWorker(optionMap); - this.undertowBufferSupport = - (undertow13Present ? new Undertow13BufferSupport() : new UndertowXnioBufferSupport()); + this.bufferPool = new DefaultByteBufferPool(false, 1024, -1, 2); } @@ -172,7 +163,7 @@ public class UndertowXhrTransport extends AbstractXhrTransport { } }; - this.undertowBufferSupport.httpClientConnect(this.httpClient, clientCallback, url, worker, this.optionMap); + this.httpClient.connect(clientCallback, url, this.worker, this.bufferPool, this.optionMap); } private static void addHttpHeaders(ClientRequest request, HttpHeaders headers) { @@ -276,8 +267,8 @@ public class UndertowXhrTransport extends AbstractXhrTransport { List responses = new CopyOnWriteArrayList(); try { - ClientConnection connection = this.undertowBufferSupport - .httpClientConnect(this.httpClient, url, this.worker, this.optionMap).get(); + ClientConnection connection = + this.httpClient.connect(url, this.worker, this.bufferPool, this.optionMap).get(); try { ClientRequest request = new ClientRequest().setMethod(method).setPath(url.getPath()); request.getRequestHeaders().add(HttpString.tryFromString(HttpHeaders.HOST), url.getHost()); @@ -317,7 +308,6 @@ public class UndertowXhrTransport extends AbstractXhrTransport { public void completed(ClientExchange result) { result.setResponseListener(new ClientCallback() { @Override - @SuppressWarnings("deprecation") public void completed(final ClientExchange result) { responses.add(result.getResponse()); new StringReadChannelListener(result.getConnection().getBufferPool()) { @@ -326,14 +316,12 @@ public class UndertowXhrTransport extends AbstractXhrTransport { result.getResponse().putAttachment(RESPONSE_BODY, string); latch.countDown(); } - @Override protected void error(IOException ex) { onFailure(latch, ex); } }.setup(result.getResponseChannel()); } - @Override public void failed(IOException ex) { onFailure(latch, ex); @@ -412,11 +400,11 @@ public class UndertowXhrTransport extends AbstractXhrTransport { throw new SockJsException("Session closed.", this.session.getId(), null); } - Object pooled = undertowBufferSupport.allocatePooledResource(); + PooledByteBuffer pooled = bufferPool.allocate(); try { int r; do { - ByteBuffer buffer = undertowBufferSupport.getByteBuffer(pooled); + ByteBuffer buffer = pooled.getBuffer(); buffer.clear(); r = channel.read(buffer); buffer.flip(); @@ -444,7 +432,7 @@ public class UndertowXhrTransport extends AbstractXhrTransport { onFailure(exc); } finally { - undertowBufferSupport.closePooledResource(pooled); + pooled.close(); } } @@ -486,118 +474,4 @@ public class UndertowXhrTransport extends AbstractXhrTransport { } } - - private interface UndertowBufferSupport { - - Object allocatePooledResource(); - - ByteBuffer getByteBuffer(Object pooled); - - void closePooledResource(Object pooled); - - void httpClientConnect(UndertowClient httpClient, final ClientCallback listener, - final URI uri, final XnioWorker worker, OptionMap options); - - IoFuture httpClientConnect(UndertowClient httpClient, final URI uri, - final XnioWorker worker, OptionMap options); - } - - - private class UndertowXnioBufferSupport implements UndertowBufferSupport { - - private final org.xnio.Pool xnioBufferPool; - - private final Method httpClientConnectCallbackMethod; - - private final Method httpClientConnectMethod; - - public UndertowXnioBufferSupport() { - this.xnioBufferPool = new org.xnio.ByteBufferSlicePool(1048, 1048); - this.httpClientConnectCallbackMethod = ReflectionUtils.findMethod(UndertowClient.class, "connect", - ClientCallback.class, URI.class, XnioWorker.class, Pool.class, OptionMap.class); - this.httpClientConnectMethod = ReflectionUtils.findMethod(UndertowClient.class, "connect", - URI.class, XnioWorker.class, Pool.class, OptionMap.class); - } - - @Override - public Object allocatePooledResource() { - return this.xnioBufferPool.allocate(); - } - - @Override - @SuppressWarnings("unchecked") - public ByteBuffer getByteBuffer(Object pooled) { - return ((org.xnio.Pooled) pooled).getResource(); - } - - @Override - @SuppressWarnings("unchecked") - public void closePooledResource(Object pooled) { - ((org.xnio.Pooled) pooled).close(); - } - - @Override - public void httpClientConnect(UndertowClient httpClient, ClientCallback listener, URI uri, - XnioWorker worker, OptionMap options) { - ReflectionUtils.invokeMethod(httpClientConnectCallbackMethod, httpClient, listener, uri, worker, - this.xnioBufferPool, options); - } - - @Override - @SuppressWarnings("unchecked") - public IoFuture httpClientConnect(UndertowClient httpClient, URI uri, - XnioWorker worker, OptionMap options) { - return (IoFuture) ReflectionUtils.invokeMethod(httpClientConnectMethod, httpClient, uri, - worker, this.xnioBufferPool, options); - } - } - - - private class Undertow13BufferSupport implements UndertowBufferSupport { - - private final ByteBufferPool undertowBufferPool; - - private final Method httpClientConnectCallbackMethod; - - private final Method httpClientConnectMethod; - - public Undertow13BufferSupport() { - this.undertowBufferPool = new DefaultByteBufferPool(false, 1024, -1, 2); - this.httpClientConnectCallbackMethod = ReflectionUtils.findMethod(UndertowClient.class, "connect", - ClientCallback.class, URI.class, XnioWorker.class, ByteBufferPool.class, OptionMap.class); - this.httpClientConnectMethod = ReflectionUtils.findMethod(UndertowClient.class, "connect", - URI.class, XnioWorker.class, ByteBufferPool.class, OptionMap.class); - } - - @Override - public Object allocatePooledResource() { - return this.undertowBufferPool.allocate(); - } - - @Override - public ByteBuffer getByteBuffer(Object pooled) { - return ((PooledByteBuffer) pooled).getBuffer(); - } - - @Override - public void closePooledResource(Object pooled) { - ((PooledByteBuffer) pooled).close(); - } - - @Override - public void httpClientConnect(UndertowClient httpClient, ClientCallback listener, URI uri, - XnioWorker worker, OptionMap options) { - ReflectionUtils.invokeMethod(httpClientConnectCallbackMethod, httpClient, listener, uri, - worker, this.undertowBufferPool, options); - } - - @Override - @SuppressWarnings("unchecked") - public IoFuture httpClientConnect(UndertowClient httpClient, URI uri, - XnioWorker worker, OptionMap options) { - return (IoFuture) ReflectionUtils.invokeMethod(httpClientConnectMethod, httpClient, uri, - worker, this.undertowBufferPool, options); - } - } - }