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