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