diff --git a/src/net/i2p/android/apps/EepGetFetcher.java b/src/net/i2p/android/apps/EepGetFetcher.java
index f3b40bfb301314869dacffdfaed234be70dd3cf7..8b64836c10d5cdfa4f7aeab0a75b7d623a3c18f1 100644
--- a/src/net/i2p/android/apps/EepGetFetcher.java
+++ b/src/net/i2p/android/apps/EepGetFetcher.java
@@ -4,6 +4,7 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 
 import net.i2p.I2PAppContext;
 import net.i2p.data.DataHelper;
@@ -29,7 +30,10 @@ public class EepGetFetcher implements EepGet.StatusListener {
     private static final String ERROR_ROUTER = "<p>Your router does not appear to be up.</p>";
     private static final String ERROR_FOOTER = "</body></html>";
 
-
+    /**
+     *  Writes to temp file, call getData()
+     *  to get the data as a String
+     */
     public EepGetFetcher(String url) {
         _context = I2PAppContext.getGlobalContext();
         _log = _context.logManager().getLog(EepGetFetcher.class);
@@ -43,6 +47,20 @@ public class EepGetFetcher implements EepGet.StatusListener {
         //_eepget.addStatusListener(this);
     }
     
+    /**
+     *  Writes to output stream
+     */
+    public EepGetFetcher(String url, OutputStream out) {
+        _context = I2PAppContext.getGlobalContext();
+        _log = _context.logManager().getLog(EepGetFetcher.class);
+        _url = url;
+        _file = null;
+        _eepget = new EepGet(_context, true, "localhost", 4444, 0, -1, MAX_LEN,
+                             null, out, url,
+                             true, null, null, null);
+        //_eepget.setWriteErrorToOutput();
+    }
+    
     public void addStatusListener(EepGet.StatusListener l) {
         _eepget.addStatusListener(l);
     }
@@ -83,6 +101,7 @@ public class EepGetFetcher implements EepGet.StatusListener {
     }
 
     /**
+     *  Only for the constructor without the output stream
      *  Only call ONCE!
      *  FIXME we don't get the proxy error pages this way
      */
diff --git a/src/net/i2p/android/router/provider/CacheProvider.java b/src/net/i2p/android/router/provider/CacheProvider.java
index ba3fd066970306420c4727efa5d5703f0daf39ed..26276b7915a5c2e47177540e3563eadead750530 100644
--- a/src/net/i2p/android/router/provider/CacheProvider.java
+++ b/src/net/i2p/android/router/provider/CacheProvider.java
@@ -8,9 +8,13 @@ import android.os.ParcelFileDescriptor;
 
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
+import net.i2p.android.apps.EepGetFetcher;
+import net.i2p.android.router.util.AppCache;
 import net.i2p.android.router.util.Util;
 
 /**
@@ -44,6 +48,11 @@ public class CacheProvider extends ContentProvider {
     public static final String DATA = "_data";
     private static final String QUERY_MARKER = "!!QUERY!!";
 
+    private static final String ERROR_HEADER = "<html><head><title>Not Found</title></head><body>";
+    private static final String ERROR_URL = "<p>Unable to load URL: ";
+    private static final String ERROR_ROUTER = "<p>Your router does not appear to be up.</p>";
+    private static final String ERROR_FOOTER = "</body></html>";
+
     /**
      *  Generate a cache content URI for a given URI key
      *  @param key must contain a scheme, authority and path
@@ -90,30 +99,64 @@ public class CacheProvider extends ContentProvider {
             throw new FileNotFoundException("Bad uri no path? " + uri);
         String[] segs = resPath.split("/", 5);
         // first seg is empty since string starts with /
-        String nonce = segs.length > 1 ? segs[1] : "unset";
-        String scheme = segs.length > 2 ? segs[2] : "unset";
-        String host = segs.length > 3 ? segs[3] : "unset";
-        String realPath = segs.length > 4 ? segs[4] : "unset";
+        String nonce = segs.length > 1 ? segs[1] : null;
+        String scheme = segs.length > 2 ? segs[2] : null;
+        String host = segs.length > 3 ? segs[3].toLowerCase() : null;
+        String realPath = segs.length > 4 ? segs[4] : "";
         String query = uri.getEncodedQuery();
         if (query == null) {
             int marker = realPath.indexOf(QUERY_MARKER);
             if (marker >= 0) {
                 realPath = realPath.substring(0, marker);
                 query = realPath.substring(marker + QUERY_MARKER.length());
-            } else {
-                query = "unset";
             }
         }
-        String debug = "Here is where we fetch: nonce: " + nonce + "scheme: " + scheme + " host: " + host + " realPath: " + realPath + " query: " + query;
+        String debug = "CacheProvider nonce: " + nonce + " scheme: " + scheme + " host: " + host + " realPath: " + realPath + " query: " + query;
         Util.e(debug);
-        // convert the encoded path to the new uri
-        //load the URL with eepget
-      /**
-        File file = new File(path);
-        ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
-        return parcel;
-       **/
-        throw new FileNotFoundException(debug);
+        if ((!NONCE.equals(nonce)) ||
+            (!"http".equals(scheme)) ||
+            (host == null) ||
+            (!host.endsWith(".i2p")))
+            throw new FileNotFoundException(debug);
+        String newUri = scheme + "://" + host + '/' + realPath;
+        if (query != null)
+            newUri += '?' + query;
+
+        Util.e("CacheProvider fetching: " + newUri);
+        return eepFetch(newUri);
+    }
+
+    private ParcelFileDescriptor eepFetch(String url) throws FileNotFoundException {
+        AppCache cache = AppCache.getInstance();
+        if (cache == null) {
+            Util.e("app cache uninitialized " + url);
+            throw new FileNotFoundException("uninitialized");
+        }
+        Uri uri = Uri.parse(url);
+        OutputStream out;
+        try {
+            out = cache.createCacheFile(uri);
+        } catch (IOException ioe) {
+            throw new FileNotFoundException(ioe.toString());
+        }
+        // in this constructor we don't use the error output, for now
+        EepGetFetcher fetcher = new EepGetFetcher(url, out);
+        boolean success = fetcher.fetch();
+        if (success) {
+            File file = cache.getCacheFile(uri);
+            if (file.length() > 0) {
+                // this call will insert it back to us
+                Uri content = cache.addCacheFile(uri);
+                ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
+                return parcel;
+            } else {
+                 Util.e("CacheProvider Sucess but no data " + uri);
+            }
+        } else {
+            Util.e("CacheProvider Eepget fail " + uri);
+        }
+        AppCache.getInstance().removeCacheFile(uri);
+        throw new FileNotFoundException("eepget fail");
     }
 
     public int delete(Uri uri, String selection, String[] selectionArgs) {
@@ -123,6 +166,7 @@ public class CacheProvider extends ContentProvider {
     }
 
     public String getType(Uri uri) {
+        Util.e("CacheProvider getType " + uri);
         return "text/html";
     }
 
diff --git a/src/net/i2p/android/router/util/AppCache.java b/src/net/i2p/android/router/util/AppCache.java
index 8308c3adc756b9e27a0825a359011602dd6549dc..bdaacf8e75fdaaaaa1525d009188fb5ce8e21a3d 100644
--- a/src/net/i2p/android/router/util/AppCache.java
+++ b/src/net/i2p/android/router/util/AppCache.java
@@ -51,6 +51,10 @@ public class AppCache {
         return _instance;
     }
 
+    public static AppCache getInstance() {
+        return _instance;
+    }
+
     private AppCache(Context ctx) {
         _cacheDir = new File(ctx.getCacheDir(), DIR_NAME);
         _cacheDir.mkdir();
@@ -116,6 +120,16 @@ public class AppCache {
         return CacheProvider.getContentUri(key);
     }
 
+    /**
+     *  Return an abolute file path for any cached content in question.
+     *  The file may or may not exist, and it may be deleted at any time.
+     *  @param key no fragment allowed
+     */
+    public File getCacheFile(Uri key) {
+        int hash = toHash(key);
+        return toFile(hash);
+    }
+
     ////// private below here
 
     private void initialize() {