You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by fi...@apache.org on 2013/06/12 19:15:58 UTC

[42/56] [abbrv] [partial] start of lazy loading: axe all vendored-in libs

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/AbstractHttpInputStream.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/AbstractHttpInputStream.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/AbstractHttpInputStream.java
deleted file mode 100644
index 187f3b6..0000000
--- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/AbstractHttpInputStream.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.squareup.okhttp.internal.http;
-
-import com.squareup.okhttp.internal.Util;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.CacheRequest;
-
-/**
- * An input stream for the body of an HTTP response.
- *
- * <p>Since a single socket's input stream may be used to read multiple HTTP
- * responses from the same server, subclasses shouldn't close the socket stream.
- *
- * <p>A side effect of reading an HTTP response is that the response cache
- * is populated. If the stream is closed early, that cache entry will be
- * invalidated.
- */
-abstract class AbstractHttpInputStream extends InputStream {
-  protected final InputStream in;
-  protected final HttpEngine httpEngine;
-  private final CacheRequest cacheRequest;
-  private final OutputStream cacheBody;
-  protected boolean closed;
-
-  AbstractHttpInputStream(InputStream in, HttpEngine httpEngine, CacheRequest cacheRequest)
-      throws IOException {
-    this.in = in;
-    this.httpEngine = httpEngine;
-
-    OutputStream cacheBody = cacheRequest != null ? cacheRequest.getBody() : null;
-
-    // some apps return a null body; for compatibility we treat that like a null cache request
-    if (cacheBody == null) {
-      cacheRequest = null;
-    }
-
-    this.cacheBody = cacheBody;
-    this.cacheRequest = cacheRequest;
-  }
-
-  /**
-   * read() is implemented using read(byte[], int, int) so subclasses only
-   * need to override the latter.
-   */
-  @Override public final int read() throws IOException {
-    return Util.readSingleByte(this);
-  }
-
-  protected final void checkNotClosed() throws IOException {
-    if (closed) {
-      throw new IOException("stream closed");
-    }
-  }
-
-  protected final void cacheWrite(byte[] buffer, int offset, int count) throws IOException {
-    if (cacheBody != null) {
-      cacheBody.write(buffer, offset, count);
-    }
-  }
-
-  /**
-   * Closes the cache entry and makes the socket available for reuse. This
-   * should be invoked when the end of the body has been reached.
-   */
-  protected final void endOfInput(boolean streamCancelled) throws IOException {
-    if (cacheRequest != null) {
-      cacheBody.close();
-    }
-    httpEngine.release(streamCancelled);
-  }
-
-  /**
-   * Calls abort on the cache entry and disconnects the socket. This
-   * should be invoked when the connection is closed unexpectedly to
-   * invalidate the cache entry and to prevent the HTTP connection from
-   * being reused. HTTP messages are sent in serial so whenever a message
-   * cannot be read to completion, subsequent messages cannot be read
-   * either and the connection must be discarded.
-   *
-   * <p>An earlier implementation skipped the remaining bytes, but this
-   * requires that the entire transfer be completed. If the intention was
-   * to cancel the transfer, closing the connection is the only solution.
-   */
-  protected final void unexpectedEndOfInput() {
-    if (cacheRequest != null) {
-      cacheRequest.abort();
-    }
-    httpEngine.release(true);
-  }
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/AbstractHttpOutputStream.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/AbstractHttpOutputStream.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/AbstractHttpOutputStream.java
deleted file mode 100644
index 90675b0..0000000
--- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/AbstractHttpOutputStream.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.squareup.okhttp.internal.http;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * An output stream for the body of an HTTP request.
- *
- * <p>Since a single socket's output stream may be used to write multiple HTTP
- * requests to the same server, subclasses should not close the socket stream.
- */
-abstract class AbstractHttpOutputStream extends OutputStream {
-  protected boolean closed;
-
-  @Override public final void write(int data) throws IOException {
-    write(new byte[] { (byte) data });
-  }
-
-  protected final void checkNotClosed() throws IOException {
-    if (closed) {
-      throw new IOException("stream closed");
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HeaderParser.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HeaderParser.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HeaderParser.java
deleted file mode 100644
index 12e6409..0000000
--- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HeaderParser.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.squareup.okhttp.internal.http;
-
-final class HeaderParser {
-
-  public interface CacheControlHandler {
-    void handle(String directive, String parameter);
-  }
-
-  /** Parse a comma-separated list of cache control header values. */
-  public static void parseCacheControl(String value, CacheControlHandler handler) {
-    int pos = 0;
-    while (pos < value.length()) {
-      int tokenStart = pos;
-      pos = skipUntil(value, pos, "=,");
-      String directive = value.substring(tokenStart, pos).trim();
-
-      if (pos == value.length() || value.charAt(pos) == ',') {
-        pos++; // consume ',' (if necessary)
-        handler.handle(directive, null);
-        continue;
-      }
-
-      pos++; // consume '='
-      pos = skipWhitespace(value, pos);
-
-      String parameter;
-
-      // quoted string
-      if (pos < value.length() && value.charAt(pos) == '\"') {
-        pos++; // consume '"' open quote
-        int parameterStart = pos;
-        pos = skipUntil(value, pos, "\"");
-        parameter = value.substring(parameterStart, pos);
-        pos++; // consume '"' close quote (if necessary)
-
-        // unquoted string
-      } else {
-        int parameterStart = pos;
-        pos = skipUntil(value, pos, ",");
-        parameter = value.substring(parameterStart, pos).trim();
-      }
-
-      handler.handle(directive, parameter);
-    }
-  }
-
-  /**
-   * Returns the next index in {@code input} at or after {@code pos} that
-   * contains a character from {@code characters}. Returns the input length if
-   * none of the requested characters can be found.
-   */
-  public static int skipUntil(String input, int pos, String characters) {
-    for (; pos < input.length(); pos++) {
-      if (characters.indexOf(input.charAt(pos)) != -1) {
-        break;
-      }
-    }
-    return pos;
-  }
-
-  /**
-   * Returns the next non-whitespace character in {@code input} that is white
-   * space. Result is undefined if input contains newline characters.
-   */
-  public static int skipWhitespace(String input, int pos) {
-    for (; pos < input.length(); pos++) {
-      char c = input.charAt(pos);
-      if (c != ' ' && c != '\t') {
-        break;
-      }
-    }
-    return pos;
-  }
-
-  /**
-   * Returns {@code value} as a positive integer, or 0 if it is negative, or
-   * -1 if it cannot be parsed.
-   */
-  public static int parseSeconds(String value) {
-    try {
-      long seconds = Long.parseLong(value);
-      if (seconds > Integer.MAX_VALUE) {
-        return Integer.MAX_VALUE;
-      } else if (seconds < 0) {
-        return 0;
-      } else {
-        return (int) seconds;
-      }
-    } catch (NumberFormatException e) {
-      return -1;
-    }
-  }
-
-  private HeaderParser() {
-  }
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpAuthenticator.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpAuthenticator.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpAuthenticator.java
deleted file mode 100644
index 4ccd12a..0000000
--- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpAuthenticator.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2012 Square, Inc.
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.squareup.okhttp.internal.http;
-
-import com.squareup.okhttp.internal.Base64;
-import java.io.IOException;
-import java.net.Authenticator;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.PasswordAuthentication;
-import java.net.Proxy;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-
-import static java.net.HttpURLConnection.HTTP_PROXY_AUTH;
-import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
-
-/** Handles HTTP authentication headers from origin and proxy servers. */
-public final class HttpAuthenticator {
-  private HttpAuthenticator() {
-  }
-
-  /**
-   * React to a failed authorization response by looking up new credentials.
-   *
-   * @return true if credentials have been added to successorRequestHeaders
-   *         and another request should be attempted.
-   */
-  public static boolean processAuthHeader(int responseCode, RawHeaders responseHeaders,
-      RawHeaders successorRequestHeaders, Proxy proxy, URL url) throws IOException {
-    if (responseCode != HTTP_PROXY_AUTH && responseCode != HTTP_UNAUTHORIZED) {
-      throw new IllegalArgumentException();
-    }
-
-    // Keep asking for username/password until authorized.
-    String challengeHeader =
-        responseCode == HTTP_PROXY_AUTH ? "Proxy-Authenticate" : "WWW-Authenticate";
-    String credentials = getCredentials(responseHeaders, challengeHeader, proxy, url);
-    if (credentials == null) {
-      return false; // Could not find credentials so end the request cycle.
-    }
-
-    // Add authorization credentials, bypassing the already-connected check.
-    String fieldName = responseCode == HTTP_PROXY_AUTH ? "Proxy-Authorization" : "Authorization";
-    successorRequestHeaders.set(fieldName, credentials);
-    return true;
-  }
-
-  /**
-   * Returns the authorization credentials that may satisfy the challenge.
-   * Returns null if a challenge header was not provided or if credentials
-   * were not available.
-   */
-  private static String getCredentials(RawHeaders responseHeaders, String challengeHeader,
-      Proxy proxy, URL url) throws IOException {
-    List<Challenge> challenges = parseChallenges(responseHeaders, challengeHeader);
-    if (challenges.isEmpty()) {
-      return null;
-    }
-
-    for (Challenge challenge : challenges) {
-      // Use the global authenticator to get the password.
-      PasswordAuthentication auth;
-      if (responseHeaders.getResponseCode() == HTTP_PROXY_AUTH) {
-        InetSocketAddress proxyAddress = (InetSocketAddress) proxy.address();
-        auth = Authenticator.requestPasswordAuthentication(proxyAddress.getHostName(),
-            getConnectToInetAddress(proxy, url), proxyAddress.getPort(), url.getProtocol(),
-            challenge.realm, challenge.scheme, url, Authenticator.RequestorType.PROXY);
-      } else {
-        auth = Authenticator.requestPasswordAuthentication(url.getHost(),
-            getConnectToInetAddress(proxy, url), url.getPort(), url.getProtocol(), challenge.realm,
-            challenge.scheme, url, Authenticator.RequestorType.SERVER);
-      }
-      if (auth == null) {
-        continue;
-      }
-
-      // Use base64 to encode the username and password.
-      String usernameAndPassword = auth.getUserName() + ":" + new String(auth.getPassword());
-      byte[] bytes = usernameAndPassword.getBytes("ISO-8859-1");
-      String encoded = Base64.encode(bytes);
-      return challenge.scheme + " " + encoded;
-    }
-
-    return null;
-  }
-
-  private static InetAddress getConnectToInetAddress(Proxy proxy, URL url) throws IOException {
-    return (proxy != null && proxy.type() != Proxy.Type.DIRECT)
-        ? ((InetSocketAddress) proxy.address()).getAddress() : InetAddress.getByName(url.getHost());
-  }
-
-  /**
-   * Parse RFC 2617 challenges. This API is only interested in the scheme
-   * name and realm.
-   */
-  private static List<Challenge> parseChallenges(RawHeaders responseHeaders,
-      String challengeHeader) {
-    // auth-scheme = token
-    // auth-param  = token "=" ( token | quoted-string )
-    // challenge   = auth-scheme 1*SP 1#auth-param
-    // realm       = "realm" "=" realm-value
-    // realm-value = quoted-string
-    List<Challenge> result = new ArrayList<Challenge>();
-    for (int h = 0; h < responseHeaders.length(); h++) {
-      if (!challengeHeader.equalsIgnoreCase(responseHeaders.getFieldName(h))) {
-        continue;
-      }
-      String value = responseHeaders.getValue(h);
-      int pos = 0;
-      while (pos < value.length()) {
-        int tokenStart = pos;
-        pos = HeaderParser.skipUntil(value, pos, " ");
-
-        String scheme = value.substring(tokenStart, pos).trim();
-        pos = HeaderParser.skipWhitespace(value, pos);
-
-        // TODO: This currently only handles schemes with a 'realm' parameter;
-        //       It needs to be fixed to handle any scheme and any parameters
-        //       http://code.google.com/p/android/issues/detail?id=11140
-
-        if (!value.regionMatches(pos, "realm=\"", 0, "realm=\"".length())) {
-          break; // Unexpected challenge parameter; give up!
-        }
-
-        pos += "realm=\"".length();
-        int realmStart = pos;
-        pos = HeaderParser.skipUntil(value, pos, "\"");
-        String realm = value.substring(realmStart, pos);
-        pos++; // Consume '"' close quote.
-        pos = HeaderParser.skipUntil(value, pos, ",");
-        pos++; // Consume ',' comma.
-        pos = HeaderParser.skipWhitespace(value, pos);
-        result.add(new Challenge(scheme, realm));
-      }
-    }
-    return result;
-  }
-
-  /** An RFC 2617 challenge. */
-  private static final class Challenge {
-    final String scheme;
-    final String realm;
-
-    Challenge(String scheme, String realm) {
-      this.scheme = scheme;
-      this.realm = realm;
-    }
-
-    @Override public boolean equals(Object o) {
-      return o instanceof Challenge
-          && ((Challenge) o).scheme.equals(scheme)
-          && ((Challenge) o).realm.equals(realm);
-    }
-
-    @Override public int hashCode() {
-      return scheme.hashCode() + 31 * realm.hashCode();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpDate.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpDate.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpDate.java
deleted file mode 100644
index acb5fda..0000000
--- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpDate.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.squareup.okhttp.internal.http;
-
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-/**
- * Best-effort parser for HTTP dates.
- */
-final class HttpDate {
-
-  /**
-   * Most websites serve cookies in the blessed format. Eagerly create the parser to ensure such
-   * cookies are on the fast path.
-   */
-  private static final ThreadLocal<DateFormat> STANDARD_DATE_FORMAT =
-      new ThreadLocal<DateFormat>() {
-        @Override protected DateFormat initialValue() {
-          DateFormat rfc1123 = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
-          rfc1123.setTimeZone(TimeZone.getTimeZone("UTC"));
-          return rfc1123;
-        }
-      };
-
-  /** If we fail to parse a date in a non-standard format, try each of these formats in sequence. */
-  private static final String[] BROWSER_COMPATIBLE_DATE_FORMATS = new String[] {
-            /* This list comes from  {@code org.apache.http.impl.cookie.BrowserCompatSpec}. */
-      "EEEE, dd-MMM-yy HH:mm:ss zzz", // RFC 1036
-      "EEE MMM d HH:mm:ss yyyy", // ANSI C asctime()
-      "EEE, dd-MMM-yyyy HH:mm:ss z", "EEE, dd-MMM-yyyy HH-mm-ss z", "EEE, dd MMM yy HH:mm:ss z",
-      "EEE dd-MMM-yyyy HH:mm:ss z", "EEE dd MMM yyyy HH:mm:ss z", "EEE dd-MMM-yyyy HH-mm-ss z",
-      "EEE dd-MMM-yy HH:mm:ss z", "EEE dd MMM yy HH:mm:ss z", "EEE,dd-MMM-yy HH:mm:ss z",
-      "EEE,dd-MMM-yyyy HH:mm:ss z", "EEE, dd-MM-yyyy HH:mm:ss z",
-
-            /* RI bug 6641315 claims a cookie of this format was once served by www.yahoo.com */
-      "EEE MMM d yyyy HH:mm:ss z", };
-
-  /**
-   * Returns the date for {@code value}. Returns null if the value couldn't be
-   * parsed.
-   */
-  public static Date parse(String value) {
-    try {
-      return STANDARD_DATE_FORMAT.get().parse(value);
-    } catch (ParseException ignore) {
-    }
-    for (String formatString : BROWSER_COMPATIBLE_DATE_FORMATS) {
-      try {
-        return new SimpleDateFormat(formatString, Locale.US).parse(value);
-      } catch (ParseException ignore) {
-      }
-    }
-    return null;
-  }
-
-  /** Returns the string for {@code value}. */
-  public static String format(Date value) {
-    return STANDARD_DATE_FORMAT.get().format(value);
-  }
-
-  private HttpDate() {
-  }
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpEngine.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpEngine.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpEngine.java
deleted file mode 100644
index 7a06dca..0000000
--- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpEngine.java
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package com.squareup.okhttp.internal.http;
-
-import com.squareup.okhttp.Address;
-import com.squareup.okhttp.Connection;
-import com.squareup.okhttp.ResponseSource;
-import com.squareup.okhttp.TunnelRequest;
-import com.squareup.okhttp.internal.Dns;
-import com.squareup.okhttp.internal.Platform;
-import com.squareup.okhttp.internal.Util;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.CacheRequest;
-import java.net.CacheResponse;
-import java.net.CookieHandler;
-import java.net.Proxy;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.zip.GZIPInputStream;
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLSocketFactory;
-
-import static com.squareup.okhttp.internal.Util.EMPTY_BYTE_ARRAY;
-import static com.squareup.okhttp.internal.Util.getDefaultPort;
-import static com.squareup.okhttp.internal.Util.getEffectivePort;
-
-/**
- * Handles a single HTTP request/response pair. Each HTTP engine follows this
- * lifecycle:
- * <ol>
- * <li>It is created.
- * <li>The HTTP request message is sent with sendRequest(). Once the request
- * is sent it is an error to modify the request headers. After
- * sendRequest() has been called the request body can be written to if
- * it exists.
- * <li>The HTTP response message is read with readResponse(). After the
- * response has been read the response headers and body can be read.
- * All responses have a response body input stream, though in some
- * instances this stream is empty.
- * </ol>
- *
- * <p>The request and response may be served by the HTTP response cache, by the
- * network, or by both in the event of a conditional GET.
- *
- * <p>This class may hold a socket connection that needs to be released or
- * recycled. By default, this socket connection is held when the last byte of
- * the response is consumed. To release the connection when it is no longer
- * required, use {@link #automaticallyReleaseConnectionToPool()}.
- */
-public class HttpEngine {
-  private static final CacheResponse GATEWAY_TIMEOUT_RESPONSE = new CacheResponse() {
-    @Override public Map<String, List<String>> getHeaders() throws IOException {
-      Map<String, List<String>> result = new HashMap<String, List<String>>();
-      result.put(null, Collections.singletonList("HTTP/1.1 504 Gateway Timeout"));
-      return result;
-    }
-    @Override public InputStream getBody() throws IOException {
-      return new ByteArrayInputStream(EMPTY_BYTE_ARRAY);
-    }
-  };
-  public static final int HTTP_CONTINUE = 100;
-
-  protected final HttpURLConnectionImpl policy;
-
-  protected final String method;
-
-  private ResponseSource responseSource;
-
-  protected Connection connection;
-  protected RouteSelector routeSelector;
-  private OutputStream requestBodyOut;
-
-  private Transport transport;
-
-  private InputStream responseTransferIn;
-  private InputStream responseBodyIn;
-
-  private CacheResponse cacheResponse;
-  private CacheRequest cacheRequest;
-
-  /** The time when the request headers were written, or -1 if they haven't been written yet. */
-  long sentRequestMillis = -1;
-
-  /**
-   * True if this client added an "Accept-Encoding: gzip" header field and is
-   * therefore responsible for also decompressing the transfer stream.
-   */
-  private boolean transparentGzip;
-
-  final URI uri;
-
-  final RequestHeaders requestHeaders;
-
-  /** Null until a response is received from the network or the cache. */
-  ResponseHeaders responseHeaders;
-
-  // The cache response currently being validated on a conditional get. Null
-  // if the cached response doesn't exist or doesn't need validation. If the
-  // conditional get succeeds, these will be used for the response headers and
-  // body. If it fails, these be closed and set to null.
-  private ResponseHeaders cachedResponseHeaders;
-  private InputStream cachedResponseBody;
-
-  /**
-   * True if the socket connection should be released to the connection pool
-   * when the response has been fully read.
-   */
-  private boolean automaticallyReleaseConnectionToPool;
-
-  /** True if the socket connection is no longer needed by this engine. */
-  private boolean connectionReleased;
-
-  /**
-   * @param requestHeaders the client's supplied request headers. This class
-   * creates a private copy that it can mutate.
-   * @param connection the connection used for an intermediate response
-   * immediately prior to this request/response pair, such as a same-host
-   * redirect. This engine assumes ownership of the connection and must
-   * release it when it is unneeded.
-   */
-  public HttpEngine(HttpURLConnectionImpl policy, String method, RawHeaders requestHeaders,
-      Connection connection, RetryableOutputStream requestBodyOut) throws IOException {
-    this.policy = policy;
-    this.method = method;
-    this.connection = connection;
-    this.requestBodyOut = requestBodyOut;
-
-    try {
-      uri = Platform.get().toUriLenient(policy.getURL());
-    } catch (URISyntaxException e) {
-      throw new IOException(e.getMessage());
-    }
-
-    this.requestHeaders = new RequestHeaders(uri, new RawHeaders(requestHeaders));
-  }
-
-  public URI getUri() {
-    return uri;
-  }
-
-  /**
-   * Figures out what the response source will be, and opens a socket to that
-   * source if necessary. Prepares the request headers and gets ready to start
-   * writing the request body if it exists.
-   */
-  public final void sendRequest() throws IOException {
-    if (responseSource != null) {
-      return;
-    }
-
-    prepareRawRequestHeaders();
-    initResponseSource();
-    if (policy.responseCache != null) {
-      policy.responseCache.trackResponse(responseSource);
-    }
-
-    // The raw response source may require the network, but the request
-    // headers may forbid network use. In that case, dispose of the network
-    // response and use a GATEWAY_TIMEOUT response instead, as specified
-    // by http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4.
-    if (requestHeaders.isOnlyIfCached() && responseSource.requiresConnection()) {
-      if (responseSource == ResponseSource.CONDITIONAL_CACHE) {
-        Util.closeQuietly(cachedResponseBody);
-      }
-      this.responseSource = ResponseSource.CACHE;
-      this.cacheResponse = GATEWAY_TIMEOUT_RESPONSE;
-      RawHeaders rawResponseHeaders = RawHeaders.fromMultimap(cacheResponse.getHeaders(), true);
-      setResponse(new ResponseHeaders(uri, rawResponseHeaders), cacheResponse.getBody());
-    }
-
-    if (responseSource.requiresConnection()) {
-      sendSocketRequest();
-    } else if (connection != null) {
-      policy.connectionPool.recycle(connection);
-      policy.getFailedRoutes().remove(connection.getRoute());
-      connection = null;
-    }
-  }
-
-  /**
-   * Initialize the source for this response. It may be corrected later if the
-   * request headers forbids network use.
-   */
-  private void initResponseSource() throws IOException {
-    responseSource = ResponseSource.NETWORK;
-    if (!policy.getUseCaches() || policy.responseCache == null) {
-      return;
-    }
-
-    CacheResponse candidate =
-        policy.responseCache.get(uri, method, requestHeaders.getHeaders().toMultimap(false));
-    if (candidate == null) {
-      return;
-    }
-
-    Map<String, List<String>> responseHeadersMap = candidate.getHeaders();
-    cachedResponseBody = candidate.getBody();
-    if (!acceptCacheResponseType(candidate)
-        || responseHeadersMap == null
-        || cachedResponseBody == null) {
-      Util.closeQuietly(cachedResponseBody);
-      return;
-    }
-
-    RawHeaders rawResponseHeaders = RawHeaders.fromMultimap(responseHeadersMap, true);
-    cachedResponseHeaders = new ResponseHeaders(uri, rawResponseHeaders);
-    long now = System.currentTimeMillis();
-    this.responseSource = cachedResponseHeaders.chooseResponseSource(now, requestHeaders);
-    if (responseSource == ResponseSource.CACHE) {
-      this.cacheResponse = candidate;
-      setResponse(cachedResponseHeaders, cachedResponseBody);
-    } else if (responseSource == ResponseSource.CONDITIONAL_CACHE) {
-      this.cacheResponse = candidate;
-    } else if (responseSource == ResponseSource.NETWORK) {
-      Util.closeQuietly(cachedResponseBody);
-    } else {
-      throw new AssertionError();
-    }
-  }
-
-  private void sendSocketRequest() throws IOException {
-    if (connection == null) {
-      connect();
-    }
-
-    if (transport != null) {
-      throw new IllegalStateException();
-    }
-
-    transport = (Transport) connection.newTransport(this);
-
-    if (hasRequestBody() && requestBodyOut == null) {
-      // Create a request body if we don't have one already. We'll already
-      // have one if we're retrying a failed POST.
-      requestBodyOut = transport.createRequestBody();
-    }
-  }
-
-  /** Connect to the origin server either directly or via a proxy. */
-  protected final void connect() throws IOException {
-    if (connection != null) {
-      return;
-    }
-    if (routeSelector == null) {
-      String uriHost = uri.getHost();
-      if (uriHost == null) {
-        throw new UnknownHostException(uri.toString());
-      }
-      SSLSocketFactory sslSocketFactory = null;
-      HostnameVerifier hostnameVerifier = null;
-      if (uri.getScheme().equalsIgnoreCase("https")) {
-        sslSocketFactory = policy.sslSocketFactory;
-        hostnameVerifier = policy.hostnameVerifier;
-      }
-      Address address = new Address(uriHost, getEffectivePort(uri), sslSocketFactory,
-          hostnameVerifier, policy.requestedProxy);
-      routeSelector = new RouteSelector(address, uri, policy.proxySelector, policy.connectionPool,
-          Dns.DEFAULT, policy.getFailedRoutes());
-    }
-    connection = routeSelector.next();
-    if (!connection.isConnected()) {
-      connection.connect(policy.getConnectTimeout(), policy.getReadTimeout(), getTunnelConfig());
-      policy.connectionPool.maybeShare(connection);
-      policy.getFailedRoutes().remove(connection.getRoute());
-    }
-    connected(connection);
-    if (connection.getRoute().getProxy() != policy.requestedProxy) {
-      // Update the request line if the proxy changed; it may need a host name.
-      requestHeaders.getHeaders().setRequestLine(getRequestLine());
-    }
-  }
-
-  /**
-   * Called after a socket connection has been created or retrieved from the
-   * pool. Subclasses use this hook to get a reference to the TLS data.
-   */
-  protected void connected(Connection connection) {
-  }
-
-  /**
-   * Called immediately before the transport transmits HTTP request headers.
-   * This is used to observe the sent time should the request be cached.
-   */
-  public void writingRequestHeaders() {
-    if (sentRequestMillis != -1) {
-      throw new IllegalStateException();
-    }
-    sentRequestMillis = System.currentTimeMillis();
-  }
-
-  /**
-   * @param body the response body, or null if it doesn't exist or isn't
-   * available.
-   */
-  private void setResponse(ResponseHeaders headers, InputStream body) throws IOException {
-    if (this.responseBodyIn != null) {
-      throw new IllegalStateException();
-    }
-    this.responseHeaders = headers;
-    if (body != null) {
-      initContentStream(body);
-    }
-  }
-
-  boolean hasRequestBody() {
-    return method.equals("POST") || method.equals("PUT");
-  }
-
-  /** Returns the request body or null if this request doesn't have a body. */
-  public final OutputStream getRequestBody() {
-    if (responseSource == null) {
-      throw new IllegalStateException();
-    }
-    return requestBodyOut;
-  }
-
-  public final boolean hasResponse() {
-    return responseHeaders != null;
-  }
-
-  public final RequestHeaders getRequestHeaders() {
-    return requestHeaders;
-  }
-
-  public final ResponseHeaders getResponseHeaders() {
-    if (responseHeaders == null) {
-      throw new IllegalStateException();
-    }
-    return responseHeaders;
-  }
-
-  public final int getResponseCode() {
-    if (responseHeaders == null) {
-      throw new IllegalStateException();
-    }
-    return responseHeaders.getHeaders().getResponseCode();
-  }
-
-  public final InputStream getResponseBody() {
-    if (responseHeaders == null) {
-      throw new IllegalStateException();
-    }
-    return responseBodyIn;
-  }
-
-  public final CacheResponse getCacheResponse() {
-    return cacheResponse;
-  }
-
-  public final Connection getConnection() {
-    return connection;
-  }
-
-  /**
-   * Returns true if {@code cacheResponse} is of the right type. This
-   * condition is necessary but not sufficient for the cached response to
-   * be used.
-   */
-  protected boolean acceptCacheResponseType(CacheResponse cacheResponse) {
-    return true;
-  }
-
-  private void maybeCache() throws IOException {
-    // Are we caching at all?
-    if (!policy.getUseCaches() || policy.responseCache == null) {
-      return;
-    }
-
-    // Should we cache this response for this request?
-    if (!responseHeaders.isCacheable(requestHeaders)) {
-      return;
-    }
-
-    // Offer this request to the cache.
-    cacheRequest = policy.responseCache.put(uri, policy.getHttpConnectionToCache());
-  }
-
-  /**
-   * Cause the socket connection to be released to the connection pool when
-   * it is no longer needed. If it is already unneeded, it will be pooled
-   * immediately. Otherwise the connection is held so that redirects can be
-   * handled by the same connection.
-   */
-  public final void automaticallyReleaseConnectionToPool() {
-    automaticallyReleaseConnectionToPool = true;
-    if (connection != null && connectionReleased) {
-      policy.connectionPool.recycle(connection);
-      connection = null;
-    }
-  }
-
-  /**
-   * Releases this engine so that its resources may be either reused or
-   * closed. Also call {@link #automaticallyReleaseConnectionToPool} unless
-   * the connection will be used to follow a redirect.
-   */
-  public final void release(boolean streamCancelled) {
-    // If the response body comes from the cache, close it.
-    if (responseBodyIn == cachedResponseBody) {
-      Util.closeQuietly(responseBodyIn);
-    }
-
-    if (!connectionReleased && connection != null) {
-      connectionReleased = true;
-
-      if (transport == null || !transport.makeReusable(streamCancelled, requestBodyOut,
-          responseTransferIn)) {
-        Util.closeQuietly(connection);
-        connection = null;
-      } else if (automaticallyReleaseConnectionToPool) {
-        policy.connectionPool.recycle(connection);
-        connection = null;
-      }
-    }
-  }
-
-  private void initContentStream(InputStream transferStream) throws IOException {
-    responseTransferIn = transferStream;
-    if (transparentGzip && responseHeaders.isContentEncodingGzip()) {
-      // If the response was transparently gzipped, remove the gzip header field
-      // so clients don't double decompress. http://b/3009828
-      //
-      // Also remove the Content-Length in this case because it contains the
-      // length 528 of the gzipped response. This isn't terribly useful and is
-      // dangerous because 529 clients can query the content length, but not
-      // the content encoding.
-      responseHeaders.stripContentEncoding();
-      responseHeaders.stripContentLength();
-      responseBodyIn = new GZIPInputStream(transferStream);
-    } else {
-      responseBodyIn = transferStream;
-    }
-  }
-
-  /**
-   * Returns true if the response must have a (possibly 0-length) body.
-   * See RFC 2616 section 4.3.
-   */
-  public final boolean hasResponseBody() {
-    int responseCode = responseHeaders.getHeaders().getResponseCode();
-
-    // HEAD requests never yield a body regardless of the response headers.
-    if (method.equals("HEAD")) {
-      return false;
-    }
-
-    if ((responseCode < HTTP_CONTINUE || responseCode >= 200)
-        && responseCode != HttpURLConnectionImpl.HTTP_NO_CONTENT
-        && responseCode != HttpURLConnectionImpl.HTTP_NOT_MODIFIED) {
-      return true;
-    }
-
-    // If the Content-Length or Transfer-Encoding headers disagree with the
-    // response code, the response is malformed. For best compatibility, we
-    // honor the headers.
-    if (responseHeaders.getContentLength() != -1 || responseHeaders.isChunked()) {
-      return true;
-    }
-
-    return false;
-  }
-
-  /**
-   * Populates requestHeaders with defaults and cookies.
-   *
-   * <p>This client doesn't specify a default {@code Accept} header because it
-   * doesn't know what content types the application is interested in.
-   */
-  private void prepareRawRequestHeaders() throws IOException {
-    requestHeaders.getHeaders().setRequestLine(getRequestLine());
-
-    if (requestHeaders.getUserAgent() == null) {
-      requestHeaders.setUserAgent(getDefaultUserAgent());
-    }
-
-    if (requestHeaders.getHost() == null) {
-      requestHeaders.setHost(getOriginAddress(policy.getURL()));
-    }
-
-    if ((connection == null || connection.getHttpMinorVersion() != 0)
-        && requestHeaders.getConnection() == null) {
-      requestHeaders.setConnection("Keep-Alive");
-    }
-
-    if (requestHeaders.getAcceptEncoding() == null) {
-      transparentGzip = true;
-      requestHeaders.setAcceptEncoding("gzip");
-    }
-
-    if (hasRequestBody() && requestHeaders.getContentType() == null) {
-      requestHeaders.setContentType("application/x-www-form-urlencoded");
-    }
-
-    long ifModifiedSince = policy.getIfModifiedSince();
-    if (ifModifiedSince != 0) {
-      requestHeaders.setIfModifiedSince(new Date(ifModifiedSince));
-    }
-
-    CookieHandler cookieHandler = policy.cookieHandler;
-    if (cookieHandler != null) {
-      requestHeaders.addCookies(
-          cookieHandler.get(uri, requestHeaders.getHeaders().toMultimap(false)));
-    }
-  }
-
-  /**
-   * Returns the request status line, like "GET / HTTP/1.1". This is exposed
-   * to the application by {@link HttpURLConnectionImpl#getHeaderFields}, so
-   * it needs to be set even if the transport is SPDY.
-   */
-  String getRequestLine() {
-    String protocol =
-        (connection == null || connection.getHttpMinorVersion() != 0) ? "HTTP/1.1" : "HTTP/1.0";
-    return method + " " + requestString() + " " + protocol;
-  }
-
-  private String requestString() {
-    URL url = policy.getURL();
-    if (includeAuthorityInRequestLine()) {
-      return url.toString();
-    } else {
-      return requestPath(url);
-    }
-  }
-
-  /**
-   * Returns the path to request, like the '/' in 'GET / HTTP/1.1'. Never
-   * empty, even if the request URL is. Includes the query component if it
-   * exists.
-   */
-  public static String requestPath(URL url) {
-    String fileOnly = url.getFile();
-    if (fileOnly == null) {
-      return "/";
-    } else if (!fileOnly.startsWith("/")) {
-      return "/" + fileOnly;
-    } else {
-      return fileOnly;
-    }
-  }
-
-  /**
-   * Returns true if the request line should contain the full URL with host
-   * and port (like "GET http://android.com/foo HTTP/1.1") or only the path
-   * (like "GET /foo HTTP/1.1").
-   *
-   * <p>This is non-final because for HTTPS it's never necessary to supply the
-   * full URL, even if a proxy is in use.
-   */
-  protected boolean includeAuthorityInRequestLine() {
-    return connection == null
-        ? policy.usingProxy() // A proxy was requested.
-        : connection.getRoute().getProxy().type() == Proxy.Type.HTTP; // A proxy was selected.
-  }
-
-  public static String getDefaultUserAgent() {
-    String agent = System.getProperty("http.agent");
-    return agent != null ? agent : ("Java" + System.getProperty("java.version"));
-  }
-
-  public static String getOriginAddress(URL url) {
-    int port = url.getPort();
-    String result = url.getHost();
-    if (port > 0 && port != getDefaultPort(url.getProtocol())) {
-      result = result + ":" + port;
-    }
-    return result;
-  }
-
-  /**
-   * Flushes the remaining request header and body, parses the HTTP response
-   * headers and starts reading the HTTP response body if it exists.
-   */
-  public final void readResponse() throws IOException {
-    if (hasResponse()) {
-      responseHeaders.setResponseSource(responseSource);
-      return;
-    }
-
-    if (responseSource == null) {
-      throw new IllegalStateException("readResponse() without sendRequest()");
-    }
-
-    if (!responseSource.requiresConnection()) {
-      return;
-    }
-
-    if (sentRequestMillis == -1) {
-      if (requestBodyOut instanceof RetryableOutputStream) {
-        int contentLength = ((RetryableOutputStream) requestBodyOut).contentLength();
-        requestHeaders.setContentLength(contentLength);
-      }
-      transport.writeRequestHeaders();
-    }
-
-    if (requestBodyOut != null) {
-      requestBodyOut.close();
-      if (requestBodyOut instanceof RetryableOutputStream) {
-        transport.writeRequestBody((RetryableOutputStream) requestBodyOut);
-      }
-    }
-
-    transport.flushRequest();
-
-    responseHeaders = transport.readResponseHeaders();
-    responseHeaders.setLocalTimestamps(sentRequestMillis, System.currentTimeMillis());
-    responseHeaders.setResponseSource(responseSource);
-
-    if (responseSource == ResponseSource.CONDITIONAL_CACHE) {
-      if (cachedResponseHeaders.validate(responseHeaders)) {
-        release(false);
-        ResponseHeaders combinedHeaders = cachedResponseHeaders.combine(responseHeaders);
-        setResponse(combinedHeaders, cachedResponseBody);
-        policy.responseCache.trackConditionalCacheHit();
-        policy.responseCache.update(cacheResponse, policy.getHttpConnectionToCache());
-        return;
-      } else {
-        Util.closeQuietly(cachedResponseBody);
-      }
-    }
-
-    if (hasResponseBody()) {
-      maybeCache(); // reentrant. this calls into user code which may call back into this!
-    }
-
-    initContentStream(transport.getTransferStream(cacheRequest));
-  }
-
-  protected TunnelRequest getTunnelConfig() {
-    return null;
-  }
-
-  public void receiveHeaders(RawHeaders headers) throws IOException {
-    CookieHandler cookieHandler = policy.cookieHandler;
-    if (cookieHandler != null) {
-      cookieHandler.put(uri, headers.toMultimap(true));
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpResponseCache.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpResponseCache.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpResponseCache.java
deleted file mode 100644
index 8735166..0000000
--- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpResponseCache.java
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.squareup.okhttp.internal.http;
-
-import com.squareup.okhttp.OkResponseCache;
-import com.squareup.okhttp.ResponseSource;
-import com.squareup.okhttp.internal.Base64;
-import com.squareup.okhttp.internal.DiskLruCache;
-import com.squareup.okhttp.internal.StrictLineReader;
-import com.squareup.okhttp.internal.Util;
-import java.io.BufferedWriter;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FilterInputStream;
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.io.Writer;
-import java.net.CacheRequest;
-import java.net.CacheResponse;
-import java.net.HttpURLConnection;
-import java.net.ResponseCache;
-import java.net.SecureCacheResponse;
-import java.net.URI;
-import java.net.URLConnection;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.Principal;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLPeerUnverifiedException;
-
-import static com.squareup.okhttp.internal.Util.US_ASCII;
-import static com.squareup.okhttp.internal.Util.UTF_8;
-
-/**
- * Cache responses in a directory on the file system. Most clients should use
- * {@code android.net.HttpResponseCache}, the stable, documented front end for
- * this.
- */
-public final class HttpResponseCache extends ResponseCache implements OkResponseCache {
-  private static final char[] DIGITS =
-      { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
-
-  // TODO: add APIs to iterate the cache?
-  private static final int VERSION = 201105;
-  private static final int ENTRY_METADATA = 0;
-  private static final int ENTRY_BODY = 1;
-  private static final int ENTRY_COUNT = 2;
-
-  private final DiskLruCache cache;
-
-  /* read and write statistics, all guarded by 'this' */
-  private int writeSuccessCount;
-  private int writeAbortCount;
-  private int networkCount;
-  private int hitCount;
-  private int requestCount;
-
-  public HttpResponseCache(File directory, long maxSize) throws IOException {
-    cache = DiskLruCache.open(directory, VERSION, ENTRY_COUNT, maxSize);
-  }
-
-  private String uriToKey(URI uri) {
-    try {
-      MessageDigest messageDigest = MessageDigest.getInstance("MD5");
-      byte[] md5bytes = messageDigest.digest(uri.toString().getBytes("UTF-8"));
-      return bytesToHexString(md5bytes);
-    } catch (NoSuchAlgorithmException e) {
-      throw new AssertionError(e);
-    } catch (UnsupportedEncodingException e) {
-      throw new AssertionError(e);
-    }
-  }
-
-  private static String bytesToHexString(byte[] bytes) {
-    char[] digits = DIGITS;
-    char[] buf = new char[bytes.length * 2];
-    int c = 0;
-    for (byte b : bytes) {
-      buf[c++] = digits[(b >> 4) & 0xf];
-      buf[c++] = digits[b & 0xf];
-    }
-    return new String(buf);
-  }
-
-  @Override public CacheResponse get(URI uri, String requestMethod,
-      Map<String, List<String>> requestHeaders) {
-    String key = uriToKey(uri);
-    DiskLruCache.Snapshot snapshot;
-    Entry entry;
-    try {
-      snapshot = cache.get(key);
-      if (snapshot == null) {
-        return null;
-      }
-      entry = new Entry(snapshot.getInputStream(ENTRY_METADATA));
-    } catch (IOException e) {
-      // Give up because the cache cannot be read.
-      return null;
-    }
-
-    if (!entry.matches(uri, requestMethod, requestHeaders)) {
-      snapshot.close();
-      return null;
-    }
-
-    return entry.isHttps() ? new EntrySecureCacheResponse(entry, snapshot)
-        : new EntryCacheResponse(entry, snapshot);
-  }
-
-  @Override public CacheRequest put(URI uri, URLConnection urlConnection) throws IOException {
-    if (!(urlConnection instanceof HttpURLConnection)) {
-      return null;
-    }
-
-    HttpURLConnection httpConnection = (HttpURLConnection) urlConnection;
-    String requestMethod = httpConnection.getRequestMethod();
-    String key = uriToKey(uri);
-
-    if (requestMethod.equals("POST") || requestMethod.equals("PUT") || requestMethod.equals(
-        "DELETE")) {
-      try {
-        cache.remove(key);
-      } catch (IOException ignored) {
-        // The cache cannot be written.
-      }
-      return null;
-    } else if (!requestMethod.equals("GET")) {
-      // Don't cache non-GET responses. We're technically allowed to cache
-      // HEAD requests and some POST requests, but the complexity of doing
-      // so is high and the benefit is low.
-      return null;
-    }
-
-    HttpEngine httpEngine = getHttpEngine(httpConnection);
-    if (httpEngine == null) {
-      // Don't cache unless the HTTP implementation is ours.
-      return null;
-    }
-
-    ResponseHeaders response = httpEngine.getResponseHeaders();
-    if (response.hasVaryAll()) {
-      return null;
-    }
-
-    RawHeaders varyHeaders =
-        httpEngine.getRequestHeaders().getHeaders().getAll(response.getVaryFields());
-    Entry entry = new Entry(uri, varyHeaders, httpConnection);
-    DiskLruCache.Editor editor = null;
-    try {
-      editor = cache.edit(key);
-      if (editor == null) {
-        return null;
-      }
-      entry.writeTo(editor);
-      return new CacheRequestImpl(editor);
-    } catch (IOException e) {
-      abortQuietly(editor);
-      return null;
-    }
-  }
-
-  /**
-   * Handles a conditional request hit by updating the stored cache response
-   * with the headers from {@code httpConnection}. The cached response body is
-   * not updated. If the stored response has changed since {@code
-   * conditionalCacheHit} was returned, this does nothing.
-   */
-  @Override public void update(CacheResponse conditionalCacheHit, HttpURLConnection httpConnection)
-      throws IOException {
-    HttpEngine httpEngine = getHttpEngine(httpConnection);
-    URI uri = httpEngine.getUri();
-    ResponseHeaders response = httpEngine.getResponseHeaders();
-    RawHeaders varyHeaders =
-        httpEngine.getRequestHeaders().getHeaders().getAll(response.getVaryFields());
-    Entry entry = new Entry(uri, varyHeaders, httpConnection);
-    DiskLruCache.Snapshot snapshot = (conditionalCacheHit instanceof EntryCacheResponse)
-        ? ((EntryCacheResponse) conditionalCacheHit).snapshot
-        : ((EntrySecureCacheResponse) conditionalCacheHit).snapshot;
-    DiskLruCache.Editor editor = null;
-    try {
-      editor = snapshot.edit(); // returns null if snapshot is not current
-      if (editor != null) {
-        entry.writeTo(editor);
-        editor.commit();
-      }
-    } catch (IOException e) {
-      abortQuietly(editor);
-    }
-  }
-
-  private void abortQuietly(DiskLruCache.Editor editor) {
-    // Give up because the cache cannot be written.
-    try {
-      if (editor != null) {
-        editor.abort();
-      }
-    } catch (IOException ignored) {
-    }
-  }
-
-  private HttpEngine getHttpEngine(URLConnection httpConnection) {
-    if (httpConnection instanceof HttpURLConnectionImpl) {
-      return ((HttpURLConnectionImpl) httpConnection).getHttpEngine();
-    } else if (httpConnection instanceof HttpsURLConnectionImpl) {
-      return ((HttpsURLConnectionImpl) httpConnection).getHttpEngine();
-    } else {
-      return null;
-    }
-  }
-
-  public DiskLruCache getCache() {
-    return cache;
-  }
-
-  public synchronized int getWriteAbortCount() {
-    return writeAbortCount;
-  }
-
-  public synchronized int getWriteSuccessCount() {
-    return writeSuccessCount;
-  }
-
-  public synchronized void trackResponse(ResponseSource source) {
-    requestCount++;
-
-    switch (source) {
-      case CACHE:
-        hitCount++;
-        break;
-      case CONDITIONAL_CACHE:
-      case NETWORK:
-        networkCount++;
-        break;
-    }
-  }
-
-  public synchronized void trackConditionalCacheHit() {
-    hitCount++;
-  }
-
-  public synchronized int getNetworkCount() {
-    return networkCount;
-  }
-
-  public synchronized int getHitCount() {
-    return hitCount;
-  }
-
-  public synchronized int getRequestCount() {
-    return requestCount;
-  }
-
-  private final class CacheRequestImpl extends CacheRequest {
-    private final DiskLruCache.Editor editor;
-    private OutputStream cacheOut;
-    private boolean done;
-    private OutputStream body;
-
-    public CacheRequestImpl(final DiskLruCache.Editor editor) throws IOException {
-      this.editor = editor;
-      this.cacheOut = editor.newOutputStream(ENTRY_BODY);
-      this.body = new FilterOutputStream(cacheOut) {
-        @Override public void close() throws IOException {
-          synchronized (HttpResponseCache.this) {
-            if (done) {
-              return;
-            }
-            done = true;
-            writeSuccessCount++;
-          }
-          super.close();
-          editor.commit();
-        }
-
-        @Override
-        public void write(byte[] buffer, int offset, int length) throws IOException {
-          // Since we don't override "write(int oneByte)", we can write directly to "out"
-          // and avoid the inefficient implementation from the FilterOutputStream.
-          out.write(buffer, offset, length);
-        }
-      };
-    }
-
-    @Override public void abort() {
-      synchronized (HttpResponseCache.this) {
-        if (done) {
-          return;
-        }
-        done = true;
-        writeAbortCount++;
-      }
-      Util.closeQuietly(cacheOut);
-      try {
-        editor.abort();
-      } catch (IOException ignored) {
-      }
-    }
-
-    @Override public OutputStream getBody() throws IOException {
-      return body;
-    }
-  }
-
-  private static final class Entry {
-    private final String uri;
-    private final RawHeaders varyHeaders;
-    private final String requestMethod;
-    private final RawHeaders responseHeaders;
-    private final String cipherSuite;
-    private final Certificate[] peerCertificates;
-    private final Certificate[] localCertificates;
-
-    /**
-     * Reads an entry from an input stream. A typical entry looks like this:
-     * <pre>{@code
-     *   http://google.com/foo
-     *   GET
-     *   2
-     *   Accept-Language: fr-CA
-     *   Accept-Charset: UTF-8
-     *   HTTP/1.1 200 OK
-     *   3
-     *   Content-Type: image/png
-     *   Content-Length: 100
-     *   Cache-Control: max-age=600
-     * }</pre>
-     *
-     * <p>A typical HTTPS file looks like this:
-     * <pre>{@code
-     *   https://google.com/foo
-     *   GET
-     *   2
-     *   Accept-Language: fr-CA
-     *   Accept-Charset: UTF-8
-     *   HTTP/1.1 200 OK
-     *   3
-     *   Content-Type: image/png
-     *   Content-Length: 100
-     *   Cache-Control: max-age=600
-     *
-     *   AES_256_WITH_MD5
-     *   2
-     *   base64-encoded peerCertificate[0]
-     *   base64-encoded peerCertificate[1]
-     *   -1
-     * }</pre>
-     * The file is newline separated. The first two lines are the URL and
-     * the request method. Next is the number of HTTP Vary request header
-     * lines, followed by those lines.
-     *
-     * <p>Next is the response status line, followed by the number of HTTP
-     * response header lines, followed by those lines.
-     *
-     * <p>HTTPS responses also contain SSL session information. This begins
-     * with a blank line, and then a line containing the cipher suite. Next
-     * is the length of the peer certificate chain. These certificates are
-     * base64-encoded and appear each on their own line. The next line
-     * contains the length of the local certificate chain. These
-     * certificates are also base64-encoded and appear each on their own
-     * line. A length of -1 is used to encode a null array.
-     */
-    public Entry(InputStream in) throws IOException {
-      try {
-        StrictLineReader reader = new StrictLineReader(in, US_ASCII);
-        uri = reader.readLine();
-        requestMethod = reader.readLine();
-        varyHeaders = new RawHeaders();
-        int varyRequestHeaderLineCount = reader.readInt();
-        for (int i = 0; i < varyRequestHeaderLineCount; i++) {
-          varyHeaders.addLine(reader.readLine());
-        }
-
-        responseHeaders = new RawHeaders();
-        responseHeaders.setStatusLine(reader.readLine());
-        int responseHeaderLineCount = reader.readInt();
-        for (int i = 0; i < responseHeaderLineCount; i++) {
-          responseHeaders.addLine(reader.readLine());
-        }
-
-        if (isHttps()) {
-          String blank = reader.readLine();
-          if (!blank.isEmpty()) {
-            throw new IOException("expected \"\" but was \"" + blank + "\"");
-          }
-          cipherSuite = reader.readLine();
-          peerCertificates = readCertArray(reader);
-          localCertificates = readCertArray(reader);
-        } else {
-          cipherSuite = null;
-          peerCertificates = null;
-          localCertificates = null;
-        }
-      } finally {
-        in.close();
-      }
-    }
-
-    public Entry(URI uri, RawHeaders varyHeaders, HttpURLConnection httpConnection)
-        throws IOException {
-      this.uri = uri.toString();
-      this.varyHeaders = varyHeaders;
-      this.requestMethod = httpConnection.getRequestMethod();
-      this.responseHeaders = RawHeaders.fromMultimap(httpConnection.getHeaderFields(), true);
-
-      if (isHttps()) {
-        HttpsURLConnection httpsConnection = (HttpsURLConnection) httpConnection;
-        cipherSuite = httpsConnection.getCipherSuite();
-        Certificate[] peerCertificatesNonFinal = null;
-        try {
-          peerCertificatesNonFinal = httpsConnection.getServerCertificates();
-        } catch (SSLPeerUnverifiedException ignored) {
-        }
-        peerCertificates = peerCertificatesNonFinal;
-        localCertificates = httpsConnection.getLocalCertificates();
-      } else {
-        cipherSuite = null;
-        peerCertificates = null;
-        localCertificates = null;
-      }
-    }
-
-    public void writeTo(DiskLruCache.Editor editor) throws IOException {
-      OutputStream out = editor.newOutputStream(ENTRY_METADATA);
-      Writer writer = new BufferedWriter(new OutputStreamWriter(out, UTF_8));
-
-      writer.write(uri + '\n');
-      writer.write(requestMethod + '\n');
-      writer.write(Integer.toString(varyHeaders.length()) + '\n');
-      for (int i = 0; i < varyHeaders.length(); i++) {
-        writer.write(varyHeaders.getFieldName(i) + ": " + varyHeaders.getValue(i) + '\n');
-      }
-
-      writer.write(responseHeaders.getStatusLine() + '\n');
-      writer.write(Integer.toString(responseHeaders.length()) + '\n');
-      for (int i = 0; i < responseHeaders.length(); i++) {
-        writer.write(responseHeaders.getFieldName(i) + ": " + responseHeaders.getValue(i) + '\n');
-      }
-
-      if (isHttps()) {
-        writer.write('\n');
-        writer.write(cipherSuite + '\n');
-        writeCertArray(writer, peerCertificates);
-        writeCertArray(writer, localCertificates);
-      }
-      writer.close();
-    }
-
-    private boolean isHttps() {
-      return uri.startsWith("https://");
-    }
-
-    private Certificate[] readCertArray(StrictLineReader reader) throws IOException {
-      int length = reader.readInt();
-      if (length == -1) {
-        return null;
-      }
-      try {
-        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
-        Certificate[] result = new Certificate[length];
-        for (int i = 0; i < result.length; i++) {
-          String line = reader.readLine();
-          byte[] bytes = Base64.decode(line.getBytes("US-ASCII"));
-          result[i] = certificateFactory.generateCertificate(new ByteArrayInputStream(bytes));
-        }
-        return result;
-      } catch (CertificateException e) {
-        throw new IOException(e);
-      }
-    }
-
-    private void writeCertArray(Writer writer, Certificate[] certificates) throws IOException {
-      if (certificates == null) {
-        writer.write("-1\n");
-        return;
-      }
-      try {
-        writer.write(Integer.toString(certificates.length) + '\n');
-        for (Certificate certificate : certificates) {
-          byte[] bytes = certificate.getEncoded();
-          String line = Base64.encode(bytes);
-          writer.write(line + '\n');
-        }
-      } catch (CertificateEncodingException e) {
-        throw new IOException(e);
-      }
-    }
-
-    public boolean matches(URI uri, String requestMethod,
-        Map<String, List<String>> requestHeaders) {
-      return this.uri.equals(uri.toString())
-          && this.requestMethod.equals(requestMethod)
-          && new ResponseHeaders(uri, responseHeaders).varyMatches(varyHeaders.toMultimap(false),
-          requestHeaders);
-    }
-  }
-
-  /**
-   * Returns an input stream that reads the body of a snapshot, closing the
-   * snapshot when the stream is closed.
-   */
-  private static InputStream newBodyInputStream(final DiskLruCache.Snapshot snapshot) {
-    return new FilterInputStream(snapshot.getInputStream(ENTRY_BODY)) {
-      @Override public void close() throws IOException {
-        snapshot.close();
-        super.close();
-      }
-    };
-  }
-
-  static class EntryCacheResponse extends CacheResponse {
-    private final Entry entry;
-    private final DiskLruCache.Snapshot snapshot;
-    private final InputStream in;
-
-    public EntryCacheResponse(Entry entry, DiskLruCache.Snapshot snapshot) {
-      this.entry = entry;
-      this.snapshot = snapshot;
-      this.in = newBodyInputStream(snapshot);
-    }
-
-    @Override public Map<String, List<String>> getHeaders() {
-      return entry.responseHeaders.toMultimap(true);
-    }
-
-    @Override public InputStream getBody() {
-      return in;
-    }
-  }
-
-  static class EntrySecureCacheResponse extends SecureCacheResponse {
-    private final Entry entry;
-    private final DiskLruCache.Snapshot snapshot;
-    private final InputStream in;
-
-    public EntrySecureCacheResponse(Entry entry, DiskLruCache.Snapshot snapshot) {
-      this.entry = entry;
-      this.snapshot = snapshot;
-      this.in = newBodyInputStream(snapshot);
-    }
-
-    @Override public Map<String, List<String>> getHeaders() {
-      return entry.responseHeaders.toMultimap(true);
-    }
-
-    @Override public InputStream getBody() {
-      return in;
-    }
-
-    @Override public String getCipherSuite() {
-      return entry.cipherSuite;
-    }
-
-    @Override public List<Certificate> getServerCertificateChain()
-        throws SSLPeerUnverifiedException {
-      if (entry.peerCertificates == null || entry.peerCertificates.length == 0) {
-        throw new SSLPeerUnverifiedException(null);
-      }
-      return Arrays.asList(entry.peerCertificates.clone());
-    }
-
-    @Override public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
-      if (entry.peerCertificates == null || entry.peerCertificates.length == 0) {
-        throw new SSLPeerUnverifiedException(null);
-      }
-      return ((X509Certificate) entry.peerCertificates[0]).getSubjectX500Principal();
-    }
-
-    @Override public List<Certificate> getLocalCertificateChain() {
-      if (entry.localCertificates == null || entry.localCertificates.length == 0) {
-        return null;
-      }
-      return Arrays.asList(entry.localCertificates.clone());
-    }
-
-    @Override public Principal getLocalPrincipal() {
-      if (entry.localCertificates == null || entry.localCertificates.length == 0) {
-        return null;
-      }
-      return ((X509Certificate) entry.localCertificates[0]).getSubjectX500Principal();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpTransport.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpTransport.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpTransport.java
deleted file mode 100644
index f6d77b2..0000000
--- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/http/HttpTransport.java
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.squareup.okhttp.internal.http;
-
-import com.squareup.okhttp.Connection;
-import com.squareup.okhttp.internal.AbstractOutputStream;
-import com.squareup.okhttp.internal.Util;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.CacheRequest;
-import java.net.ProtocolException;
-import java.net.Socket;
-
-import static com.squareup.okhttp.internal.Util.checkOffsetAndCount;
-
-public final class HttpTransport implements Transport {
-  /**
-   * The timeout to use while discarding a stream of input data. Since this is
-   * used for connection reuse, this timeout should be significantly less than
-   * the time it takes to establish a new connection.
-   */
-  private static final int DISCARD_STREAM_TIMEOUT_MILLIS = 100;
-
-  public static final int DEFAULT_CHUNK_LENGTH = 1024;
-
-  private final HttpEngine httpEngine;
-  private final InputStream socketIn;
-  private final OutputStream socketOut;
-
-  /**
-   * This stream buffers the request headers and the request body when their
-   * combined size is less than MAX_REQUEST_BUFFER_LENGTH. By combining them
-   * we can save socket writes, which in turn saves a packet transmission.
-   * This is socketOut if the request size is large or unknown.
-   */
-  private OutputStream requestOut;
-
-  public HttpTransport(HttpEngine httpEngine, OutputStream outputStream, InputStream inputStream) {
-    this.httpEngine = httpEngine;
-    this.socketOut = outputStream;
-    this.requestOut = outputStream;
-    this.socketIn = inputStream;
-  }
-
-  @Override public OutputStream createRequestBody() throws IOException {
-    boolean chunked = httpEngine.requestHeaders.isChunked();
-    if (!chunked
-        && httpEngine.policy.getChunkLength() > 0
-        && httpEngine.connection.getHttpMinorVersion() != 0) {
-      httpEngine.requestHeaders.setChunked();
-      chunked = true;
-    }
-
-    // Stream a request body of unknown length.
-    if (chunked) {
-      int chunkLength = httpEngine.policy.getChunkLength();
-      if (chunkLength == -1) {
-        chunkLength = DEFAULT_CHUNK_LENGTH;
-      }
-      writeRequestHeaders();
-      return new ChunkedOutputStream(requestOut, chunkLength);
-    }
-
-    // Stream a request body of a known length.
-    int fixedContentLength = httpEngine.policy.getFixedContentLength();
-    if (fixedContentLength != -1) {
-      httpEngine.requestHeaders.setContentLength(fixedContentLength);
-      writeRequestHeaders();
-      return new FixedLengthOutputStream(requestOut, fixedContentLength);
-    }
-
-    // Buffer a request body of a known length.
-    int contentLength = httpEngine.requestHeaders.getContentLength();
-    if (contentLength != -1) {
-      writeRequestHeaders();
-      return new RetryableOutputStream(contentLength);
-    }
-
-    // Buffer a request body of an unknown length. Don't write request
-    // headers until the entire body is ready; otherwise we can't set the
-    // Content-Length header correctly.
-    return new RetryableOutputStream();
-  }
-
-  @Override public void flushRequest() throws IOException {
-    requestOut.flush();
-    requestOut = socketOut;
-  }
-
-  @Override public void writeRequestBody(RetryableOutputStream requestBody) throws IOException {
-    requestBody.writeToSocket(requestOut);
-  }
-
-  /**
-   * Prepares the HTTP headers and sends them to the server.
-   *
-   * <p>For streaming requests with a body, headers must be prepared
-   * <strong>before</strong> the output stream has been written to. Otherwise
-   * the body would need to be buffered!
-   *
-   * <p>For non-streaming requests with a body, headers must be prepared
-   * <strong>after</strong> the output stream has been written to and closed.
-   * This ensures that the {@code Content-Length} header field receives the
-   * proper value.
-   */
-  public void writeRequestHeaders() throws IOException {
-    httpEngine.writingRequestHeaders();
-    RawHeaders headersToSend = httpEngine.requestHeaders.getHeaders();
-    byte[] bytes = headersToSend.toBytes();
-    requestOut.write(bytes);
-  }
-
-  @Override public ResponseHeaders readResponseHeaders() throws IOException {
-    RawHeaders headers = RawHeaders.fromBytes(socketIn);
-    httpEngine.connection.setHttpMinorVersion(headers.getHttpMinorVersion());
-    httpEngine.receiveHeaders(headers);
-    return new ResponseHeaders(httpEngine.uri, headers);
-  }
-
-  public boolean makeReusable(boolean streamCancelled, OutputStream requestBodyOut,
-      InputStream responseBodyIn) {
-    if (streamCancelled) {
-      return false;
-    }
-
-    // We cannot reuse sockets that have incomplete output.
-    if (requestBodyOut != null && !((AbstractOutputStream) requestBodyOut).isClosed()) {
-      return false;
-    }
-
-    // If the request specified that the connection shouldn't be reused, don't reuse it.
-    if (httpEngine.requestHeaders.hasConnectionClose()) {
-      return false;
-    }
-
-    // If the response specified that the connection shouldn't be reused, don't reuse it.
-    if (httpEngine.responseHeaders != null && httpEngine.responseHeaders.hasConnectionClose()) {
-      return false;
-    }
-
-    if (responseBodyIn instanceof UnknownLengthHttpInputStream) {
-      return false;
-    }
-
-    if (responseBodyIn != null) {
-      return discardStream(httpEngine, responseBodyIn);
-    }
-
-    return true;
-  }
-
-  /**
-   * Discards the response body so that the connection can be reused. This
-   * needs to be done judiciously, since it delays the current request in
-   * order to speed up a potential future request that may never occur.
-   */
-  private static boolean discardStream(HttpEngine httpEngine, InputStream responseBodyIn) {
-    Connection connection = httpEngine.connection;
-    if (connection == null) return false;
-    Socket socket = connection.getSocket();
-    if (socket == null) return false;
-    try {
-      int socketTimeout = socket.getSoTimeout();
-      socket.setSoTimeout(DISCARD_STREAM_TIMEOUT_MILLIS);
-      try {
-        Util.skipAll(responseBodyIn);
-        return true;
-      } finally {
-        socket.setSoTimeout(socketTimeout);
-      }
-    } catch (IOException e) {
-      return false;
-    }
-  }
-
-  @Override public InputStream getTransferStream(CacheRequest cacheRequest) throws IOException {
-    if (!httpEngine.hasResponseBody()) {
-      return new FixedLengthInputStream(socketIn, cacheRequest, httpEngine, 0);
-    }
-
-    if (httpEngine.responseHeaders.isChunked()) {
-      return new ChunkedInputStream(socketIn, cacheRequest, this);
-    }
-
-    if (httpEngine.responseHeaders.getContentLength() != -1) {
-      return new FixedLengthInputStream(socketIn, cacheRequest, httpEngine,
-          httpEngine.responseHeaders.getContentLength());
-    }
-
-    // Wrap the input stream from the connection (rather than just returning
-    // "socketIn" directly here), so that we can control its use after the
-    // reference escapes.
-    return new UnknownLengthHttpInputStream(socketIn, cacheRequest, httpEngine);
-  }
-
-  /** An HTTP body with a fixed length known in advance. */
-  private static final class FixedLengthOutputStream extends AbstractOutputStream {
-    private final OutputStream socketOut;
-    private int bytesRemaining;
-
-    private FixedLengthOutputStream(OutputStream socketOut, int bytesRemaining) {
-      this.socketOut = socketOut;
-      this.bytesRemaining = bytesRemaining;
-    }
-
-    @Override public void write(byte[] buffer, int offset, int count) throws IOException {
-      checkNotClosed();
-      checkOffsetAndCount(buffer.length, offset, count);
-      if (count > bytesRemaining) {
-        throw new ProtocolException("expected " + bytesRemaining + " bytes but received " + count);
-      }
-      socketOut.write(buffer, offset, count);
-      bytesRemaining -= count;
-    }
-
-    @Override public void flush() throws IOException {
-      if (closed) {
-        return; // don't throw; this stream might have been closed on the caller's behalf
-      }
-      socketOut.flush();
-    }
-
-    @Override public void close() throws IOException {
-      if (closed) {
-        return;
-      }
-      closed = true;
-      if (bytesRemaining > 0) {
-        throw new ProtocolException("unexpected end of stream");
-      }
-    }
-  }
-
-  /**
-   * An HTTP body with alternating chunk sizes and chunk bodies. Chunks are
-   * buffered until {@code maxChunkLength} bytes are ready, at which point the
-   * chunk is written and the buffer is cleared.
-   */
-  private static final class ChunkedOutputStream extends AbstractOutputStream {
-    private static final byte[] CRLF = { '\r', '\n' };
-    private static final byte[] HEX_DIGITS = {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
-    };
-    private static final byte[] FINAL_CHUNK = new byte[] { '0', '\r', '\n', '\r', '\n' };
-
-    /** Scratch space for up to 8 hex digits, and then a constant CRLF. */
-    private final byte[] hex = { 0, 0, 0, 0, 0, 0, 0, 0, '\r', '\n' };
-
-    private final OutputStream socketOut;
-    private final int maxChunkLength;
-    private final ByteArrayOutputStream bufferedChunk;
-
-    private ChunkedOutputStream(OutputStream socketOut, int maxChunkLength) {
-      this.socketOut = socketOut;
-      this.maxChunkLength = Math.max(1, dataLength(maxChunkLength));
-      this.bufferedChunk = new ByteArrayOutputStream(maxChunkLength);
-    }
-
-    /**
-     * Returns the amount of data that can be transmitted in a chunk whose total
-     * length (data+headers) is {@code dataPlusHeaderLength}. This is presumably
-     * useful to match sizes with wire-protocol packets.
-     */
-    private int dataLength(int dataPlusHeaderLength) {
-      int headerLength = 4; // "\r\n" after the size plus another "\r\n" after the data
-      for (int i = dataPlusHeaderLength - headerLength; i > 0; i >>= 4) {
-        headerLength++;
-      }
-      return dataPlusHeaderLength - headerLength;
-    }
-
-    @Override public synchronized void write(byte[] buffer, int offset, int count)
-        throws IOException {
-      checkNotClosed();
-      checkOffsetAndCount(buffer.length, offset, count);
-
-      while (count > 0) {
-        int numBytesWritten;
-
-        if (bufferedChunk.size() > 0 || count < maxChunkLength) {
-          // fill the buffered chunk and then maybe write that to the stream
-          numBytesWritten = Math.min(count, maxChunkLength - bufferedChunk.size());
-          // TODO: skip unnecessary copies from buffer->bufferedChunk?
-          bufferedChunk.write(buffer, offset, numBytesWritten);
-          if (bufferedChunk.size() == maxChunkLength) {
-            writeBufferedChunkToSocket();
-          }
-        } else {
-          // write a single chunk of size maxChunkLength to the stream
-          numBytesWritten = maxChunkLength;
-          writeHex(numBytesWritten);
-          socketOut.write(buffer, offset, numBytesWritten);
-          socketOut.write(CRLF);
-        }
-
-        offset += numBytesWritten;
-        count -= numBytesWritten;
-      }
-    }
-
-    /**
-     * Equivalent to, but cheaper than writing Integer.toHexString().getBytes()
-     * followed by CRLF.
-     */
-    private void writeHex(int i) throws IOException {
-      int cursor = 8;
-      do {
-        hex[--cursor] = HEX_DIGITS[i & 0xf];
-      } while ((i >>>= 4) != 0);
-      socketOut.write(hex, cursor, hex.length - cursor);
-    }
-
-    @Override public synchronized void flush() throws IOException {
-      if (closed) {
-        return; // don't throw; this stream might have been closed on the caller's behalf
-      }
-      writeBufferedChunkToSocket();
-      socketOut.flush();
-    }
-
-    @Override public synchronized void close() throws IOException {
-      if (closed) {
-        return;
-      }
-      closed = true;
-      writeBufferedChunkToSocket();
-      socketOut.write(FINAL_CHUNK);
-    }
-
-    private void writeBufferedChunkToSocket() throws IOException {
-      int size = bufferedChunk.size();
-      if (size <= 0) {
-        return;
-      }
-
-      writeHex(size);
-      bufferedChunk.writeTo(socketOut);
-      bufferedChunk.reset();
-      socketOut.write(CRLF);
-    }
-  }
-
-  /** An HTTP body with a fixed length specified in advance. */
-  private static class FixedLengthInputStream extends AbstractHttpInputStream {
-    private int bytesRemaining;
-
-    public FixedLengthInputStream(InputStream is, CacheRequest cacheRequest, HttpEngine httpEngine,
-        int length) throws IOException {
-      super(is, httpEngine, cacheRequest);
-      bytesRemaining = length;
-      if (bytesRemaining == 0) {
-        endOfInput(false);
-      }
-    }
-
-    @Override public int read(byte[] buffer, int offset, int count) throws IOException {
-      checkOffsetAndCount(buffer.length, offset, count);
-      checkNotClosed();
-      if (bytesRemaining == 0) {
-        return -1;
-      }
-      int read = in.read(buffer, offset, Math.min(count, bytesRemaining));
-      if (read == -1) {
-        unexpectedEndOfInput(); // the server didn't supply the promised content length
-        throw new ProtocolException("unexpected end of stream");
-      }
-      bytesRemaining -= read;
-      cacheWrite(buffer, offset, read);
-      if (bytesRemaining == 0) {
-        endOfInput(false);
-      }
-      return read;
-    }
-
-    @Override public int available() throws IOException {
-      checkNotClosed();
-      return bytesRemaining == 0 ? 0 : Math.min(in.available(), bytesRemaining);
-    }
-
-    @Override public void close() throws IOException {
-      if (closed) {
-        return;
-      }
-      if (bytesRemaining != 0 && !discardStream(httpEngine, this)) {
-        unexpectedEndOfInput();
-      }
-      closed = true;
-    }
-  }
-
-  /** An HTTP body with alternating chunk sizes and chunk bodies. */
-  private static class ChunkedInputStream extends AbstractHttpInputStream {
-    private static final int NO_CHUNK_YET = -1;
-    private final HttpTransport transport;
-    private int bytesRemainingInChunk = NO_CHUNK_YET;
-    private boolean hasMoreChunks = true;
-
-    ChunkedInputStream(InputStream is, CacheRequest cacheRequest, HttpTransport transport)
-        throws IOException {
-      super(is, transport.httpEngine, cacheRequest);
-      this.transport = transport;
-    }
-
-    @Override public int read(byte[] buffer, int offset, int count) throws IOException {
-      checkOffsetAndCount(buffer.length, offset, count);
-      checkNotClosed();
-
-      if (!hasMoreChunks) {
-        return -1;
-      }
-      if (bytesRemainingInChunk == 0 || bytesRemainingInChunk == NO_CHUNK_YET) {
-        readChunkSize();
-        if (!hasMoreChunks) {
-          return -1;
-        }
-      }
-      int read = in.read(buffer, offset, Math.min(count, bytesRemainingInChunk));
-      if (read == -1) {
-        unexpectedEndOfInput(); // the server didn't supply the promised chunk length
-        throw new IOException("unexpected end of stream");
-      }
-      bytesRemainingInChunk -= read;
-      cacheWrite(buffer, offset, read);
-      return read;
-    }
-
-    private void readChunkSize() throws IOException {
-      // read the suffix of the previous chunk
-      if (bytesRemainingInChunk != NO_CHUNK_YET) {
-        Util.readAsciiLine(in);
-      }
-      String chunkSizeString = Util.readAsciiLine(in);
-      int index = chunkSizeString.indexOf(";");
-      if (index != -1) {
-        chunkSizeString = chunkSizeString.substring(0, index);
-      }
-      try {
-        bytesRemainingInChunk = Integer.parseInt(chunkSizeString.trim(), 16);
-      } catch (NumberFormatException e) {
-        throw new ProtocolException("Expected a hex chunk size but was " + chunkSizeString);
-      }
-      if (bytesRemainingInChunk == 0) {
-        hasMoreChunks = false;
-        RawHeaders rawResponseHeaders = httpEngine.responseHeaders.getHeaders();
-        RawHeaders.readHeaders(transport.socketIn, rawResponseHeaders);
-        httpEngine.receiveHeaders(rawResponseHeaders);
-        endOfInput(false);
-      }
-    }
-
-    @Override public int available() throws IOException {
-      checkNotClosed();
-      if (!hasMoreChunks || bytesRemainingInChunk == NO_CHUNK_YET) {
-        return 0;
-      }
-      return Math.min(in.available(), bytesRemainingInChunk);
-    }
-
-    @Override public void close() throws IOException {
-      if (closed) {
-        return;
-      }
-      if (hasMoreChunks && !discardStream(httpEngine, this)) {
-        unexpectedEndOfInput();
-      }
-      closed = true;
-    }
-  }
-}