1 //
2 // ========================================================================
3 // Copyright (c) 1995-2012 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.http;
20
21 import java.nio.ByteBuffer;
22
23 import org.eclipse.jetty.util.StringMap;
24 import org.eclipse.jetty.util.StringUtil;
25
26
27 /* ------------------------------------------------------------------------------- */
28 public enum HttpVersion
29 {
30 HTTP_0_9("HTTP/0.9",9),
31 HTTP_1_0("HTTP/1.0",10),
32 HTTP_1_1("HTTP/1.1",11),
33 HTTP_2_0("HTTP/2.0",20);
34
35 /* ------------------------------------------------------------ */
36 public final static StringMap<HttpVersion> CACHE= new StringMap<HttpVersion>(true);
37 static
38 {
39 for (HttpVersion version : HttpVersion.values())
40 CACHE.put(version.toString(),version);
41 }
42
43 /* ------------------------------------------------------------ */
44 /**
45 * Optimised lookup to find a Http Version and whitespace in a byte array.
46 * @param bytes Array containing ISO-8859-1 characters
47 * @param position The first valid index
48 * @param limit The first non valid index
49 * @return A HttpMethod if a match or null if no easy match.
50 */
51 public static HttpVersion lookAheadGet(byte[] bytes, int position, int limit)
52 {
53 int length=limit-position;
54 if (length<9)
55 return null;
56
57 if (bytes[position+4]=='/' && bytes[position+6]=='.' && Character.isWhitespace((char)bytes[position+8]) &&
58 ((bytes[position]=='H' && bytes[position+1]=='T' && bytes[position+2]=='T' && bytes[position+3]=='P') ||
59 (bytes[position]=='h' && bytes[position+1]=='t' && bytes[position+2]=='t' && bytes[position+3]=='p')))
60 {
61 switch(bytes[position+5])
62 {
63 case '1':
64 switch(bytes[position+7])
65 {
66 case '0':
67 return HTTP_1_0;
68 case '1':
69 return HTTP_1_1;
70 }
71 break;
72 case '2':
73 switch(bytes[position+7])
74 {
75 case '0':
76 return HTTP_2_0;
77 }
78 break;
79 }
80 }
81
82 return null;
83 }
84
85 /* ------------------------------------------------------------ */
86 /**
87 * Optimised lookup to find a HTTP Version and trailing white space in a byte array.
88 * @param buffer buffer containing ISO-8859-1 characters
89 * @return A HttpVersion if a match or null if no easy match.
90 */
91 public static HttpVersion lookAheadGet(ByteBuffer buffer)
92 {
93 if (buffer.hasArray())
94 return lookAheadGet(buffer.array(),buffer.arrayOffset()+buffer.position(),buffer.arrayOffset()+buffer.limit());
95 return null;
96 }
97
98
99 private final String _string;
100 private final byte[] _bytes;
101 private final ByteBuffer _buffer;
102 private final int _version;
103
104 /* ------------------------------------------------------------ */
105 HttpVersion(String s,int version)
106 {
107 _string=s;
108 _bytes=StringUtil.getBytes(s);
109 _buffer=ByteBuffer.wrap(_bytes);
110 _version=version;
111 }
112
113 /* ------------------------------------------------------------ */
114 public byte[] toBytes()
115 {
116 return _bytes;
117 }
118
119 /* ------------------------------------------------------------ */
120 public ByteBuffer toBuffer()
121 {
122 return _buffer.asReadOnlyBuffer();
123 }
124
125 /* ------------------------------------------------------------ */
126 public int getVersion()
127 {
128 return _version;
129 }
130
131 /* ------------------------------------------------------------ */
132 public boolean is(String s)
133 {
134 return _string.equalsIgnoreCase(s);
135 }
136
137 /* ------------------------------------------------------------ */
138 public String asString()
139 {
140 return _string;
141 }
142
143 /* ------------------------------------------------------------ */
144 @Override
145 public String toString()
146 {
147 return _string;
148 }
149
150 /**
151 * Case insensitive fromString() conversion
152 * @param version the String to convert to enum constant
153 * @return the enum constant or null if version unknown
154 */
155 public static HttpVersion fromString(String version)
156 {
157 return CACHE.get(version);
158 }
159
160 /* ------------------------------------------------------------ */
161 public static HttpVersion fromVersion(int version)
162 {
163 switch(version)
164 {
165 case 9: return HttpVersion.HTTP_0_9;
166 case 10: return HttpVersion.HTTP_1_0;
167 case 11: return HttpVersion.HTTP_1_1;
168 default: throw new IllegalArgumentException();
169 }
170 }
171 }