Source code: org/apache/http/HttpVersion.java
1 /*
2 * $HeadURL: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpcore/tags/4.0-alpha2/src/java/org/apache/http/HttpVersion.java $
3 * $Revision: 389604 $
4 * $Date: 2006-03-28 23:03:47 +0200 (Tue, 28 Mar 2006) $
5 *
6 * ====================================================================
7 *
8 * Copyright 1999-2006 The Apache Software Foundation
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 * ====================================================================
22 *
23 * This software consists of voluntary contributions made by many
24 * individuals on behalf of the Apache Software Foundation. For more
25 * information on the Apache Software Foundation, please see
26 * <http://www.apache.org/>.
27 *
28 */
29
30 package org.apache.http;
31
32 import org.apache.http.io.CharArrayBuffer;
33 import org.apache.http.protocol.HTTP;
34
35 /**
36 * <p>HTTP version, as specified in RFC 2616.</p>
37 * <p>
38 * HTTP uses a "<major>.<minor>" numbering scheme to indicate
39 * versions of the protocol. The protocol versioning policy is intended to
40 * allow the sender to indicate the format of a message and its capacity for
41 * understanding further HTTP communication, rather than the features
42 * obtained via that communication. No change is made to the version
43 * number for the addition of message components which do not affect
44 * communication behavior or which only add to extensible field values.
45 * The <minor> number is incremented when the changes made to the
46 * protocol add features which do not change the general message parsing
47 * algorithm, but which may add to the message semantics and imply
48 * additional capabilities of the sender. The <major> number is
49 * incremented when the format of a message within the protocol is
50 * changed. See RFC 2145 [36] for a fuller explanation.
51 * </p>
52 * <p>
53 * The version of an HTTP message is indicated by an HTTP-Version field
54 * in the first line of the message.
55 * </p>
56 * <pre>
57 * HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
58 * </pre>
59 * <p>
60 * Note that the major and minor numbers MUST be treated as separate
61 * integers and that each MAY be incremented higher than a single digit.
62 * Thus, HTTP/2.4 is a lower version than HTTP/2.13, which in turn is
63 * lower than HTTP/12.3. Leading zeros MUST be ignored by recipients and
64 * MUST NOT be sent.
65 * </p>
66 *
67 * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
68 *
69 * @version $Revision: 389604 $ $Date: 2006-03-28 23:03:47 +0200 (Tue, 28 Mar 2006) $
70 *
71 * @since 3.0
72 */
73 public class HttpVersion implements Comparable {
74
75 /** Major version number of the HTTP protocol */
76 private int major = 0;
77
78 /** Minor version number of the HTTP protocol */
79 private int minor = 0;
80
81 /** HTTP protocol version 0.9 */
82 public static final HttpVersion HTTP_0_9 = new HttpVersion(0, 9);
83
84 /** HTTP protocol version 1.0 */
85 public static final HttpVersion HTTP_1_0 = new HttpVersion(1, 0);
86
87 /** HTTP protocol version 1.1 */
88 public static final HttpVersion HTTP_1_1 = new HttpVersion(1, 1);
89
90 /**
91 * Create an HTTP protocol version designator.
92 *
93 * @param major the major version number of the HTTP protocol
94 * @param minor the minor version number of the HTTP protocol
95 *
96 * @throws IllegalArgumentException if either major or minor version number is negative
97 */
98 public HttpVersion(int major, int minor) {
99 if (major < 0) {
100 throw new IllegalArgumentException("HTTP major version number may not be negative");
101 }
102 this.major = major;
103 if (minor < 0) {
104 throw new IllegalArgumentException("HTTP minor version number may not be negative");
105 }
106 this.minor = minor;
107 }
108
109 /**
110 * Returns the major version number of the HTTP protocol.
111 *
112 * @return the major version number.
113 */
114 public int getMajor() {
115 return major;
116 }
117
118 /**
119 * Returns the minor version number of the HTTP protocol.
120 *
121 * @return the minor version number.
122 */
123 public int getMinor() {
124 return minor;
125 }
126
127 /**
128 * @see java.lang.Object#hashCode()
129 */
130 public int hashCode() {
131 return this.major * 100000 + this.minor;
132 }
133
134 /**
135 * @see java.lang.Object#equals(java.lang.Object)
136 */
137 public boolean equals(Object obj) {
138 if (this == obj) {
139 return true;
140 }
141 if (!(obj instanceof HttpVersion)) {
142 return false;
143 }
144 return equals((HttpVersion)obj);
145 }
146
147 /**
148 * Compares this HTTP protocol version with another one.
149 *
150 * @param anotherVer the version to be compared with.
151 *
152 * @return a negative integer, zero, or a positive integer as this version is less than,
153 * equal to, or greater than the specified version.
154 */
155 public int compareTo(HttpVersion anotherVer) {
156 if (anotherVer == null) {
157 throw new IllegalArgumentException("Version parameter may not be null");
158 }
159 int delta = getMajor() - anotherVer.getMajor();
160 if (delta == 0) {
161 delta = getMinor() - anotherVer.getMinor();
162 }
163 return delta;
164 }
165
166 /**
167 * @see java.lang.Comparable#compareTo(java.lang.Object)
168 */
169 public int compareTo(Object o) {
170 return compareTo((HttpVersion)o);
171 }
172
173 /**
174 * Test if the HTTP protocol version is equal to the given number.
175 *
176 * @return <tt>true</tt> if HTTP protocol version is given to the given number,
177 * <tt>false</tt> otherwise.
178 */
179 public boolean equals(HttpVersion version) {
180 return compareTo(version) == 0;
181 }
182
183 /**
184 * Test if the HTTP protocol version is greater or equal to the given number.
185 *
186 * @return <tt>true</tt> if HTTP protocol version is greater or equal given to the
187 * given number, <tt>false</tt> otherwise.
188 */
189 public boolean greaterEquals(HttpVersion version) {
190 return compareTo(version) >= 0;
191 }
192
193 /**
194 * Test if the HTTP protocol version is less or equal to the given number.
195 *
196 * @return <tt>true</tt> if HTTP protocol version is less or equal to given to the
197 * given number, <tt>false</tt> otherwise.
198 */
199 public boolean lessEquals(HttpVersion version) {
200 return compareTo(version) <= 0;
201 }
202
203 /**
204 * @see java.lang.Object#toString()
205 */
206 public String toString() {
207 CharArrayBuffer buffer = new CharArrayBuffer(16);
208 buffer.append("HTTP/");
209 buffer.append(Integer.toString(this.major));
210 buffer.append('.');
211 buffer.append(Integer.toString(this.minor));
212 return buffer.toString();
213 }
214
215 /**
216 * Parses the textual representation of the given HTTP protocol version.
217 *
218 * @return HTTP protocol version.
219 *
220 * @throws ProtocolException if the string is not a valid HTTP protocol version.
221 */
222 public static HttpVersion parse(
223 final CharArrayBuffer buffer, final int indexFrom, final int indexTo)
224 throws ProtocolException {
225 if (buffer == null) {
226 throw new IllegalArgumentException("Char array buffer may not be null");
227 }
228 if (indexFrom < 0) {
229 throw new IndexOutOfBoundsException();
230 }
231 if (indexTo > buffer.length()) {
232 throw new IndexOutOfBoundsException();
233 }
234 if (indexFrom > indexTo) {
235 throw new IndexOutOfBoundsException();
236 }
237 try {
238 int major, minor;
239
240 int i = indexFrom;
241 while (HTTP.isWhitespace(buffer.charAt(i))) {
242 i++;
243 }
244 if (buffer.charAt(i ) != 'H'
245 || buffer.charAt(i + 1) != 'T'
246 || buffer.charAt(i + 2) != 'T'
247 || buffer.charAt(i + 3) != 'P'
248 || buffer.charAt(i + 4) != '/') {
249 throw new ProtocolException("Not a valid HTTP version string: " +
250 buffer.substring(indexFrom, indexTo));
251 }
252 i += 5;
253 int period = buffer.indexOf('.', i, indexTo);
254 if (period == -1) {
255 throw new ProtocolException("Invalid HTTP version number: " +
256 buffer.substring(indexFrom, indexTo));
257 }
258 try {
259 major = Integer.parseInt(buffer.substringTrimmed(i, period));
260 } catch (NumberFormatException e) {
261 throw new ProtocolException("Invalid HTTP major version number: " +
262 buffer.substring(indexFrom, indexTo));
263 }
264 try {
265 minor = Integer.parseInt(buffer.substringTrimmed(period + 1, indexTo));
266 } catch (NumberFormatException e) {
267 throw new ProtocolException("Invalid HTTP minor version number: " +
268 buffer.substring(indexFrom, indexTo));
269 }
270 return new HttpVersion(major, minor);
271
272 } catch (IndexOutOfBoundsException e) {
273 throw new ProtocolException("Invalid HTTP version string: " +
274 buffer.substring(indexFrom, indexTo));
275 }
276 }
277
278 public static final HttpVersion parse(final String s)
279 throws ProtocolException {
280 if (s == null) {
281 throw new IllegalArgumentException("String may not be null");
282 }
283 CharArrayBuffer buffer = new CharArrayBuffer(s.length());
284 buffer.append(s);
285 return parse(buffer, 0, buffer.length());
286 }
287
288 public static void format(final CharArrayBuffer buffer, final HttpVersion ver) {
289 if (buffer == null) {
290 throw new IllegalArgumentException("String buffer may not be null");
291 }
292 if (ver == null) {
293 throw new IllegalArgumentException("Version may not be null");
294 }
295 buffer.append("HTTP/");
296 buffer.append(Integer.toString(ver.getMajor()));
297 buffer.append('.');
298 buffer.append(Integer.toString(ver.getMinor()));
299 }
300
301 public static String format(final HttpVersion ver) {
302 CharArrayBuffer buffer = new CharArrayBuffer(16);
303 format(buffer, ver);
304 return buffer.toString();
305 }
306
307 }