13c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerpackage com.squareup.okhttp.internal.http; 23c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 33c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport com.squareup.okhttp.Headers; 43c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport com.squareup.okhttp.Request; 53c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport com.squareup.okhttp.Response; 63c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport com.squareup.okhttp.internal.Platform; 73c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport java.util.ArrayList; 83c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport java.util.Collections; 93c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport java.util.Comparator; 103c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport java.util.List; 113c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport java.util.Map; 123c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport java.util.TreeMap; 133c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 143c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller/** Headers and utilities for internal use by OkHttp. */ 153c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerpublic final class OkHeaders { 163c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private static final Comparator<String> FIELD_NAME_COMPARATOR = new Comparator<String>() { 173c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller // @FindBugsSuppressWarnings("ES_COMPARING_PARAMETER_STRING_WITH_EQ") 183c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Override public int compare(String a, String b) { 193c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller if (a == b) { 203c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return 0; 213c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } else if (a == null) { 223c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return -1; 233c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } else if (b == null) { 243c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return 1; 253c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } else { 263c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return String.CASE_INSENSITIVE_ORDER.compare(a, b); 273c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 283c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 293c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller }; 303c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 313c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller static final String PREFIX = Platform.get().getPrefix(); 323c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 333c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller /** 343c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Synthetic response header: the local time when the request was sent. 353c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller */ 363c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public static final String SENT_MILLIS = PREFIX + "-Sent-Millis"; 373c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 383c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller /** 393c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Synthetic response header: the local time when the response was received. 403c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller */ 413c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public static final String RECEIVED_MILLIS = PREFIX + "-Received-Millis"; 423c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 433c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller /** 443c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Synthetic response header: the response source and status code like 453c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * "CONDITIONAL_CACHE 304". 463c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller */ 473c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public static final String RESPONSE_SOURCE = PREFIX + "-Response-Source"; 483c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 493c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller /** 503c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Synthetic response header: the selected 513c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * {@link com.squareup.okhttp.Protocol protocol} ("spdy/3.1", "http/1.1", etc). 523c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller */ 533c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public static final String SELECTED_PROTOCOL = PREFIX + "-Selected-Protocol"; 543c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 553c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private OkHeaders() { 563c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 573c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 583c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public static long contentLength(Request request) { 593c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return contentLength(request.headers()); 603c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 613c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 623c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public static long contentLength(Response response) { 633c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return contentLength(response.headers()); 643c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 653c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 663c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public static long contentLength(Headers headers) { 673c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return stringToLong(headers.get("Content-Length")); 683c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 693c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 703c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private static long stringToLong(String s) { 713c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller if (s == null) return -1; 723c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller try { 733c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return Long.parseLong(s); 743c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } catch (NumberFormatException e) { 753c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return -1; 763c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 773c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 783c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 793c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller /** 803c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Returns an immutable map containing each field to its list of values. 813c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * 823c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * @param valueForNullKey the request line for requests, or the status line 833c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * for responses. If non-null, this value is mapped to the null key. 843c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller */ 853c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public static Map<String, List<String>> toMultimap(Headers headers, String valueForNullKey) { 863c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Map<String, List<String>> result = new TreeMap<String, List<String>>(FIELD_NAME_COMPARATOR); 873c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller for (int i = 0; i < headers.size(); i++) { 883c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller String fieldName = headers.name(i); 893c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller String value = headers.value(i); 903c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 913c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller List<String> allValues = new ArrayList<String>(); 923c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller List<String> otherValues = result.get(fieldName); 933c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller if (otherValues != null) { 943c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller allValues.addAll(otherValues); 953c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 963c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller allValues.add(value); 973c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller result.put(fieldName, Collections.unmodifiableList(allValues)); 983c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 993c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller if (valueForNullKey != null) { 1003c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller result.put(null, Collections.unmodifiableList(Collections.singletonList(valueForNullKey))); 1013c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1023c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return Collections.unmodifiableMap(result); 1033c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1043c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1053c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public static void addCookies(Request.Builder builder, Map<String, List<String>> cookieHeaders) { 1063c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller for (Map.Entry<String, List<String>> entry : cookieHeaders.entrySet()) { 1073c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller String key = entry.getKey(); 1083c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller if (("Cookie".equalsIgnoreCase(key) || "Cookie2".equalsIgnoreCase(key)) 1093c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller && !entry.getValue().isEmpty()) { 1103c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller builder.addHeader(key, buildCookieHeader(entry.getValue())); 1113c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1123c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1133c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1143c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1153c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller /** 1163c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Send all cookies in one big header, as recommended by 1173c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * <a href="http://tools.ietf.org/html/rfc6265#section-4.2.1">RFC 6265</a>. 1183c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller */ 1193c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private static String buildCookieHeader(List<String> cookies) { 1203c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller if (cookies.size() == 1) return cookies.get(0); 1213c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller StringBuilder sb = new StringBuilder(); 1223c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller for (int i = 0; i < cookies.size(); i++) { 1233c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller if (i > 0) sb.append("; "); 1243c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller sb.append(cookies.get(i)); 1253c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1263c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return sb.toString(); 1273c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1283c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller} 129