Home | History | Annotate | Download | only in http
      1 package com.squareup.okhttp.internal.http;
      2 
      3 import com.squareup.okhttp.Protocol;
      4 import com.squareup.okhttp.Response;
      5 import java.io.IOException;
      6 import java.net.ProtocolException;
      7 
      8 /** An HTTP response status line like "HTTP/1.1 200 OK". */
      9 public final class StatusLine {
     10   /** Numeric status code, 307: Temporary Redirect. */
     11   public static final int HTTP_TEMP_REDIRECT = 307;
     12   public static final int HTTP_PERM_REDIRECT = 308;
     13   public static final int HTTP_CONTINUE = 100;
     14 
     15   public final Protocol protocol;
     16   public final int code;
     17   public final String message;
     18 
     19   public StatusLine(Protocol protocol, int code, String message) {
     20     this.protocol = protocol;
     21     this.code = code;
     22     this.message = message;
     23   }
     24 
     25   public static StatusLine get(Response response) {
     26     return new StatusLine(response.protocol(), response.code(), response.message());
     27   }
     28 
     29   public static StatusLine parse(String statusLine) throws IOException {
     30     // H T T P / 1 . 1   2 0 0   T e m p o r a r y   R e d i r e c t
     31     // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
     32 
     33     // Parse protocol like "HTTP/1.1" followed by a space.
     34     int codeStart;
     35     Protocol protocol;
     36     if (statusLine.startsWith("HTTP/1.")) {
     37       if (statusLine.length() < 9 || statusLine.charAt(8) != ' ') {
     38         throw new ProtocolException("Unexpected status line: " + statusLine);
     39       }
     40       int httpMinorVersion = statusLine.charAt(7) - '0';
     41       codeStart = 9;
     42       if (httpMinorVersion == 0) {
     43         protocol = Protocol.HTTP_1_0;
     44       } else if (httpMinorVersion == 1) {
     45         protocol = Protocol.HTTP_1_1;
     46       } else {
     47         throw new ProtocolException("Unexpected status line: " + statusLine);
     48       }
     49     } else if (statusLine.startsWith("ICY ")) {
     50       // Shoutcast uses ICY instead of "HTTP/1.0".
     51       protocol = Protocol.HTTP_1_0;
     52       codeStart = 4;
     53     } else {
     54       throw new ProtocolException("Unexpected status line: " + statusLine);
     55     }
     56 
     57     // Parse response code like "200". Always 3 digits.
     58     if (statusLine.length() < codeStart + 3) {
     59       throw new ProtocolException("Unexpected status line: " + statusLine);
     60     }
     61     int code;
     62     try {
     63       code = Integer.parseInt(statusLine.substring(codeStart, codeStart + 3));
     64     } catch (NumberFormatException e) {
     65       throw new ProtocolException("Unexpected status line: " + statusLine);
     66     }
     67 
     68     // Parse an optional response message like "OK" or "Not Modified". If it
     69     // exists, it is separated from the response code by a space.
     70     String message = "";
     71     if (statusLine.length() > codeStart + 3) {
     72       if (statusLine.charAt(codeStart + 3) != ' ') {
     73         throw new ProtocolException("Unexpected status line: " + statusLine);
     74       }
     75       message = statusLine.substring(codeStart + 4);
     76     }
     77 
     78     return new StatusLine(protocol, code, message);
     79   }
     80 
     81   @Override public String toString() {
     82     StringBuilder result = new StringBuilder();
     83     result.append(protocol == Protocol.HTTP_1_0 ? "HTTP/1.0" : "HTTP/1.1");
     84     result.append(' ').append(code);
     85     if (message != null) {
     86       result.append(' ').append(message);
     87     }
     88     return result.toString();
     89   }
     90 }
     91