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.servlet;
20  
21  import java.net.HttpCookie;
22  import java.net.InetSocketAddress;
23  import java.net.URISyntaxException;
24  import java.security.Principal;
25  import java.security.cert.X509Certificate;
26  import java.util.ArrayList;
27  import java.util.Arrays;
28  import java.util.Collections;
29  import java.util.Enumeration;
30  import java.util.HashMap;
31  import java.util.List;
32  import java.util.Locale;
33  import java.util.Map;
34  
35  import javax.servlet.http.Cookie;
36  import javax.servlet.http.HttpServletRequest;
37  import javax.servlet.http.HttpSession;
38  
39  import org.eclipse.jetty.websocket.api.UpgradeRequest;
40  import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
41  import org.eclipse.jetty.websocket.api.util.WSURI;
42  
43  /**
44   * Servlet specific {@link UpgradeRequest} implementation.
45   */
46  public class ServletUpgradeRequest extends UpgradeRequest
47  {
48      private final UpgradeHttpServletRequest request;
49  
50      public ServletUpgradeRequest(HttpServletRequest httpRequest) throws URISyntaxException
51      {
52          super(WSURI.toWebsocket(httpRequest.getRequestURL(), httpRequest.getQueryString()));
53          this.request = new UpgradeHttpServletRequest(httpRequest);
54  
55          // Parse protocols.
56          Enumeration<String> requestProtocols = request.getHeaders("Sec-WebSocket-Protocol");
57          if (requestProtocols != null)
58          {
59              List<String> protocols = new ArrayList<>(2);
60              while (requestProtocols.hasMoreElements())
61              {
62                  String candidate = requestProtocols.nextElement();
63                  Collections.addAll(protocols, parseProtocols(candidate));
64              }
65              setSubProtocols(protocols);
66          }
67  
68          // Parse extensions.
69          Enumeration<String> e = request.getHeaders("Sec-WebSocket-Extensions");
70          setExtensions(ExtensionConfig.parseEnum(e));
71  
72          // Copy cookies.
73          Cookie[] requestCookies = request.getCookies();
74          if (requestCookies != null)
75          {
76              List<HttpCookie> cookies = new ArrayList<>();
77              for (Cookie requestCookie : requestCookies)
78              {
79                  HttpCookie cookie = new HttpCookie(requestCookie.getName(), requestCookie.getValue());
80                  // No point handling domain/path/expires/secure/httponly on client request cookies
81                  cookies.add(cookie);
82              }
83              setCookies(cookies);
84          }
85  
86          setHeaders(request.getHeaders());
87  
88          // Copy parameters.
89          Map<String, String[]> requestParams = request.getParameterMap();
90          if (requestParams != null)
91          {
92              Map<String, List<String>> params = new HashMap<>(requestParams.size());
93              for (Map.Entry<String, String[]> entry : requestParams.entrySet())
94                  params.put(entry.getKey(), Arrays.asList(entry.getValue()));
95              setParameterMap(params);
96          }
97  
98          setSession(request.getSession(false));
99  
100         setHttpVersion(request.getProtocol());
101         setMethod(request.getMethod());
102     }
103 
104     public X509Certificate[] getCertificates()
105     {
106         return (X509Certificate[])request.getAttribute("javax.servlet.request.X509Certificate");
107     }
108 
109     /**
110      * Return the underlying HttpServletRequest that existed at Upgrade time.
111      * <p>
112      * Note: many features of the HttpServletRequest are invalid when upgraded,
113      * especially ones that deal with body content, streams, readers, and responses.
114      *
115      * @return a limited version of the underlying HttpServletRequest
116      */
117     public HttpServletRequest getHttpServletRequest()
118     {
119         return request;
120     }
121 
122     /**
123      * Equivalent to {@link HttpServletRequest#getLocalAddr()}
124      *
125      * @return the local address
126      */
127     public String getLocalAddress()
128     {
129         return request.getLocalAddr();
130     }
131 
132     /**
133      * Equivalent to {@link HttpServletRequest#getLocalName()}
134      *
135      * @return the local host name
136      */
137     public String getLocalHostName()
138     {
139         return request.getLocalName();
140     }
141 
142     /**
143      * Equivalent to {@link HttpServletRequest#getLocalPort()}
144      *
145      * @return the local port
146      */
147     public int getLocalPort()
148     {
149         return request.getLocalPort();
150     }
151 
152     /**
153      * Return a {@link InetSocketAddress} for the local socket.
154      * <p>
155      * Warning: this can cause a DNS lookup
156      *
157      * @return the local socket address
158      */
159     public InetSocketAddress getLocalSocketAddress()
160     {
161         return new InetSocketAddress(getLocalAddress(), getLocalPort());
162     }
163 
164     /**
165      * Equivalent to {@link HttpServletRequest#getLocale()}
166      *
167      * @return the preferred <code>Locale</code> for the client
168      */
169     public Locale getLocale()
170     {
171         return request.getLocale();
172     }
173 
174     /**
175      * Equivalent to {@link HttpServletRequest#getLocales()}
176      *
177      * @return an Enumeration of preferred Locale objects
178      */
179     public Enumeration<Locale> getLocales()
180     {
181         return request.getLocales();
182     }
183 
184     /**
185      * @return the principal
186      * @deprecated use {@link #getUserPrincipal()} instead
187      */
188     @Deprecated
189     public Principal getPrincipal()
190     {
191         return getUserPrincipal();
192     }
193 
194     /**
195      * Equivalent to {@link HttpServletRequest#getUserPrincipal()}
196      */
197     public Principal getUserPrincipal()
198     {
199         return request.getUserPrincipal();
200     }
201 
202     /**
203      * Equivalent to {@link HttpServletRequest#getRemoteAddr()}
204      *
205      * @return the remote address
206      */
207     public String getRemoteAddress()
208     {
209         return request.getRemoteAddr();
210     }
211 
212     /**
213      * Equivalent to {@link HttpServletRequest#getRemoteHost()}
214      *
215      * @return the remote host name
216      */
217     public String getRemoteHostName()
218     {
219         return request.getRemoteHost();
220     }
221 
222     /**
223      * Equivalent to {@link HttpServletRequest#getRemotePort()}
224      *
225      * @return the remote port
226      */
227     public int getRemotePort()
228     {
229         return request.getRemotePort();
230     }
231 
232     /**
233      * Return a {@link InetSocketAddress} for the remote socket.
234      * <p>
235      * Warning: this can cause a DNS lookup
236      *
237      * @return the remote socket address
238      */
239     public InetSocketAddress getRemoteSocketAddress()
240     {
241         return new InetSocketAddress(getRemoteAddress(), getRemotePort());
242     }
243 
244     public Map<String, Object> getServletAttributes()
245     {
246         return request.getAttributes();
247     }
248 
249     public Map<String, List<String>> getServletParameters()
250     {
251         return getParameterMap();
252     }
253 
254     /**
255      * Return the HttpSession if it exists.
256      * <p>
257      * Note: this is equivalent to {@link HttpServletRequest#getSession(boolean)}
258      * and will not create a new HttpSession.
259      */
260     @Override
261     public HttpSession getSession()
262     {
263         return request.getSession(false);
264     }
265 
266     public void setServletAttribute(String name, Object value)
267     {
268         request.setAttribute(name, value);
269     }
270 
271     public Object getServletAttribute(String name)
272     {
273         return request.getAttribute(name);
274     }
275 
276     public boolean isUserInRole(String role)
277     {
278         return request.isUserInRole(role);
279     }
280 
281     public String getRequestPath()
282     {
283         // Since this can be called from a filter, we need to be smart about determining the target request path.
284         String contextPath = request.getContextPath();
285         String requestPath = request.getRequestURI();
286         if (requestPath.startsWith(contextPath))
287             requestPath = requestPath.substring(contextPath.length());
288         return requestPath;
289     }
290 
291     private String[] parseProtocols(String protocol)
292     {
293         if (protocol == null)
294             return new String[0];
295         protocol = protocol.trim();
296         if (protocol.length() == 0)
297             return new String[0];
298         return protocol.split("\\s*,\\s*");
299     }
300 
301     public void complete()
302     {
303         request.complete();
304     }
305 }