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