You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ol...@apache.org on 2003/10/19 20:49:56 UTC
cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient TestStatusLine.java
olegk 2003/10/19 11:49:56
Modified: httpclient/src/java/org/apache/commons/httpclient Tag:
HTTPCLIENT_2_0_BRANCH HttpMethodBase.java
StatusLine.java
httpclient/src/test/org/apache/commons/httpclient Tag:
HTTPCLIENT_2_0_BRANCH TestStatusLine.java
Log:
HTTP status line parser changed to be more robust when dealing with non-compliant HTTP responses (leading blanks before 'HTTP' signature)
Problem reported by Tim McCune <tmccune at hmsonline.com>
Contributed by Oleg Kalnichevski
Reviewed by Michael Becke
Revision Changes Path
No revision
No revision
1.159.2.15 +11 -11 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.159.2.14
retrieving revision 1.159.2.15
diff -u -r1.159.2.14 -r1.159.2.15
--- HttpMethodBase.java 13 Oct 2003 12:19:22 -0000 1.159.2.14
+++ HttpMethodBase.java 19 Oct 2003 18:49:56 -0000 1.159.2.15
@@ -2165,14 +2165,14 @@
LOG.trace("enter HttpMethodBase.readStatusLine(HttpState, HttpConnection)");
//read out the HTTP status string
- String statusString = conn.readLine();
- while ((statusString != null) && !statusString.startsWith("HTTP")) {
+ String s = conn.readLine();
+ while ((s != null) && !StatusLine.startsWithHTTP(s)) {
if (Wire.enabled()) {
- Wire.input(statusString + "\r\n");
+ Wire.input(s + "\r\n");
}
- statusString = conn.readLine();
+ s = conn.readLine();
}
- if (statusString == null) {
+ if (s == null) {
// A null statusString means the connection was lost before we got a
// response. Try again.
throw new HttpRecoverableException("Error in parsing the status "
@@ -2180,10 +2180,10 @@
+ " \"HTTP\"");
}
if (Wire.enabled()) {
- Wire.input(statusString + "\r\n");
+ Wire.input(s + "\r\n");
}
//create the status line from the status string
- statusLine = new StatusLine(statusString);
+ statusLine = new StatusLine(s);
//check for a valid HTTP-Version
String httpVersion = statusLine.getHttpVersion();
1.9.2.1 +40 -15 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/StatusLine.java
Index: StatusLine.java
===================================================================
RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/StatusLine.java,v
retrieving revision 1.9
retrieving revision 1.9.2.1
diff -u -r1.9 -r1.9.2.1
--- StatusLine.java 1 Apr 2003 00:25:24 -0000 1.9
+++ StatusLine.java 19 Oct 2003 18:49:56 -0000 1.9.2.1
@@ -112,28 +112,33 @@
* @param statusLine the status line returned from the HTTP server
* @throws HttpException if the status line is invalid
*/
- public StatusLine(String statusLine)
+ public StatusLine(final 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");
+ int at = 0;
+ int start = 0;
+ try {
+ while (Character.isWhitespace(statusLine.charAt(at))) {
+ ++at;
+ ++start;
+ }
+ if (!"HTTP".equals(statusLine.substring(at, at += 4))) {
+ throw new HttpException("Status-Line '" + statusLine
+ + "' does not start with HTTP");
+ }
+ } catch (StringIndexOutOfBoundsException e) {
+ throw new HttpException("Status-Line '" + statusLine + "' is not valid");
}
-
//handle the HTTP-Version
- int at = statusLine.indexOf(" ");
+ at = statusLine.indexOf(" ", at);
if (at <= 0) {
throw new HttpException(
"Unable to parse HTTP-Version from the status line: '"
+ statusLine + "'");
}
- this.httpVersion = (statusLine.substring(0, at)).toUpperCase();
+ this.httpVersion = (statusLine.substring(start, at)).toUpperCase();
//advance through spaces
while (statusLine.charAt(at) == ' ') {
@@ -165,6 +170,8 @@
throw new HttpException("Status text not specified: '"
+ statusLine + "'");
}
+ //save the original Status-Line if everything is OK
+ this.statusLine = new String(statusLine);
}
@@ -197,5 +204,23 @@
*/
public final String toString() {
return statusLine;
+ }
+
+ /**
+ * Tests if the string starts with 'HTTP' signature.
+ * @param s string to test
+ * @return <tt>true</tt> if the line starts with 'HTTP'
+ * signature, <tt>false</tt> otherwise.
+ */
+ public static boolean startsWithHTTP(final String s) {
+ try {
+ int at = 0;
+ while (Character.isWhitespace(s.charAt(at))) {
+ ++at;
+ }
+ return ("HTTP".equals(s.substring(at, at + 4)));
+ } catch (StringIndexOutOfBoundsException e) {
+ return false;
+ }
}
}
No revision
No revision
1.6.2.1 +26 -4 jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestStatusLine.java
Index: TestStatusLine.java
===================================================================
RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestStatusLine.java,v
retrieving revision 1.6
retrieving revision 1.6.2.1
diff -u -r1.6 -r1.6.2.1
--- TestStatusLine.java 7 Feb 2003 04:50:03 -0000 1.6
+++ TestStatusLine.java 19 Oct 2003 18:49:56 -0000 1.6.2.1
@@ -96,6 +96,16 @@
// ----------------------------------------------------------- Test Methods
+ public void testIfStatusLine() throws Exception {
+ assertTrue(StatusLine.startsWithHTTP("HTTP"));
+ assertTrue(StatusLine.startsWithHTTP(" HTTP"));
+ assertTrue(StatusLine.startsWithHTTP("\rHTTP"));
+ assertTrue(StatusLine.startsWithHTTP("\tHTTP"));
+ assertFalse(StatusLine.startsWithHTTP("crap"));
+ assertFalse(StatusLine.startsWithHTTP("HTT"));
+ assertFalse(StatusLine.startsWithHTTP("http"));
+ }
+
public void testSuccess() throws Exception {
//typical status line
statusLine = new StatusLine("HTTP/1.1 200 OK");
@@ -131,6 +141,18 @@
statusLine = new StatusLine("HTTP/1.1 200 OK");
assertEquals(200, statusLine.getStatusCode());
assertEquals("OK", statusLine.getReasonPhrase());
+
+ //this is not strictly valid, but is lienent
+ statusLine = new StatusLine("\rHTTP/1.1 200 OK");
+ assertEquals(200, statusLine.getStatusCode());
+ assertEquals("OK", statusLine.getReasonPhrase());
+ assertEquals("HTTP/1.1", statusLine.getHttpVersion());
+
+ //this is not strictly valid, but is lienent
+ statusLine = new StatusLine(" HTTP/1.1 200 OK");
+ assertEquals(200, statusLine.getStatusCode());
+ assertEquals("OK", statusLine.getReasonPhrase());
+ assertEquals("HTTP/1.1", statusLine.getHttpVersion());
}
public void testFailure() throws Exception {
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org