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.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
140      * access.
141      * <p>
142      * Use this when the origin or authentication is invalid.
143      * 
144      * @param message
145      *            the short 1 line detail message about the forbidden response
146      * @throws IOException
147      *             if unable to send the forbidden
148      */
149     public void sendForbidden(String message) throws IOException
150     {
151         throw new UnsupportedOperationException("Not supported");
152     }
153 
154     /**
155      * Set the accepted WebSocket Protocol.
156      * 
157      * @param protocol
158      *            the protocol to list as accepted
159      */
160     public void setAcceptedSubProtocol(String protocol)
161     {
162         setHeader(SEC_WEBSOCKET_PROTOCOL,protocol);
163     }
164 
165     /**
166      * Set the list of extensions that are approved for use with this websocket.
167      * <p>
168      * Notes:
169      * <ul>
170      * <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>
171      * <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
172      * available in this WebSocket server implementation.</li>
173      * </ul>
174      * 
175      * @param extensions
176      *            the list of extensions to use.
177      */
178     public void setExtensions(List<ExtensionConfig> extensions)
179     {
180         this.extensions.clear();
181         if (extensions != null)
182         {
183             this.extensions.addAll(extensions);
184         }
185     }
186 
187     public void setHeader(String name, String value)
188     {
189         List<String> values = new ArrayList<>();
190         values.add(value);
191         headers.put(name,values);
192     }
193 
194     public void setStatusCode(int statusCode)
195     {
196         this.statusCode = statusCode;
197     }
198 
199     public void setStatusReason(String statusReason)
200     {
201         this.statusReason = statusReason;
202     }
203 
204     public void setSuccess(boolean success)
205     {
206         this.success = success;
207     }
208 }