[undertow] 03/05: Add alpn-not-supported.patch
Markus Koschany
apo-guest at moszumanska.debian.org
Sat Oct 31 16:27:13 UTC 2015
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 <apo at debian.org>
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 <apo at debian.org>
+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
More information about the pkg-java-commits
mailing list