View Javadoc
1   /*
2    * Copyright 2013 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package org.jboss.netty.handler.codec.spdy;
17  
18  import org.jboss.netty.handler.codec.http.HttpMethod;
19  import org.jboss.netty.handler.codec.http.HttpResponseStatus;
20  import org.jboss.netty.handler.codec.http.HttpVersion;
21  
22  import java.util.Collections;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Set;
27  
28  /**
29   * Provides the constants for the standard SPDY HTTP header names and commonly
30   * used utility methods that access a {@link SpdyHeadersFrame}.
31   */
32  public abstract class SpdyHeaders implements Iterable<Map.Entry<String, String>> {
33  
34      public static final SpdyHeaders EMPTY_HEADERS = new SpdyHeaders() {
35  
36          @Override
37          public List<String> getAll(String name) {
38              return Collections.emptyList();
39          }
40  
41          @Override
42          public List<Map.Entry<String, String>> entries() {
43              return Collections.emptyList();
44          }
45  
46          @Override
47          public boolean contains(String name) {
48              return false;
49          }
50  
51          @Override
52          public boolean isEmpty() {
53              return true;
54          }
55  
56          @Override
57          public Set<String> names() {
58              return Collections.emptySet();
59          }
60  
61          @Override
62          public SpdyHeaders add(String name, Object value) {
63              throw new UnsupportedOperationException("read only");
64          }
65  
66          @Override
67          public SpdyHeaders add(String name, Iterable<?> values) {
68              throw new UnsupportedOperationException("read only");
69          }
70  
71          @Override
72          public SpdyHeaders set(String name, Object value) {
73              throw new UnsupportedOperationException("read only");
74          }
75  
76          @Override
77          public SpdyHeaders set(String name, Iterable<?> values) {
78              throw new UnsupportedOperationException("read only");
79          }
80  
81          @Override
82          public SpdyHeaders remove(String name) {
83              throw new UnsupportedOperationException("read only");
84          }
85  
86          @Override
87          public SpdyHeaders clear() {
88              throw new UnsupportedOperationException("read only");
89          }
90  
91          @Override
92          public Iterator<Map.Entry<String, String>> iterator() {
93              return entries().iterator();
94          }
95  
96          @Override
97          public String get(String name) {
98              return null;
99          }
100     };
101 
102     /**
103      * SPDY HTTP header names
104      */
105     public static final class HttpNames {
106         /**
107          * {@code ":host"}
108          */
109         public static final String HOST = ":host";
110         /**
111          * {@code ":method"}
112          */
113         public static final String METHOD = ":method";
114         /**
115          * {@code ":path"}
116          */
117         public static final String PATH = ":path";
118         /**
119          * {@code ":scheme"}
120          */
121         public static final String SCHEME = ":scheme";
122         /**
123          * {@code ":status"}
124          */
125         public static final String STATUS = ":status";
126         /**
127          * {@code ":version"}
128          */
129         public static final String VERSION = ":version";
130 
131         private HttpNames() { }
132     }
133 
134     /**
135      * Returns the header value with the specified header name.  If there are
136      * more than one header value for the specified header name, the first
137      * value is returned.
138      *
139      * @return the header value or {@code null} if there is no such header
140      */
141     public static String getHeader(SpdyHeadersFrame frame, String name) {
142         return frame.headers().get(name);
143     }
144 
145     /**
146      * Returns the header value with the specified header name.  If there are
147      * more than one header value for the specified header name, the first
148      * value is returned.
149      *
150      * @return the header value or the {@code defaultValue} if there is no such
151      *         header
152      */
153     public static String getHeader(SpdyHeadersFrame frame, String name, String defaultValue) {
154         String value = frame.headers().get(name);
155         if (value == null) {
156             return defaultValue;
157         }
158         return value;
159     }
160 
161     /**
162      * Sets a new header with the specified name and value.  If there is an
163      * existing header with the same name, the existing header is removed.
164      */
165     public static void setHeader(SpdyHeadersFrame frame, String name, Object value) {
166         frame.headers().set(name, value);
167     }
168 
169     /**
170      * Sets a new header with the specified name and values.  If there is an
171      * existing header with the same name, the existing header is removed.
172      */
173     public static void setHeader(SpdyHeadersFrame frame, String name, Iterable<?> values) {
174         frame.headers().set(name, values);
175     }
176 
177     /**
178      * Adds a new header with the specified name and value.
179      */
180     public static void addHeader(SpdyHeadersFrame frame, String name, Object value) {
181         frame.headers().add(name, value);
182     }
183 
184     /**
185      * Removes the SPDY host header.
186      */
187     public static void removeHost(SpdyHeadersFrame frame) {
188         frame.headers().remove(HttpNames.HOST);
189     }
190 
191     /**
192      * Returns the SPDY host header.
193      */
194     public static String getHost(SpdyHeadersFrame frame) {
195         return frame.headers().get(HttpNames.HOST);
196     }
197 
198     /**
199      * Set the SPDY host header.
200      */
201     public static void setHost(SpdyHeadersFrame frame, String host) {
202         frame.headers().set(HttpNames.HOST, host);
203     }
204 
205     /**
206      * Removes the HTTP method header.
207      */
208     public static void removeMethod(int spdyVersion, SpdyHeadersFrame frame) {
209         frame.headers().remove(HttpNames.METHOD);
210     }
211 
212     /**
213      * Returns the {@link HttpMethod} represented by the HTTP method header.
214      */
215     public static HttpMethod getMethod(int spdyVersion, SpdyHeadersFrame frame) {
216         try {
217             return HttpMethod.valueOf(frame.headers().get(HttpNames.METHOD));
218         } catch (Exception e) {
219             return null;
220         }
221     }
222 
223     /**
224      * Sets the HTTP method header.
225      */
226     public static void setMethod(int spdyVersion, SpdyHeadersFrame frame, HttpMethod method) {
227         frame.headers().set(HttpNames.METHOD, method.getName());
228     }
229 
230     /**
231      * Removes the URL scheme header.
232      */
233     public static void removeScheme(int spdyVersion, SpdyHeadersFrame frame) {
234         frame.headers().remove(HttpNames.SCHEME);
235     }
236 
237     /**
238      * Returns the value of the URL scheme header.
239      */
240     public static String getScheme(int spdyVersion, SpdyHeadersFrame frame) {
241         return frame.headers().get(HttpNames.SCHEME);
242     }
243 
244     /**
245      * Sets the URL scheme header.
246      */
247     public static void setScheme(int spdyVersion, SpdyHeadersFrame frame, String scheme) {
248         frame.headers().set(HttpNames.SCHEME, scheme);
249     }
250 
251     /**
252      * Removes the HTTP response status header.
253      */
254     public static void removeStatus(int spdyVersion, SpdyHeadersFrame frame) {
255         frame.headers().remove(HttpNames.STATUS);
256     }
257 
258     /**
259      * Returns the {@link HttpResponseStatus} represented by the HTTP response status header.
260      */
261     public static HttpResponseStatus getStatus(int spdyVersion, SpdyHeadersFrame frame) {
262         try {
263             String status = frame.headers().get(HttpNames.STATUS);
264             int space = status.indexOf(' ');
265             if (space == -1) {
266                 return HttpResponseStatus.valueOf(Integer.parseInt(status));
267             } else {
268                 int code = Integer.parseInt(status.substring(0, space));
269                 String reasonPhrase = status.substring(space + 1);
270                 HttpResponseStatus responseStatus = HttpResponseStatus.valueOf(code);
271                 if (responseStatus.getReasonPhrase().equals(reasonPhrase)) {
272                     return responseStatus;
273                 } else {
274                     return new HttpResponseStatus(code, reasonPhrase);
275                 }
276             }
277         } catch (Exception e) {
278             return null;
279         }
280     }
281 
282     /**
283      * Sets the HTTP response status header.
284      */
285     public static void setStatus(int spdyVersion, SpdyHeadersFrame frame, HttpResponseStatus status) {
286         frame.headers().set(HttpNames.STATUS, status.toString());
287     }
288 
289     /**
290      * Removes the URL path header.
291      */
292     public static void removeUrl(int spdyVersion, SpdyHeadersFrame frame) {
293         frame.headers().remove(HttpNames.PATH);
294     }
295 
296     /**
297      * Returns the value of the URL path header.
298      */
299     public static String getUrl(int spdyVersion, SpdyHeadersFrame frame) {
300         return frame.headers().get(HttpNames.PATH);
301     }
302 
303     /**
304      * Sets the URL path header.
305      */
306     public static void setUrl(int spdyVersion, SpdyHeadersFrame frame, String path) {
307         frame.headers().set(HttpNames.PATH, path);
308     }
309 
310     /**
311      * Removes the HTTP version header.
312      */
313     public static void removeVersion(int spdyVersion, SpdyHeadersFrame frame) {
314         frame.headers().remove(HttpNames.VERSION);
315     }
316 
317     /**
318      * Returns the {@link HttpVersion} represented by the HTTP version header.
319      */
320     public static HttpVersion getVersion(int spdyVersion, SpdyHeadersFrame frame) {
321         try {
322             return HttpVersion.valueOf(frame.headers().get(HttpNames.VERSION));
323         } catch (Exception e) {
324             return null;
325         }
326     }
327 
328     /**
329      * Sets the HTTP version header.
330      */
331     public static void setVersion(int spdyVersion, SpdyHeadersFrame frame, HttpVersion httpVersion) {
332         frame.headers().set(HttpNames.VERSION, httpVersion.getText());
333     }
334 
335     @Override
336     public Iterator<Map.Entry<String, String>> iterator() {
337         return entries().iterator();
338     }
339 
340     /**
341      * Returns the header value with the specified header name.  If there is
342      * more than one header value for the specified header name, the first
343      * value is returned.
344      *
345      * @return the header value or {@code null} if there is no such header
346      */
347     public abstract String get(String name);
348 
349     /**
350      * Returns the header values with the specified header name.
351      *
352      * @return the {@link List} of header values.  An empty list if there is no
353      *         such header.
354      */
355     public abstract List<String> getAll(String name);
356 
357     /**
358      * Returns all header names and values that this frame contains.
359      *
360      * @return the {@link List} of the header name-value pairs.  An empty list
361      *         if there is no header in this message.
362      */
363     public abstract List<Map.Entry<String, String>> entries();
364 
365     /**
366      * Returns {@code true} if and only if there is a header with the specified
367      * header name.
368      */
369     public abstract boolean contains(String name);
370 
371     /**
372      * Returns the {@link Set} of all header names that this frame contains.
373      */
374     public abstract Set<String> names();
375 
376     /**
377      * Adds a new header with the specified name and value.
378      */
379     public abstract SpdyHeaders add(String name, Object value);
380 
381     /**
382      * Adds a new header with the specified name and values.  If there is an
383      * existing header with the same name, the existing header is removed.
384      */
385     public abstract SpdyHeaders add(String name, Iterable<?> values);
386 
387     /**
388      * Sets a new header with the specified name and value.  If there is an
389      * existing header with the same name, the existing header is removed.
390      */
391     public abstract SpdyHeaders set(String name, Object value);
392 
393     /**
394      * Sets a new header with the specified name and values.  If there is an
395      * existing header with the same name, the existing header is removed.
396      */
397     public abstract SpdyHeaders set(String name, Iterable<?> values);
398 
399     /**
400      * Removes the header with the specified name.
401      */
402     public abstract SpdyHeaders remove(String name);
403 
404     /**
405      * Removes all headers from this frame.
406      */
407     public abstract SpdyHeaders clear();
408 
409     /**
410      * Checks if no header exists.
411      */
412     public abstract boolean isEmpty();
413 }