This is an automated email from the git hooks/post-receive script. apo-guest pushed a commit to branch master in repository undertow.
commit 374d7a3041d3f1124d5ea9552941e21581961da6 Author: Markus Koschany <[email protected]> Date: Sat Oct 31 15:12:58 2015 +0100 Add alpn-not-supported.patch --- debian/patches/alpn-not-supported.patch | 1333 +++++++++++++++++++++++++++++++ debian/patches/series | 1 + 2 files changed, 1334 insertions(+) diff --git a/debian/patches/alpn-not-supported.patch b/debian/patches/alpn-not-supported.patch new file mode 100644 index 0000000..5bb8c67 --- /dev/null +++ b/debian/patches/alpn-not-supported.patch @@ -0,0 +1,1333 @@ +From: Markus Koschany <[email protected]> +Date: Sat, 31 Oct 2015 15:11:58 +0100 +Subject: alpn not supported + +--- + core/src/main/java/io/undertow/Undertow.java | 23 +- + .../undertow/client/http/HttpClientProvider.java | 14 +- + .../undertow/client/http2/Http2ClientProvider.java | 68 ---- + .../undertow/client/spdy/SpdyClientConnection.java | 331 ------------------- + .../undertow/client/spdy/SpdyClientExchange.java | 140 -------- + .../undertow/client/spdy/SpdyClientProvider.java | 356 --------------------- + .../server/protocol/http/AlpnOpenListener.java | 279 ---------------- + 7 files changed, 2 insertions(+), 1209 deletions(-) + delete mode 100644 core/src/main/java/io/undertow/client/spdy/SpdyClientConnection.java + delete mode 100644 core/src/main/java/io/undertow/client/spdy/SpdyClientExchange.java + delete mode 100644 core/src/main/java/io/undertow/client/spdy/SpdyClientProvider.java + delete mode 100644 core/src/main/java/io/undertow/server/protocol/http/AlpnOpenListener.java + +diff --git a/core/src/main/java/io/undertow/Undertow.java b/core/src/main/java/io/undertow/Undertow.java +index 1d36782..e8746fa 100644 +--- a/core/src/main/java/io/undertow/Undertow.java ++++ b/core/src/main/java/io/undertow/Undertow.java +@@ -22,10 +22,8 @@ import io.undertow.protocols.ssl.UndertowXnioSsl; + import io.undertow.server.DefaultByteBufferPool; + import io.undertow.server.HttpHandler; + import io.undertow.server.protocol.ajp.AjpOpenListener; +-import io.undertow.server.protocol.http.AlpnOpenListener; + import io.undertow.server.protocol.http.HttpOpenListener; + import io.undertow.server.protocol.http2.Http2OpenListener; +-import io.undertow.server.protocol.spdy.SpdyOpenListener; + import org.xnio.ChannelListener; + import org.xnio.ChannelListeners; + import org.xnio.IoUtils; +@@ -142,26 +140,7 @@ public final class Undertow { + + HttpOpenListener httpOpenListener = new HttpOpenListener(buffers, undertowOptions); + httpOpenListener.setRootHandler(rootHandler); +- +- boolean spdy = serverOptions.get(UndertowOptions.ENABLE_SPDY, false); +- boolean http2 = serverOptions.get(UndertowOptions.ENABLE_HTTP2, false); +- if(spdy || http2) { +- AlpnOpenListener alpn = new AlpnOpenListener(buffers, undertowOptions, httpOpenListener); +- if(spdy) { +- SpdyOpenListener spdyListener = new SpdyOpenListener(buffers, new DefaultByteBufferPool(false, 1024, -1, 2, 0), undertowOptions); +- spdyListener.setRootHandler(rootHandler); +- alpn.addProtocol(SpdyOpenListener.SPDY_3_1, spdyListener, 5); +- } +- if(http2) { +- Http2OpenListener http2Listener = new Http2OpenListener(buffers, undertowOptions); +- http2Listener.setRootHandler(rootHandler); +- alpn.addProtocol(Http2OpenListener.HTTP2, http2Listener, 10); +- alpn.addProtocol(Http2OpenListener.HTTP2_14, http2Listener, 7); +- } +- openListener = alpn; +- } else { +- openListener = httpOpenListener; +- } ++ openListener = httpOpenListener; + ChannelListener<AcceptingChannel<StreamConnection>> acceptListener = ChannelListeners.openListenerAdapter(openListener); + XnioSsl xnioSsl; + if (listener.sslContext != null) { +diff --git a/core/src/main/java/io/undertow/client/http/HttpClientProvider.java b/core/src/main/java/io/undertow/client/http/HttpClientProvider.java +index ccb32f0..572e45d 100644 +--- a/core/src/main/java/io/undertow/client/http/HttpClientProvider.java ++++ b/core/src/main/java/io/undertow/client/http/HttpClientProvider.java +@@ -24,7 +24,6 @@ import io.undertow.client.ClientCallback; + import io.undertow.client.ClientConnection; + import io.undertow.client.ClientProvider; + import io.undertow.client.http2.Http2ClientProvider; +-import io.undertow.client.spdy.SpdyClientProvider; + import org.xnio.ChannelListener; + import org.xnio.IoFuture; + import org.xnio.OptionMap; +@@ -129,18 +128,7 @@ public class HttpClientProvider implements ClientProvider { + + + private void handleConnected(final StreamConnection connection, final ClientCallback<ClientConnection> listener, final ByteBufferPool bufferPool, final OptionMap options, URI uri) { +- if (options.get(UndertowOptions.ENABLE_SPDY, false) && connection instanceof SslConnection && SpdyClientProvider.isEnabled()) { +- try { +- SpdyClientProvider.handlePotentialSpdyConnection(connection, listener, bufferPool, options, new ChannelListener<SslConnection>() { +- @Override +- public void handleEvent(SslConnection channel) { +- listener.completed(new HttpClientConnection(connection, options, bufferPool)); +- } +- }); +- } catch (Exception e) { +- listener.failed(new IOException(e)); +- } +- } else if (options.get(UndertowOptions.ENABLE_HTTP2, false) && connection instanceof SslConnection && Http2ClientProvider.isEnabled()) { ++ if (options.get(UndertowOptions.ENABLE_HTTP2, false) && connection instanceof SslConnection && Http2ClientProvider.isEnabled()) { + try { + Http2ClientProvider.handlePotentialHttp2Connection(connection, listener, bufferPool, options, new ChannelListener<SslConnection>() { + @Override +diff --git a/core/src/main/java/io/undertow/client/http2/Http2ClientProvider.java b/core/src/main/java/io/undertow/client/http2/Http2ClientProvider.java +index 0af0977..80dc0f1 100644 +--- a/core/src/main/java/io/undertow/client/http2/Http2ClientProvider.java ++++ b/core/src/main/java/io/undertow/client/http2/Http2ClientProvider.java +@@ -36,7 +36,6 @@ import io.undertow.conduits.ByteActivityCallback; + import io.undertow.conduits.BytesReceivedStreamSourceConduit; + import io.undertow.conduits.BytesSentStreamSinkConduit; + import io.undertow.protocols.ssl.UndertowXnioSsl; +-import org.eclipse.jetty.alpn.ALPN; + import org.xnio.ChannelListener; + import org.xnio.IoFuture; + import org.xnio.OptionMap; +@@ -181,29 +180,12 @@ public class Http2ClientProvider implements ClientProvider { + final SslConnection sslConnection = (SslConnection) connection; + final SSLEngine sslEngine = UndertowXnioSsl.getSslEngine(sslConnection); + +- final Http2SelectionProvider http2SelectionProvider = new Http2SelectionProvider(sslEngine); +- try { +- ALPN_PUT_METHOD.invoke(null, sslEngine, http2SelectionProvider); +- } catch (Exception e) { +- http2FailedListener.handleEvent(sslConnection); +- return; +- } +- + try { + sslConnection.startHandshake(); + sslConnection.getSourceChannel().getReadSetter().set(new ChannelListener<StreamSourceChannel>() { + @Override + public void handleEvent(StreamSourceChannel channel) { + +- if (http2SelectionProvider.selected != null) { +- if (http2SelectionProvider.selected.equals(HTTP_1_1)) { +- sslConnection.getSourceChannel().suspendReads(); +- http2FailedListener.handleEvent(sslConnection); +- return; +- } else if (http2SelectionProvider.selected.equals(HTTP2)) { +- listener.completed(createHttp2Channel(connection, bufferPool, options, uri.getHost())); +- } +- } else { + ByteBuffer buf = ByteBuffer.allocate(100); + try { + int read = channel.read(buf); +@@ -213,25 +195,10 @@ public class Http2ClientProvider implements ClientProvider { + pb.pushBack(new ImmediatePooled<>(buf)); + connection.getSourceChannel().setConduit(pb); + } +- if (http2SelectionProvider.selected == null) { +- http2SelectionProvider.selected = (String) sslEngine.getSession().getValue(PROTOCOL_KEY); +- } +- if ((http2SelectionProvider.selected == null && read > 0) || HTTP_1_1.equals(http2SelectionProvider.selected)) { +- sslConnection.getSourceChannel().suspendReads(); +- http2FailedListener.handleEvent(sslConnection); +- return; +- } else if (http2SelectionProvider.selected != null) { +- //we have spdy +- if (http2SelectionProvider.selected.equals(HTTP2)) { +- listener.completed(createHttp2Channel(connection, bufferPool, options, uri.getHost())); +- } +- } + } catch (IOException e) { + listener.failed(e); + } +- } + } +- + }); + sslConnection.getSourceChannel().resumeReads(); + } catch (IOException e) { +@@ -268,41 +235,6 @@ public class Http2ClientProvider implements ClientProvider { + return new Http2ClientConnection(http2Channel, false, defaultHost, clientStatistics); + } + +- private static class Http2SelectionProvider implements ALPN.ClientProvider { +- private String selected; +- private final SSLEngine sslEngine; +- +- private Http2SelectionProvider(SSLEngine sslEngine) { +- this.sslEngine = sslEngine; +- } +- +- @Override +- public boolean supports() { +- return true; +- } +- +- @Override +- public List<String> protocols() { +- return PROTOCOLS; +- } +- +- @Override +- public void unsupported() { +- selected = HTTP_1_1; +- } +- +- @Override +- public void selected(String s) { +- +- ALPN.remove(sslEngine); +- selected = s; +- sslEngine.getHandshakeSession().putValue(PROTOCOL_KEY, selected); +- } +- +- private String getSelected() { +- return selected; +- } +- } + + + private static class ClientStatisticsImpl implements ClientStatistics { +diff --git a/core/src/main/java/io/undertow/client/spdy/SpdyClientConnection.java b/core/src/main/java/io/undertow/client/spdy/SpdyClientConnection.java +deleted file mode 100644 +index c5a05be..0000000 +--- a/core/src/main/java/io/undertow/client/spdy/SpdyClientConnection.java ++++ /dev/null +@@ -1,331 +0,0 @@ +-/* +- * JBoss, Home of Professional Open Source. +- * Copyright 2014 Red Hat, Inc., and individual contributors +- * as indicated by the @author tags. +- * +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-package io.undertow.client.spdy; +- +-import io.undertow.UndertowLogger; +-import io.undertow.UndertowMessages; +-import io.undertow.client.ClientCallback; +-import io.undertow.client.ClientConnection; +-import io.undertow.client.ClientExchange; +-import io.undertow.client.ClientRequest; +-import io.undertow.client.ClientStatistics; +-import io.undertow.protocols.spdy.SpdyChannel; +-import io.undertow.protocols.spdy.SpdyPingStreamSourceChannel; +-import io.undertow.protocols.spdy.SpdyRstStreamStreamSourceChannel; +-import io.undertow.protocols.spdy.SpdyStreamSourceChannel; +-import io.undertow.protocols.spdy.SpdySynReplyStreamSourceChannel; +-import io.undertow.protocols.spdy.SpdySynStreamStreamSinkChannel; +-import io.undertow.util.Headers; +-import io.undertow.util.HttpString; +-import org.xnio.ChannelExceptionHandler; +-import org.xnio.ChannelListener; +-import org.xnio.ChannelListeners; +-import org.xnio.IoUtils; +-import org.xnio.Option; +-import io.undertow.connector.ByteBufferPool; +-import org.xnio.StreamConnection; +-import org.xnio.XnioIoThread; +-import org.xnio.XnioWorker; +-import org.xnio.channels.StreamSinkChannel; +- +-import java.io.IOException; +-import java.net.SocketAddress; +-import java.util.Map; +-import java.util.concurrent.ConcurrentHashMap; +- +-import static io.undertow.util.Headers.CONTENT_LENGTH; +-import static io.undertow.util.Headers.TRANSFER_ENCODING; +- +-/** +- * @author Stuart Douglas +- */ +-public class SpdyClientConnection implements ClientConnection { +- +- +- static final HttpString METHOD = new HttpString(":method"); +- static final HttpString PATH = new HttpString(":path"); +- static final HttpString SCHEME = new HttpString(":scheme"); +- static final HttpString VERSION = new HttpString(":version"); +- static final HttpString HOST = new HttpString(":host"); +- static final HttpString STATUS = new HttpString(":status"); +- +- private final SpdyChannel spdyChannel; +- private final ChannelListener.SimpleSetter<ClientConnection> closeSetter = new ChannelListener.SimpleSetter<>(); +- +- private final Map<Integer, SpdyClientExchange> currentExchanges = new ConcurrentHashMap<>(); +- +- private final ClientStatistics clientStatistics; +- public SpdyClientConnection(SpdyChannel spdyChannel, ClientStatistics clientStatistics) { +- this.spdyChannel = spdyChannel; +- this.clientStatistics = clientStatistics; +- spdyChannel.getReceiveSetter().set(new SpdyReceiveListener()); +- spdyChannel.resumeReceives(); +- spdyChannel.addCloseTask(new ChannelListener<SpdyChannel>() { +- @Override +- public void handleEvent(SpdyChannel channel) { +- ChannelListeners.invokeChannelListener(SpdyClientConnection.this, closeSetter.get()); +- } +- }); +- } +- +- @Override +- public void sendRequest(ClientRequest request, ClientCallback<ClientExchange> clientCallback) { +- request.getRequestHeaders().put(PATH, request.getPath()); +- request.getRequestHeaders().put(SCHEME, "https"); +- request.getRequestHeaders().put(VERSION, request.getProtocol().toString()); +- request.getRequestHeaders().put(METHOD, request.getMethod().toString()); +- request.getRequestHeaders().put(HOST, request.getRequestHeaders().getFirst(Headers.HOST)); +- request.getRequestHeaders().remove(Headers.HOST); +- +- SpdySynStreamStreamSinkChannel sinkChannel; +- try { +- sinkChannel = spdyChannel.createStream(request.getRequestHeaders()); +- } catch (IOException e) { +- clientCallback.failed(e); +- return; +- } +- SpdyClientExchange exchange = new SpdyClientExchange(this, sinkChannel, request); +- currentExchanges.put(sinkChannel.getStreamId(), exchange); +- +- +- boolean hasContent = true; +- +- String fixedLengthString = request.getRequestHeaders().getFirst(CONTENT_LENGTH); +- String transferEncodingString = request.getRequestHeaders().getLast(TRANSFER_ENCODING); +- if (fixedLengthString != null) { +- try { +- long length = Long.parseLong(fixedLengthString); +- hasContent = length != 0; +- } catch (NumberFormatException e) { +- handleError(new IOException(e)); +- return; +- } +- } else if (transferEncodingString == null) { +- hasContent = false; +- } +- if(clientCallback != null) { +- clientCallback.completed(exchange); +- } +- if (!hasContent) { +- //if there is no content we flush the response channel. +- //otherwise it is up to the user +- try { +- sinkChannel.shutdownWrites(); +- if (!sinkChannel.flush()) { +- sinkChannel.getWriteSetter().set(ChannelListeners.flushingChannelListener(null, new ChannelExceptionHandler<StreamSinkChannel>() { +- @Override +- public void handleException(StreamSinkChannel channel, IOException exception) { +- handleError(exception); +- } +- })); +- sinkChannel.resumeWrites(); +- } +- } catch (IOException e) { +- handleError(e); +- } +- } else if (!sinkChannel.isWriteResumed()) { +- try { +- //TODO: this needs some more thought +- if (!sinkChannel.flush()) { +- sinkChannel.getWriteSetter().set(new ChannelListener<StreamSinkChannel>() { +- @Override +- public void handleEvent(StreamSinkChannel channel) { +- try { +- if (channel.flush()) { +- channel.suspendWrites(); +- } +- } catch (IOException e) { +- handleError(e); +- } +- } +- }); +- sinkChannel.resumeWrites(); +- } +- } catch (IOException e) { +- handleError(e); +- } +- } +- } +- +- private void handleError(IOException e) { +- +- UndertowLogger.REQUEST_IO_LOGGER.ioException(e); +- IoUtils.safeClose(SpdyClientConnection.this); +- for (Map.Entry<Integer, SpdyClientExchange> entry : currentExchanges.entrySet()) { +- try { +- entry.getValue().failed(e); +- } catch (Exception ex) { +- UndertowLogger.REQUEST_IO_LOGGER.ioException(new IOException(ex)); +- } +- } +- } +- +- @Override +- public StreamConnection performUpgrade() throws IOException { +- throw UndertowMessages.MESSAGES.upgradeNotSupported(); +- } +- +- @Override +- public ByteBufferPool getBufferPool() { +- return spdyChannel.getBufferPool(); +- } +- +- @Override +- public SocketAddress getPeerAddress() { +- return spdyChannel.getPeerAddress(); +- } +- +- @Override +- public <A extends SocketAddress> A getPeerAddress(Class<A> type) { +- return spdyChannel.getPeerAddress(type); +- } +- +- @Override +- public ChannelListener.Setter<? extends ClientConnection> getCloseSetter() { +- return closeSetter; +- } +- +- @Override +- public SocketAddress getLocalAddress() { +- return spdyChannel.getLocalAddress(); +- } +- +- @Override +- public <A extends SocketAddress> A getLocalAddress(Class<A> type) { +- return spdyChannel.getLocalAddress(type); +- } +- +- @Override +- public XnioWorker getWorker() { +- return spdyChannel.getWorker(); +- } +- +- @Override +- public XnioIoThread getIoThread() { +- return spdyChannel.getIoThread(); +- } +- +- @Override +- public boolean isOpen() { +- return spdyChannel.isOpen(); +- } +- +- @Override +- public void close() throws IOException { +- spdyChannel.sendGoAway(SpdyChannel.CLOSE_OK); +- } +- +- @Override +- public boolean supportsOption(Option<?> option) { +- return false; +- } +- +- @Override +- public <T> T getOption(Option<T> option) throws IOException { +- return null; +- } +- +- @Override +- public <T> T setOption(Option<T> option, T value) throws IllegalArgumentException, IOException { +- return null; +- } +- +- @Override +- public boolean isUpgraded() { +- return false; +- } +- +- @Override +- public boolean isPushSupported() { +- return true; +- } +- +- @Override +- public boolean isMultiplexingSupported() { +- return true; +- } +- +- @Override +- public ClientStatistics getStatistics() { +- return clientStatistics; +- } +- +- private class SpdyReceiveListener implements ChannelListener<SpdyChannel> { +- +- @Override +- public void handleEvent(SpdyChannel channel) { +- try { +- SpdyStreamSourceChannel result = channel.receive(); +- if (result instanceof SpdySynReplyStreamSourceChannel) { +- final int streamId = ((SpdySynReplyStreamSourceChannel) result).getStreamId(); +- SpdyClientExchange request = currentExchanges.get(streamId); +- result.addCloseTask(new ChannelListener<SpdyStreamSourceChannel>() { +- @Override +- public void handleEvent(SpdyStreamSourceChannel channel) { +- currentExchanges.remove(streamId); +- } +- }); +- if (request == null) { +- +- //server side initiated stream, we can't deal with that at the moment +- //just fail +- //TODO: either handle this properly or at the very least send RST_STREAM +- channel.sendGoAway(SpdyChannel.CLOSE_PROTOCOL_ERROR); +- IoUtils.safeClose(SpdyClientConnection.this); +- return; +- } +- request.responseReady((SpdySynReplyStreamSourceChannel) result); +- +- } else if (result instanceof SpdyPingStreamSourceChannel) { +- handlePing((SpdyPingStreamSourceChannel) result); +- } else if (result instanceof SpdyRstStreamStreamSourceChannel) { +- int stream = ((SpdyRstStreamStreamSourceChannel)result).getStreamId(); +- UndertowLogger.REQUEST_LOGGER.debugf("Client received RST_STREAM for stream %s", stream); +- SpdyClientExchange exchange = currentExchanges.get(stream); +- if(exchange != null) { +- exchange.failed(UndertowMessages.MESSAGES.spdyStreamWasReset()); +- } +- } else if(!channel.isOpen()) { +- throw UndertowMessages.MESSAGES.channelIsClosed(); +- } +- +- } catch (IOException e) { +- UndertowLogger.REQUEST_IO_LOGGER.ioException(e); +- IoUtils.safeClose(SpdyClientConnection.this); +- for (Map.Entry<Integer, SpdyClientExchange> entry : currentExchanges.entrySet()) { +- try { +- entry.getValue().failed(e); +- } catch (Exception ex) { +- UndertowLogger.REQUEST_IO_LOGGER.ioException(new IOException(ex)); +- } +- } +- } +- +- } +- +- private void handlePing(SpdyPingStreamSourceChannel frame) { +- int id = frame.getId(); +- if (id % 2 == 0) { +- //server side ping, return it +- frame.getSpdyChannel().sendPing(id); +- } +- } +- +- } +-} +diff --git a/core/src/main/java/io/undertow/client/spdy/SpdyClientExchange.java b/core/src/main/java/io/undertow/client/spdy/SpdyClientExchange.java +deleted file mode 100644 +index ae282bf..0000000 +--- a/core/src/main/java/io/undertow/client/spdy/SpdyClientExchange.java ++++ /dev/null +@@ -1,140 +0,0 @@ +-/* +- * JBoss, Home of Professional Open Source. +- * Copyright 2014 Red Hat, Inc., and individual contributors +- * as indicated by the @author tags. +- * +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-package io.undertow.client.spdy; +- +-import io.undertow.client.ClientCallback; +-import io.undertow.client.ClientConnection; +-import io.undertow.client.ClientExchange; +-import io.undertow.client.ClientRequest; +-import io.undertow.client.ClientResponse; +-import io.undertow.client.ContinueNotification; +-import io.undertow.client.PushCallback; +-import io.undertow.protocols.spdy.SpdyStreamSinkChannel; +-import io.undertow.protocols.spdy.SpdyStreamSourceChannel; +-import io.undertow.protocols.spdy.SpdySynReplyStreamSourceChannel; +-import io.undertow.util.AbstractAttachable; +-import io.undertow.util.HeaderMap; +-import io.undertow.util.Headers; +-import org.xnio.channels.StreamSinkChannel; +-import org.xnio.channels.StreamSourceChannel; +- +-import java.io.IOException; +- +-/** +- * @author Stuart Douglas +- */ +-public class SpdyClientExchange extends AbstractAttachable implements ClientExchange { +- private ClientCallback<ClientExchange> responseListener; +- private ContinueNotification continueNotification; +- private SpdyStreamSourceChannel response; +- private ClientResponse clientResponse; +- private final ClientConnection clientConnection; +- private final SpdyStreamSinkChannel request; +- private final ClientRequest clientRequest; +- private IOException failedReason; +- private PushCallback pushCallback; +- +- public SpdyClientExchange(ClientConnection clientConnection, SpdyStreamSinkChannel request, ClientRequest clientRequest) { +- this.clientConnection = clientConnection; +- this.request = request; +- this.clientRequest = clientRequest; +- } +- +- @Override +- public void setResponseListener(ClientCallback<ClientExchange> responseListener) { +- this.responseListener = responseListener; +- if (responseListener != null) { +- if (failedReason != null) { +- responseListener.failed(failedReason); +- } else if (clientResponse != null) { +- responseListener.completed(this); +- } +- } +- } +- +- @Override +- public void setContinueHandler(ContinueNotification continueHandler) { +- String expect = clientRequest.getRequestHeaders().getFirst(Headers.EXPECT); +- if ("100-continue".equalsIgnoreCase(expect)) { +- continueHandler.handleContinue(this); +- } +- } +- +- @Override +- public void setPushHandler(PushCallback pushCallback) { +- this.pushCallback = pushCallback; +- } +- +- PushCallback getPushCallback() { +- return pushCallback; +- } +- +- @Override +- public StreamSinkChannel getRequestChannel() { +- return request; +- } +- +- @Override +- public StreamSourceChannel getResponseChannel() { +- return response; +- } +- +- @Override +- public ClientRequest getRequest() { +- return clientRequest; +- } +- +- @Override +- public ClientResponse getResponse() { +- return clientResponse; +- } +- +- @Override +- public ClientResponse getContinueResponse() { +- return null; +- } +- +- @Override +- public ClientConnection getConnection() { +- return clientConnection; +- } +- +- void failed(final IOException e) { +- this.failedReason = e; +- if(responseListener != null) { +- responseListener.failed(e); +- } +- } +- +- void responseReady(SpdySynReplyStreamSourceChannel result) { +- this.response = result; +- HeaderMap headers = result.getHeaders(); +- final String status = result.getHeaders().getFirst(SpdyClientConnection.STATUS); +- int statusCode = 500; +- if (status != null && status.length() > 3) { +- statusCode = Integer.parseInt(status.substring(0, 3)); +- } +- headers.remove(SpdyClientConnection.VERSION); +- headers.remove(SpdyClientConnection.STATUS); +- clientResponse = new ClientResponse(statusCode, status != null ? status.substring(3) : "", clientRequest.getProtocol(), headers); +- if (responseListener != null) { +- responseListener.completed(this); +- } +- } +-} +diff --git a/core/src/main/java/io/undertow/client/spdy/SpdyClientProvider.java b/core/src/main/java/io/undertow/client/spdy/SpdyClientProvider.java +deleted file mode 100644 +index 7540f6e..0000000 +--- a/core/src/main/java/io/undertow/client/spdy/SpdyClientProvider.java ++++ /dev/null +@@ -1,356 +0,0 @@ +-/* +- * JBoss, Home of Professional Open Source. +- * Copyright 2014 Red Hat, Inc., and individual contributors +- * as indicated by the @author tags. +- * +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-package io.undertow.client.spdy; +- +-import java.io.IOException; +-import java.lang.reflect.Method; +-import java.net.InetSocketAddress; +-import java.net.URI; +-import java.nio.ByteBuffer; +-import java.util.Arrays; +-import java.util.Collections; +-import java.util.HashSet; +-import java.util.List; +-import java.util.Set; +-import javax.net.ssl.SSLEngine; +- +-import io.undertow.UndertowOptions; +-import io.undertow.client.ClientStatistics; +-import io.undertow.conduits.ByteActivityCallback; +-import io.undertow.conduits.BytesReceivedStreamSourceConduit; +-import io.undertow.conduits.BytesSentStreamSinkConduit; +-import io.undertow.protocols.ssl.UndertowXnioSsl; +-import io.undertow.server.DefaultByteBufferPool; +-import org.eclipse.jetty.alpn.ALPN; +-import org.xnio.ChannelListener; +-import org.xnio.IoFuture; +-import org.xnio.OptionMap; +-import org.xnio.Options; +-import io.undertow.connector.ByteBufferPool; +-import org.xnio.StreamConnection; +-import org.xnio.XnioIoThread; +-import org.xnio.XnioWorker; +-import org.xnio.channels.StreamSourceChannel; +-import org.xnio.conduits.PushBackStreamSourceConduit; +-import org.xnio.ssl.SslConnection; +-import org.xnio.ssl.XnioSsl; +- +-import io.undertow.UndertowLogger; +-import io.undertow.UndertowMessages; +-import io.undertow.client.ClientCallback; +-import io.undertow.client.ClientConnection; +-import io.undertow.client.ClientProvider; +-import io.undertow.protocols.spdy.SpdyChannel; +-import io.undertow.util.ImmediatePooled; +- +-/** +- * Dedicated SPDY client that will never fall back to HTTPS +- * +- * @author Stuart Douglas +- */ +-public class SpdyClientProvider implements ClientProvider { +- +- private static final String PROTOCOL_KEY = SpdyClientProvider.class.getName() + ".protocol"; +- +- private static final String SPDY_3 = "spdy/3"; +- private static final String SPDY_3_1 = "spdy/3.1"; +- private static final String HTTP_1_1 = "http/1.1"; +- +- private static final List<String> PROTOCOLS = Collections.unmodifiableList(Arrays.asList(SPDY_3_1, HTTP_1_1)); +- +- private static final Method ALPN_PUT_METHOD; +- +- static { +- Method npnPutMethod; +- try { +- Class<?> npnClass = Class.forName("org.eclipse.jetty.alpn.ALPN", false, SpdyClientProvider.class.getClassLoader()); +- npnPutMethod = npnClass.getDeclaredMethod("put", SSLEngine.class, Class.forName("org.eclipse.jetty.alpn.ALPN$Provider", false, SpdyClientProvider.class.getClassLoader())); +- } catch (Exception e) { +- UndertowLogger.CLIENT_LOGGER.jettyALPNNotFound("SPDY"); +- npnPutMethod = null; +- } +- ALPN_PUT_METHOD = npnPutMethod; +- } +- +- +- @Override +- public void connect(final ClientCallback<ClientConnection> listener, final URI uri, final XnioWorker worker, final XnioSsl ssl, final ByteBufferPool bufferPool, final OptionMap options) { +- connect(listener, null, uri, worker, ssl, bufferPool, options); +- } +- +- @Override +- public void connect(final ClientCallback<ClientConnection> listener, final URI uri, final XnioIoThread ioThread, final XnioSsl ssl, final ByteBufferPool bufferPool, final OptionMap options) { +- connect(listener, null, uri, ioThread, ssl, bufferPool, options); +- } +- +- @Override +- public Set<String> handlesSchemes() { +- return new HashSet<>(Arrays.asList(new String[]{"spdy", "spdy-plain"})); +- } +- +- @Override +- public void connect(final ClientCallback<ClientConnection> listener, InetSocketAddress bindAddress, final URI uri, final XnioWorker worker, final XnioSsl ssl, final ByteBufferPool bufferPool, final OptionMap options) { +- if(uri.getScheme().equals("spdy-plain")) { +- +- if(bindAddress == null) { +- worker.openStreamConnection(new InetSocketAddress(uri.getHost(), uri.getPort() == -1 ? 443 : uri.getPort()), createOpenListener(listener, uri, ssl, bufferPool, options), options).addNotifier(createNotifier(listener), null); +- } else { +- worker.openStreamConnection(bindAddress, new InetSocketAddress(uri.getHost(), uri.getPort() == -1 ? 443 : uri.getPort()), createOpenListener(listener, uri, ssl, bufferPool, options), null, options).addNotifier(createNotifier(listener), null); +- } +- return; +- } +- +- +- if(ALPN_PUT_METHOD == null) { +- listener.failed(UndertowMessages.MESSAGES.jettyNPNNotAvailable()); +- return; +- } +- if (ssl == null) { +- listener.failed(UndertowMessages.MESSAGES.sslWasNull()); +- return; +- } +- OptionMap tlsOptions = OptionMap.builder().addAll(options).set(Options.SSL_STARTTLS, true).getMap(); +- if(bindAddress == null) { +- ssl.openSslConnection(worker, new InetSocketAddress(uri.getHost(), uri.getPort() == -1 ? 443 : uri.getPort()), createOpenListener(listener, uri, ssl, bufferPool, tlsOptions), tlsOptions).addNotifier(createNotifier(listener), null); +- } else { +- ssl.openSslConnection(worker, bindAddress, new InetSocketAddress(uri.getHost(), uri.getPort() == -1 ? 443 : uri.getPort()), createOpenListener(listener, uri, ssl, bufferPool, tlsOptions), tlsOptions).addNotifier(createNotifier(listener), null); +- } +- +- } +- +- @Override +- public void connect(final ClientCallback<ClientConnection> listener, InetSocketAddress bindAddress, final URI uri, final XnioIoThread ioThread, final XnioSsl ssl, final ByteBufferPool bufferPool, final OptionMap options) { +- if(uri.getScheme().equals("spdy-plain")) { +- +- if(bindAddress == null) { +- ioThread.openStreamConnection(new InetSocketAddress(uri.getHost(), uri.getPort() == -1 ? 443 : uri.getPort()), createOpenListener(listener, uri, ssl, bufferPool, options), options).addNotifier(createNotifier(listener), null); +- } else { +- ioThread.openStreamConnection(bindAddress, new InetSocketAddress(uri.getHost(), uri.getPort() == -1 ? 443 : uri.getPort()), createOpenListener(listener, uri, ssl, bufferPool, options), null, options).addNotifier(createNotifier(listener), null); +- } +- return; +- } +- +- if(ALPN_PUT_METHOD == null) { +- listener.failed(UndertowMessages.MESSAGES.jettyNPNNotAvailable()); +- return; +- } +- if (ssl == null) { +- listener.failed(UndertowMessages.MESSAGES.sslWasNull()); +- return; +- } +- OptionMap tlsOptions = OptionMap.builder().addAll(options).set(Options.SSL_STARTTLS, true).getMap(); +- if(bindAddress == null) { +- ssl.openSslConnection(ioThread, new InetSocketAddress(uri.getHost(), uri.getPort() == -1 ? 443 : uri.getPort()), createOpenListener(listener, uri, ssl, bufferPool, tlsOptions), tlsOptions).addNotifier(createNotifier(listener), null); +- } else { +- ssl.openSslConnection(ioThread, bindAddress, new InetSocketAddress(uri.getHost(), uri.getPort() == -1 ? 443 : uri.getPort()), createOpenListener(listener, uri, ssl, bufferPool, tlsOptions), tlsOptions).addNotifier(createNotifier(listener), null); +- } +- +- } +- +- private IoFuture.Notifier<StreamConnection, Object> createNotifier(final ClientCallback<ClientConnection> listener) { +- return new IoFuture.Notifier<StreamConnection, Object>() { +- @Override +- public void notify(IoFuture<? extends StreamConnection> ioFuture, Object o) { +- if (ioFuture.getStatus() == IoFuture.Status.FAILED) { +- listener.failed(ioFuture.getException()); +- } +- } +- }; +- } +- +- private ChannelListener<StreamConnection> createOpenListener(final ClientCallback<ClientConnection> listener, final URI uri, final XnioSsl ssl, final ByteBufferPool bufferPool, final OptionMap options) { +- return new ChannelListener<StreamConnection>() { +- @Override +- public void handleEvent(StreamConnection connection) { +- handleConnected(connection, listener, uri, ssl, bufferPool, options); +- } +- }; +- } +- +- private void handleConnected(StreamConnection connection, final ClientCallback<ClientConnection> listener, URI uri, XnioSsl ssl, ByteBufferPool bufferPool, OptionMap options) { +- if(connection instanceof SslConnection) { +- handlePotentialSpdyConnection(connection, listener, bufferPool, options, new ChannelListener<SslConnection>() { +- @Override +- public void handleEvent(SslConnection channel) { +- listener.failed(UndertowMessages.MESSAGES.spdyNotSupported()); +- } +- }); +- } else { +- listener.completed(createSpdyChannel(connection, bufferPool, options)); +- } +- } +- +- public static boolean isEnabled() { +- return ALPN_PUT_METHOD != null; +- } +- +- /** +- * Not really part of the public API, but is used by the HTTP client to initiate a SPDY connection for HTTPS requests. +- */ +- public static void handlePotentialSpdyConnection(final StreamConnection connection, final ClientCallback<ClientConnection> listener, final ByteBufferPool bufferPool, final OptionMap options, final ChannelListener<SslConnection> spdyFailedListener) { +- +- final SslConnection sslConnection = (SslConnection) connection; +- final SSLEngine sslEngine = UndertowXnioSsl.getSslEngine(sslConnection); +- +- final SpdySelectionProvider spdySelectionProvider = new SpdySelectionProvider(sslEngine); +- try { +- ALPN_PUT_METHOD.invoke(null, sslEngine, spdySelectionProvider); +- } catch (Exception e) { +- spdyFailedListener.handleEvent(sslConnection); +- return; +- } +- +- try { +- sslConnection.startHandshake(); +- sslConnection.getSourceChannel().getReadSetter().set(new ChannelListener<StreamSourceChannel>() { +- @Override +- public void handleEvent(StreamSourceChannel channel) { +- +- if (spdySelectionProvider.selected != null) { +- if (spdySelectionProvider.selected.equals(HTTP_1_1)) { +- sslConnection.getSourceChannel().suspendReads(); +- spdyFailedListener.handleEvent(sslConnection); +- return; +- } else if (spdySelectionProvider.selected.equals(SPDY_3) || spdySelectionProvider.selected.equals(SPDY_3_1)) { +- listener.completed(createSpdyChannel(connection, bufferPool, options)); +- } +- } else { +- ByteBuffer buf = ByteBuffer.allocate(100); +- try { +- int read = channel.read(buf); +- if (read > 0) { +- buf.flip(); +- PushBackStreamSourceConduit pb = new PushBackStreamSourceConduit(connection.getSourceChannel().getConduit()); +- pb.pushBack(new ImmediatePooled<>(buf)); +- connection.getSourceChannel().setConduit(pb); +- } +- if(spdySelectionProvider.selected == null) { +- spdySelectionProvider.selected = (String) sslEngine.getSession().getValue(PROTOCOL_KEY); +- } +- if ((spdySelectionProvider.selected == null && read > 0) || HTTP_1_1.equals(spdySelectionProvider.selected)) { +- sslConnection.getSourceChannel().suspendReads(); +- spdyFailedListener.handleEvent(sslConnection); +- return; +- } else if (spdySelectionProvider.selected != null) { +- //we have spdy +- if (spdySelectionProvider.selected.equals(SPDY_3) || spdySelectionProvider.selected.equals(SPDY_3_1)) { +- listener.completed(createSpdyChannel(connection, bufferPool, options)); +- } +- } +- } catch (IOException e) { +- listener.failed(e); +- } +- } +- } +- +- }); +- sslConnection.getSourceChannel().resumeReads(); +- } catch (IOException e) { +- listener.failed(e); +- } +- +- +- } +- +- private static SpdyClientConnection createSpdyChannel(StreamConnection connection, ByteBufferPool bufferPool, OptionMap options) { +- +- final ClientStatisticsImpl clientStatistics; +- //first we set up statistics, if required +- if (options.get(UndertowOptions.ENABLE_STATISTICS, false)) { +- clientStatistics = new ClientStatisticsImpl(); +- connection.getSinkChannel().setConduit(new BytesSentStreamSinkConduit(connection.getSinkChannel().getConduit(), new ByteActivityCallback() { +- @Override +- public void activity(long bytes) { +- clientStatistics.written += bytes; +- } +- })); +- connection.getSourceChannel().setConduit(new BytesReceivedStreamSourceConduit(connection.getSourceChannel().getConduit(), new ByteActivityCallback() { +- @Override +- public void activity(long bytes) { +- clientStatistics.read += bytes; +- } +- })); +- } else { +- clientStatistics = null; +- } +- SpdyChannel spdyChannel = new SpdyChannel(connection, bufferPool, null, new DefaultByteBufferPool(false, 8192), true, options); +- return new SpdyClientConnection(spdyChannel, clientStatistics); +- } +- +- private static class SpdySelectionProvider implements ALPN.ClientProvider { +- private String selected; +- private final SSLEngine sslEngine; +- +- private SpdySelectionProvider(SSLEngine sslEngine) { +- this.sslEngine = sslEngine; +- } +- +- @Override +- public boolean supports() { +- return true; +- } +- +- @Override +- public List<String> protocols() { +- return PROTOCOLS; +- } +- +- @Override +- public void unsupported() { +- selected = HTTP_1_1; +- } +- +- @Override +- public void selected(String s) { +- +- ALPN.remove(sslEngine); +- selected = s; +- sslEngine.getHandshakeSession().putValue(PROTOCOL_KEY, selected); +- } +- +- private String getSelected() { +- return selected; +- } +- } +- +- private static class ClientStatisticsImpl implements ClientStatistics { +- private long requestCount, read, written; +- @Override +- public long getRequests() { +- return requestCount; +- } +- +- @Override +- public long getRead() { +- return read; +- } +- +- @Override +- public long getWritten() { +- return written; +- } +- +- @Override +- public void reset() { +- read = 0; +- written = 0; +- requestCount = 0; +- } +- } +-} +diff --git a/core/src/main/java/io/undertow/server/protocol/http/AlpnOpenListener.java b/core/src/main/java/io/undertow/server/protocol/http/AlpnOpenListener.java +deleted file mode 100644 +index 75c5a16..0000000 +--- a/core/src/main/java/io/undertow/server/protocol/http/AlpnOpenListener.java ++++ /dev/null +@@ -1,279 +0,0 @@ +-/* +- * JBoss, Home of Professional Open Source. +- * Copyright 2014 Red Hat, Inc., and individual contributors +- * as indicated by the @author tags. +- * +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-package io.undertow.server.protocol.http; +- +-import java.io.IOException; +-import java.nio.ByteBuffer; +-import java.util.ArrayList; +-import java.util.HashMap; +-import java.util.List; +-import java.util.Map; +- +-import javax.net.ssl.SSLEngine; +- +-import io.undertow.UndertowLogger; +-import io.undertow.UndertowMessages; +-import io.undertow.UndertowOptions; +-import io.undertow.protocols.ssl.UndertowXnioSsl; +-import io.undertow.server.AggregateConnectorStatistics; +-import io.undertow.server.ConnectorStatistics; +-import io.undertow.server.DelegateOpenListener; +-import io.undertow.server.HttpHandler; +-import io.undertow.server.OpenListener; +-import io.undertow.server.XnioByteBufferPool; +-import org.eclipse.jetty.alpn.ALPN; +-import org.xnio.ChannelListener; +-import org.xnio.IoUtils; +-import org.xnio.OptionMap; +-import io.undertow.connector.ByteBufferPool; +-import io.undertow.connector.PooledByteBuffer; +-import org.xnio.Pool; +-import org.xnio.StreamConnection; +-import org.xnio.channels.StreamSourceChannel; +-import org.xnio.ssl.SslConnection; +- +-/** +- * Open listener adaptor for ALPN connections +- * +- * Not a proper open listener as such, but more a mechanism for selecting between them +- * +- * @author Stuart Douglas +- */ +-public class AlpnOpenListener implements ChannelListener<StreamConnection>, OpenListener { +- +- private static final String PROTOCOL_KEY = AlpnOpenListener.class.getName() + ".protocol"; +- +- private final ByteBufferPool bufferPool; +- +- private final Map<String, ListenerEntry> listeners = new HashMap<>(); +- private final String fallbackProtocol; +- private volatile HttpHandler rootHandler; +- private volatile OptionMap undertowOptions; +- private volatile boolean statisticsEnabled; +- +- public AlpnOpenListener(Pool<ByteBuffer> bufferPool, OptionMap undertowOptions, DelegateOpenListener httpListener) { +- this(bufferPool, undertowOptions, "http/1.1", httpListener); +- } +- +- public AlpnOpenListener(Pool<ByteBuffer> bufferPool, OptionMap undertowOptions) { +- this(bufferPool, undertowOptions, null, null); +- } +- +- public AlpnOpenListener(Pool<ByteBuffer> bufferPool, OptionMap undertowOptions, String fallbackProtocol, DelegateOpenListener fallbackListener) { +- this(new XnioByteBufferPool(bufferPool), undertowOptions, fallbackProtocol, fallbackListener); +- } +- +- public AlpnOpenListener(ByteBufferPool bufferPool, OptionMap undertowOptions, DelegateOpenListener httpListener) { +- this(bufferPool, undertowOptions, "http/1.1", httpListener); +- } +- +- public AlpnOpenListener(ByteBufferPool bufferPool) { +- this(bufferPool, OptionMap.EMPTY, null, null); +- } +- public AlpnOpenListener(ByteBufferPool bufferPool, OptionMap undertowOptions) { +- this(bufferPool, undertowOptions, null, null); +- } +- +- public AlpnOpenListener(ByteBufferPool bufferPool, OptionMap undertowOptions, String fallbackProtocol, DelegateOpenListener fallbackListener) { +- this.bufferPool = bufferPool; +- this.fallbackProtocol = fallbackProtocol; +- if(fallbackProtocol != null && fallbackListener != null) { +- addProtocol(fallbackProtocol, fallbackListener, 0); +- } +- statisticsEnabled = undertowOptions.get(UndertowOptions.ENABLE_CONNECTOR_STATISTICS, false); +- this.undertowOptions = undertowOptions; +- } +- +- +- @Override +- public HttpHandler getRootHandler() { +- return rootHandler; +- } +- +- @Override +- public void setRootHandler(HttpHandler rootHandler) { +- this.rootHandler = rootHandler; +- for(Map.Entry<String, ListenerEntry> delegate : listeners.entrySet()) { +- delegate.getValue().listener.setRootHandler(rootHandler); +- } +- } +- +- @Override +- public OptionMap getUndertowOptions() { +- return undertowOptions; +- } +- +- @Override +- public void setUndertowOptions(OptionMap undertowOptions) { +- if (undertowOptions == null) { +- throw UndertowMessages.MESSAGES.argumentCannotBeNull("undertowOptions"); +- } +- this.undertowOptions = undertowOptions; +- for(Map.Entry<String, ListenerEntry> delegate : listeners.entrySet()) { +- delegate.getValue().listener.setRootHandler(rootHandler); +- } +- statisticsEnabled = undertowOptions.get(UndertowOptions.ENABLE_CONNECTOR_STATISTICS, false); +- } +- +- @Override +- public ByteBufferPool getBufferPool() { +- return bufferPool; +- } +- +- @Override +- public ConnectorStatistics getConnectorStatistics() { +- if(statisticsEnabled) { +- List<ConnectorStatistics> stats = new ArrayList<>(); +- for(Map.Entry<String, ListenerEntry> l : listeners.entrySet()) { +- ConnectorStatistics c = l.getValue().listener.getConnectorStatistics(); +- if(c != null) { +- stats.add(c); +- } +- } +- return new AggregateConnectorStatistics(stats.toArray(new ConnectorStatistics[stats.size()])); +- } +- return null; +- } +- +- private static class ListenerEntry { +- DelegateOpenListener listener; +- int weight; +- +- public ListenerEntry(DelegateOpenListener listener, int weight) { +- this.listener = listener; +- this.weight = weight; +- } +- } +- +- public AlpnOpenListener addProtocol(String name, DelegateOpenListener listener, int weight) { +- listeners.put(name, new ListenerEntry(listener, weight)); +- return this; +- } +- +- public void handleEvent(final StreamConnection channel) { +- if (UndertowLogger.REQUEST_LOGGER.isTraceEnabled()) { +- UndertowLogger.REQUEST_LOGGER.tracef("Opened connection with %s", channel.getPeerAddress()); +- } +- final AlpnConnectionListener potentialConnection = new AlpnConnectionListener(channel); +- channel.getSourceChannel().setReadListener(potentialConnection); +- final SSLEngine sslEngine = UndertowXnioSsl.getSslEngine((SslConnection) channel); +- ALPN.put(sslEngine, new ALPN.ServerProvider() { +- @Override +- public void unsupported() { +- final String existing = (String) sslEngine.getHandshakeSession().getValue(PROTOCOL_KEY); +- if (existing == null || !listeners.containsKey(existing)) { +- if(fallbackProtocol == null) { +- UndertowLogger.REQUEST_IO_LOGGER.noALPNFallback(channel.getPeerAddress()); +- IoUtils.safeClose(channel); +- } +- potentialConnection.selected = fallbackProtocol; +- } else { +- potentialConnection.selected = existing; +- } +- } +- +- @Override +- public String select(List<String> strings) { +- +- ALPN.remove(sslEngine); +- +- String match = null; +- int lastWeight = -1; +- for (String s : strings) { +- ListenerEntry listener = listeners.get(s); +- if (listener != null && listener.weight > lastWeight) { +- match = s; +- lastWeight = listener.weight; +- } +- } +- +- if (match != null) { +- sslEngine.getHandshakeSession().putValue(PROTOCOL_KEY, match); +- return potentialConnection.selected = match; +- } +- +- if(fallbackProtocol == null) { +- UndertowLogger.REQUEST_IO_LOGGER.noALPNFallback(channel.getPeerAddress()); +- IoUtils.safeClose(channel); +- return null; +- } +- sslEngine.getHandshakeSession().putValue(PROTOCOL_KEY, fallbackProtocol); +- potentialConnection.selected = fallbackProtocol; +- return fallbackProtocol; +- } +- }); +- potentialConnection.handleEvent(channel.getSourceChannel()); +- +- } +- +- private class AlpnConnectionListener implements ChannelListener<StreamSourceChannel> { +- private String selected; +- private final StreamConnection channel; +- +- private AlpnConnectionListener(StreamConnection channel) { +- this.channel = channel; +- } +- +- @Override +- public void handleEvent(StreamSourceChannel source) { +- PooledByteBuffer buffer = bufferPool.allocate(); +- boolean free = true; +- try { +- while (true) { +- int res = channel.getSourceChannel().read(buffer.getBuffer()); +- if (res == -1) { +- IoUtils.safeClose(channel); +- return; +- } +- buffer.getBuffer().flip(); +- if(selected != null) { +- DelegateOpenListener listener = listeners.get(selected).listener; +- source.getReadSetter().set(null); +- listener.handleEvent(channel, buffer); +- free = false; +- return; +- } else if(res > 0) { +- if(fallbackProtocol == null) { +- UndertowLogger.REQUEST_IO_LOGGER.noALPNFallback(channel.getPeerAddress()); +- IoUtils.safeClose(channel); +- return; +- } +- DelegateOpenListener listener = listeners.get(fallbackProtocol).listener; +- source.getReadSetter().set(null); +- listener.handleEvent(channel, buffer); +- free = false; +- return; +- } else if (res == 0) { +- channel.getSourceChannel().resumeReads(); +- return; +- } +- } +- +- } catch (IOException e) { +- UndertowLogger.REQUEST_IO_LOGGER.ioException(e); +- IoUtils.safeClose(channel); +- } finally { +- if (free) { +- buffer.close(); +- } +- } +- } +- } +- +-} diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..b8238fe --- /dev/null +++ b/debian/patches/series @@ -0,0 +1 @@ +alpn-not-supported.patch -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/undertow.git _______________________________________________ pkg-java-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-java-commits

