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