You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2015/04/08 22:57:56 UTC
svn commit: r1672177 - in /tomcat/trunk/java/org/apache: coyote/ coyote/ajp/
coyote/http11/ coyote/http2/ coyote/spdy/ tomcat/util/net/
Author: markt
Date: Wed Apr 8 20:57:56 2015
New Revision: 1672177
URL: http://svn.apache.org/r1672177
Log:
First pass at the plumbing to link from ALPN to creating a protocol specific processor to handle the connection. Some, but not all, of the plumbing that will be required for HTTP upgrade is also provided.
Added:
tomcat/trunk/java/org/apache/coyote/UpgradeProtocol.java (with props)
tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java (with props)
tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java (with props)
Modified:
tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java
tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
tomcat/trunk/java/org/apache/coyote/spdy/SpdyProxyProtocol.java
tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties
tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java
Modified: tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java?rev=1672177&r1=1672176&r2=1672177&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java Wed Apr 8 20:57:56 2015
@@ -365,6 +365,15 @@ public abstract class AbstractProtocol<S
protected abstract String getProtocolName();
+ /**
+ * @param name The name of the requested negotiated protocol.
+ *
+ * @return The instance where {@link UpgradeProtocol#getAlpnName()} matches
+ * the requested protocol
+ */
+ protected abstract UpgradeProtocol getNegotiatedProtocol(String name);
+
+
// ----------------------------------------------------- JMX related methods
protected String domain;
@@ -634,6 +643,16 @@ public abstract class AbstractProtocol<S
try {
if (processor == null) {
+ String negotiatedProtocol = wrapper.getNegotiatedProtocol();
+ if (negotiatedProtocol != null) {
+ UpgradeProtocol upgradeProtocol =
+ getProtocol().getNegotiatedProtocol(negotiatedProtocol);
+ if (upgradeProtocol != null) {
+ processor = upgradeProtocol.getProcessor(wrapper);
+ }
+ }
+ }
+ if (processor == null) {
processor = recycledProcessors.pop();
}
if (processor == null) {
Added: tomcat/trunk/java/org/apache/coyote/UpgradeProtocol.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/UpgradeProtocol.java?rev=1672177&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/UpgradeProtocol.java (added)
+++ tomcat/trunk/java/org/apache/coyote/UpgradeProtocol.java Wed Apr 8 20:57:56 2015
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.coyote;
+
+import org.apache.tomcat.util.net.SocketWrapperBase;
+
+public interface UpgradeProtocol {
+
+ /**
+ * @return The name that clients will use to request an upgrade to this
+ * protocol via an HTTP/1.1 upgrade request or <code>null</code> if
+ * upgrade via an HTTP/1.1 upgrade request is not supported.
+ */
+ public String getHttpUpgradeName();
+
+ /**
+ * @return The byte sequence as listed in the IANA registry for this
+ * protocol or <code>null</code> if upgrade via ALPN is not
+ * supported.
+ */
+ public byte[] getAlpnIdentifier();
+
+ /**
+ * @return The name of the protocol as listed in the IANA registry if and
+ * only if {@link #getAlpnIdentifier()} returns the UTF-8 encoding
+ * of this name. If {@link #getAlpnIdentifier()} returns some other
+ * byte sequence, then this method returns the empty string. If
+ * upgrade via ALPN is not supported then <code>null</code> is
+ * returned.
+ */
+ /*
+ * Implementation note: If Tomcat ever supports ALPN for a protocol where
+ * the identifier is not the UTF-8 encoding of the name
+ * then some refactoring is going to be required.
+ *
+ * Implementation note: Tomcat assumes that the UTF-8 encoding of this name
+ * will not exceed 255 bytes. Tomcat's behaviour if
+ * longer names are used is undefined.
+ */
+ public String getAlpnName();
+
+ /**
+ *
+ * @return A processor instance for processing a connection using this
+ * protocol.
+ */
+ public Processor getProcessor(SocketWrapperBase<?> socketWrapper);
+}
Propchange: tomcat/trunk/java/org/apache/coyote/UpgradeProtocol.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tomcat/trunk/java/org/apache/coyote/UpgradeProtocol.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java?rev=1672177&r1=1672176&r2=1672177&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java Wed Apr 8 20:57:56 2015
@@ -22,6 +22,7 @@ import javax.servlet.http.HttpUpgradeHan
import org.apache.coyote.AbstractProtocol;
import org.apache.coyote.Processor;
+import org.apache.coyote.UpgradeProtocol;
import org.apache.tomcat.util.net.AbstractEndpoint;
import org.apache.tomcat.util.net.SocketWrapperBase;
import org.apache.tomcat.util.res.StringManager;
@@ -67,6 +68,17 @@ public abstract class AbstractAjpProtoco
}
+ /**
+ * {@inheritDoc}
+ *
+ * AJP does not support protocol negotiation so this always returns null.
+ */
+ @Override
+ protected UpgradeProtocol getNegotiatedProtocol(String name) {
+ return null;
+ }
+
+
// ------------------------------------------------- AJP specific properties
// ------------------------------------------ managed in the ProtocolHandler
Modified: tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java?rev=1672177&r1=1672176&r2=1672177&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java Wed Apr 8 20:57:56 2015
@@ -20,9 +20,11 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -30,6 +32,7 @@ import javax.servlet.http.HttpUpgradeHan
import org.apache.coyote.AbstractProtocol;
import org.apache.coyote.Processor;
+import org.apache.coyote.UpgradeProtocol;
import org.apache.coyote.http11.upgrade.InternalHttpUpgradeHandler;
import org.apache.coyote.http11.upgrade.UpgradeProcessorExternal;
import org.apache.coyote.http11.upgrade.UpgradeProcessorInternal;
@@ -41,6 +44,13 @@ public abstract class AbstractHttp11Prot
public AbstractHttp11Protocol(AbstractEndpoint<S> endpoint) {
super(endpoint);
setSoTimeout(Constants.DEFAULT_CONNECTION_TIMEOUT);
+
+ // TODO: Make this configurable via nested UpgradeProtocol elements in
+ // the Connector.
+ // This is disabled by default otherwise it will break the
+ // APR/native connector with clients that support h2 with ALPN
+ // (because the Http2Protocol is only stubbed out)
+ //addUpgradeProtocol(new Http2Protocol());
}
@@ -256,6 +266,27 @@ public abstract class AbstractHttp11Prot
}
+ /**
+ * The protocols that are available via internal Tomcat support for access
+ * via HTTP upgrade.
+ */
+ private final Map<String,UpgradeProtocol> httpUpgradeProtocols = new HashMap<>();
+ /**
+ * The protocols that are available via internal Tomcat support for access
+ * via ALPN negotiation.
+ */
+ private final Map<String,UpgradeProtocol> negotiatedProtocols = new HashMap<>();
+ public void addUpgradeProtocol(UpgradeProtocol upgradeProtocol) {
+ httpUpgradeProtocols.put(upgradeProtocol.getHttpUpgradeName(), upgradeProtocol);
+ negotiatedProtocols.put(upgradeProtocol.getAlpnName(), upgradeProtocol);
+ getEndpoint().addNegotiatedProtocol(upgradeProtocol.getAlpnName());
+ }
+ @Override
+ public UpgradeProtocol getNegotiatedProtocol(String negotiatedName) {
+ return negotiatedProtocols.get(negotiatedName);
+ }
+
+
// ------------------------------------------------ HTTP specific properties
// ------------------------------------------ passed through to the EndPoint
Added: tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java?rev=1672177&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java (added)
+++ tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java Wed Apr 8 20:57:56 2015
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.coyote.http2;
+
+import java.nio.charset.StandardCharsets;
+
+import org.apache.coyote.Processor;
+import org.apache.coyote.UpgradeProtocol;
+import org.apache.coyote.http11.upgrade.UpgradeProcessorInternal;
+import org.apache.tomcat.util.net.SocketWrapperBase;
+
+public class Http2Protocol implements UpgradeProtocol {
+
+ private static final String HTTP_UPGRADE_NAME = "h2c";
+ private static final String ALPN_NAME = "h2";
+ private static final byte[] ALPN_IDENTIFIER = ALPN_NAME.getBytes(StandardCharsets.UTF_8);
+
+ @Override
+ public String getHttpUpgradeName() {
+ return HTTP_UPGRADE_NAME;
+ }
+
+ @Override
+ public byte[] getAlpnIdentifier() {
+ return ALPN_IDENTIFIER;
+ }
+
+ @Override
+ public String getAlpnName() {
+ return ALPN_NAME;
+ }
+
+ @Override
+ public Processor getProcessor(SocketWrapperBase<?> socketWrapper) {
+ UpgradeProcessorInternal processor =
+ new UpgradeProcessorInternal(socketWrapper, null, new Http2UpgradeHandler());
+ return processor;
+ }
+}
Propchange: tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java?rev=1672177&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java (added)
+++ tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java Wed Apr 8 20:57:56 2015
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.coyote.http2;
+
+import javax.servlet.http.WebConnection;
+
+import org.apache.coyote.http11.upgrade.InternalHttpUpgradeHandler;
+import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
+import org.apache.tomcat.util.net.SocketStatus;
+import org.apache.tomcat.util.net.SocketWrapperBase;
+
+public class Http2UpgradeHandler implements InternalHttpUpgradeHandler {
+
+ @Override
+ public void init(WebConnection connection) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void setSocketWrapper(SocketWrapperBase<?> wrapper) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public SocketState upgradeDispatch(SocketStatus status) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void destroy() {
+ // TODO Auto-generated method stub
+ }
+}
Propchange: tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: tomcat/trunk/java/org/apache/coyote/spdy/SpdyProxyProtocol.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/spdy/SpdyProxyProtocol.java?rev=1672177&r1=1672176&r2=1672177&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/spdy/SpdyProxyProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/spdy/SpdyProxyProtocol.java Wed Apr 8 20:57:56 2015
@@ -20,6 +20,7 @@ import java.io.IOException;
import java.nio.channels.SocketChannel;
import org.apache.coyote.AbstractProtocol;
+import org.apache.coyote.UpgradeProtocol;
import org.apache.coyote.ajp.Constants;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
@@ -136,4 +137,10 @@ public class SpdyProxyProtocol extends A
// TODO Auto-generated method stub
}
}
+
+ @Override
+ protected UpgradeProtocol getNegotiatedProtocol(String name) {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java?rev=1672177&r1=1672176&r2=1672177&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java Wed Apr 8 20:57:56 2015
@@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;
@@ -496,6 +497,11 @@ public abstract class AbstractEndpoint<S
protected abstract boolean getDeferAccept();
+ protected final List<String> negotiableProtocols = new ArrayList<>();
+ public void addNegotiatedProtocol(String negotiableProtocol) {
+ negotiableProtocols.add(negotiableProtocol);
+ }
+
/**
* Attributes provide a way for configuration to be passed to sub-components
* without the {@link org.apache.coyote.ProtocolHandler} being aware of the
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=1672177&r1=1672176&r2=1672177&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Wed Apr 8 20:57:56 2015
@@ -20,8 +20,10 @@ import java.io.EOFException;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
@@ -67,13 +69,17 @@ import org.apache.tomcat.util.net.Abstra
*/
public class AprEndpoint extends AbstractEndpoint<Long> {
-
// -------------------------------------------------------------- Constants
-
private static final Log log = LogFactory.getLog(AprEndpoint.class);
+ // http/1.1 with preceding length
+ private static final byte[] ALPN_DEFAULT =
+ new byte[] { 0x08, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 };
+
+
// ----------------------------------------------------------------- Fields
+
/**
* Root APR memory pool.
*/
@@ -628,9 +634,52 @@ public class AprEndpoint extends Abstrac
log.warn(sm.getString("endpoint.apr.noSendfileWithSSL"));
}
}
+
+ if (negotiableProtocols.size() > 0) {
+ byte[] protocols = buildAlpnConfig(negotiableProtocols);
+ if (SSLContext.setALPN(sslContext, protocols, protocols.length) != 0) {
+ log.warn(sm.getString("endpoint.alpn.fail", negotiableProtocols));
+ }
+ }
+ } else if (negotiableProtocols.size() > 0) {
+ log.info(sm.getString("endpoint.noNegotiation", getName(), negotiableProtocols.toString()));
+ }
+ }
+
+
+ private byte[] buildAlpnConfig(List<String> protocols) {
+ /*
+ * The expected format is zero or more of the following:
+ * - Single byte for size
+ * - Sequence of size bytes for the identifier
+ */
+ byte[][] protocolsBytes = new byte[protocols.size()][];
+ int i = 0;
+ int size = 0;
+ for (String protocol : protocols) {
+ protocolsBytes[i] = protocol.getBytes(StandardCharsets.UTF_8);
+ size += protocolsBytes[i].length;
+ // And one byte to store the size
+ size++;
+ i++;
+ }
+
+ size += ALPN_DEFAULT.length;
+
+ byte[] result = new byte[size];
+ int pos = 0;
+ for (byte[] protocolBytes : protocolsBytes) {
+ result[pos++] = (byte) (0xff & protocolBytes.length);
+ System.arraycopy(protocolBytes, 0, result, pos, protocolBytes.length);
+ pos += protocolBytes.length;
}
+
+ System.arraycopy(ALPN_DEFAULT, 0, result, pos, ALPN_DEFAULT.length);
+
+ return result;
}
+
public long getJniSslContext() {
return sslContext;
}
@@ -857,6 +906,18 @@ public class AprEndpoint extends Abstrac
wrapper.setSecure(isSSLEnabled());
wrapper.setReadTimeout(getSoTimeout());
wrapper.setWriteTimeout(getSoTimeout());
+ if (isSSLEnabled() && negotiableProtocols.size() > 0) {
+ byte[] negotiated = new byte[256];
+ int len = SSLSocket.getALPN(socket, negotiated);
+ String negotiatedProtocol =
+ new String(negotiated, 0, len, StandardCharsets.UTF_8);
+ if (negotiatedProtocol.length() > 0) {
+ wrapper.setNegotiatedProtocol(negotiatedProtocol);
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("endpoint.alpn.negotiated", negotiatedProtocol));
+ }
+ }
+ }
connections.put(Long.valueOf(socket), wrapper);
getExecutor().execute(new SocketWithOptionsProcessor(wrapper));
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties?rev=1672177&r1=1672176&r2=1672177&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties Wed Apr 8 20:57:56 2015
@@ -41,12 +41,15 @@ endpoint.debug.socket=socket [{0}]
endpoint.debug.socketCloseFail=Failed to close socket
endpoint.debug.socketTimeout=Timing out [{0}]
endpoint.debug.unlock=Caught exception trying to unlock accept on port {0}
+endpoint.accept.fail=Socket accept failed
+endpoint.alpn.fail=Failed to configure endpoint for ALPN using {0}
+endpoint.alpn.negotiated=Negotiated [{0}] protocol using ALPN
endpoint.executor.fail=Executor rejected socket [{0}] for processing
+endpoint.getAttribute=[{0}] is [{1}]
endpoint.init.bind=Socket bind failed: [{0}] {1}
endpoint.init.listen=Socket listen failed: [{0}] {1}
endpoint.init.notavail=APR not available
-endpoint.accept.fail=Socket accept failed
-endpoint.getAttribute=[{0}] is [{1}]
+endpoint.noNegotiation=TLS was not configured for the [{0}] connector so negotiation via ALPN for {1} is not available
endpoint.poll.limitedpollsize=Failed to create poller with specified size of {0}
endpoint.poll.initfail=Poller creation failed
endpoint.poll.fail=Critical poller failure (restarting poller): [{0}] {1}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java?rev=1672177&r1=1672176&r2=1672177&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java Wed Apr 8 20:57:56 2015
@@ -52,6 +52,7 @@ public abstract class SocketWrapperBase<
private boolean keptAlive = false;
private volatile boolean upgraded = false;
private boolean secure = false;
+ private String negotiatedProtocol = null;
/*
* Following cached for speed / reduced GC
*/
@@ -154,6 +155,10 @@ public abstract class SocketWrapperBase<
public void setUpgraded(boolean upgraded) { this.upgraded = upgraded; }
public boolean isSecure() { return secure; }
public void setSecure(boolean secure) { this.secure = secure; }
+ public String getNegotiatedProtocol() { return negotiatedProtocol; }
+ public void setNegotiatedProtocol(String negotiatedProtocol) {
+ this.negotiatedProtocol = negotiatedProtocol;
+ }
/**
* Set the timeout for reading. Values of zero or less will be changed to]
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org