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.api;
20  
21  import java.io.IOException;
22  import java.util.ArrayList;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.Set;
26  import java.util.TreeMap;
27  
28  import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
29  import org.eclipse.jetty.websocket.api.util.QuoteUtil;
30  
31  public class UpgradeResponse
32  {
33      public static final String SEC_WEBSOCKET_PROTOCOL = "Sec-WebSocket-Protocol";
34      private int statusCode;
35      private String statusReason;
36      private Map<String, List<String>> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
37      private List<ExtensionConfig> extensions = new ArrayList<>();
38      private boolean success = false;
39  
40      public void addHeader(String name, String value)
41      {
42          String key = name;
43          List<String> values = headers.get(key);
44          if (values == null)
45          {
46              values = new ArrayList<>();
47          }
48          values.add(value);
49          headers.put(key,values);
50      }
51  
52      /**
53       * Get the accepted WebSocket protocol.
54       * 
55       * @return the accepted WebSocket protocol.
56       */
57      public String getAcceptedSubProtocol()
58      {
59          return getHeader(SEC_WEBSOCKET_PROTOCOL);
60      }
61  
62      /**
63       * Get the list of extensions that should be used for the websocket.
64       * 
65       * @return the list of negotiated extensions to use.
66       */
67      public List<ExtensionConfig> getExtensions()
68      {
69          return extensions;
70      }
71  
72      public String getHeader(String name)
73      {
74          List<String> values = getHeaders(name);
75          // no value list
76          if (values == null)
77          {
78              return null;
79          }
80          int size = values.size();
81          // empty value list
82          if (size <= 0)
83          {
84              return null;
85          }
86          // simple return
87          if (size == 1)
88          {
89              return values.get(0);
90          }
91          // join it with commas
92          boolean needsDelim = false;
93          StringBuilder ret = new StringBuilder();
94          for (String value : values)
95          {
96              if (needsDelim)
97              {
98                  ret.append(", ");
99              }
100             QuoteUtil.quoteIfNeeded(ret,value,QuoteUtil.ABNF_REQUIRED_QUOTING);
101             needsDelim = true;
102         }
103         return ret.toString();
104     }
105 
106     public Set<String> getHeaderNames()
107     {
108         return headers.keySet();
109     }
110 
111     public Map<String, List<String>> getHeaders()
112     {
113         return headers;
114     }
115 
116     public List<String> getHeaders(String name)
117     {
118         return headers.get(name);
119     }
120 
121     public int getStatusCode()
122     {
123         return statusCode;
124     }
125 
126     public String getStatusReason()
127     {
128         return statusReason;
129     }
130 
131     public boolean isSuccess()
132     {
133         return success;
134     }
135 
136     /**
137      * Issue a forbidden upgrade response.
138      * <p>
139      * This means that the websocket endpoint was valid, but the conditions to use a WebSocket resulted in a forbidden access.
140      * <p>
141      * Use this when the origin or authentication is invalid.
142      * 
143      * @param message
144      *            the short 1 line detail message about the forbidden response
145      * @throws IOException
146      */
147     public void sendForbidden(String message) throws IOException
148     {
149         throw new UnsupportedOperationException("Not supported");
150     }
151 
152     /**
153      * Set the accepted WebSocket Protocol.
154      * 
155      * @param protocol
156      *            the protocol to list as accepted
157      */
158     public void setAcceptedSubProtocol(String protocol)
159     {
160         setHeader(SEC_WEBSOCKET_PROTOCOL,protocol);
161     }
162 
163     /**
164      * Set the list of extensions that are approved for use with this websocket.
165      * <p>
166      * Notes:
167      * <ul>
168      * <li>Per the spec you cannot add extensions that have not been seen in the {@link UpgradeRequest}, just remove entries you don't want to use</li>
169      * <li>If this is unused, or a null is passed, then the list negotiation will follow default behavior and use the complete list of extensions that are
170      * available in this WebSocket server implementation.</li>
171      * </ul>
172      * 
173      * @param extensions
174      *            the list of extensions to use.
175      */
176     public void setExtensions(List<ExtensionConfig> extensions)
177     {
178         this.extensions.clear();
179         if (extensions != null)
180         {
181             this.extensions.addAll(extensions);
182         }
183     }
184 
185     public void setHeader(String name, String value)
186     {
187         List<String> values = new ArrayList<>();
188         values.add(value);
189         headers.put(name,values);
190     }
191 
192     public void setStatusCode(int statusCode)
193     {
194         this.statusCode = statusCode;
195     }
196 
197     public void setStatusReason(String statusReason)
198     {
199         this.statusReason = statusReason;
200     }
201 
202     public void setSuccess(boolean success)
203     {
204         this.success = success;
205     }
206 }