View Javadoc

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