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