View Javadoc

1   /*
2    * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/oac.hc3x/trunk/src/java/org/apache/commons/httpclient/StatusLine.java $
3    * $Revision$
4    * $Date$
5    *
6    * ====================================================================
7    *
8    *  Licensed to the Apache Software Foundation (ASF) under one or more
9    *  contributor license agreements.  See the NOTICE file distributed with
10   *  this work for additional information regarding copyright ownership.
11   *  The ASF licenses this file to You under the Apache License, Version 2.0
12   *  (the "License"); you may not use this file except in compliance with
13   *  the License.  You may obtain a copy of the License at
14   *
15   *      http://www.apache.org/licenses/LICENSE-2.0
16   *
17   *  Unless required by applicable law or agreed to in writing, software
18   *  distributed under the License is distributed on an "AS IS" BASIS,
19   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20   *  See the License for the specific language governing permissions and
21   *  limitations under the License.
22   * ====================================================================
23   *
24   * This software consists of voluntary contributions made by many
25   * individuals on behalf of the Apache Software Foundation.  For more
26   * information on the Apache Software Foundation, please see
27   * <http://www.apache.org/>.
28   *
29   */
30  
31  package org.apache.commons.httpclient;
32  
33  /***
34   * Represents a Status-Line as returned from a HTTP server.
35   *
36   * <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a> states
37   * the following regarding the Status-Line:
38   * <pre>
39   * 6.1 Status-Line
40   *
41   *  The first line of a Response message is the Status-Line, consisting
42   *  of the protocol version followed by a numeric status code and its
43   *  associated textual phrase, with each element separated by SP
44   *  characters. No CR or LF is allowed except in the final CRLF sequence.
45   *
46   *      Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
47   * </pre>
48   * <p>
49   * This class is immutable and is inherently thread safe.
50   *
51   * @see HttpStatus
52   * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
53   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
54   * @version $Id: StatusLine.java 608014 2008-01-02 05:48:53Z rolandw $
55   * @since 2.0
56   */
57  public class StatusLine {
58  
59      // ----------------------------------------------------- Instance Variables
60  
61      /*** The original Status-Line. */
62      private final String statusLine;
63  
64      /*** The HTTP-Version. */
65      private final String httpVersion;
66  
67      /*** The Status-Code. */
68      private final int statusCode;
69  
70      /*** The Reason-Phrase. */
71      private final String reasonPhrase;
72  
73  
74      // ----------------------------------------------------------- Constructors
75  
76      /***
77       * Default constructor.
78       *
79       * @param statusLine the status line returned from the HTTP server
80       * @throws HttpException if the status line is invalid
81       */
82      public StatusLine(final String statusLine) throws HttpException {
83  
84          int length = statusLine.length();
85          int at = 0;
86          int start = 0;
87          try {
88              while (Character.isWhitespace(statusLine.charAt(at))) {
89                  ++at;
90                  ++start;
91              }
92              if (!"HTTP".equals(statusLine.substring(at, at += 4))) {
93                  throw new HttpException("Status-Line '" + statusLine 
94                      + "' does not start with HTTP");
95              }
96              //handle the HTTP-Version
97              at = statusLine.indexOf(" ", at);
98              if (at <= 0) {
99                  throw new ProtocolException(
100                         "Unable to parse HTTP-Version from the status line: '"
101                         + statusLine + "'");
102             }
103             this.httpVersion = (statusLine.substring(start, at)).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.substring(at, to));
117             } catch (NumberFormatException e) {
118                 throw new ProtocolException(
119                     "Unable to parse status code from status line: '" 
120                     + statusLine + "'");
121             }
122             //handle the Reason-Phrase
123             at = to + 1;
124             if (at < length) {
125                 this.reasonPhrase = statusLine.substring(at).trim();
126             } else {
127                 this.reasonPhrase = "";
128             }
129         } catch (StringIndexOutOfBoundsException e) {
130             throw new HttpException("Status-Line '" + statusLine + "' is not valid"); 
131         }
132         //save the original Status-Line
133         this.statusLine = statusLine;
134     }
135 
136 
137     // --------------------------------------------------------- Public Methods
138 
139     /***
140      * @return the Status-Code
141      */
142     public final int getStatusCode() {
143         return statusCode;
144     }
145 
146     /***
147      * @return the HTTP-Version
148      */
149     public final String getHttpVersion() {
150         return httpVersion;
151     }
152 
153     /***
154      * @return the Reason-Phrase
155      */
156     public final String getReasonPhrase() {
157         return reasonPhrase;
158     }
159 
160     /***
161      * Return a string representation of this object.
162      * @return a string represenation of this object.
163      */
164     public final String toString() {
165         return statusLine;
166     }
167 
168     /***
169      * Tests if the string starts with 'HTTP' signature.
170      * @param s string to test
171      * @return <tt>true</tt> if the line starts with 'HTTP' 
172      *   signature, <tt>false</tt> otherwise.
173      */
174     public static boolean startsWithHTTP(final String s) {
175         try {
176             int at = 0;
177             while (Character.isWhitespace(s.charAt(at))) {
178                 ++at;
179             }
180             return ("HTTP".equals(s.substring(at, at + 4)));
181         } catch (StringIndexOutOfBoundsException e) {
182             return false;
183         }
184     }
185 }