X-Git-Url: https://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Futils%2FDownloader.java;h=68e4dd73e285a941e3193ac6155d846fea2e8316;hb=1dbed6237611f74292af13f20f9d80c446a60020;hp=30ce4e798aff5300b30e14f200546b1e4d09ef16;hpb=eb6dcdbff86d9f55acae34af6f7d828ff0056aed;p=fanfix.git
diff --git a/src/be/nikiroo/utils/Downloader.java b/src/be/nikiroo/utils/Downloader.java
index 30ce4e7..4191d0a 100644
--- a/src/be/nikiroo/utils/Downloader.java
+++ b/src/be/nikiroo/utils/Downloader.java
@@ -30,6 +30,7 @@ public class Downloader {
private CookieManager cookies;
private TraceHandler tracer = new TraceHandler();
private Cache cache;
+ private boolean offline;
/**
* Create a new {@link Downloader}.
@@ -38,7 +39,7 @@ public class Downloader {
* the User-Agent to use to download the resources -- note that
* some websites require one, some actively blacklist real UAs
* like the one from wget, some whitelist a couple of browsers
- * only (!)
+ * only (!) -- can be NULL
*/
public Downloader(String UA) {
this(UA, null);
@@ -51,18 +52,43 @@ public class Downloader {
* the User-Agent to use to download the resources -- note that
* some websites require one, some actively blacklist real UAs
* like the one from wget, some whitelist a couple of browsers
- * only (!)
+ * only (!) -- can be NULL
* @param cache
* the {@link Cache} to use for all access (can be NULL)
*/
public Downloader(String UA, Cache cache) {
this.UA = UA;
- cookies = new CookieManager();
- cookies.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
+ cookies = new CookieManager(null, CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(cookies);
- this.cache = cache;
+ setCache(cache);
+ }
+
+ /**
+ * This {@link Downloader} is forbidden to try and connect to the network.
+ *
+ * If TRUE, it will only check the cache if any.
+ *
+ * Default is FALSE.
+ *
+ * @return TRUE if offline
+ */
+ public boolean isOffline() {
+ return offline;
+ }
+
+ /**
+ * This {@link Downloader} is forbidden to try and connect to the network.
+ *
+ * If TRUE, it will only check the cache if any.
+ *
+ * Default is FALSE.
+ *
+ * @param offline TRUE for offline, FALSE for online
+ */
+ public void setOffline(boolean offline) {
+ this.offline = offline;
}
/**
@@ -168,7 +194,7 @@ public class Downloader {
* @return the {@link InputStream} of the opened page
*
* @throws IOException
- * in case of I/O error
+ * in case of I/O error (including offline mode + not in cache)
*/
public InputStream open(URL url, URL currentReferer,
Map cookiesValues, Map postParams,
@@ -200,7 +226,7 @@ public class Downloader {
* @return the {@link InputStream} of the opened page
*
* @throws IOException
- * in case of I/O error
+ * in case of I/O error (including offline mode + not in cache)
*/
public InputStream open(URL url, URL currentReferer,
Map cookiesValues, Map postParams,
@@ -237,7 +263,7 @@ public class Downloader {
* @return the {@link InputStream} of the opened page
*
* @throws IOException
- * in case of I/O error
+ * in case of I/O error (including offline mode + not in cache)
*/
public InputStream open(URL url, final URL originalUrl, URL currentReferer,
Map cookiesValues, Map postParams,
@@ -255,6 +281,13 @@ public class Downloader {
}
}
+ String protocol = originalUrl == null ? null : originalUrl
+ .getProtocol();
+ if (isOffline() && !"file".equalsIgnoreCase(protocol)) {
+ tracer.error("Downloader OFFLINE, cannot proceed to URL: " + url);
+ throw new IOException("Downloader is currently OFFLINE, cannot download: " + url);
+ }
+
tracer.trace("Download: " + url);
URLConnection conn = openConnectionWithCookies(url, currentReferer,
@@ -266,9 +299,9 @@ public class Downloader {
params = postParams;
}
+ StringBuilder requestData = null;
if ((params != null || oauth != null)
&& conn instanceof HttpURLConnection) {
- StringBuilder requestData = null;
if (params != null) {
requestData = new StringBuilder();
for (Map.Entry param : params.entrySet()) {
@@ -281,15 +314,14 @@ public class Downloader {
String.valueOf(param.getValue()), "UTF-8"));
}
- conn.setDoOutput(true);
-
if (getParams == null && postParams != null) {
((HttpURLConnection) conn).setRequestMethod("POST");
}
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
- conn.setRequestProperty("charset", "utf-8");
+ conn.setRequestProperty("Content-Length",
+ Integer.toString(requestData.length()));
}
if (oauth != null) {
@@ -297,22 +329,28 @@ public class Downloader {
}
if (requestData != null) {
- OutputStreamWriter writer = null;
+ conn.setDoOutput(true);
+ OutputStreamWriter writer = new OutputStreamWriter(
+ conn.getOutputStream());
try {
- writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(requestData.toString());
writer.flush();
} finally {
- if (writer != null) {
- writer.close();
- }
+ writer.close();
}
}
}
+ // Manual redirection, much better for POST data
+ if (conn instanceof HttpURLConnection) {
+ ((HttpURLConnection) conn).setInstanceFollowRedirects(false);
+ }
+
conn.connect();
// Check if redirect
+ // BEWARE! POST data cannot be redirected (some webservers complain) for
+ // HTTP codes 302 and 303
if (conn instanceof HttpURLConnection) {
int repCode = 0;
try {
@@ -324,32 +362,53 @@ public class Downloader {
if (repCode / 100 == 3) {
String newUrl = conn.getHeaderField("Location");
return open(new URL(newUrl), originalUrl, currentReferer,
- cookiesValues, postParams, getParams, oauth, stable);
+ cookiesValues, //
+ (repCode == 302 || repCode == 303) ? null : postParams, //
+ getParams, oauth, stable);
}
}
- InputStream in = conn.getInputStream();
- if ("gzip".equals(conn.getContentEncoding())) {
- in = new GZIPInputStream(in);
- }
+ try {
+ InputStream in = conn.getInputStream();
+ if ("gzip".equals(conn.getContentEncoding())) {
+ in = new GZIPInputStream(in);
+ }
- if (in != null && cache != null) {
- tracer.trace("Save to cache: " + originalUrl);
- try {
+ if (in == null) {
+ throw new IOException("No InputStream!");
+ }
+
+ if (cache != null) {
+ String size = conn.getContentLength() < 0 ? "unknown size"
+ : StringUtils.formatNumber(conn.getContentLength())
+ + "bytes";
+ tracer.trace("Save to cache (" + size + "): " + originalUrl);
try {
- cache.save(in, originalUrl);
- } finally {
- in.close();
+ try {
+ long bytes = cache.save(in, originalUrl);
+ tracer.trace("Saved to cache: "
+ + StringUtils.formatNumber(bytes) + "bytes");
+ } finally {
+ in.close();
+ }
+ in = cache.load(originalUrl, true, true);
+ } catch (IOException e) {
+ tracer.error(new IOException(
+ "Cannot save URL to cache, will ignore cache: "
+ + url, e));
}
- in = cache.load(originalUrl, true, false);
- } catch (IOException e) {
- tracer.error(new IOException(
- "Cannot save URL to cache, will ignore cache: " + url,
- e));
}
- }
- return in;
+ if (in == null) {
+ throw new IOException(
+ "Cannot retrieve the file after storing it in the cache (??)");
+ }
+
+ return in;
+ } catch (IOException e) {
+ throw new IOException(String.format(
+ "Cannot find %s (current URL: %s)", originalUrl, url), e);
+ }
}
/**
@@ -369,9 +428,18 @@ public class Downloader {
throws IOException {
URLConnection conn = url.openConnection();
- conn.setRequestProperty("User-Agent", UA);
- conn.setRequestProperty("Cookie", generateCookies(cookiesValues));
+ String cookies = generateCookies(cookiesValues);
+ if (cookies != null && !cookies.isEmpty()) {
+ conn.setRequestProperty("Cookie", cookies);
+ }
+
+ if (UA != null) {
+ conn.setRequestProperty("User-Agent", UA);
+ }
conn.setRequestProperty("Accept-Encoding", "gzip");
+ conn.setRequestProperty("Accept", "*/*");
+ conn.setRequestProperty("Charset", "utf-8");
+
if (currentReferer != null) {
conn.setRequestProperty("Referer", currentReferer.toString());
conn.setRequestProperty("Host", currentReferer.getHost());