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