You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by js...@apache.org on 2002/09/05 02:21:57 UTC
cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient TestStatusLine.java TestNoHost.java
jsdever 2002/09/04 17:21:57
Modified: httpclient/src/java/org/apache/commons/httpclient
HttpMethod.java HttpMethodBase.java
httpclient/src/java/org/apache/commons/httpclient/util
HttpURLConnection.java
httpclient/src/test/org/apache/commons/httpclient
TestNoHost.java
Added: httpclient/src/java/org/apache/commons/httpclient
StatusLine.java
httpclient/src/test/org/apache/commons/httpclient
TestStatusLine.java
Log:
Status-Line encapsulation.
Contributor: Jeff Dever
Revision Changes Path
1.17 +10 -4 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethod.java
Index: HttpMethod.java
===================================================================
RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethod.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- HttpMethod.java 3 Sep 2002 01:36:26 -0000 1.16
+++ HttpMethod.java 5 Sep 2002 00:21:56 -0000 1.17
@@ -302,4 +302,10 @@
* Use this method internally to add footers.
*/
public void addResponseFooter(Header footer);
+
+ /**
+ * Return the Status-Line from the response.
+ * @since 2.0
+ */
+ public String getStatusLine();
}
1.56 +38 -58 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodBase.java
Index: HttpMethodBase.java
===================================================================
RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodBase.java,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -r1.55 -r1.56
--- HttpMethodBase.java 3 Sep 2002 11:19:35 -0000 1.55
+++ HttpMethodBase.java 5 Sep 2002 00:21:56 -0000 1.56
@@ -183,6 +183,9 @@
/** My request headers, if any. */
private HashMap requestHeaders = new HashMap();
+ /** The Status-Line from the response. */
+ private StatusLine statusLine = null;
+
/** My response headers, if any. */
private HashMap responseHeaders = new HashMap();
@@ -201,9 +204,6 @@
/** My query string, if any. */
private String queryString = null;
- /** My response status text, if any. */
- private String statusText = null;
-
/** The response body, assuming it has not be intercepted by a sub-class. */
private InputStream responseStream = null;
@@ -231,8 +231,6 @@
*/
private int maxRetries = 3;
- /** My response status code, if any. */
- private int statusCode = -1;
//~ Constructors �����������������������������������������������������������
@@ -446,9 +444,10 @@
* Provide access to the status code.
*
* @return the status code associated with the latest response.
+ * @deprecated use getStatusLine().getStatusCode()
*/
public int getStatusCode() {
- return statusCode;
+ return statusLine.getStatusCode();
}
/**
@@ -585,9 +584,10 @@
*
* @return the status text (or "reason phrase") associated with the latest
* response.
+ * @deprecated use getStatusLine.getReasonPhrase()
*/
public String getStatusText() {
- return statusText;
+ return statusLine.getReasonPhrase();
}
/**
@@ -659,7 +659,7 @@
private boolean shouldCloseConnection() {
if (!http11) {
if (getName().equals(ConnectMethod.NAME) &&
- (statusCode == HttpStatus.SC_OK)) {
+ (statusLine.getStatusCode() == HttpStatus.SC_OK)) {
log.debug("Will leave connection open for tunneling");
return false;
} else {
@@ -741,6 +741,7 @@
//if SC_CONTINUE write the request body
writeRemainingRequestBody(state, conn);
+ int statusCode = statusLine.getStatusCode();
switch (statusCode) {
case HttpStatus.SC_UNAUTHORIZED:
case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
@@ -886,8 +887,7 @@
queryString = null;
requestHeaders.clear();
responseHeaders.clear();
- statusCode = -1;
- statusText = null;
+ statusLine = null;
used = false;
http11 = true;
bodySent = false;
@@ -1425,7 +1425,8 @@
* @param conn the {@link HttpConnection} to read the response from
* @return InputStream to read the response body from
*/
- private InputStream _readResponseBody(HttpState state, HttpConnection conn) throws IOException {
+ private InputStream _readResponseBody(HttpState state, HttpConnection conn)
+ throws IOException {
log.trace("enter HttpMethodBase.readResponseBody(HttpState, HttpConnection)");
responseBody = null; // is this desired?
@@ -1447,7 +1448,8 @@
if ("chunked".equalsIgnoreCase(transferEncodingHeader.getValue())) {
result = new ChunkedInputStream(is, this);
}
- } else if(canResponseHaveBody(statusCode) && !getName().equals(ConnectMethod.NAME)){
+ } else if(canResponseHaveBody(statusLine.getStatusCode())
+ && !getName().equals(ConnectMethod.NAME)){
result = is;
}
if (result == null) return null;
@@ -1558,63 +1560,40 @@
* @throws HttpRecoverableException when the status line is null and the
* request should be retried
*
- * @see #readResponse
- * @see #processStatusLine
+ * @see StatusLine
*/
protected void readStatusLine(HttpState state, HttpConnection conn)
throws IOException, HttpRecoverableException, HttpException {
log.trace(
"enter HttpMethodBase.readStatusLine(HttpState, HttpConnection)");
- statusCode = -1;
- statusText = null;
-
- String statusLine = conn.readLine();
-
- while ((statusLine != null) && !statusLine.startsWith("HTTP/")) {
- statusLine = conn.readLine();
+ //read out the HTTP status string
+ String statusString = conn.readLine();
+ while ((statusString != null) && !statusString.startsWith("HTTP/")) {
+ statusString = conn.readLine();
}
- if (statusLine == null) {
- // A null statusLine means the connection was lost before we got a
+ if (statusString == null) {
+ // A null statusString means the connection was lost before we got a
// response. Try again.
throw new HttpRecoverableException("Error in parsing the status "
+ " line from the response: unable to find line starting with"
+ " \"HTTP/\"");
}
- if ((!statusLine.startsWith("HTTP/1.1")
- && !statusLine.startsWith("HTTP/1.0"))) {
- throw new HttpException("Unrecognized server protocol :"
- + statusLine);
- }
-
- http11 = statusLine.startsWith("HTTP/1.1");
-
- int at = statusLine.indexOf(" ");
- if (at < 0) {
- throw new HttpException("Unable to parse the status line: "
- + statusLine);
- }
-
- int to = statusLine.indexOf(" ", at + 1);
- if (to < 0) {
- to = statusLine.length();
- }
+ //create the status line from the status string
+ statusLine = new StatusLine(statusString);
- try {
- statusCode = Integer.parseInt(statusLine.substring(at + 1, to));
- } catch (NumberFormatException e) {
- throw new HttpException(
- "Unable to parse status code from status line: " + statusLine);
+ //check for a valid HTTP-Version
+ String httpVersion = statusLine.getHttpVersion();
+ if (httpVersion.equals("HTTP/1.0")){
+ http11 = false;
+ } else if (httpVersion.equals("HTTP/1.1")){
+ http11 = true;
+ } else {
+ throw new HttpException("Unrecognized server protocol: '"
+ + httpVersion + "'");
}
- try {
- if (to < statusLine.length()) {
- statusText = statusLine.substring(to + 1);
- }
- } catch (StringIndexOutOfBoundsException e) {
- throw new HttpException("Status text not specified: " + statusLine);
- }
}
// ------------------------------------------------------ Protected Methods
@@ -1892,6 +1871,7 @@
log.trace("enter HttpMethodBase.processAuthenticationResponse("
+ "HttpState, HttpConnection)");
+ int statusCode = statusLine.getStatusCode();
// handle authentication required
Header wwwauth = null;
Set realmsUsed = null;
@@ -2046,7 +2026,7 @@
throws HttpException, IOException {
log.trace("enter writeRemainingRequestBody(HttpState, HttpConnection)");
- if (HttpStatus.SC_CONTINUE == statusCode) {
+ if (HttpStatus.SC_CONTINUE == statusLine.getStatusCode()) {
if (!bodySent) {
bodySent = writeRequestBody(state, connection);
} else {
1.1 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/StatusLine.java
Index: StatusLine.java
===================================================================
/*
* $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/StatusLine.java,v 1.1 2002/09/05 00:21:56 jsdever Exp $
* $Revision: 1.1 $
* $Date: 2002/09/05 00:21:56 $
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "HttpClient", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.commons.httpclient;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
/**
* Represents a Status-Line as returned from a HTTP server.
*
* <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a> states
* the following regarding the Status-Line:
* <pre>
* 6.1 Status-Line
*
* The first line of a Response message is the Status-Line, consisting
* of the protocol version followed by a numeric status code and its
* associated textual phrase, with each element separated by SP
* characters. No CR or LF is allowed except in the final CRLF sequence.
*
* Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
* </pre>
* <p>
* This class is immutable and is inherently thread safe.
*
* @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
* @version $Id: StatusLine.java,v 1.1 2002/09/05 00:21:56 jsdever Exp $
* @since 2.0
*/
public class StatusLine {
// ----------------------------------------------------- Instance Variables
/** The original Status-Line. */
private final String statusLine;
/** The HTTP-Version. */
private final String httpVersion;
/** The Status-Code. */
private final int statusCode;
/** The Reason-Phrase. */
private final String reasonPhrase;
// ----------------------------------------------------------- Constructors
/**
* Default constructor.
*
* @param statusLine the status line returned from the HTTP server
* @throws HttpException if the status line is invalid
*/
public StatusLine(String statusLine)
throws HttpException {
//save the original Status-Line
this.statusLine = new String(statusLine);
int length = statusLine.length();
//check validity of the Status-Line
if (! statusLine.startsWith("HTTP/")) {
throw new HttpException("Status-Line '" + statusLine +
"' does not start with HTTP/");
}
//handle the HTTP-Version
int at = statusLine.indexOf(" ");
if (at <= 0) {
throw new HttpException(
"Unable to parse HTTP-Version from the status line: '"
+ statusLine + "'");
}
this.httpVersion = (statusLine.substring(0, at)).toUpperCase();
//handle the Status-Code
int to = statusLine.indexOf(" ", at + 1);
if (to < 0) {
to = length;
}
try {
this.statusCode = Integer.parseInt(statusLine.substring(at+1, to));
} catch (NumberFormatException e) {
throw new HttpException(
"Unable to parse status code from status line: '"
+ statusLine + "'");
}
//handle the Reason-Phrase
try {
if (to < length) {
if (statusLine.endsWith("\n\r")) {
this.reasonPhrase = statusLine.substring(to+1, length-2);
} else {
this.reasonPhrase = statusLine.substring(to+1);
}
} else {
this.reasonPhrase = "";
}
} catch (StringIndexOutOfBoundsException e) {
throw new HttpException("Status text not specified: '"
+ statusLine + "'");
}
}
// --------------------------------------------------------- Public Methods
/**
* @return the Status-Code
*/
public final int getStatusCode() {
return statusCode;
}
/**
* @return the HTTP-Version
*/
public final String getHttpVersion() {
return httpVersion;
}
/**
* @return the Reason-Phrase
*/
public final String getReasonPhrase() {
return reasonPhrase;
}
public final String toString() {
return statusLine;
}
}
1.6 +5 -12 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/util/HttpURLConnection.java
Index: HttpURLConnection.java
===================================================================
RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/util/HttpURLConnection.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- HttpURLConnection.java 4 Sep 2002 00:58:26 -0000 1.5
+++ HttpURLConnection.java 5 Sep 2002 00:21:57 -0000 1.6
@@ -63,7 +63,6 @@
package org.apache.commons.httpclient.util;
import org.apache.commons.httpclient.HttpMethod;
-import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.Header;
import org.apache.commons.logging.LogFactory;
@@ -273,13 +272,7 @@
// return the status line. Hence the special case below ...
if (position == 0) {
- if (((HttpMethodBase) this.method).isHttp11()) {
- return "HTTP/1.1 " + this.method.getStatusCode()
- + " " + this.method.getStatusText();
- } else {
- return "HTTP/1.0 " + this.method.getStatusCode()
- + " " + this.method.getStatusText();
- }
+ return this.method.getStatusLine();
}
// Note: I hope the header fields are kept in the correct order when
1.12 +5 -4 jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestNoHost.java
Index: TestNoHost.java
===================================================================
RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestNoHost.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- TestNoHost.java 2 Sep 2002 14:52:48 -0000 1.11
+++ TestNoHost.java 5 Sep 2002 00:21:57 -0000 1.12
@@ -98,6 +98,7 @@
suite.addTest(TestResponseHeaders.suite());
suite.addTest(TestRequestHeaders.suite());
suite.addTest(TestStreams.suite());
+ suite.addTest(TestStatusLine.suite());
return suite;
}
1.1 jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestStatusLine.java
Index: TestStatusLine.java
===================================================================
/*
* $Header: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestStatusLine.java,v 1.1 2002/09/05 00:21:57 jsdever Exp $
* $Revision: 1.1 $
* $Date: 2002/09/05 00:21:57 $
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.commons.httpclient;
import junit.framework.*;
/**
* Simple tests for {@link StatusLine}.
*
* @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
* @version $Id: TestStatusLine.java,v 1.1 2002/09/05 00:21:57 jsdever Exp $
*/
public class TestStatusLine extends TestCase {
private StatusLine statusLine = null;
// ------------------------------------------------------------ Constructor
public TestStatusLine(String testName) {
super(testName);
}
// ------------------------------------------------------------------- Main
public static void main(String args[]) {
String[] testCaseName = { TestStatusLine.class.getName() };
junit.textui.TestRunner.main(testCaseName);
}
// ------------------------------------------------------- TestCase Methods
public static Test suite() {
return new TestSuite(TestStatusLine.class);
}
// ------------------------------------------------------ Protected Methods
// ----------------------------------------------------------- Test Methods
public void testSuccess() throws Exception {
//typical status line
statusLine = new StatusLine("HTTP/1.1 200 OK");
assertEquals("HTTP/1.1 200 OK", statusLine.toString());
assertEquals("HTTP/1.1", statusLine.getHttpVersion());
assertEquals(200, statusLine.getStatusCode());
assertEquals("OK", statusLine.getReasonPhrase());
//status line with multi word reason phrase
statusLine = new StatusLine("HTTP/1.1 404 Not Found");
assertEquals(404, statusLine.getStatusCode());
assertEquals("Not Found", statusLine.getReasonPhrase());
//reason phrase can be anyting
statusLine = new StatusLine("HTTP/1.1 404 Non Trouv�");
assertEquals("Non Trouv�", statusLine.getReasonPhrase());
//its ok to end with a \n\r
statusLine = new StatusLine("HTTP/1.1 404 Not Found\n\r");
assertEquals("Not Found", statusLine.getReasonPhrase());
//this is valid according to the Status-Line BNF
statusLine = new StatusLine("HTTP/1.1 200 ");
assertEquals(200, statusLine.getStatusCode());
assertEquals("", statusLine.getReasonPhrase());
//this is not strictly valid, but is lienent
statusLine = new StatusLine("HTTP/1.1 200");
assertEquals(200, statusLine.getStatusCode());
assertEquals("", statusLine.getReasonPhrase());
}
public void testFailure() throws Exception {
try {
statusLine = new StatusLine(null);
fail();
} catch (NullPointerException e) { /* expected */ }
try {
statusLine = new StatusLine("xxx 200 OK");
fail();
} catch (HttpException e) { /* expected */ }
try {
statusLine = new StatusLine("HTTP/1.1 xxx OK");
fail();
} catch (HttpException e) { /* expected */ }
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>