View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 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.websocket.jsr356.server;
20  
21  import java.util.List;
22  import java.util.ServiceLoader;
23  
24  import javax.websocket.Extension;
25  import javax.websocket.HandshakeResponse;
26  import javax.websocket.server.HandshakeRequest;
27  import javax.websocket.server.ServerEndpointConfig;
28  import javax.websocket.server.ServerEndpointConfig.Configurator;
29  
30  import org.eclipse.jetty.util.log.Log;
31  import org.eclipse.jetty.util.log.Logger;
32  import org.eclipse.jetty.websocket.api.util.QuoteUtil;
33  
34  /**
35   * The "Container Default Configurator" per the JSR-356 spec.
36   * 
37   * @see ServiceLoader behavior of {@link javax.websocket.server.ServerEndpointConfig.Configurator}
38   */
39  public final class ContainerDefaultConfigurator extends Configurator
40  {
41      private static final Logger LOG = Log.getLogger(ContainerDefaultConfigurator.class);
42      private static final String NO_SUBPROTOCOL = "";
43      
44      /**
45       * Default Constructor required, as
46       * javax.websocket.server.ServerEndpointConfig$Configurator.fetchContainerDefaultConfigurator()
47       * will be the one that instantiates this class in most cases.
48       */
49      public ContainerDefaultConfigurator()
50      {
51          super();
52      }
53  
54      @Override
55      public boolean checkOrigin(String originHeaderValue)
56      {
57          return true;
58      }
59  
60      @Override
61      public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException
62      {
63          if (LOG.isDebugEnabled())
64          {
65              LOG.debug(".getEndpointInstance({})",endpointClass);
66          }
67          
68          try
69          {
70              // Since this is started via a ServiceLoader, this class has no Scope or context
71              // that can be used to obtain a ObjectFactory from.
72              return endpointClass.newInstance();
73          }
74          catch (IllegalAccessException e)
75          {
76              throw new InstantiationException(String.format("%s: %s",e.getClass().getName(),e.getMessage()));
77          }
78      }
79  
80      @Override
81      public List<Extension> getNegotiatedExtensions(List<Extension> installed, List<Extension> requested)
82      {
83          return requested;
84      }
85  
86      @Override
87      public String getNegotiatedSubprotocol(List<String> supported, List<String> requested)
88      {
89          if ((requested == null) || (requested.size() == 0))
90          {
91              // nothing requested, don't return anything
92              return NO_SUBPROTOCOL;
93          }
94  
95          // Nothing specifically called out as being supported by the endpoint
96          if ((supported == null) || (supported.isEmpty()))
97          {
98              // Just return the first hit in this case
99              LOG.warn("Client requested Subprotocols on endpoint with none supported: {}",QuoteUtil.join(requested,","));
100             return NO_SUBPROTOCOL;
101         }
102 
103         // Return the first matching hit from the list of supported protocols.
104         for (String possible : requested)
105         {
106             if (possible == null)
107             {
108                 // skip null
109                 continue;
110             }
111 
112             if (supported.contains(possible))
113             {
114                 return possible;
115             }
116         }
117 
118         LOG.warn("Client requested subprotocols {} do not match any endpoint supported subprotocols {}",QuoteUtil.join(requested,","),
119                 QuoteUtil.join(supported,","));
120         return NO_SUBPROTOCOL;
121     }
122 
123     @Override
124     public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response)
125     {
126         /* do nothing */
127     }
128 }