package net.i2p.android.apps; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import net.i2p.I2PAppContext; import net.i2p.data.DataHelper; import net.i2p.util.EepGet; import net.i2p.util.Log; /** * EepGet and return as a string. 256KB max. */ public class EepGetFetcher implements EepGet.StatusListener { private final I2PAppContext _context; private final Log _log; private final String _url; private final EepGet _eepget; private final File _file; private boolean _success; private static final long MAX_LEN = 256*1024; 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 (or the HTTP proxy) does not appear to be running.</p>"; private static final String ERROR_FOOTER = "</body></html>"; /** * Writes to temp file, call getData() * to get the data as a String. * Temp file sticks around forever. */ public EepGetFetcher(String url) { _context = I2PAppContext.getGlobalContext(); _log = _context.logManager().getLog(EepGetFetcher.class); _url = url; _file = new File(_context.getTempDir(), "eepget-" + _context.random().nextLong()); _eepget = new EepGet(_context, true, "localhost", 4444, 0, -1, MAX_LEN, _file.getAbsolutePath(), null, url, true, null, null, null); // use new 0.8.8 feature _eepget.setWriteErrorToOutput(); //_eepget.addStatusListener(this); } /** * Writes to output stream */ public EepGetFetcher(String url, OutputStream out, boolean writeErrorToStream) { _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); if (writeErrorToStream) _eepget.setWriteErrorToOutput(); } public void addStatusListener(EepGet.StatusListener l) { _eepget.addStatusListener(l); } public boolean fetch() { _success = _eepget.fetch(); return _success; } /** * @return non-null */ public String getContentType() { if (_eepget.getStatusCode() < 0) return "text/html"; String rv = _eepget.getContentType(); if (rv == null) return "text/html"; int semi = rv.indexOf(";"); if (semi > 0) rv = rv.substring(0, semi); return rv.toLowerCase(); } /** * @return non-null */ public String getEncoding() { if (_eepget.getStatusCode() < 0) return "UTF-8"; String type = _eepget.getContentType(); String rv; if (type == null || !type.startsWith("text")) rv = "ISO-8859-1"; else rv = "UTF-8"; return rv; } /** * @return -1 if nothing back from server */ public int getStatusCode() { return _eepget.getStatusCode(); } /** * Only for the constructor without the output stream * Only call ONCE! * FIXME we don't get the proxy error pages this way */ public String getData() { String rv; int statusCode = _eepget.getStatusCode(); if (statusCode < 0) { rv = ERROR_HEADER + ERROR_URL + "<a href=\"" + _url + "\">" + _url + "</a></p>" + ERROR_ROUTER + ERROR_FOOTER; _file.delete(); } else if (_file.length() <= 0) { rv = ERROR_HEADER + ERROR_URL + "<a href=\"" + _url + "\">" + _url + "</a> No data returned, error code: " + statusCode + "</p>" + ERROR_FOOTER; _file.delete(); } else { InputStream fis = null; try { fis = new FileInputStream(_file); byte[] data = new byte[(int) _file.length()]; DataHelper.read(fis, data); rv = new String(data, getEncoding()); } catch (IOException ioe) { _log.error("fetcher", ioe); rv = "I/O error"; } finally { if (fis != null) try { fis.close(); } catch (IOException ioe) {} _file.delete(); } } return rv; } public void attemptFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt, int numRetries, Exception cause) {} public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) {} public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) {} public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) {} public void headerReceived(String url, int attemptNum, String key, String val) {} public void attempting(String url) {} }