Code Monkey home page Code Monkey logo

httpresponsecache's Introduction

HttpResponseCache

The HttpResponseCache library provides transparent and automatic caching of HTTP and HTTPS requests that use the java.net.HttpUrlConnection classes.

For information on how to use HttpUrlConnection, refer to the (Android documentation)[https://developer.android.com/reference/java/net/HttpURLConnection.html] - don't worry, the information also applies to non-Android Java.

Requirements

This library will work on Java 5 and later, and (theoretically) any version of Android (it has only been tested back to 1.5).

Usage

When using Maven (or any of the dependency management systems that use Maven's library, such as Ivy), simply add the dependency reference. The library, and its dependencies, are in Maven Central: http://mvnrepository.com/artifact/com.integralblue/httpresponsecache For example, for a Maven pom.xml:

<dependency>
  <groupId>com.integralblue</groupId>
  <artifactId>httpresponsecache</artifactId>
  <version>1.3</version>
</dependency>

If Maven is not in use, such as when using a non-Maven Android project, include the httpresponsecache jar and its dependency, DiskLruCache.

In the application, before making any HTTP(s) requests, simply call:

com.integralblue.httpresponsecache.HttpResponseCache.install(File directory, long maxSize);

Where directory is the directory to hold cache data, and maxSize is the maximum size of the cache in bytes.

On Android, it may be desirable to use Android 4.0 and higher's built in HttpResponseCache and fall back to this library on older versions of Android. This code would do that:

final long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
final File httpCacheDir = new File(getCacheDir(), "http");
try {
    Class.forName("android.net.http.HttpResponseCache")
        .getMethod("install", File.class, long.class)
        .invoke(null, httpCacheDir, httpCacheSize);
} catch (Exception httpResponseCacheNotAvailable) {
    Ln.d(httpResponseCacheNotAvailable, "android.net.http.HttpResponseCache not available, probably because we're running on a pre-ICS version of Android. Using com.integralblue.httpresponsecache.HttpHttpResponseCache.");
    try{
        com.integralblue.httpresponsecache.HttpResponseCache.install(httpCacheDir, httpCacheSize);
    }catch(Exception e){
        Ln.e(e, "Failed to set up com.integralblue.httpresponsecache.HttpResponseCache");
    }
}

Note that this library may be more up to date and have more bug fixes / features / performance improvements than the version included with the Android platform being targeted. For example, this library includes some performance improvements that are in Jelly Bean (4.1) but not in ICS (4.0). So if you want users on ICS to get these performance improvements, always use this library, and do not conditionally use the one from Android. In other words, you may want to always simply use:

com.integralblue.httpresponsecache.HttpResponseCache.install(httpCacheDir, httpCacheSize);

and not use the conditional code above.

License

This library is licensed under the terms of the Apache License, Version 2.0. You may obtain a copy of the license at http://www.apache.org/licenses/LICENSE-2.0

Origin/Contributors

This library consists of code copied from the Android Open Source Project (AOSP). android.net.http.HttpResponseCache was copied, along with all of its non-standard-Java dependencies, to a new namespace and then modified to work under standard Java. Special thanks for Jesse Wilson for writing android.net.http.HttpResponseCache and assisting in the creation of this library. Also special thanks to Jake Wharton for porting DiskLruCache from AOSP, greatly reducing the amount of work necessary to create this library.

httpresponsecache's People

Contributors

candrews avatar kevinsawicki avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

httpresponsecache's Issues

java.lang.NoSuchMethodError: java.lang.String.isEmpty on Android 2.2

After upgrade code from Android 4.1 it doesn't wok on older Android:

08-13 08:00:25.909: E/AndroidRuntime(1836): Caused by: java.lang.NoSuchMethodError: java.lang.String.isEmpty
08-13 08:00:25.909: E/AndroidRuntime(1836): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.readHeaders(HttpEngine.java:612)
08-13 08:00:25.909: E/AndroidRuntime(1836): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:565)
08-13 08:00:25.909: E/AndroidRuntime(1836): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.readResponse(HttpEngine.java:817)
08-13 08:00:25.909: E/AndroidRuntime(1836): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:286)
08-13 08:00:25.909: E/AndroidRuntime(1836): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:498)

Handling Temporary Redirects (Http Response Code: 307)

This happen when using HTTPResponseCache on a site that redirects to other address. The site will return code 307 and will provide Location parameter in the header.

When this happens, the following stack trace will be displayed:
09-21 10:47:47.846: E/ConnectionManagement(1532): Error found: java.net.SocketTimeoutException: failed to connect to abcd.efgh.com/12.923.211.34 (port 80) after 60000ms
09-21 10:47:47.846: E/ConnectionManagement(1532): at libcore.io.IoBridge.connectErrno(IoBridge.java:150)
09-21 10:47:47.846: E/ConnectionManagement(1532): at libcore.io.IoBridge.connect(IoBridge.java:112)
09-21 10:47:47.846: E/ConnectionManagement(1532): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
09-21 10:47:47.846: E/ConnectionManagement(1532): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
09-21 10:47:47.846: E/ConnectionManagement(1532): at java.net.Socket.connect(Socket.java:842)
09-21 10:47:47.846: E/ConnectionManagement(1532): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpConnection.(HttpConnection.java:78)
09-21 10:47:47.846: E/ConnectionManagement(1532): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpConnection.(HttpConnection.java:51)
09-21 10:47:47.846: E/ConnectionManagement(1532): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:359)
09-21 10:47:47.846: E/ConnectionManagement(1532): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:80)
09-21 10:47:47.846: E/ConnectionManagement(1532): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpConnection.connect(HttpConnection.java:129)
09-21 10:47:47.846: E/ConnectionManagement(1532): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:313)
09-21 10:47:47.846: E/ConnectionManagement(1532): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.connect(HttpEngine.java:308)
09-21 10:47:47.846: E/ConnectionManagement(1532): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:287)
09-21 10:47:47.846: E/ConnectionManagement(1532): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:237)

Responses are not cached

I'm running into some strange issues that I'm having a hard time tracking down, I'm wondering if anyone else has encountered something similar. This issue is present with the port and the built in HttpResponseCache.

I'm making a series of api calls to my server and they are being cached so the next time the user loads a portion of the app the cached response is used. It works very well, but there are a few times when the response does not get cached (This is not a max cache size issue, the cache is initialized at 10mb and the responses are a few hundred k of json and they are not cached even when the cache is empy).

It seems like it is related to the size of the response as when I reduce the number of records I'm returning from the server the response is successfully cached and when I step the number of results up there is a point when it stops caching. One response is 7.83k and it is successfully cached, but increasing the number of results in the response which results in a 17.6k response results in a failure to cache. To make it even more complicated, on an older device it is happening more often.

I'm not familiar with DiskLruCache, but is this a device memory issue?

HttpResponseCache slow down UrlConnection

in simulator with "slow" file system access and mobile devices with bad file system performance:
A simple http get download is slower when HttpResponseCache is enabled.

URLConnection con = url.openConnection();
...
InputStream is = (InputStream) con.getContent();

i suppose HttpResponseCache store it on filesystem before the app is allowed to access the inputstream.

in my opinion this library should only be used if you expect high cache hit ratio.

Our service used "Etag" and "If Modified Since" headers. (for instance for images with size of about 15kb)
With enabled HttpResponseCache it was noticeable slower (with 304-not modified header) than regular urlConnection without caching at all.

Failed to cache data on 3.0 Honeycomb

08-13 23:27:18.365: E/ConnectionManagement(422): Error found: java.net.ConnectException: /192.168.0.101:8888 - Connection refused
08-13 23:27:18.365: E/ConnectionManagement(422): at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:211)
08-13 23:27:18.365: E/ConnectionManagement(422): at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:431)
08-13 23:27:18.365: E/ConnectionManagement(422): at java.net.Socket.connect(Socket.java:901)
08-13 23:27:18.365: E/ConnectionManagement(422): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpConnection.(HttpConnection.java:78)
08-13 23:27:18.365: E/ConnectionManagement(422): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpConnection.(HttpConnection.java:51)
08-13 23:27:18.365: E/ConnectionManagement(422): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:359)
08-13 23:27:18.365: E/ConnectionManagement(422): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:80)
08-13 23:27:18.365: E/ConnectionManagement(422): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpConnection.connect(HttpConnection.java:129)
08-13 23:27:18.365: E/ConnectionManagement(422): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:313)
08-13 23:27:18.365: E/ConnectionManagement(422): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.connect(HttpEngine.java:308)
08-13 23:27:18.365: E/ConnectionManagement(422): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:287)
08-13 23:27:18.365: E/ConnectionManagement(422): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:237)
08-13 23:27:18.365: E/ConnectionManagement(422): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:84)

The application already access the web page once (the page header Cache-Control is 60). Then the server is disabled within 60 second and application tries to access again. No data found and the stack trace above is produce.
Using same library in Android 4.x, it will retrieve the page from the cache.

Concurrent modification exception in HttpResponseCache.uriToKey

Hi,

I am not sure if I am doing things wrong or if this is a known issue. I have an ImageLoader using this awesome project (just have to mark this because its really great stuff) where I have two working threads running concurrently using ThreadPoolExecutor. However ocassionally I get problem with the fact that MessageDigest.getInstance is not thread safe and its used to generate the cache file names. (I am using a Galaxy Nexus phone).

For each working thread I have the following flow:

            URL url = new URL(resultHolder.uri);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestProperty("User-Agent", userAgent);
            conn.setReadTimeout(SOCKET_READ_TIMOUT_MS);
            conn.setConnectTimeout(SOCKET_CONNECTION_TIMOUT_MS);
            conn.setRequestProperty("Accept-Encoding", "native");
            conn.setDoInput(true);
            conn.setUseCaches(true);


            long startTimeMs = System.currentTimeMillis();

            conn.connect();                 

and occasionally I get different exceptions in MessageDigest.getInstance as seen below.

Is there some special thing that I can do when working with multiple threads to avoid this (currently I am performing a retry)?

09-25 16:29:57.544: E/sml.ImageLoader(2989): java.util.ConcurrentModificationException
09-25 16:29:57.544: E/sml.ImageLoader(2989): at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:569)
09-25 16:29:57.544: E/sml.ImageLoader(2989): at org.apache.harmony.security.fortress.Services.updateServiceInfo(Services.java:186)
09-25 16:29:57.544: E/sml.ImageLoader(2989): at org.apache.harmony.security.fortress.Services.refresh(Services.java:234)
09-25 16:29:57.544: E/sml.ImageLoader(2989): at org.apache.harmony.security.fortress.Engine.getInstance(Engine.java:137)
09-25 16:29:57.544: E/sml.ImageLoader(2989): at java.security.MessageDigest.getInstance(MessageDigest.java:91)
09-25 16:29:57.544: E/sml.ImageLoader(2989): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpResponseCache.uriToKey(HttpResponseCache.java:87)
09-25 16:29:57.544: E/sml.ImageLoader(2989): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpResponseCache.get(HttpResponseCache.java:97)
09-25 16:29:57.544: E/sml.ImageLoader(2989): at com.integralblue.httpresponsecache.HttpResponseCache.get(HttpResponseCache.java:205)
09-25 16:29:57.544: E/sml.ImageLoader(2989): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.initResponseSource(HttpEngine.java:260)
09-25 16:29:57.544: E/sml.ImageLoader(2989): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:221)
09-25 16:29:57.544: E/sml.ImageLoader(2989): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:84)

Regards/
Lars

setDefaultHostnameVerifier in install()

It is good Idea to do this in install method?
HttpsURLConnection.setDefaultHostnameVerifier(new DefaultHostnameVerifier());
If I already have custom verifier it override it.
I think that better would be if some custom verifier was already set before do this.
What do you think?

NameConstraints use incorrect signature

Hi.
I'm trying to build HttpResponseCache myself using eclipse.
I've added all of the necessary libraries, including the latest BouncyCastle build.
The only build error still left is NameConstraints reference in TestKeyStore.java file.
According to specification here http://www.bouncycastle.org/docs/docs1.5on/index.html it should be having GeneralSubtree[] as arguments, but you use Vectors in your code.

https://github.com/candrews/HttpResponseCache/blob/master/src/test/java/com/integralblue/httpresponsecache/compat/java/security/TestKeyStore.java
x509cg.addExtension(X509Extensions.NameConstraints,
true,
new NameConstraints(permittedNameConstraints,
excludedNameConstraints));

I'll switch to jars for now and leaving a message here just for you to know that issue is present.

Not respecting max-age: 0 for Cache-Control

For some reason even if I put a addRequestProptery("Cache-Control", "max-age: 0") on a connection, the HttpResponseCache is always returning the cached data. If I disable the HttpResponseCache completely, then the most current data is always returned.

I checked the headers being returned using Chrome and the Response headers are setting the max-age headers with a value of zero.

Is there a way to ignore the cache during a particular connection, particularly if you are doing a put or a get with a parameter that may do updates?

Snapshot give unknown method error in Android 2.2

08-06 22:02:27.794: E/AndroidRuntime(312): Caused by: java.lang.NoSuchMethodError: java.lang.String.getBytes
08-06 22:02:27.794: E/AndroidRuntime(312): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.writeRequestHeaders(HttpEngine.java:642)
08-06 22:02:27.794: E/AndroidRuntime(312): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.readResponse(HttpEngine.java:803)
08-06 22:02:27.794: E/AndroidRuntime(312): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:286)
08-06 22:02:27.794: E/AndroidRuntime(312): at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:180)

SimpleDateFormat can be extremely slow to parse

When you use like

new SimpleDateFormat("formatString", Locale.US)

the system takes a long time to load time zone names for en_US in the logcat window.

When I changed it to Locale.getDefault(), no more "Loaded time zone names for en_US in"

default ssl socket factory set after cache install is ignored on 2.2

I'm doing the following:

  1. Installing HttpResponseCache (1.3 latest), then
  2. Setting a default SSL socket factory via HttpsURLConnection.setDefaultSSLSocketFactory() in order to do two-way SSL authentication.

This works fine in 2.3 and above. In 2.2, however, when HttpResponseCache is installed, SSL connections ignore the default SSL socket factory I set.

Any thoughts on how to work around this? Would it be possible to patch HttpResponseCache so that the behavior on 2.2 matches the behavior on 2.3+?

java.net.SocketException: sendto failed: EPIPE (Broken pipe)

We are seeing random, but frequent, socket exceptions when upgrading our lib from 1.2 to 1.3. This issue is being observed on ICS, but doesn't happen on Gingerbread. Also, as stated, we don't get this problem in version 1.2 of the library.

Observed on:
Verizon HTC Rezound
Android Version: 4.0.3
HTC Sense Version: 3.6

Stack trace:
W/System.err(14248): java.net.SocketException: sendto failed: EPIPE (Broken pipe)
W/System.err(14248): at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:496)
W/System.err(14248): at libcore.io.IoBridge.sendto(IoBridge.java:465)
W/System.err(14248): at java.net.PlainSocketImpl.write(PlainSocketImpl.java:507)
W/System.err(14248): at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:46)
W/System.err(14248): at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:269)
W/System.err(14248): at java.io.BufferedOutputStream.flushInternal(BufferedOutputStream.java:185)
W/System.err(14248): at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:85)
W/System.err(14248): at com.integralblue.httpresponsecache.compat.libcore.net.http.FixedLengthOutputStream.flush(FixedLengthOutputStream.java:48)
W/System.err(14248): at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:86)
W/System.err(14248): at java.io.FilterOutputStream.close(FilterOutputStream.java:61)
W/System.err(14248): at java.io.BufferedOutputStream.close(BufferedOutputStream.java:152)
-- SNIP --
W/System.err(14248): Caused by: libcore.io.ErrnoException: sendto failed: EPIPE (Broken pipe)
W/System.err(14248): at libcore.io.Posix.sendtoBytes(Native Method)
W/System.err(14248): at libcore.io.Posix.sendto(Posix.java:146)
W/System.err(14248): at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177)
W/System.err(14248): at libcore.io.IoBridge.sendto(IoBridge.java:463)
W/System.err(14248): ... 23 more

Reinstalling the cache fails every time

Use Case: User wants to clear all data stored in the cache.

To achieve that, I called HttpResponceCache.delete(). Everything worked as expected, but I lost the http cache in the process. After trying to install() again, I received the following exception:

08-04 17:59:37.270: E/AndroidRuntime(328): java.lang.RuntimeException: An error occured while executing doInBackground()
...
08-04 17:59:37.270: E/AndroidRuntime(328): Caused by: java.lang.Error: Attempt to set factory more than once.
08-04 17:59:37.270: E/AndroidRuntime(328): at java.net.URL.setURLStreamHandlerFactory(URL.java:139)
08-04 17:59:37.270: E/AndroidRuntime(328): at com.integralblue.httpresponsecache.HttpResponseCache.install(HttpResponseCache.java:186)

Add support for non-shared cache?

HttpResponseCache (in android) has been implemented following the guidelines for a shared cache.
This means that requests containing an 'Authorization' header are never cached, while you might want this in some cases.

When installing a cache, a flag could indicate wheter you want it to behave as shared or non-shared (private). It is then obviously up to the developer to make sure no sensitive informations such as credentials are cached on the filesystem.

java.lang.NoClassDefFoundError

I use the HttpResponseCache for several weeks now. Since today I get the following error when istalling the cache with "com.integralblue.httpresponsecache.HttpResponseCache.install(httpCacheDir, httpCacheSize)":

W/dalvikvm(14655): VFY: unable to resolve static method 11: Lcom/integralblue/httpresponsecache/HttpResponseCache;.install (Ljava/io/File;J)Lcom/integralblue/httpresponsecache/HttpResponseCache;
W/dalvikvm(14655): threadid=1: thread exiting with uncaught exception (group=0x40020ac0)
E/AndroidRuntime(14655): FATAL EXCEPTION: main
E/AndroidRuntime(14655): java.lang.NoClassDefFoundError: com.integralblue.httpresponsecache.HttpResponseCache

The error occurs on Android 2.2. The source code ist unaltered I did not change anything. The only things I did, I updated some components of the Android SDK and the ADT plugin (now v. 17.0.0).

POST method request throws ProtocolException("POST does not support writing") when use it in Java

        try {
            if (doOutput) {
                if (method == HttpEngine.GET) {
                    // they are requesting a stream to write to. This implies a POST method
                    method = HttpEngine.POST;
                } else if (method != HttpEngine.POST && method != HttpEngine.PUT) {
                    // If the request method is neither POST nor PUT, then you're not writing
                    throw new ProtocolException(method + " does not support writing");
                }
            }
            httpEngine = newHttpEngine(method, rawRequestHeaders, null, null);
        } catch (IOException e) {
            httpEngineFailure = e;
            throw e;
        }

why did you use "==" while comparing two strings instead of equals method ?

if 'only-if-cached' cache control value is set, it should return 504 not 502ader

first of all,
thx for this great library. it really help me.

when only-if-cached header is set, below response is responsed,

private static final CacheResponse BAD_GATEWAY_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 502 Bad Gateway"));
        return result;
    }

but, rfc 2616 sys, it should be HTTP/1.1 504 Gateway Timeout
...
To do this, the client may include the only-if-cached directive in a request. If it receives this directive, a cache SHOULD either respond using a cached entry that is consistent with the other constraints of the request, or respond with a 504 (Gateway Timeout) status.
...

please check this doc.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4

thx again.

Detect if data is from cache

When I repeat GET request before date defined in Expires header, HTTPUrlCoonection witch enabled cache doesn't make request to server, but return data directly from cache, but I don't found way how to detect this situation.

Only way that I found is
System.currentTimeMillis() - Long.parseLong(getResponseHeader("X-Android-Received-Millis")) > 100;
But this depends on local time precision.
Will be much better if in response will be same special header which allow to recognize data from cache.
But it is probably problem of original AOSP implementation :-(

stat tracking doesn't work

We're installing an android.net.http.HttpResponseCache, but libcore's HttpEngine uses 'instanceof libcore.net.http.HttpResponseCache' to guard calls to the trackResponse() methods. So stats tracking isn't working for HTTP response caches installed through the documented API.

It worked in the tests because they don't use the android.net wrapper. Ugh.

See https://code.google.com/p/android/issues/detail?id=25418

Data not cached when gzip content-encoding is combined with chunked transfer-encoding.

See line 68 in ChunkedInputStream:

    if (bytesRemainingInChunk == 0 && in.available() >= MIN_LAST_CHUNK_LENGTH) {

Using available() on an InputStream is generally a bad idea, I guess. In many cases this will return 0.

In case of a server returning gzipped data (content-encoding: gzip) of more than a few KB, it will probably turn on chunked encoding (transfer-encoding: chunked). Most probably to support non-buffered streaming mode.

In this case the ChunkedInputStream will never commit the response data to the cache.

The easy fix is probably to reduce the if statement in line 68 to:

    if (bytesRemainingInChunk == 0) {

Does that make sense to anyone? ^^

Cheers,

dl

PUT request method are not caching

Hi ,
The PUT request methods are not caching i dont understand what is the problem with it ,and the same is not working in the case of using android.net.http.HttpResponseCache.There is no problem with the POST and GET methods.Can you please help me from this issue

Return code -1

I found very interesting thing. I started using this cache more intensively. I have about 135 files in the cache with total size 1MB.

Sometimes happen that HttpURLConnection start return -1 as HTTP return code instead of 200 and input stream is empty. When I check cache files it contain desired file, it is image and I can display it. Internet connection is OK, but it doesn't try to load new data from server, it still return only -1. If I delete cache it work normally some times.

I don't understand journal file yet, but it contain 54x hash of file that can't be loaded.

I'm testing it on the Xoom with 4.0.4 Android.

java.lang.NoSuchMethodError: Llibcore/net/http/HttpResponseCache.getCache

When executing

 HttpResponseCache.install(new File(context.getCacheDir(), "http"), size * 1024 * 1024);

I get a java.lang.NoSuchMethodError: Llibcore/net/http/HttpResponseCache.getCache error. The stack trace is pointing to

DiskLruCache installedCache = installed.delegate.getCache();

in the install method in HttpResponseCache.

I'm having the problem on Android 4.2, I haven't tested it on other versions yet

com.integralblue.httpresponsecache.compat.libcore.net.http.ResponseHeaders.chooseResponseSource(long, RequestHeaders) does not honor only-if-cached cache control directive

com.integralblue.httpresponsecache.compat.libcore.net.http.ResponseHeaders.chooseResponseSource(long, RequestHeaders) does not honor only-if-cached cache control directive

This method returns ResponseSource.CONDITIONAL_CACHE which then later does not satisfy response from cache even if it can.

Solution: check for request.onlyIfCached flag and return ResponseSource.CACHE irrespective of age and freshness

Allow pages not ending in newline

Line 202 of Streams.java bombs out if a page ends in a non-newline. Seems extreme, should allow such a scenario (I'm running into it right now!).

I would suggest just completing the read process there instead of throwing the Exception.

ArrayIndexOutOfBoundsException

I just published first app which use httpresponsecache and I start receiving this error from Crittercism. I'm not able to reproduce it, it look that all reports are from Samsung Galaxy S II phone so far, but I'm not able to recognize if this is official ROM :-(

I use 1.2 version.
I looks that this happen only for HTTPS connections.
Maybe problem is not directly in httpresponsecache but in security provider.

Has someone found similar problem?

java.lang.ArrayIndexOutOfBoundsException: src.length=20 srcPos=20 dst.length=1024 dstPos=0 length=8 at java.lang.System.arraycopy(Native Method) at org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl.engineNextBytes(SHA1PRNG_SecureRandomImpl.java:339) at org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl.engineGenerateSeed(SHA1PRNG_SecureRandomImpl.java:247) at java.security.SecureRandom.generateSeed(SecureRandom.java:348) at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:363) at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:328) at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:218) at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:480) at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:435) at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:293) at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:243) at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:84) at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:167)

Cache not updated

Seems to me that the cache is not updated, when newer files are available on the server.
To test, I wrote this little test:
public void testServerReturnsDocumentNewerThanCache() throws Exception {
server.enqueue(new MockResponse().setBody("A")
.addHeader("Last-Modified: " + formatDate(-4, TimeUnit.HOURS)));
server.enqueue(new MockResponse().setBody("B")
.addHeader("Last-Modified: " + formatDate(-2, TimeUnit.HOURS)));
server.play();

    URL url = server.getUrl("/");

    assertEquals("A", readAscii(url.openConnection()));
    assertEquals("B", readAscii(url.openConnection()));
}

It fails on the last assert. A is returned instead of B.

Cache size surpassing limit

I installed the HTTP Cache and set to it a maximum size of 5Mb, however I can constantly reproduce the cache going over the limits. I saw once, for example, this same cache dir with 20Mb of size.
Things that might or not influence this behavior:

  • I use Jake Wharton's DiskLruCache to store images also, and as far as I know it is the same algorithm used by the HTTP cache to store data. Each one is configured to its own directory, so it shouldn't influence the other. However, my image cache always trims correctly at the limit size.
  • I use AdMob to monetize my app, and I noticed that it is by far the one that is cached most. Some light use of my app with AdMob surpassed the 5Mb limit easily.

broken test

I get the follow error:

junit.framework.AssertionFailedError: expected:<[a=FIRST]> but was:<[]>
at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpResponseCacheTest.assertCookies(HttpResponseCacheTest.java:1582)
at com.integralblue.httpresponsecache.compat.libcore.net.http.HttpResponseCacheTest.testCachePlusCookies(HttpResponseCacheTest.java:1494)

Great work though!

gzip Header disappers after a requests with "max-age=0"

Hi!
I am using your lib in version 1.3 and disklrucache 1.2.1 and I have the following issue.

I make request without any extra caching request properties. I get the Response (200).
The file in the cache dir (***.0) has the following line:
Content-Encoding: gzip

Now I reload the same url with the following cache propery: addRequestProperty("Cache-Control", "max-age=0");

I get the Resonse (304) and the result is still correct. But after this request the encoding line in the ***.0 file disappears and when i make another request I get and 304 but the data isn't correct anymore.
I guess it is because the "Content-Encoding: gzip" line disappears.

Ability to override uriToKey?

I have a specific use-case where i need to override the key generation mechanism in HttpResponseCache.uriToKey

Since HttpResponseCache is a final class, it seems i cant extend it.

I want to access the same object using different urls, but they should correspond to the same object in the cache. Is there a way i can put my own hashing algorithm without cloning/forking the codebase? Or some other interface to provide a normalized url?

example:-
i access
http://foo.example.com/bar.png
http://bar.example.com/abc.png

Both should use the same object in the cache, my app knows the logic to normalize both these URLs into something common for caching purposes.

Question: If I attempt to add this myself and send pull request, is there a possibility this would make it to the codebase here? i.e. is the goal of this library to be 100% clone of Androids implementation, or is there some scope to add features that Android's lib doesn't provide?

Failed test 'testConditionalHitUpdatesCache'

In current master version, release as 1.1 is one failed test? It is bug in test or in library?

Failed tests: testConditionalHitUpdatesCache(com.integralblue.httpresponsecache.compat.libcore.net.http.HttpResponseCacheTest): null expected:<[A]> but was:<[B]>

Tests run: 131, Failures: 1, Errors: 0, Skipped: 0

incorrect content-length causes problems on ssl connection

I'm seeing an issue where, with the cache installed, loading images over an SSL connection occasionally results in garbage bytes being returned. This doesn't happen when they're loaded over plain HTTP. It also doesn't happen when the images are loaded over SSL without the HttpResponseCache installed.

I verified that the behavior is present even when I use the stock HttpResponseCache in Android 4.2.2. So it's not a problem with your port per se. Figured I'd post here, though, since I currently use your version in my app even when the stock version is present.

My current hunch is that it's misbehavior on Apache's part that's triggering this. My Apache installation seems to respond with an incorrect content length when the images are loaded over SSL. I say this because when I load them in Firefox and click "View Image Info" the non-SSL-loaded version always reports the right size whereas the SSL-loaded version reports an incorrect size. I'm guessing Firefox just uses the Content-Length value in that dialog instead of the actual number of bytes it read. It can decode and display the images in both cases, though, even when the Content-Length is wrong, so it's getting the correct bytes.

Here are two URLs that illustrate the bad Apache behavior. The only difference is HTTP vs. HTTPS:

http://rsdevelopment.malauzai.com/images/organizationdata/MMB/3.0.0/android-high-dpi/en_us/share_facebookbutton_img_20130502105154.png

https://rsdevelopment.malauzai.com/images/organizationdata/MMB/3.0.0/android-high-dpi/en_us/share_facebookbutton_img_20130502105154.png

Any thoughts on how I might start debugging this and whether it's likely to be fixable in the HttpResponseCache (or DiskLruCache) code?

Or, alternately, any idea what the hell is wrong with my Apache server? :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.