001: /*
002: * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/StatusLine.java,v 1.14 2004/07/19 20:24:21 olegk Exp $
003: * $Revision: 480424 $
004: * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
005: *
006: * ====================================================================
007: *
008: * Licensed to the Apache Software Foundation (ASF) under one or more
009: * contributor license agreements. See the NOTICE file distributed with
010: * this work for additional information regarding copyright ownership.
011: * The ASF licenses this file to You under the Apache License, Version 2.0
012: * (the "License"); you may not use this file except in compliance with
013: * the License. You may obtain a copy of the License at
014: *
015: * http://www.apache.org/licenses/LICENSE-2.0
016: *
017: * Unless required by applicable law or agreed to in writing, software
018: * distributed under the License is distributed on an "AS IS" BASIS,
019: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
020: * See the License for the specific language governing permissions and
021: * limitations under the License.
022: * ====================================================================
023: *
024: * This software consists of voluntary contributions made by many
025: * individuals on behalf of the Apache Software Foundation. For more
026: * information on the Apache Software Foundation, please see
027: * <http://www.apache.org/>.
028: *
029: */
030:
031: package org.apache.commons.httpclient;
032:
033: /**
034: * Represents a Status-Line as returned from a HTTP server.
035: *
036: * <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a> states
037: * the following regarding the Status-Line:
038: * <pre>
039: * 6.1 Status-Line
040: *
041: * The first line of a Response message is the Status-Line, consisting
042: * of the protocol version followed by a numeric status code and its
043: * associated textual phrase, with each element separated by SP
044: * characters. No CR or LF is allowed except in the final CRLF sequence.
045: *
046: * Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
047: * </pre>
048: * <p>
049: * This class is immutable and is inherently thread safe.
050: *
051: * @see HttpStatus
052: * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
053: * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
054: * @version $Id: StatusLine.java 480424 2006-11-29 05:56:49Z bayard $
055: * @since 2.0
056: */
057: public class StatusLine {
058:
059: // ----------------------------------------------------- Instance Variables
060:
061: /** The original Status-Line. */
062: private final String statusLine;
063:
064: /** The HTTP-Version. */
065: private final String httpVersion;
066:
067: /** The Status-Code. */
068: private final int statusCode;
069:
070: /** The Reason-Phrase. */
071: private final String reasonPhrase;
072:
073: // ----------------------------------------------------------- Constructors
074:
075: /**
076: * Default constructor.
077: *
078: * @param statusLine the status line returned from the HTTP server
079: * @throws HttpException if the status line is invalid
080: */
081: public StatusLine(final String statusLine) throws HttpException {
082:
083: int length = statusLine.length();
084: int at = 0;
085: int start = 0;
086: try {
087: while (Character.isWhitespace(statusLine.charAt(at))) {
088: ++at;
089: ++start;
090: }
091: if (!"HTTP".equals(statusLine.substring(at, at += 4))) {
092: throw new HttpException("Status-Line '" + statusLine
093: + "' does not start with HTTP");
094: }
095: //handle the HTTP-Version
096: at = statusLine.indexOf(" ", at);
097: if (at <= 0) {
098: throw new ProtocolException(
099: "Unable to parse HTTP-Version from the status line: '"
100: + statusLine + "'");
101: }
102: this .httpVersion = (statusLine.substring(start, at))
103: .toUpperCase();
104:
105: //advance through spaces
106: while (statusLine.charAt(at) == ' ') {
107: at++;
108: }
109:
110: //handle the Status-Code
111: int to = statusLine.indexOf(" ", at);
112: if (to < 0) {
113: to = length;
114: }
115: try {
116: this .statusCode = Integer.parseInt(statusLine
117: .substring(at, to));
118: } catch (NumberFormatException e) {
119: throw new ProtocolException(
120: "Unable to parse status code from status line: '"
121: + statusLine + "'");
122: }
123: //handle the Reason-Phrase
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
132: + "' is not valid");
133: }
134: //save the original Status-Line
135: this .statusLine = statusLine;
136: }
137:
138: // --------------------------------------------------------- Public Methods
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 a string representation of this object.
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: }
|