aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/network
diff options
context:
space:
mode:
authorSamuel Tardieu <sam@rfc1149.net>2012-03-25 11:29:30 +0200
committerSamuel Tardieu <sam@rfc1149.net>2012-03-25 12:57:27 +0200
commitdb2f78f8d4641ded7acf26308976fc1216ffa1bb (patch)
tree951b79c94e662152759fe15dfbfc43b4e5d6a6d9 /main/src/cgeo/geocaching/network
parent3156aedd92ab76b9727a6108d9a8e9e78b816b63 (diff)
downloadcgeo-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.java25
-rw-r--r--main/src/cgeo/geocaching/network/Network.java55
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", "~");
}
}