View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.server;
20  
21  import java.util.Arrays;
22  import java.util.Iterator;
23  import java.util.List;
24  import javax.net.ssl.SSLEngine;
25  
26  import org.eclipse.jetty.io.AbstractConnection;
27  import org.eclipse.jetty.io.Connection;
28  import org.eclipse.jetty.io.EndPoint;
29  import org.eclipse.jetty.io.ssl.SslConnection;
30  import org.eclipse.jetty.server.AbstractConnectionFactory;
31  import org.eclipse.jetty.server.Connector;
32  
33  public abstract class NegotiatingServerConnectionFactory extends AbstractConnectionFactory
34  {
35      private final List<String> protocols;
36      private String defaultProtocol;
37  
38      public NegotiatingServerConnectionFactory(String protocol, String... protocols)
39      {
40          super(protocol);
41          this.protocols = Arrays.asList(protocols);
42      }
43  
44      public String getDefaultProtocol()
45      {
46          return defaultProtocol;
47      }
48  
49      public void setDefaultProtocol(String defaultProtocol)
50      {
51          this.defaultProtocol = defaultProtocol;
52      }
53  
54      public List<String> getProtocols()
55      {
56          return protocols;
57      }
58  
59      @Override
60      public Connection newConnection(Connector connector, EndPoint endPoint)
61      {
62          List<String> protocols = this.protocols;
63          if (protocols.isEmpty())
64          {
65              protocols = connector.getProtocols();
66              Iterator<String> i = protocols.iterator();
67              while (i.hasNext())
68              {
69                  String protocol = i.next();
70                  String prefix = "ssl-";
71                  if (protocol.regionMatches(true, 0, prefix, 0, prefix.length()) || protocol.equalsIgnoreCase("alpn"))
72                  {
73                      i.remove();
74                  }
75              }
76          }
77  
78          String dft = defaultProtocol;
79          if (dft == null && !protocols.isEmpty())
80              dft = protocols.get(0);
81  
82          SSLEngine engine = null;
83          EndPoint ep = endPoint;
84          while (engine == null && ep != null)
85          {
86              // TODO make more generic
87              if (ep instanceof SslConnection.DecryptedEndPoint)
88                  engine = ((SslConnection.DecryptedEndPoint)ep).getSslConnection().getSSLEngine();
89              else
90                  ep = null;
91          }
92  
93          return configure(newServerConnection(connector, endPoint, engine, protocols, dft), connector, endPoint);
94      }
95  
96      protected abstract AbstractConnection newServerConnection(Connector connector, EndPoint endPoint, SSLEngine engine, List<String> protocols, String defaultProtocol);
97  
98      @Override
99      public String toString()
100     {
101         return String.format("%s@%x{%s,%s,%s}", getClass().getSimpleName(), hashCode(), getProtocol(), getDefaultProtocol(), getProtocols());
102     }
103 }