View Javadoc

1   /*
2    * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/StatusLine.java,v 1.9.2.4 2004/07/19 20:25:02 olegk Exp $
3    * $Revision: 1.9.2.4 $
4    * $Date: 2004/07/19 20:25:02 $
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   * [Additional notices, if required by prior licensing conditions]
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      // ----------------------------------------------------- Instance Variables
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      // ----------------------------------------------------------- Constructors
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              //handle the HTTP-Version
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             //advance through spaces
108             while (statusLine.charAt(at) == ' ') {
109                 at++;
110             }
111             //handle the Status-Code
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             //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 + "' is not valid"); 
132         }
133         //save the original Status-Line if everything is OK
134         this.statusLine = new String(statusLine);
135     }
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 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 }