1a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath/* 2a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * Copyright (C) 2013 Square, Inc. 3a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * 4a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * Licensed under the Apache License, Version 2.0 (the "License"); 5a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * you may not use this file except in compliance with the License. 6a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * You may obtain a copy of the License at 7a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * 8a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * http://www.apache.org/licenses/LICENSE-2.0 9a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * 10a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * Unless required by applicable law or agreed to in writing, software 11a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * distributed under the License is distributed on an "AS IS" BASIS, 12a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * See the License for the specific language governing permissions and 14a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * limitations under the License. 15a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath */ 16a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamathpackage com.squareup.okhttp; 17a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 183c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport com.squareup.okhttp.internal.http.OkHeaders; 193c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport java.util.Collections; 20a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamathimport java.util.List; 213c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 22e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static com.squareup.okhttp.internal.http.StatusLine.HTTP_PERM_REDIRECT; 23e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static com.squareup.okhttp.internal.http.StatusLine.HTTP_TEMP_REDIRECT; 24e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static java.net.HttpURLConnection.HTTP_MOVED_PERM; 25e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static java.net.HttpURLConnection.HTTP_MOVED_TEMP; 26e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static java.net.HttpURLConnection.HTTP_MULT_CHOICE; 27e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static java.net.HttpURLConnection.HTTP_PROXY_AUTH; 28e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static java.net.HttpURLConnection.HTTP_SEE_OTHER; 29e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static java.net.HttpURLConnection.HTTP_UNAUTHORIZED; 30a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 31a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath/** 32a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * An HTTP response. Instances of this class are not immutable: the response 33a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * body is a one-shot value that may be consumed only once. All other properties 34a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * are immutable. 35a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath */ 363c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerpublic final class Response { 37a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath private final Request request; 38e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private final Protocol protocol; 39e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private final int code; 40e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private final String message; 413c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private final Handshake handshake; 423c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private final Headers headers; 43e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private final ResponseBody body; 44f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller private Response networkResponse; 45f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller private Response cacheResponse; 46f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller private final Response priorResponse; 47a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 483c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private volatile CacheControl cacheControl; // Lazily initialized. 493c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 50a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath private Response(Builder builder) { 51a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath this.request = builder.request; 52e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller this.protocol = builder.protocol; 53e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller this.code = builder.code; 54e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller this.message = builder.message; 553c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller this.handshake = builder.handshake; 563c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller this.headers = builder.headers.build(); 57a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath this.body = builder.body; 58f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller this.networkResponse = builder.networkResponse; 59f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller this.cacheResponse = builder.cacheResponse; 60f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller this.priorResponse = builder.priorResponse; 61a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 62a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 63a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath /** 64e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * The wire-level request that initiated this HTTP response. This is not 65e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * necessarily the same request issued by the application: 66a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * <ul> 67a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * <li>It may be transformed by the HTTP client. For example, the client 68e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * may copy headers like {@code Content-Length} from the request body. 69e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * <li>It may be the request generated in response to an HTTP redirect or 70e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * authentication challenge. In this case the request URL may be 71e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * different than the initial request URL. 72a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * </ul> 73a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath */ 74a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath public Request request() { 75a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath return request; 76a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 77a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 78e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** 79e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Returns the HTTP protocol, such as {@link Protocol#HTTP_1_1} or {@link 80e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Protocol#HTTP_1_0}. 81e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 82e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public Protocol protocol() { 83e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return protocol; 843c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 853c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 86e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** Returns the HTTP status code. */ 87a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath public int code() { 88e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return code; 89a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 90a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 91e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** 92e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Returns true if the code is in [200..300), which means the request was 93e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * successfully received, understood, and accepted. 94e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 95e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public boolean isSuccessful() { 96e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return code >= 200 && code < 300; 97a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 98a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 99e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** Returns the HTTP status message or null if it is unknown. */ 100e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public String message() { 101e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return message; 102a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 103a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 1043c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller /** 1053c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Returns the TLS handshake of the connection that carried this response, or 1063c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * null if the response was received without TLS. 1073c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller */ 1083c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public Handshake handshake() { 1093c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return handshake; 110a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 111a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 1123c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public List<String> headers(String name) { 1133c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return headers.values(name); 114a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 115a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 1163c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public String header(String name) { 1173c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return header(name, null); 118a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 119a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 1203c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public String header(String name, String defaultValue) { 1213c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller String result = headers.get(name); 1223c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return result != null ? result : defaultValue; 123a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 124a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 1253c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public Headers headers() { 1263c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return headers; 127a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 128a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 129e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public ResponseBody body() { 130a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath return body; 131a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 132a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 1333c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public Builder newBuilder() { 1343c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return new Builder(this); 1353c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1363c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 137e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** Returns true if this response redirects to another resource. */ 138e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public boolean isRedirect() { 139e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller switch (code) { 140e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller case HTTP_PERM_REDIRECT: 141e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller case HTTP_TEMP_REDIRECT: 142e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller case HTTP_MULT_CHOICE: 143e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller case HTTP_MOVED_PERM: 144e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller case HTTP_MOVED_TEMP: 145e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller case HTTP_SEE_OTHER: 146e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return true; 147e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller default: 148e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return false; 149e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 150f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller } 151f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller 152f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller /** 153f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller * Returns the raw response received from the network. Will be null if this 154f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller * response didn't use the network, such as when the response is fully cached. 155f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller * The body of the returned response should not be read. 156f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller */ 157f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller public Response networkResponse() { 158f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller return networkResponse; 159f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller } 160f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller 161f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller /** 162f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller * Returns the raw response received from the cache. Will be null if this 163f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller * response didn't use the cache. For conditional get requests the cache 164f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller * response and network response may both be non-null. The body of the 165f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller * returned response should not be read. 166f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller */ 167f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller public Response cacheResponse() { 168f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller return cacheResponse; 169a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 170a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 1713c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller /** 172e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Returns the response for the HTTP redirect or authorization challenge that 173e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * triggered this response, or null if this response wasn't triggered by an 174e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * automatic retry. The body of the returned response should not be read 175e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * because it has already been consumed by the redirecting client. 1763c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller */ 177e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public Response priorResponse() { 178e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return priorResponse; 1793c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1803c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1813c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller /** 182e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Returns the authorization challenges appropriate for this response's code. 183e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * If the response code is 401 unauthorized, this returns the 184e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * "WWW-Authenticate" challenges. If the response code is 407 proxy 185e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * unauthorized, this returns the "Proxy-Authenticate" challenges. Otherwise 186e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * this returns an empty list of challenges. 1873c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller */ 188e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public List<Challenge> challenges() { 189e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller String responseField; 190e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller if (code == HTTP_UNAUTHORIZED) { 191e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller responseField = "WWW-Authenticate"; 192e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } else if (code == HTTP_PROXY_AUTH) { 193e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller responseField = "Proxy-Authenticate"; 194e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } else { 195e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return Collections.emptyList(); 196a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 197e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return OkHeaders.parseChallenges(headers(), responseField); 1983c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1993c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 2003c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller /** 2013c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Returns the cache control directives for this response. This is never null, 2023c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * even if this response contains no {@code Cache-Control} header. 2033c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller */ 2043c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public CacheControl cacheControl() { 2053c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller CacheControl result = cacheControl; 2063c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return result != null ? result : (cacheControl = CacheControl.parse(headers)); 2073c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 2083c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 209e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Override public String toString() { 210e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return "Response{protocol=" 211e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller + protocol 212e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller + ", code=" 213e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller + code 214e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller + ", message=" 215e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller + message 216e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller + ", url=" 217e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller + request.urlString() 218e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller + '}'; 219a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 220a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 221a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath public static class Builder { 2223c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private Request request; 223e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private Protocol protocol; 224e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private int code = -1; 225e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private String message; 2263c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private Handshake handshake; 2273c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private Headers.Builder headers; 228e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private ResponseBody body; 229f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller private Response networkResponse; 230f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller private Response cacheResponse; 231f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller private Response priorResponse; 232a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 2333c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public Builder() { 2343c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller headers = new Headers.Builder(); 2353c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 2363c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 2373c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private Builder(Response response) { 2383c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller this.request = response.request; 239e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller this.protocol = response.protocol; 240e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller this.code = response.code; 241e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller this.message = response.message; 2423c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller this.handshake = response.handshake; 2433c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller this.headers = response.headers.newBuilder(); 2443c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller this.body = response.body; 245f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller this.networkResponse = response.networkResponse; 246f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller this.cacheResponse = response.cacheResponse; 247f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller this.priorResponse = response.priorResponse; 2483c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 2493c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 2503c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public Builder request(Request request) { 251a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath this.request = request; 2523c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return this; 2533c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 2543c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 255e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public Builder protocol(Protocol protocol) { 256e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller this.protocol = protocol; 2573c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return this; 2583c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 2593c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 260e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public Builder code(int code) { 261e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller this.code = code; 262e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return this; 263e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 264e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 265e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public Builder message(String message) { 266e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller this.message = message; 267e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return this; 2683c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 2693c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 2703c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public Builder handshake(Handshake handshake) { 2713c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller this.handshake = handshake; 2723c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return this; 273a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 274a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 275a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath /** 276a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * Sets the header named {@code name} to {@code value}. If this request 277a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * already has any headers with that name, they are all replaced. 278a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath */ 279a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath public Builder header(String name, String value) { 280a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath headers.set(name, value); 281a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath return this; 282a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 283a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 284a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath /** 285a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * Adds a header with {@code name} and {@code value}. Prefer this method for 286a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath * multiply-valued headers like "Set-Cookie". 287a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath */ 288a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath public Builder addHeader(String name, String value) { 289a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath headers.add(name, value); 290a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath return this; 291a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 292a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 2933c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public Builder removeHeader(String name) { 2943c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller headers.removeAll(name); 2953c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return this; 2963c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 2973c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 2983c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller /** Removes all headers on this builder and adds {@code headers}. */ 2993c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller public Builder headers(Headers headers) { 3003c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller this.headers = headers.newBuilder(); 3013c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return this; 3023c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 3033c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 304e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller public Builder body(ResponseBody body) { 305a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath this.body = body; 306a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath return this; 307a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 308a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 309f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller public Builder networkResponse(Response networkResponse) { 310f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller if (networkResponse != null) checkSupportResponse("networkResponse", networkResponse); 311f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller this.networkResponse = networkResponse; 312f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller return this; 313f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller } 314f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller 315f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller public Builder cacheResponse(Response cacheResponse) { 316f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller if (cacheResponse != null) checkSupportResponse("cacheResponse", cacheResponse); 317f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller this.cacheResponse = cacheResponse; 318f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller return this; 319f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller } 320f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller 321f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller private void checkSupportResponse(String name, Response response) { 322f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller if (response.body != null) { 323f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller throw new IllegalArgumentException(name + ".body != null"); 324f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller } else if (response.networkResponse != null) { 325f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller throw new IllegalArgumentException(name + ".networkResponse != null"); 326f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller } else if (response.cacheResponse != null) { 327f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller throw new IllegalArgumentException(name + ".cacheResponse != null"); 328f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller } else if (response.priorResponse != null) { 329f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller throw new IllegalArgumentException(name + ".priorResponse != null"); 330f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller } 331f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller } 332f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller 333f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller public Builder priorResponse(Response priorResponse) { 334e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller if (priorResponse != null) checkPriorResponse(priorResponse); 335f6af62d5c9bb5e15649a80ebae973463e8e2dc46Neil Fuller this.priorResponse = priorResponse; 336a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath return this; 337a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 338a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath 339e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private void checkPriorResponse(Response response) { 340e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller if (response.body != null) { 341e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller throw new IllegalArgumentException("priorResponse.body != null"); 342e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 343e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 344e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 345a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath public Response build() { 3463c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller if (request == null) throw new IllegalStateException("request == null"); 347e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller if (protocol == null) throw new IllegalStateException("protocol == null"); 348e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller if (code < 0) throw new IllegalStateException("code < 0: " + code); 349a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath return new Response(this); 350a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 351a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath } 352a82f42bbeedd0b07f3892f3b0efaa8122dc8f264Narayan Kamath} 353