Source code: org/apache/http/StatusLine.java
1 /*
2 * $HeadURL: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpcore/tags/4.0-alpha2/src/java/org/apache/http/StatusLine.java $
3 * $Revision: 376961 $
4 * $Date: 2006-02-11 11:32:50 +0100 (Sat, 11 Feb 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 * Represents a Status-Line as returned from a HTTP server.
37 *
38 * <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a> states
39 * the following regarding the Status-Line:
40 * <pre>
41 * 6.1 Status-Line
42 *
43 * The first line of a Response message is the Status-Line, consisting
44 * of the protocol version followed by a numeric status code and its
45 * associated textual phrase, with each element separated by SP
46 * characters. No CR or LF is allowed except in the final CRLF sequence.
47 *
48 * Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
49 * </pre>
50 * <p>
51 * This class is immutable and is inherently thread safe.
52 *
53 * @see HttpStatus
54 * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
55 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
56 * @version $Id: StatusLine.java 376961 2006-02-11 10:32:50Z olegk $
57 *
58 * @since 2.0
59 */
60 public class StatusLine {
61
62 // ----------------------------------------------------- Instance Variables
63
64 /** The HTTP-Version. */
65 private final HttpVersion httpVersion;
66
67 /** The Status-Code. */
68 private final int statusCode;
69
70 /** The Reason-Phrase. */
71 private final String reasonPhrase;
72
73 // ----------------------------------------------------------- Constructors
74 /**
75 * Default constructor
76 */
77 public StatusLine(final HttpVersion httpVersion, int statusCode, final String reasonPhrase) {
78 super();
79 if (httpVersion == null) {
80 throw new IllegalArgumentException("HTTP version may not be null");
81 }
82 if (statusCode < 0) {
83 throw new IllegalArgumentException("Status code may not be negative");
84 }
85 this.httpVersion = httpVersion;
86 this.statusCode = statusCode;
87 this.reasonPhrase = reasonPhrase;
88 }
89
90 public StatusLine(final HttpVersion httpVersion, int statusCode) {
91 this(httpVersion, statusCode, HttpStatus.getStatusText(statusCode));
92 }
93
94 /**
95 * Parses the status line returned from the HTTP server.
96 *
97 * @param buffer the buffer from which to parse
98 * @param indexFrom where to start parsing in the buffer
99 * @param indexTo where to stop parsing in the buffer
100 *
101 * @throws HttpException if the status line is invalid
102 *
103 * @since 4.0
104 */
105 public static StatusLine parse(
106 final CharArrayBuffer buffer, final int indexFrom, final int indexTo)
107 throws ProtocolException {
108 if (buffer == null) {
109 throw new IllegalArgumentException("Char array buffer may not be null");
110 }
111 if (indexFrom < 0) {
112 throw new IndexOutOfBoundsException();
113 }
114 if (indexTo > buffer.length()) {
115 throw new IndexOutOfBoundsException();
116 }
117 if (indexFrom > indexTo) {
118 throw new IndexOutOfBoundsException();
119 }
120 try {
121 int i = indexFrom;
122 //handle the HTTP-Version
123 while (HTTP.isWhitespace(buffer.charAt(i))) {
124 i++;
125 }
126 int blank = buffer.indexOf(' ', i, indexTo);
127 if (blank <= 0) {
128 throw new ProtocolException(
129 "Unable to parse HTTP-Version from the status line: "
130 + buffer.substring(indexFrom, indexTo));
131 }
132 HttpVersion ver = HttpVersion.parse(buffer, i, blank);
133
134 i = blank;
135 //advance through spaces
136 while (HTTP.isWhitespace(buffer.charAt(i))) {
137 i++;
138 }
139
140 //handle the Status-Code
141 blank = buffer.indexOf(' ', i, indexTo);
142 if (blank < 0) {
143 blank = indexTo;
144 }
145 int statusCode = 0;
146 try {
147 statusCode = Integer.parseInt(buffer.substringTrimmed(i, blank));
148 } catch (NumberFormatException e) {
149 throw new ProtocolException(
150 "Unable to parse status code from status line: "
151 + buffer.substring(indexFrom, indexTo));
152 }
153 //handle the Reason-Phrase
154 i = blank;
155 String reasonPhrase = null;
156 if (i < indexTo) {
157 reasonPhrase = buffer.substringTrimmed(i, indexTo);
158 } else {
159 reasonPhrase = "";
160 }
161 return new StatusLine(ver, statusCode, reasonPhrase);
162 } catch (IndexOutOfBoundsException e) {
163 throw new ProtocolException("Invalid status line: " +
164 buffer.substring(indexFrom, indexTo));
165 }
166 }
167
168 public static final StatusLine parse(final String s)
169 throws ProtocolException {
170 if (s == null) {
171 throw new IllegalArgumentException("String may not be null");
172 }
173 CharArrayBuffer buffer = new CharArrayBuffer(s.length());
174 buffer.append(s);
175 return parse(buffer, 0, buffer.length());
176 }
177
178 // --------------------------------------------------------- Public Methods
179
180 /**
181 * @return the Status-Code
182 */
183 public final int getStatusCode() {
184 return this.statusCode;
185 }
186
187 /**
188 * @return the HTTP-Version
189 */
190 public final HttpVersion getHttpVersion() {
191 return this.httpVersion;
192 }
193
194 /**
195 * @return the Reason-Phrase
196 */
197 public final String getReasonPhrase() {
198 return this.reasonPhrase;
199 }
200
201 public final String toString() {
202 CharArrayBuffer buffer = new CharArrayBuffer(64);
203 buffer.append(this.httpVersion);
204 buffer.append(' ');
205 buffer.append(Integer.toString(this.statusCode));
206 if (this.reasonPhrase != null && !this.reasonPhrase.equals("")) {
207 buffer.append(' ');
208 buffer.append(this.reasonPhrase);
209 }
210 return buffer.toString();
211 }
212
213 public static void format(final CharArrayBuffer buffer, final StatusLine statusline) {
214 if (buffer == null) {
215 throw new IllegalArgumentException("String buffer may not be null");
216 }
217 if (statusline == null) {
218 throw new IllegalArgumentException("Status line may not be null");
219 }
220 HttpVersion.format(buffer, statusline.getHttpVersion());
221 buffer.append(' ');
222 buffer.append(Integer.toString(statusline.getStatusCode()));
223 if (statusline.getReasonPhrase() != null) {
224 buffer.append(' ');
225 buffer.append(statusline.getReasonPhrase());
226 }
227 }
228
229 public static String format(final StatusLine statusline) {
230 CharArrayBuffer buffer = new CharArrayBuffer(32);
231 format(buffer, statusline);
232 return buffer.toString();
233 }
234
235 }