16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Copyright (C) 2013 Square, Inc. 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Licensed under the Apache License, Version 2.0 (the "License"); 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * you may not use this file except in compliance with the License. 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * You may obtain a copy of the License at 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * http://www.apache.org/licenses/LICENSE-2.0 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Unless required by applicable law or agreed to in writing, software 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * distributed under the License is distributed on an "AS IS" BASIS, 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * See the License for the specific language governing permissions and 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * limitations under the License. 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgpackage com.squareup.okhttp; 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgimport com.squareup.okhttp.internal.Platform; 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgimport com.squareup.okhttp.internal.Util; 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgimport java.io.File; 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgimport java.io.FileInputStream; 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgimport java.io.IOException; 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgimport java.io.InputStream; 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgimport java.io.UnsupportedEncodingException; 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgimport java.net.MalformedURLException; 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgimport java.net.URI; 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgimport java.net.URISyntaxException; 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgimport java.net.URL; 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgimport java.util.List; 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgimport okio.BufferedSink; 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * An HTTP request. Instances of this class are immutable if their {@link #body} 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * is null or itself immutable. 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgpublic final class Request { 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private final URL url; 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private final String method; 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private final Headers headers; 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private final Body body; 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private final Object tag; 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private volatile ParsedHeaders parsedHeaders; // Lazily initialized. 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private volatile URI uri; // Lazily initialized. 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private volatile CacheControl cacheControl; // Lazily initialized. 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private Request(Builder builder) { 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.url = builder.url; 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.method = builder.method; 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.headers = builder.headers.build(); 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.body = builder.body; 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.tag = builder.tag != null ? builder.tag : this; 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public URL url() { 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return url; 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public URI uri() throws IOException { 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org try { 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URI result = uri; 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result != null ? result : (uri = Platform.get().toUriLenient(url)); 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } catch (URISyntaxException e) { 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org throw new IOException(e.getMessage()); 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public String urlString() { 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return url.toString(); 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public String method() { 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return method; 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Headers headers() { 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return headers; 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public String header(String name) { 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return headers.get(name); 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public List<String> headers(String name) { 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return headers.values(name); 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Body body() { 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return body; 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Object tag() { 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return tag; 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Builder newBuilder() { 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return new Builder(this); 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Headers getHeaders() { 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return headers; 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public String getUserAgent() { 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return parsedHeaders().userAgent; 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public String getProxyAuthorization() { 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return parsedHeaders().proxyAuthorization; 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private ParsedHeaders parsedHeaders() { 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ParsedHeaders result = parsedHeaders; 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result != null ? result : (parsedHeaders = new ParsedHeaders(headers)); 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /** 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Returns the cache control directives for this response. This is never null, 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * even if this response contains no {@code Cache-Control} header. 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public CacheControl cacheControl() { 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org CacheControl result = cacheControl; 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result != null ? result : (cacheControl = CacheControl.parse(headers)); 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public boolean isHttps() { 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return url().getProtocol().equals("https"); 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /** Parsed request headers, computed on-demand and cached. */ 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private static class ParsedHeaders { 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private String userAgent; 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private String proxyAuthorization; 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public ParsedHeaders(Headers headers) { 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int i = 0; i < headers.size(); i++) { 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org String fieldName = headers.name(i); 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org String value = headers.value(i); 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ("User-Agent".equalsIgnoreCase(fieldName)) { 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org userAgent = value; 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if ("Proxy-Authorization".equalsIgnoreCase(fieldName)) { 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org proxyAuthorization = value; 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public abstract static class Body { 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /** Returns the Content-Type header for this body. */ 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public abstract MediaType contentType(); 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /** 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Returns the number of bytes that will be written to {@code out} in a call 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * to {@link #writeTo}, or -1 if that count is unknown. 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public long contentLength() { 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /** Writes the content of this request to {@code out}. */ 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public abstract void writeTo(BufferedSink sink) throws IOException; 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /** 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Returns a new request body that transmits {@code content}. If {@code 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * contentType} lacks a charset, this will use UTF-8. 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public static Body create(MediaType contentType, String content) { 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org contentType = contentType.charset() != null 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ? contentType 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org : MediaType.parse(contentType + "; charset=utf-8"); 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org try { 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org byte[] bytes = content.getBytes(contentType.charset().name()); 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return create(contentType, bytes); 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } catch (UnsupportedEncodingException e) { 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org throw new AssertionError(); 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /** Returns a new request body that transmits {@code content}. */ 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public static Body create(final MediaType contentType, final byte[] content) { 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (contentType == null) throw new NullPointerException("contentType == null"); 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (content == null) throw new NullPointerException("content == null"); 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return new Body() { 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org @Override public MediaType contentType() { 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return contentType; 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org @Override public long contentLength() { 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return content.length; 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org @Override public void writeTo(BufferedSink sink) throws IOException { 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sink.write(content); 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }; 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /** Returns a new request body that transmits the content of {@code file}. */ 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public static Body create(final MediaType contentType, final File file) { 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (contentType == null) throw new NullPointerException("contentType == null"); 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (file == null) throw new NullPointerException("content == null"); 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return new Body() { 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org @Override public MediaType contentType() { 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return contentType; 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org @Override public long contentLength() { 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return file.length(); 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org @Override public void writeTo(BufferedSink sink) throws IOException { 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org long length = contentLength(); 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (length == 0) return; 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org InputStream in = null; 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org try { 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org in = new FileInputStream(file); 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org byte[] buffer = new byte[(int) Math.min(8192, length)]; 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int c; (c = in.read(buffer)) != -1; ) { 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sink.write(buffer, 0, c); 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } finally { 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Util.closeQuietly(in); 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }; 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public static class Builder { 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private URL url; 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private String method; 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private Headers.Builder headers; 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private Body body; 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private Object tag; 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Builder() { 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.method = "GET"; 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.headers = new Headers.Builder(); 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private Builder(Request request) { 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.url = request.url; 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.method = request.method; 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.body = request.body; 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.tag = request.tag; 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.headers = request.headers.newBuilder(); 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Builder url(String url) { 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org try { 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return url(new URL(url)); 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } catch (MalformedURLException e) { 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org throw new IllegalArgumentException("Malformed URL: " + url); 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Builder url(URL url) { 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (url == null) throw new IllegalArgumentException("url == null"); 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.url = url; 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return this; 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /** 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Sets the header named {@code name} to {@code value}. If this request 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * already has any headers with that name, they are all replaced. 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Builder header(String name, String value) { 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org headers.set(name, value); 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return this; 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /** 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Adds a header with {@code name} and {@code value}. Prefer this method for 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * multiply-valued headers like "Cookie". 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Builder addHeader(String name, String value) { 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org headers.add(name, value); 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return this; 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Builder removeHeader(String name) { 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org headers.removeAll(name); 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return this; 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /** Removes all headers on this builder and adds {@code headers}. */ 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Builder headers(Headers headers) { 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.headers = headers.newBuilder(); 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return this; 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Builder setUserAgent(String userAgent) { 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return header("User-Agent", userAgent); 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Builder get() { 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return method("GET", null); 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Builder head() { 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return method("HEAD", null); 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Builder post(Body body) { 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return method("POST", body); 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Builder put(Body body) { 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return method("PUT", body); 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Builder method(String method, Body body) { 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (method == null || method.length() == 0) { 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org throw new IllegalArgumentException("method == null || method.length() == 0"); 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.method = method; 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.body = body; 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return this; 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /** 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Attaches {@code tag} to the request. It can be used later to cancel the 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * request. If the tag is unspecified or null, the request is canceled by 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * using the request itself as the tag. 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Builder tag(Object tag) { 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this.tag = tag; 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return this; 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public Request build() { 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (url == null) throw new IllegalStateException("url == null"); 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return new Request(this); 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org