1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package org.apache.commons.httpclient;
33
34 /***
35 * Represents a Status-Line as returned from a HTTP server.
36 *
37 * <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a> states
38 * the following regarding the Status-Line:
39 * <pre>
40 * 6.1 Status-Line
41 *
42 * The first line of a Response message is the Status-Line, consisting
43 * of the protocol version followed by a numeric status code and its
44 * associated textual phrase, with each element separated by SP
45 * characters. No CR or LF is allowed except in the final CRLF sequence.
46 *
47 * Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
48 * </pre>
49 * <p>
50 * This class is immutable and is inherently thread safe.
51 *
52 * @see HttpStatus
53 * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
54 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
55 * @version $Id: StatusLine.java,v 1.9.2.4 2004/07/19 20:25:02 olegk Exp $
56 * @since 2.0
57 */
58 public class StatusLine {
59
60
61
62 /*** The original Status-Line. */
63 private final String statusLine;
64
65 /*** The HTTP-Version. */
66 private final String httpVersion;
67
68 /*** The Status-Code. */
69 private final int statusCode;
70
71 /*** The Reason-Phrase. */
72 private final String reasonPhrase;
73
74
75
76
77 /***
78 * Default constructor.
79 *
80 * @param statusLine the status line returned from the HTTP server
81 * @throws HttpException if the status line is invalid
82 */
83 public StatusLine(final String statusLine)
84 throws HttpException {
85
86 int length = statusLine.length();
87
88 int at = 0;
89 int start = 0;
90 try {
91 while (Character.isWhitespace(statusLine.charAt(at))) {
92 ++at;
93 ++start;
94 }
95 if (!"HTTP".equals(statusLine.substring(at, at += 4))) {
96 throw new HttpException("Status-Line '" + statusLine
97 + "' does not start with HTTP");
98 }
99
100 at = statusLine.indexOf(" ", at);
101 if (at <= 0) {
102 throw new HttpException(
103 "Unable to parse HTTP-Version from the status line: '"
104 + statusLine + "'");
105 }
106 this.httpVersion = (statusLine.substring(start, at)).toUpperCase();
107
108 while (statusLine.charAt(at) == ' ') {
109 at++;
110 }
111
112 int to = statusLine.indexOf(" ", at);
113 if (to < 0) {
114 to = length;
115 }
116 try {
117 this.statusCode = Integer.parseInt(statusLine.substring(at, to));
118 } catch (NumberFormatException e) {
119 throw new HttpException(
120 "Unable to parse status code from status line: '"
121 + statusLine + "'");
122 }
123
124 at = to + 1;
125 if (at < length) {
126 this.reasonPhrase = statusLine.substring(at).trim();
127 } else {
128 this.reasonPhrase = "";
129 }
130 } catch (StringIndexOutOfBoundsException e) {
131 throw new HttpException("Status-Line '" + statusLine + "' is not valid");
132 }
133
134 this.statusLine = new String(statusLine);
135 }
136
137
138
139
140 /***
141 * @return the Status-Code
142 */
143 public final int getStatusCode() {
144 return statusCode;
145 }
146
147 /***
148 * @return the HTTP-Version
149 */
150 public final String getHttpVersion() {
151 return httpVersion;
152 }
153
154 /***
155 * @return the Reason-Phrase
156 */
157 public final String getReasonPhrase() {
158 return reasonPhrase;
159 }
160
161 /***
162 * Return the status line as it was set by the constructor.
163 * @return a string represenation of this object.
164 */
165 public final String toString() {
166 return statusLine;
167 }
168
169 /***
170 * Tests if the string starts with 'HTTP' signature.
171 * @param s string to test
172 * @return <tt>true</tt> if the line starts with 'HTTP'
173 * signature, <tt>false</tt> otherwise.
174 */
175 public static boolean startsWithHTTP(final String s) {
176 try {
177 int at = 0;
178 while (Character.isWhitespace(s.charAt(at))) {
179 ++at;
180 }
181 return ("HTTP".equals(s.substring(at, at + 4)));
182 } catch (StringIndexOutOfBoundsException e) {
183 return false;
184 }
185 }
186 }