View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 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.Iterator;
32  import java.util.List;
33  import java.util.Map;
34  
35  import javax.servlet.http.Cookie;
36  import javax.servlet.http.HttpServletRequest;
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.QuoteUtil;
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 HttpServletRequest req;
49  
50      public ServletUpgradeRequest(HttpServletRequest request) throws URISyntaxException
51      {
52          super(WSURI.toWebsocket(request.getRequestURL(),request.getQueryString()));
53          this.req = request;
54  
55          // Copy Request Line Details
56          setMethod(request.getMethod());
57          setHttpVersion(request.getProtocol());
58  
59          // Copy parameters
60          super.setParameterMap(request.getParameterMap());
61  
62          // Copy Cookies
63          Cookie rcookies[] = request.getCookies();
64          if (rcookies != null)
65          {
66              List<HttpCookie> cookies = new ArrayList<>();
67              for (Cookie rcookie : rcookies)
68              {
69                  HttpCookie hcookie = new HttpCookie(rcookie.getName(),rcookie.getValue());
70                  // no point handling domain/path/expires/secure/httponly on client request cookies
71                  cookies.add(hcookie);
72              }
73              super.setCookies(cookies);
74          }
75  
76          // Copy Headers
77          Enumeration<String> headerNames = request.getHeaderNames();
78          while (headerNames.hasMoreElements())
79          {
80              String name = headerNames.nextElement();
81              Enumeration<String> valuesEnum = request.getHeaders(name);
82              List<String> values = new ArrayList<>();
83              while (valuesEnum.hasMoreElements())
84              {
85                  values.add(valuesEnum.nextElement());
86              }
87              setHeader(name,values);
88          }
89  
90          // Parse Sub Protocols
91          Enumeration<String> protocols = request.getHeaders("Sec-WebSocket-Protocol");
92          List<String> subProtocols = new ArrayList<>();
93          String protocol = null;
94          while ((protocol == null) && (protocols != null) && protocols.hasMoreElements())
95          {
96              String candidate = protocols.nextElement();
97              for (String p : parseProtocols(candidate))
98              {
99                  subProtocols.add(p);
100             }
101         }
102         setSubProtocols(subProtocols);
103 
104         // Parse Extension Configurations
105         Enumeration<String> e = request.getHeaders("Sec-WebSocket-Extensions");
106         while (e.hasMoreElements())
107         {
108             Iterator<String> extTokenIter = QuoteUtil.splitAt(e.nextElement(),",");
109             while (extTokenIter.hasNext())
110             {
111                 String extToken = extTokenIter.next();
112                 ExtensionConfig config = ExtensionConfig.parse(extToken);
113                 addExtensions(config);
114             }
115         }
116     }
117 
118     public X509Certificate[] getCertificates()
119     {
120         return (X509Certificate[])req.getAttribute("javax.servlet.request.X509Certificate");
121     }
122 
123     /**
124      * Equivalent to {@link HttpServletRequest#getLocalAddr()}
125      * 
126      * @return the local address
127      */
128     public String getLocalAddress()
129     {
130         return req.getLocalAddr();
131     }
132 
133     /**
134      * Equivalent to {@link HttpServletRequest#getLocalName()}
135      * 
136      * @return the local host name
137      */
138     public String getLocalHostName()
139     {
140         return req.getLocalName();
141     }
142 
143     /**
144      * Equivalent to {@link HttpServletRequest#getLocalPort()}
145      * 
146      * @return the local port
147      */
148     public int getLocalPort()
149     {
150         return req.getLocalPort();
151     }
152 
153     /**
154      * Return a {@link InetSocketAddress} for the local socket.
155      * <p>
156      * Warning: this can cause a DNS lookup
157      * 
158      * @return the local socket address
159      */
160     public InetSocketAddress getLocalSocketAddress()
161     {
162         return new InetSocketAddress(req.getLocalAddr(),req.getLocalPort());
163     }
164 
165     public Principal getPrincipal()
166     {
167         return req.getUserPrincipal();
168     }
169 
170     /**
171      * Equivalent to {@link HttpServletRequest#getRemoteAddr()}
172      * 
173      * @return the remote address
174      */
175     public String getRemoteAddress()
176     {
177         return req.getRemoteAddr();
178     }
179 
180     /**
181      * Equivalent to {@link HttpServletRequest#getRemoteHost()}
182      * 
183      * @return the remote host name
184      */
185     public String getRemoteHostName()
186     {
187         return req.getRemoteHost();
188     }
189 
190     /**
191      * Equivalent to {@link HttpServletRequest#getRemotePort()}
192      * 
193      * @return the remote port
194      */
195     public int getRemotePort()
196     {
197         return req.getRemotePort();
198     }
199 
200     /**
201      * Return a {@link InetSocketAddress} for the remote socket.
202      * <p>
203      * Warning: this can cause a DNS lookup
204      * 
205      * @return the remote socket address
206      */
207     public InetSocketAddress getRemoteSocketAddress()
208     {
209         return new InetSocketAddress(req.getRemoteAddr(),req.getRemotePort());
210     }
211 
212     public Map<String, Object> getServletAttributes()
213     {
214         Map<String, Object> attributes = new HashMap<String, Object>();
215 
216         for (String name : Collections.list(req.getAttributeNames()))
217         {
218             attributes.put(name,req.getAttribute(name));
219         }
220 
221         return attributes;
222     }
223 
224     public Map<String, List<String>> getServletParameters()
225     {
226         Map<String, List<String>> parameters = new HashMap<String, List<String>>();
227 
228         for (String name : Collections.list(req.getParameterNames()))
229         {
230             parameters.put(name,Collections.unmodifiableList(Arrays.asList(req.getParameterValues(name))));
231         }
232 
233         return parameters;
234     }
235 
236     /**
237      * Return the HttpSession if it exists.
238      * <p>
239      * Note: this is equivalent to {@link HttpServletRequest#getSession()} and will not create a new HttpSession.
240      */
241     @Override
242     public Object getSession()
243     {
244         return this.req.getSession(false);
245     }
246 
247     protected String[] parseProtocols(String protocol)
248     {
249         if (protocol == null)
250         {
251             return new String[] {};
252         }
253         protocol = protocol.trim();
254         if ((protocol == null) || (protocol.length() == 0))
255         {
256             return new String[] {};
257         }
258         String[] passed = protocol.split("\\s*,\\s*");
259         String[] protocols = new String[passed.length];
260         System.arraycopy(passed,0,protocols,0,passed.length);
261         return protocols;
262     }
263 
264     public void setServletAttribute(String name, Object o)
265     {
266         this.req.setAttribute(name,o);
267     }
268 
269 }