diff options
author | Samuel Tardieu <sam@rfc1149.net> | 2012-03-25 11:29:30 +0200 |
---|---|---|
committer | Samuel Tardieu <sam@rfc1149.net> | 2012-03-25 12:57:27 +0200 |
commit | db2f78f8d4641ded7acf26308976fc1216ffa1bb (patch) | |
tree | 951b79c94e662152759fe15dfbfc43b4e5d6a6d9 /main/src/cgeo/geocaching/network | |
parent | 3156aedd92ab76b9727a6108d9a8e9e78b816b63 (diff) | |
download | cgeo-db2f78f8d4641ded7acf26308976fc1216ffa1bb.zip cgeo-db2f78f8d4641ded7acf26308976fc1216ffa1bb.tar.gz cgeo-db2f78f8d4641ded7acf26308976fc1216ffa1bb.tar.bz2 |
Cache ETag and Last-Modified HTTP headers for images
Instead of comparing the "Last-Modified" dates and adding a round-trip to
the server, this now caches the "ETag" and "Last-Modified" headers if
they are present in the server HTTP response.
Those values are given back (using respectively "If-None-Match" and
"If-Modified-Since" request headers) to the server when requesting an
update. Most servers will answer with a "304" (use local copy) if the
requested resource has not been updated. In the unlikely case that the
server does not honor those headers, the image will be refreshed in any
case, so we will not serve old images to the user.
The rationale for storing the "Last-Modified" return value is to conform
to RFC 2616 advice to treat it as opaque because the server might do an
exact string comparison instead of an ordered date comparison.
Diffstat (limited to 'main/src/cgeo/geocaching/network')
-rw-r--r-- | main/src/cgeo/geocaching/network/HtmlImage.java | 25 | ||||
-rw-r--r-- | main/src/cgeo/geocaching/network/Network.java | 55 |
2 files changed, 34 insertions, 46 deletions
diff --git a/main/src/cgeo/geocaching/network/HtmlImage.java b/main/src/cgeo/geocaching/network/HtmlImage.java index df47392..0aa349a 100644 --- a/main/src/cgeo/geocaching/network/HtmlImage.java +++ b/main/src/cgeo/geocaching/network/HtmlImage.java @@ -72,24 +72,7 @@ public class HtmlImage implements Html.ImageGetter { return new BitmapDrawable(getTransparent1x1Image()); } - Bitmap imagePre = null; - - // if image is just being stored, check if online version is newer than stored version - if (onlySave) { - // returns 0 if file does not exists - final long localDate = LocalStorage.getStorageFile(geocode, url, true, false).lastModified(); - // returns 0 if website does not support last modified date or error occurs - final long onlineDate = Network.requestLastModifiedDate(makeAbsoluteURL(url)); - // image was stored since it was last changed online, so no need to download again - if (localDate > onlineDate) { - return null; - } - } - - // Load image from cache - if (!onlySave) { - imagePre = loadImageFromStorage(url); - } + Bitmap imagePre = onlySave ? null : loadImageFromStorage(url); // Download image and save it to the cache if (imagePre == null || onlySave) { @@ -97,9 +80,9 @@ public class HtmlImage implements Html.ImageGetter { if (absoluteURL != null) { try { - final HttpResponse httpResponse = Network.request(absoluteURL, null, false); - if (httpResponse != null) { - final File file = LocalStorage.getStorageFile(geocode, url, true, true); + final File file = LocalStorage.getStorageFile(geocode, url, true, true); + final HttpResponse httpResponse = Network.request(absoluteURL, null, false, file); + if (httpResponse != null && httpResponse.getStatusLine().getStatusCode() == 200) { LocalStorage.saveEntityToFile(httpResponse, file); } } catch (Exception e) { diff --git a/main/src/cgeo/geocaching/network/Network.java b/main/src/cgeo/geocaching/network/Network.java index b7beed2..4798d83 100644 --- a/main/src/cgeo/geocaching/network/Network.java +++ b/main/src/cgeo/geocaching/network/Network.java @@ -3,6 +3,7 @@ package cgeo.geocaching.network; import cgeo.geocaching.Settings; import cgeo.geocaching.cgBase; import cgeo.geocaching.enumerations.StatusCode; +import cgeo.geocaching.files.LocalStorage; import cgeo.geocaching.utils.BaseUtils; import org.apache.commons.collections.CollectionUtils; @@ -40,11 +41,9 @@ import org.json.JSONObject; import android.net.Uri; import android.util.Log; +import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; import java.net.URLEncoder; import java.util.List; import java.util.zip.GZIPInputStream; @@ -209,9 +208,11 @@ public abstract class Network { * @param uri * @param params * @param xContentType + * @param cacheFile + * the name of the file storing the cached resource, or null not to use one * @return */ - public static HttpResponse request(final String uri, final Parameters params, final boolean xContentType) { + public static HttpResponse request(final String uri, final Parameters params, final boolean xContentType, final File cacheFile) { final String fullUri = params == null ? uri : Uri.parse(uri).buildUpon().encodedQuery(params.toString()).build().toString(); final HttpRequestBase request = new HttpGet(fullUri); @@ -221,9 +222,33 @@ public abstract class Network { request.setHeader("Content-Type", "application/x-www-form-urlencoded"); } + if (cacheFile != null) { + final String etag = LocalStorage.getSavedHeader(cacheFile, "etag"); + if (etag != null) { + request.setHeader("If-None-Match", etag); + } else { + final String lastModified = LocalStorage.getSavedHeader(cacheFile, "last-modified"); + if (lastModified != null) { + request.setHeader("If-Modified-Since", lastModified); + } + } + } + return Network.request(request); } + /** + * GET HTTP request + * + * @param uri + * @param params + * @param xContentType + * @return + */ + public static HttpResponse request(final String uri, final Parameters params, final boolean xContentType) { + return request(uri, params, xContentType, null); + } + public static HttpResponse request(final HttpRequestBase request) { request.setHeader("Accept-Charset", "utf-8,iso-8859-1;q=0.8,utf-16;q=0.8,*;q=0.7"); request.setHeader("Accept-Language", "en-US,*;q=0.9"); @@ -360,27 +385,7 @@ public abstract class Network { } public static String urlencode_rfc3986(String text) { - final String encoded = StringUtils.replace(URLEncoder.encode(text).replace("+", "%20"), "%7E", "~"); - - return encoded; - } - - /** - * Returns the value of the response header field <code>last-modified</code> or 0 if this value is not set. - * - * @param url - * to retrieve last modified date of - * @return the value of the <cod>last-modified</code> header field. - */ - public static long requestLastModifiedDate(String url) { - try { - return ((HttpURLConnection) new URL(url).openConnection()).getLastModified(); - } catch (MalformedURLException e) { - Log.e(Settings.tag, "Failed to get last modified date for: " + url + " " + e); - } catch (IOException e) { - Log.e(Settings.tag, "Failed to get last modified date for: " + url + " " + e); - } - return 0; + return StringUtils.replace(URLEncoder.encode(text).replace("+", "%20"), "%7E", "~"); } } |