com.crashlytics.tools.android_2.1.0

rivate boolean heuristicCachingEnabled;
  private float heuristicCoefficient;
  private long heuristicDefaultLifetime;
  private boolean isSharedCache;
  private int asynchronousWorkersMax;
  private int asynchronousWorkersCore;
  private int asynchronousWorkerIdleLifetimeSecs;
  private int revalidationQueueSize;
  private boolean neverCacheHTTP10ResponsesWithQuery;
  
  @Deprecated
  public CacheConfig()
  {
    maxObjectSize = 8192L;
    maxCacheEntries = 1000;
    maxUpdateRetries = 1;
    allow303Caching = false;
    weakETagOnPutDeleteAllowed = false;
    heuristicCachingEnabled = false;
    heuristicCoefficient = 0.1F;
    heuristicDefaultLifetime = 0L;
    isSharedCache = true;
    asynchronousWorkersMax = 1;
    asynchronousWorkersCore = 1;
    asynchronousWorkerIdleLifetimeSecs = 60;
    revalidationQueueSize = 100;
  }
  
  CacheConfig(long maxObjectSize, int maxCacheEntries, int maxUpdateRetries, boolean allow303Caching, boolean weakETagOnPutDeleteAllowed, boolean heuristicCachingEnabled, float heuristicCoefficient, long heuristicDefaultLifetime, boolean isSharedCache, int asynchronousWorkersMax, int asynchronousWorkersCore, int asynchronousWorkerIdleLifetimeSecs, int revalidationQueueSize, boolean neverCacheHTTP10ResponsesWithQuery)
  {
    this.maxObjectSize = maxObjectSize;
    this.maxCacheEntries = maxCacheEntries;
    this.maxUpdateRetries = maxUpdateRetries;
    this.allow303Caching = allow303Caching;
    this.weakETagOnPutDeleteAllowed = weakETagOnPutDeleteAllowed;
    this.heuristicCachingEnabled = heuristicCachingEnabled;
    this.heuristicCoefficient = heuristicCoefficient;
    this.heuristicDefaultLifetime = heuristicDefaultLifetime;
    this.isSharedCache = isSharedCache;
    this.asynchronousWorkersMax = asynchronousWorkersMax;
    this.asynchronousWorkersCore = asynchronousWorkersCore;
    this.asynchronousWorkerIdleLifetimeSecs = asynchronousWorkerIdleLifetimeSecs;
    this.revalidationQueueSize = revalidationQueueSize;
  }
  
  @Deprecated
  public int getMaxObjectSizeBytes()
  {
    return maxObjectSize > 2147483647L ? Integer.MAX_VALUE : (int)maxObjectSize;
  }
  
  @Deprecated
  public void setMaxObjectSizeBytes(int maxObjectSizeBytes)
  {
    if (maxObjectSizeBytes > Integer.MAX_VALUE) {
      maxObjectSize = 2147483647L;
    } else {
      maxObjectSize = maxObjectSizeBytes;
    }
  }
  
  public long getMaxObjectSize()
  {
    return maxObjectSize;
  }
  
  @Deprecated
  public void setMaxObjectSize(long maxObjectSize)
  {
    this.maxObjectSize = maxObjectSize;
  }
  
  public boolean isNeverCacheHTTP10ResponsesWithQuery()
  {
    return neverCacheHTTP10ResponsesWithQuery;
  }
  
  public int getMaxCacheEntries()
  {
    return maxCacheEntries;
  }
  
  @Deprecated
  public void setMaxCacheEntries(int maxCacheEntries)
  {
    this.maxCacheEntries = maxCacheEntries;
  }
  
  public int getMaxUpdateRetries()
  {
    return maxUpdateRetries;
  }
  
  @Deprecated
  public void setMaxUpdateRetries(int maxUpdateRetries)
  {
    this.maxUpdateRetries = maxUpdateRetries;
  }
  
  public boolean is303CachingEnabled()
  {
    return allow303Caching;
  }
  
  public boolean isWeakETagOnPutDeleteAllowed()
  {
    return weakETagOnPutDeleteAllowed;
  }
  
  public boolean isHeuristicCachingEnabled()
  {
    return heuristicCachingEnabled;
  }
  
  @Deprecated
  public void setHeuristicCachingEnabled(boolean heuristicCachingEnabled)
  {
    this.heuristicCachingEnabled = heuristicCachingEnabled;
  }
  
  public float getHeuristicCoefficient()
  {
    return heuristicCoefficient;
  }
  
  @Deprecated
  public void setHeuristicCoefficient(float heuristicCoefficient)
  {
    this.heuristicCoefficient = heuristicCoefficient;
  }
  
  public long getHeuristicDefaultLifetime()
  {
    return heuristicDefaultLifetime;
  }
  
  @Deprecated
  public void setHeuristicDefaultLifetime(long heuristicDefaultLifetimeSecs)
  {
    heuristicDefaultLifetime = heuristicDefaultLifetimeSecs;
  }
  
  public boolean isSharedCache()
  {
    return isSharedCache;
  }
  
  @Deprecated
  public void setSharedCache(boolean isSharedCache)
  {
    this.isSharedCache = isSharedCache;
  }
  
  public int getAsynchronousWorkersMax()
  {
    return asynchronousWorkersMax;
  }
  
  @Deprecated
  public void setAsynchronousWorkersMax(int max)
  {
    asynchronousWorkersMax = max;
  }
  
  public int getAsynchronousWorkersCore()
  {
    return asynchronousWorkersCore;
  }
  
  @Deprecated
  public void setAsynchronousWorkersCore(int min)
  {
    asynchronousWorkersCore = min;
  }
  
  public int getAsynchronousWorkerIdleLifetimeSecs()
  {
    return asynchronousWorkerIdleLifetimeSecs;
  }
  
  @Deprecated
  public void setAsynchronousWorkerIdleLifetimeSecs(int secs)
  {
    asynchronousWorkerIdleLifetimeSecs = secs;
  }
  
  public int getRevalidationQueueSize()
  {
    return revalidationQueueSize;
  }
  
  @Deprecated
  public void setRevalidationQueueSize(int size)
  {
    revalidationQueueSize = size;
  }
  
  protected CacheConfig clone()
    throws CloneNotSupportedException
  {
    return (CacheConfig)super.clone();
  }
  
  public static Builder custom()
  {
    return new Builder();
  }
  
  public static Builder copy(CacheConfig config)
  {
    Args.notNull(config, "Cache config");
    return new Builder().setMaxObjectSize(config.getMaxObjectSize()).setMaxCacheEntries(config.getMaxCacheEntries()).setMaxUpdateRetries(config.getMaxUpdateRetries()).setHeuristicCachingEnabled(config.isHeuristicCachingEnabled()).setHeuristicCoefficient(config.getHeuristicCoefficient()).setHeuristicDefaultLifetime(config.getHeuristicDefaultLifetime()).setSharedCache(config.isSharedCache()).setAsynchronousWorkersMax(config.getAsynchronousWorkersMax()).setAsynchronousWorkersCore(config.getAsynchronousWorkersCore()).setAsynchronousWorkerIdleLifetimeSecs(config.getAsynchronousWorkerIdleLifetimeSecs()).setRevalidationQueueSize(config.getRevalidationQueueSize()).setNeverCacheHTTP10ResponsesWithQueryString(config.isNeverCacheHTTP10ResponsesWithQuery());
  }
  
  public static class Builder
  {
    private long maxObjectSize;
    private int maxCacheEntries;
    private int maxUpdateRetries;
    private boolean allow303Caching;
    private boolean weakETagOnPutDeleteAllowed;
    private boolean heuristicCachingEnabled;
    private float heuristicCoefficient;
    private long heuristicDefaultLifetime;
    private boolean isSharedCache;
    private int asynchronousWorkersMax;
    private int asynchronousWorkersCore;
    private int asynchronousWorkerIdleLifetimeSecs;
    private int revalidationQueueSize;
    private boolean neverCacheHTTP10ResponsesWithQuery;
    
    Builder()
    {
      maxObjectSize = 8192L;
      maxCacheEntries = 1000;
      maxUpdateRetries = 1;
      allow303Caching = false;
      weakETagOnPutDeleteAllowed = false;
      heuristicCachingEnabled = false;
      heuristicCoefficient = 0.1F;
      heuristicDefaultLifetime = 0L;
      isSharedCache = true;
      asynchronousWorkersMax = 1;
      asynchronousWorkersCore = 1;
      asynchronousWorkerIdleLifetimeSecs = 60;
      revalidationQueueSize = 100;
    }
    
    public Builder setMaxObjectSize(long maxObjectSize)
    {
      this.maxObjectSize = maxObjectSize;
      return this;
    }
    
    public Builder setMaxCacheEntries(int maxCacheEntries)
    {
      this.maxCacheEntries = maxCacheEntries;
      return this;
    }
    
    public Builder setMaxUpdateRetries(int maxUpdateRetries)
    {
      this.maxUpdateRetries = maxUpdateRetries;
      return this;
    }
    
    public Builder setAllow303Caching(boolean allow303Caching)
    {
      this.allow303Caching = allow303Caching;
      return this;
    }
    
    public Builder setWeakETagOnPutDeleteAllowed(boolean weakETagOnPutDeleteAllowed)
    {
      this.weakETagOnPutDeleteAllowed = weakETagOnPutDeleteAllowed;
      return this;
    }
    
    public Builder setHeuristicCachingEnabled(boolean heuristicCachingEnabled)
    {
      this.heuristicCachingEnabled = heuristicCachingEnabled;
      return this;
    }
    
    public Builder setHeuristicCoefficient(float heuristicCoefficient)
    {
      this.heuristicCoefficient = heuristicCoefficient;
      return this;
    }
    
    public Builder setHeuristicDefaultLifetime(long heuristicDefaultLifetime)
    {
      this.heuristicDefaultLifetime = heuristicDefaultLifetime;
      return this;
    }
    
    public Builder setSharedCache(boolean isSharedCache)
    {
      this.isSharedCache = isSharedCache;
      return this;
    }
    
    public Builder setAsynchronousWorkersMax(int asynchronousWorkersMax)
    {
      this.asynchronousWorkersMax = asynchronousWorkersMax;
      return this;
    }
    
    public Builder setAsynchronousWorkersCore(int asynchronousWorkersCore)
    {
      this.asynchronousWorkersCore = asynchronousWorkersCore;
      return this;
    }
    
    public Builder setAsynchronousWorkerIdleLifetimeSecs(int asynchronousWorkerIdleLifetimeSecs)
    {
      this.asynchronousWorkerIdleLifetimeSecs = asynchronousWorkerIdleLifetimeSecs;
      return this;
    }
    
    public Builder setRevalidationQueueSize(int revalidationQueueSize)
    {
      this.revalidationQueueSize = revalidationQueueSize;
      return this;
    }
    
    public Builder setNeverCacheHTTP10ResponsesWithQueryString(boolean neverCacheHTTP10ResponsesWithQuery)
    {
      this.neverCacheHTTP10ResponsesWithQuery = neverCacheHTTP10ResponsesWithQuery;
      return this;
    }
    
    public CacheConfig build()
    {
      return new CacheConfig(maxObjectSize, maxCacheEntries, maxUpdateRetries, allow303Caching, weakETagOnPutDeleteAllowed, heuristicCachingEnabled, heuristicCoefficient, heuristicDefaultLifetime, isSharedCache, asynchronousWorkersMax, asynchronousWorkersCore, asynchronousWorkerIdleLifetimeSecs, revalidationQueueSize, neverCacheHTTP10ResponsesWithQuery);
    }
  }
  
  public String toString()
  {
    StringBuilder builder = new StringBuilder();
    builder.append("[maxObjectSize=").append(maxObjectSize).append(", maxCacheEntries=").append(maxCacheEntries).append(", maxUpdateRetries=").append(maxUpdateRetries).append(", 303CachingEnabled=").append(allow303Caching).append(", weakETagOnPutDeleteAllowed=").append(weakETagOnPutDeleteAllowed).append(", heuristicCachingEnabled=").append(heuristicCachingEnabled).append(", heuristicCoefficient=").append(heuristicCoefficient).append(", heuristicDefaultLifetime=").append(heuristicDefaultLifetime).append(", isSharedCache=").append(isSharedCache).append(", asynchronousWorkersMax=").append(asynchronousWorkersMax).append(", asynchronousWorkersCore=").append(asynchronousWorkersCore).append(", asynchronousWorkerIdleLifetimeSecs=").append(asynchronousWorkerIdleLifetimeSecs).append(", revalidationQueueSize=").append(revalidationQueueSize).append(", neverCacheHTTP10ResponsesWithQuery=").append(neverCacheHTTP10ResponsesWithQuery).append("]");
    
    return builder.toString();
  }
}

/* Location:
 * Qualified Name:     org.apache.http.impl.client.cache.CacheConfig
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.apache.http.impl.client.cache;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.annotation.Immutable;
import org.apache.http.client.cache.HttpCacheEntry;
import org.apache.http.client.cache.Resource;
import org.apache.http.util.Args;

@Immutable
class CacheEntity
  implements HttpEntity, Serializable
{
  private static final long serialVersionUID = -3467082284120936233L;
  private final HttpCacheEntry cacheEntry;
  
  public CacheEntity(HttpCacheEntry cacheEntry)
  {
    this.cacheEntry = cacheEntry;
  }
  
  public Header getContentType()
  {
    return cacheEntry.getFirstHeader("Content-Type");
  }
  
  public Header getContentEncoding()
  {
    return cacheEntry.getFirstHeader("Content-Encoding");
  }
  
  public boolean isChunked()
  {
    return false;
  }
  
  public boolean isRepeatable()
  {
    return true;
  }
  
  public long getContentLength()
  {
    return cacheEntry.getResource().length();
  }
  
  public InputStream getContent()
    throws IOException
  {
    return cacheEntry.getResource().getInputStream();
  }
  
  public void writeTo(OutputStream outstream)
    throws IOException
  {
    Args.notNull(outstream, "Output stream");
    InputStream instream = cacheEntry.getResource().getInputStream();
    try
    {
      IOUtils.copy(instream, outstream);
    }
    finally
    {
      instream.close();
    }
  }
  
  public boolean isStreaming()
  {
    return false;
  }
  
  public void consumeContent()
    throws IOException
  {}
  
  public Object clone()
    throws CloneNotSupportedException
  {
    return super.clone();
  }
}

/* Location:
 * Qualified Name:     org.apache.http.impl.client.cache.CacheEntity
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.apache.http.impl.client.cache;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.ListIterator;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.annotation.Immutable;
import org.apache.http.client.cache.HttpCacheEntry;
import org.apache.http.client.cache.Resource;
import org.apache.http.client.cache.ResourceFactory;
import org.apache.http.client.utils.DateUtils;
import org.apache.http.util.Args;

@Immutable
class CacheEntryUpdater
{
  private final ResourceFactory resourceFactory;
  
  CacheEntryUpdater()
  {
    this(new HeapResourceFactory());
  }
  
  CacheEntryUpdater(ResourceFactory resourceFactory)
  {
    this.resourceFactory = resourceFactory;
  }
  
  public HttpCacheEntry updateCacheEntry(String requestId, HttpCacheEntry entry, Date requestDate, Date responseDate, HttpResponse response)
    throws IOException
  {
    Args.check(response.getStatusLine().getStatusCode() == 304, "Response must have 304 status code");
    
    Header[] mergedHeaders = mergeHeaders(entry, response);
    Resource resource = null;
    if (entry.getResource() != null) {
      resource = resourceFactory.copy(requestId, entry.getResource());
    }
    return new HttpCacheEntry(requestDate, responseDate, entry.getStatusLine(), mergedHeaders, resource);
  }
  
  protected Header[] mergeHeaders(HttpCacheEntry entry, HttpResponse response)
  {
    if ((entryAndResponseHaveDateHeader(entry, response)) && (entryDateHeaderNewerThenResponse(entry, response))) {
      return entry.getAllHeaders();
    }
    List<Header> cacheEntryHeaderList = new ArrayList(Arrays.asList(entry.getAllHeaders()));
    
    removeCacheHeadersThatMatchResponse(cacheEntryHeaderList, response);
    removeCacheEntry1xxWarnings(cacheEntryHeaderList, entry);
    cacheEntryHeaderList.addAll(Arrays.asList(response.getAllHeaders()));
    
    return (Header[])cacheEntryHeaderList.toArray(new Header[cacheEntryHeaderList.size()]);
  }
  
  private void removeCacheHeadersThatMatchResponse(List<Header> cacheEntryHeaderList, HttpResponse response)
  {
    for (Header responseHeader : response.getAllHeaders())
    {
      ListIterator<Header> cacheEntryHeaderListIter = cacheEntryHeaderList.listIterator();
      while (cacheEntryHeaderListIter.hasNext())
      {
        String cacheEntryHeaderName = ((Header)cacheEntryHeaderListIter.next()).getName();
        if (cacheEntryHeaderName.equals(responseHeader.getName())) {
          cacheEntryHeaderListIter.remove();
        }
      }
    }
  }
  
  private void removeCacheEntry1xxWarnings(List<Header> cacheEntryHeaderList, HttpCacheEntry entry)
  {
    ListIterator<Header> cacheEntryHeaderListIter = cacheEntryHeaderList.listIterator();
    while (cacheEntryHeaderListIter.hasNext())
    {
      String cacheEntryHeaderName = ((Header)cacheEntryHeaderListIter.next()).getName();
      if ("Warning".equals(cacheEntryHeaderName)) {
        for (Header cacheEntryWarning : entry.getHeaders("Warning")) {
          if (cacheEntryWarning.getValue().startsWith("1")) {
            cacheEntryHeaderListIter.remove();
          }
        }
      }
    }
  }
  
  private boolean entryDateHeaderNewerThenResponse(HttpCacheEntry entry, HttpResponse response)
  {
    Date entryDate = DateUtils.parseDate(entry.getFirstHeader("Date").getValue());
    
    Date responseDate = DateUtils.parseDate(response.getFirstHeader("Date").getValue());
    if ((entryDate == null) || (responseDate == null)) {
      return false;
    }
    if (!entryDate.after(responseDate)) {
      return false;
    }
    return true;
  }
  
  private boolean entryAndResponseHaveDateHeader(HttpCacheEntry entry, HttpResponse response)
  {
    if ((entry.getFirstHeader("Date") != null) && (response.getFirstHeader("Date") != null)) {
      return true;
    }
    return false;
  }
}

/* Location:
 * Qualified Name:     org.apache.http.impl.client.cache.CacheEntryUpdater
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.apache.http.impl.client.cache;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.RequestLine;
import org.apache.http.StatusLine;
import org.apache.http.annotation.Immutable;
import org.apache.http.client.cache.HttpCacheEntry;
import org.apache.http.client.cache.HttpCacheInvalidator;
import org.apache.http.client.cache.HttpCacheStorage;
import org.apache.http.client.utils.DateUtils;

@Immutable
class CacheInvalidator
  implements HttpCacheInvalidator
{
  private final HttpCacheStorage storage;
  private final CacheKeyGenerator cacheKeyGenerator;
  private final Log log = LogFactory.getLog(getClass());
  
  public CacheInvalidator(CacheKeyGenerator uriExtractor, HttpCacheStorage storage)
  {
    cacheKeyGenerator = uriExtractor;
    this.storage = storage;
  }
  
  public void flushInvalidatedCacheEntries(HttpHost host, HttpRequest req)
  {
    if (requestShouldNotBeCached(req))
    {
      log.debug("Request should not be cached");
      
      String theUri = cacheKeyGenerator.getURI(host, req);
      
      HttpCacheEntry parent = getEntry(theUri);
      
      log.debug("parent entry: " + parent);
      if (parent != null)
      {
        for (String variantURI : parent.getVariantMap().values()) {
          flushEntry(variantURI);
        }
        flushEntry(theUri);
      }
      URL reqURL = getAbsoluteURL(theUri);
      if (reqURL == null)
      {
        log.error("Couldn't transform request into valid URL");
        return;
      }
      Header clHdr = req.getFirstHeader("Content-Location");
      if (clHdr != null)
      {
        String contentLocation = clHdr.getValue();
        if (!flushAbsoluteUriFromSameHost(reqURL, contentLocation)) {
          flushRelativeUriFromSameHost(reqURL, contentLocation);
        }
      }
      Header lHdr = req.getFirstHeader("Location");
      if (lHdr != null) {
        flushAbsoluteUriFromSameHost(reqURL, lHdr.getValue());
      }
    }
  }
  
  private void flushEntry(String uri)
  {
    try
    {
      storage.removeEntry(uri);
    }
    catch (IOException ioe)
    {
      log.warn("unable to flush cache entry", ioe);
    }
  }
  
  private HttpCacheEntry getEntry(String theUri)
  {
    try
    {
      return storage.getEntry(theUri);
    }
    catch (IOException ioe)
    {
      log.warn("could not retrieve entry from storage", ioe);
    }
    return null;
  }
  
  protected void flushUriIfSameHost(URL requestURL, URL targetURL)
  {
    URL canonicalTarget = getAbsoluteURL(cacheKeyGenerator.canonicalizeUri(targetURL.toString()));
    if (canonicalTarget == null) {
      return;
    }
    if (canonicalTarget.getAuthority().equalsIgnoreCase(requestURL.getAuthority())) {
      flushEntry(canonicalTarget.toString());
    }
  }
  
  protected void flushRelativeUriFromSameHost(URL reqURL, String relUri)
  {
    URL relURL = getRelativeURL(reqURL, relUri);
    if (relURL == null) {
      return;
    }
    flushUriIfSameHost(reqURL, relURL);
  }
  
  protected boolean flushAbsoluteUriFromSameHost(URL reqURL, String uri)
  {
    URL absURL = getAbsoluteURL(uri);
    if (absURL == null) {
      return false;
    }
    flushUriIfSameHost(reqURL, absURL);
    return true;
  }
  
  private URL getAbsoluteURL(String uri)
  {
    URL absURL = null;
    try
    {
      absURL = new URL(uri);
    }
    catch (MalformedURLException mue) {}
    return absURL;
  }
  
  private URL getRelativeURL(URL reqURL, String relUri)
  {
    URL relURL = null;
    try
    {
      relURL = new URL(reqURL, relUri);
    }
    catch (MalformedURLException e) {}
    return relURL;
  }
  
  protected boolean requestShouldNotBeCached(HttpRequest req)
  {
    String method = req.getRequestLine().getMethod();
    return notGetOrHeadRequest(method);
  }
  
  private boolean notGetOrHeadRequest(String method)
  {
    return (!"GET".equals(method)) && (!"HEAD".equals(method));
  }
  
  public void flushInvalidatedCacheEntries(HttpHost host, HttpRequest request, HttpResponse response)
  {
    int status = response.getStatusLine().getStatusCode();
    if ((status < 200) || (status > 299)) {
      return;
    }
    URL reqURL = getAbsoluteURL(cacheKeyGenerator.getURI(host, request));
    if (reqURL == null) {
      return;
    }
    URL contentLocation = getContentLocationURL(reqURL, response);
    if (contentLocation != null) {
      flushLocationCacheEntry(reqURL, response, contentLocation);
    }
    URL location = getLocationURL(reqURL, response);
    if (location != null) {
      flushLocationCacheEntry(reqURL, response, location);
    }
  }
  
  private void flushLocationCacheEntry(URL reqURL, HttpResponse response, URL location)
  {
    String cacheKey = cacheKeyGenerator.canonicalizeUri(location.toString());
    HttpCacheEntry entry = getEntry(cacheKey);
    if (entry == null) {
      return;
    }
    if (responseDateOlderThanEntryDate(response, entry)) {
      return;
    }
    if (!responseAndEntryEtagsDiffer(response, entry)) {
      return;
    }
    flushUriIfSameHost(reqURL, location);
  }
  
  private URL getContentLocationURL(URL reqURL, HttpResponse response)
  {
    Header clHeader = response.getFirstHeader("Content-Location");
    if (clHeader == null) {
      return null;
    }
    String contentLocation = clHeader.getValue();
    URL canonURL = getAbsoluteURL(contentLocation);
    if (canonURL != null) {
      return canonURL;
    }
    return getRelativeURL(reqURL, contentLocation);
  }
  
  private URL getLocationURL(URL reqURL, HttpResponse response)
  {
    Header clHeader = response.getFirstHeader("Location");
    if (clHeader == null) {
      return null;
    }
    String location = clHeader.getValue();
    URL canonURL = getAbsoluteURL(location);
    if (canonURL != null) {
      return canonURL;
    }
    return getRelativeURL(reqURL, location);
  }
  
  private boolean responseAndEntryEtagsDiffer(HttpResponse response, HttpCacheEntry entry)
  {
    Header entryEtag = entry.getFirstHeader("ETag");
    Header responseEtag = response.getFirstHeader("ETag");
    if ((entryEtag == null) || (responseEtag == null)) {
      return false;
    }
    return !entryEtag.getValue().equals(responseEtag.getValue());
  }
  
  private boolean responseDateOlderThanEntryDate(HttpResponse response, HttpCacheEntry entry)
  {
    Header entryDateHeader = entry.getFirstHeader("Date");
    Header responseDateHeader = response.getFirstHeader("Date");
    if ((entryDateHeader == null) || (responseDateHeader == null)) {
      return false;
    }
    Date entryDate = DateUtils.parseDate(entryDateHeader.getValue());
    Date responseDate = DateUtils.parseDate(responseDateHeader.getValue());
    if ((entryDate == null) || (responseDate == null)) {
      return false;
    }
    return responseDate.before(entryDate);
  }
}

/* Location:
 * Qualified Name:     org.apache.http.impl.client.cache.CacheInvalidator
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.apache.http.impl.client.cache;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.RequestLine;
import org.apache.http.annotation.Immutable;
import org.apache.http.client.cache.HttpCacheEntry;
import org.apache.http.client.utils.URIUtils;

@Immutable
class CacheKeyGenerator
{
  private static final URI BASE_URI = URI.create("http://example.com/");
  
  public String getURI(HttpHost host, HttpRequest req)
  {
    if (isRelativeRequest(req)) {
      return canonicalizeUri(String.format("%s%s", new Object[] { host.toString(), req.getRequestLine().getUri() }));
    }
    return canonicalizeUri(req.getRequestLine().getUri());
  }
  
  public String canonicalizeUri(String uri)
  {
    try
    {
      URI normalized = URIUtils.resolve(BASE_URI, uri);
      URL u = new URL(normalized.toASCIIString());
      String protocol = u.getProtocol();
      String hostname = u.getHost();
      int port = canonicalizePort(u.getPort(), protocol);
      String path = u.getPath();
      String query = u.getQuery();
      String file = query != null ? path + "?" + query : path;
      URL out = new URL(protocol, hostname, port, file);
      return out.toString();
    }
    catch (IllegalArgumentException e)
    {
      return uri;
    }
    catch (MalformedURLException e) {}
    return uri;
  }
  
  private int canonicalizePort(int port, String protocol)
  {
    if ((port == -1) && ("http".equalsIgnoreCase(protocol))) {
      return 80;
    }
    if ((port == -1) && ("https".equalsIgnoreCase(protocol))) {
      return 443;
    }
    return port;
  }
  
  private boolean isRelativeRequest(HttpRequest req)
  {
    String requestUri = req.getRequestLine().getUri();
    return ("*".equals(requestUri)) || (requestUri.startsWith("/"));
  }
  
  protected String getFullHeaderValue(Header[] headers)
  {
    if (headers == null) {
      return "";
    }
    StringBuilder buf = new StringBuilder("");
    boolean first = true;
    for (Header hdr : headers)
    {
      if (!first) {
        buf.append(", ");
      }
      buf.append(hdr.getValue().trim());
      first = false;
    }
    return buf.toString();
  }
  
  public String getVariantURI(HttpHost host, HttpRequest req, HttpCacheEntry entry)
  {
    if (!entry.hasVariants()) {
      return getURI(host, req);
    }
    return getVariantKey(req, entry) + getURI(host, req);
  }
  
  public String getVariantKey(HttpRequest req, HttpCacheEntry entry)
  {
    List<String> variantHeaderNames = new ArrayList();
    for (Header varyHdr : entry.getHeaders("Vary")) {
      for (HeaderElement elt : varyHdr.getElements()) {
        variantHeaderNames.add(elt.getName());
      }
    }
    Collections.sort(variantHeaderNames);
    StringBuilder buf;
    try
    {
      buf = new StringBuilder("{");
      boolean first = true;
      for (String headerName : variantHeaderNames)
      {
        if (!first) {
          buf.append("&");
        }
        buf.append(URLEncoder.encode(headerName, Consts.UTF_8.name()));
        buf.append("=");
        buf.append(URLEncoder.encode(getFullHeaderValue(req.getHeaders(headerName)), Consts.UTF_8.name()));
        
        first = false;
      }
      buf.append("}");
    }
    catch (UnsupportedEncodingException uee)
    {
      throw new RuntimeException("couldn't encode to UTF-8", uee);
    }
    return buf.toString();
  }
}

/* Location:
 * Qualified Name:     org.apache.http.impl.client.cache.CacheKeyGenerator
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.apache.http.impl.client.cache;

import java.util.LinkedHashMap;
import java.util.Map.Entry;
import org.apache.http.client.cache.HttpCacheEntry;

final class CacheMap
  extends LinkedHashMap<String, HttpCacheEntry>
{
  private static final long serialVersionUID = -7750025207539768511L;
  private final int maxEntries;
  
  CacheMap(int maxEntries)
  {
    super(20, 0.75F, true);
    this.maxEntries = maxEntries;
  }
  
  protected boolean removeEldestEntry(Map.Entry<String, HttpCacheEntry> eldest)
  {
    return size() > maxEntries;
  }
}

/* Location:
 * Qualified Name:     org.apache.http.impl.client.cache.CacheMap
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.apache.http.impl.client.cache;

import java.util.Date;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpRequest;
import org.apache.http.annotation.Immutable;
import org.apache.http.client.cache.HttpCacheEntry;
import org.apache.http.client.cache.Resource;
import org.apache.http.client.utils.DateUtils;

@Immutable
class CacheValidityPolicy
{
  public static final long MAX_AGE = 2147483648L;
  
  public long getCurrentAgeSecs(HttpCacheEntry entry, Date now)
  {
    return getCorrectedInitialAgeSecs(entry) + getResidentTimeSecs(entry, now);
  }
  
  public long getFreshnessLifetimeSecs(HttpCacheEntry entry)
  {
    long maxage = getMaxAge(entry);
    if (maxage > -1L) {
      return maxage;
    }
    Date dateValue = entry.getDate();
    if (dateValue == null) {
      return 0L;
    }
    Date expiry = getExpirationDate(entry);
    if (expiry == null) {
      return 0L;
    }
    long diff = expiry.getTime() - dateValue.getTime();
    return diff / 1000L;
  }
  
  public boolean isResponseFresh(HttpCacheEntry entry, Date now)
  {
    return getCurrentAgeSecs(entry, now) < getFreshnessLifetimeSecs(entry);
  }
  
  public boolean isResponseHeuristicallyFresh(HttpCacheEntry entry, Date now, float coefficient, long defaultLifetime)
  {
    return getCurrentAgeSecs(entry, now) < getHeuristicFreshnessLifetimeSecs(entry, coefficient, defaultLifetime);
  }
  
  public long getHeuristicFreshnessLifetimeSecs(HttpCacheEntry entry, float coefficient, long defaultLifetime)
  {
    Date dateValue = entry.getDate();
    Date lastModifiedValue = getLastModifiedValue(entry);
    if ((dateValue != null) && (lastModifiedValue != null))
    {
      long diff = dateValue.getTime() - lastModifiedValue.getTime();
      if (diff < 0L) {
        return 0L;
      }
      return (coefficient * (float)(diff / 1000L));
    }
    return defaultLifetime;
  }
  
  public boolean isRevalidatable(HttpCacheEntry entry)
  {
    return (entry.getFirstHeader("ETag") != null) || (entry.getFirstHeader("Last-Modified") != null);
  }
  
  public boolean mustRevalidate(HttpCacheEntry entry)
  {
    return hasCacheControlDirective(entry, "must-revalidate");
  }
  
  public boolean proxyRevalidate(HttpCacheEntry entry)
  {
    return hasCacheControlDirective(entry, "proxy-revalidate");
  }
  
  public boolean mayReturnStaleWhileRevalidating(HttpCacheEntry entry, Date now)
  {
    for (Header h : entry.getHeaders("Cache-Control")) {
      for (HeaderElement elt : h.getElements()) {
        if ("stale-while-revalidate".equalsIgnoreCase(elt.getName())) {
          try
          {
            int allowedStalenessLifetime = Integer.parseInt(elt.getValue());
            if (getStalenessSecs(entry, now) <= allowedStalenessLifetime) {
              return true;
            }
          }
          catch (NumberFormatException nfe) {}
        }
      }
    }
    return false;
  }
  
  public boolean mayReturnStaleIfError(HttpRequest request, HttpCacheEntry entry, Date now)
  {
    long stalenessSecs = getStalenessSecs(entry, now);
    return (mayReturnStaleIfError(request.getHeaders("Cache-Control"), stalenessSecs)) || (mayReturnStaleIfError(entry.getHeaders("Cache-Control"), stalenessSecs));
  }
  
  private boolean mayReturnStaleIfError(Header[] headers, long stalenessSecs)
  {
    boolean result = false;
    for (Header h : headers) {
      for (HeaderElement elt : h.getElements()) {
        if ("stale-if-error".equals(elt.getName())) {
          try
          {
            int staleIfErrorSecs = Integer.parseInt(elt.getValue());
            if (stalenessSecs <= staleIfErrorSecs)
            {
              result = true;
              break;
            }
          }
          catch (NumberFormatException nfe) {}
        }
      }
    }
    return result;
  }
  
  @Deprecated
  protected Date getDateValue(HttpCacheEntry entry)
  {
    return entry.getDate();
  }
  
  protected Date getLastModifiedValue(HttpCacheEntry entry)
  {
    Header dateHdr = entry.getFirstHeader("Last-Modified");
    if (dateHdr == null) {
      return null;
    }
    return DateUtils.parseDate(dateHdr.getValue());
  }
  
  protected long getContentLengthValue(HttpCacheEntry entry)
  {
    Header cl = entry.getFirstHeader("Content-Length");
    if (cl == null) {
      return -1L;
    }
    try
    {
      return Long.parseLong(cl.getValue());
    }
    catch (NumberFormatException ex) {}
    return -1L;
  }
  
  protected boolean hasContentLengthHeader(HttpCacheEntry entry)
  {
    return null != entry.getFirstHeader("Content-Length");
  }
  
  protected boolean contentLengthHeaderMatchesActualLength(HttpCacheEntry entry)
  {
    return (!hasContentLengthHeader(entry)) || (getContentLengthValue(entry) == entry.getResource().length());
  }
  
  protected long getApparentAgeSecs(HttpCacheEntry entry)
  {
    Date dateValue = entry.getDate();
    if (dateValue == null) {
      return 2147483648L;
    }
    long diff = entry.getResponseDate().getTime() - dateValue.getTime();
    if (diff < 0L) {
      return 0L;
    }
    return diff / 1000L;
  }
  
  protected long getAgeValue(HttpCacheEntry entry)
  {
    long ageValue = 0L;
    for (Header hdr : entry.getHeaders("Age"))
    {
      long hdrAge;
      try
      {
        hdrAge = Long.parseLong(hdr.getValue());
        if (hdrAge < 0L) {
          hdrAge = 2147483648L;
        }
      }
      catch (NumberFormatException nfe)
      {
        hdrAge = 2147483648L;
      }
      ageValue = hdrAge > ageValue ? hdrAge : ageValue;
    }
    return ageValue;
  }
  
  protected long getCorrectedReceivedAgeSecs(HttpCacheEntry entry)
  {
    long apparentAge = getApparentAgeSecs(entry);
    long ageValue = getAgeValue(entry);
    return apparentAge > ageValue ? apparentAge : ageValue;
  }
  
  protected long getResponseDelaySecs(HttpCacheEntry entry)
  {
    long diff = entry.getResponseDate().getTime() - entry.getRequestDate().getTime();
    return diff / 1000L;
  }
  
  protected long getCorrectedInitialAgeSecs(HttpCacheEntry entry)
  {
    return getCorrectedReceivedAgeSecs(entry) + getResponseDelaySecs(entry);
  }
  
  protected long getResidentTimeSecs(HttpCacheEntry entry, Date now)
  {
    long diff = now.getTime() - entry.getResponseDate().getTime();
    return diff / 1000L;
  }
  
  protected long getMaxAge(HttpCacheEntry entry)
  {
    long maxage = -1L;
    for (Header hdr : entry.getHeaders("Cache-Control")) {
      for (HeaderElement elt : hdr.getElements()) {
        if (("max-age".equals(elt.getName())) || ("s-maxage".equals(elt.getName()))) {
          try
          {
            long currMaxAge = Long.parseLong(elt.getValue());
            if ((maxage == -1L) || (currMaxAge < maxage)) {
              maxage = currMaxAge;
            }
          }
          catch (NumberFormatException nfe)
          {
            maxage = 0L;
          }
        }
      }
    }
    return maxage;
  }
  
  protected Date getExpirationDate(HttpCacheEntry entry)
  {
    Header expiresHeader = entry.getFirstHeader("Expires");
    if (expiresHeader == null) {
      return null;
    }
    return DateUtils.parseDate(expiresHeader.getValue());
  }
  
  public boolean hasCacheControlDirective(HttpCacheEntry entry, String directive)
  {
    for (Header h : entry.getHeaders("Cache-Control")) {
      for (HeaderElement elt : h.getElements()) {
        if (directive.equalsIgnoreCase(elt.getName())) {
          return true;
        }
      }
    }
    return false;
  }
  
  public long getStalenessSecs(HttpCacheEntry entry, Date now)
  {
    long age = getCurrentAgeSecs(entry, now);
    long freshness = getFreshnessLifetimeSecs(entry);
    if (age <= freshness) {
      return 0L;
    }
    return age - freshness;
  }
}

/* Location:
 * Qualified Name:     org.apache.http.impl.client.cache.CacheValidityPolicy
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.apache.http.impl.client.cache;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpRequest;
import org.apache.http.HttpVersion;
import org.apache.http.ProtocolVersion;
import org.apache.http.RequestLine;
import org.apache.http.annotation.Immutable;

@Immutable
class CacheableRequestPolicy
{
  private final Log log = LogFactory.getLog(getClass());
  
  public boolean isServableFromCache(HttpRequest request)
  {
    String method = request.getRequestLine().getMethod();
    
    ProtocolVersion pv = request.getRequestLine().getProtocolVersion();
    if (HttpVersion.HTTP_1_1.compareToVersion(pv) != 0)
    {
      log.trace("non-HTTP/1.1 request was not serveable from cache");
      return false;
    }
    if (!method.equals("GET"))
    {
      log.trace("non-GET request was not serveable from cache");
      return false;
    }
    if (request.getHeaders("Pragma").length > 0)
    {
      log.trace("request with Pragma header was not serveable from cache");
      return false;
    }
    Header[] cacheControlHeaders = request.getHeaders("Cache-Control");
    for (Header cacheControl : cacheControlHeaders) {
      for (HeaderElement cacheControlElement : cacheControl.getElements())
      {
        if ("no-store".equalsIgnoreCase(cacheControlElement.getName()))
        {
          log.trace("Request with no-store was not serveable from cache");
          return false;
        }
        if ("no-cache".equalsIgnoreCase(cacheControlElement.getName()))
        {
          log.trace("Request with no-cache was not serveable from cache");
          return false;
        }
      }
    }
    log.trace("Request was serveable from cache");
    return true;
  }
}

/* Location:
 * Qualified Name:     org.apache.http.impl.client.cache.CacheableRequestPolicy
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.apache.http.impl.client.cache;

import java.util.Date;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.annotation.Immutable;
import org.apache.http.client.cache.HttpCacheEntry;
import org.apache.http.client.utils.DateUtils;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicHttpResponse;

@Immutable
class CachedHttpResponseGenerator
{
  private final CacheValidityPolicy validityStrategy;
  
  CachedHttpResponseGenerator(CacheValidityPolicy validityStrategy)
  {
    this.validityStrategy = validityStrategy;
  }
  
  CachedHttpResponseGenerator()
  {
    this(new CacheValidityPolicy());
  }
  
  HttpResponse generateResponse(HttpCacheEntry entry)
  {
    Date now = new Date();
    HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, entry.getStatusCode(), entry.getReasonPhrase());
    
    response.setHeaders(entry.getAllHeaders());
    if (entry.getResource() != null)
    {
      HttpEntity entity = new CacheEntity(entry);
      addMi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2019. Infinite Loop Ltd