public Entry(
        URI uri,
        RawHeaders varyHeaders,
        AsyncHttpRequest request,
        ResponseHeaders responseHeaders) {
      this.uri = uri.toString();
      this.varyHeaders = varyHeaders;
      this.requestMethod = request.getMethod();
      this.responseHeaders = responseHeaders.getHeaders();

      //            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;
      //            }
    }
  // step 1) see if we can serve request from the cache directly.
  // also see if this can be turned into a conditional cache request.
  @Override
  public Cancellable getSocket(final GetSocketData data) {
    if (cache == null) return null;

    if (!caching) return null;
    if (data.request.getHeaders().isNoCache()) return null;
    //        Log.i(LOGTAG, "getting cache socket: " + request.getUri().toString());

    String key = uriToKey(data.request.getUri());
    DiskLruCache.Snapshot snapshot;
    Entry entry;
    try {
      snapshot = cache.get(key);
      if (snapshot == null) {
        //                Log.i(LOGTAG, "snapshot fail");
        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(
        data.request.getUri(),
        data.request.getMethod(),
        data.request.getHeaders().getHeaders().toMultimap())) {
      snapshot.close();
      return null;
    }

    ResponseSource responseSource = ResponseSource.NETWORK;

    CacheResponse candidate =
        entry.isHttps()
            ? new EntrySecureCacheResponse(entry, snapshot)
            : new EntryCacheResponse(entry, snapshot);

    Map<String, List<String>> responseHeadersMap;
    InputStream cachedResponseBody;
    try {
      responseHeadersMap = candidate.getHeaders();
      cachedResponseBody = candidate.getBody();
    } catch (Exception e) {
      return null;
    }
    if (responseHeadersMap == null || cachedResponseBody == null) {
      try {
        cachedResponseBody.close();
      } catch (Exception e) {
      }
      return null;
    }

    RawHeaders rawResponseHeaders = RawHeaders.fromMultimap(responseHeadersMap);
    ResponseHeaders cachedResponseHeaders =
        new ResponseHeaders(data.request.getUri(), rawResponseHeaders);

    long now = System.currentTimeMillis();
    responseSource = cachedResponseHeaders.chooseResponseSource(now, data.request.getHeaders());

    if (responseSource == ResponseSource.CACHE) {
      cacheStoreCount++;
      final CachedSocket socket =
          entry.isHttps()
              ? new CachedSSLSocket((EntrySecureCacheResponse) candidate)
              : new CachedSocket((EntryCacheResponse) candidate);

      client
          .getServer()
          .post(
              new Runnable() {
                @Override
                public void run() {
                  data.connectCallback.onConnectCompleted(null, socket);
                  socket.spewInternal();
                }
              });
    } else if (responseSource == ResponseSource.CONDITIONAL_CACHE) {
      CacheData cacheData = new CacheData();
      cacheData.cachedResponseHeaders = cachedResponseHeaders;
      cacheData.candidate = candidate;
      data.state.putParcelable("cache-data", cacheData);

      return null;
    } else {
      // NETWORK or other
      try {
        cachedResponseBody.close();
      } catch (Exception e) {
      }
      return null;
    }

    return new SimpleCancelable();
  }