Behave more gracefully when patch files do not exist.

It is possible to use versioned mode without patch files, though there's no way
to specifically tell Getdown whether or not you are using patch files, so it
always tries to download them. If they don't exist, it should now log one
reasonable warning and then proceed to update based on resource hashes.
This commit is contained in:
Michael Bayne
2019-06-05 16:09:51 -07:00
parent 157b12dbfa
commit e7818030a7
3 changed files with 37 additions and 11 deletions
@@ -143,15 +143,23 @@ public class Connector {
* If the connection failed for proxy related reasons, this changes the state of this connector
* to reflect the needed proxy information.
*/
public void checkConnectOK (URLConnection conn, String errpre) throws IOException
{
// if it's not an HTTP connection, there's nothing to check
if (!(conn instanceof HttpURLConnection)) return;
public void checkConnectOK (URLConnection conn, String errpre) throws IOException {
int code = checkConnectStatus(conn);
if (code != HttpURLConnection.HTTP_OK) {
throw new IOException(errpre + " [code=" + code + "]");
}
}
/**
* Returns the connection status of {@code conn}. If the connection failed for proxy related
* reasons, this changes the state of this connector to reflect the needed proxy information.
*/
public int checkConnectStatus (URLConnection conn) throws IOException {
// if it's not an HTTP connection, we assume it's OK
if (!(conn instanceof HttpURLConnection)) return HttpURLConnection.HTTP_OK;
int code = ((HttpURLConnection)conn).getResponseCode();
switch (code) {
case HttpURLConnection.HTTP_OK:
return;
case HttpURLConnection.HTTP_FORBIDDEN:
case HttpURLConnection.HTTP_USE_PROXY:
state = State.NEED_PROXY;
@@ -160,7 +168,7 @@ public class Connector {
state = State.NEED_PROXY_AUTH;
break;
}
throw new IOException(errpre + " [code=" + code + "]");
return code;
}
/**
@@ -140,6 +140,11 @@ public class Downloader
*/
protected void downloadFailed (Resource rsrc, Exception cause) {}
/**
* Called when a to-be-downloaded resource returns a 404 not found.
*/
protected void resourceMissing (Resource rsrc) {}
/**
* Performs the protocol-specific portion of checking download size.
*/
@@ -150,9 +155,10 @@ public class Downloader
if (conn instanceof HttpURLConnection) {
((HttpURLConnection)conn).setRequestMethod("HEAD");
}
// make sure we got a satisfactory response code
_conn.checkConnectOK(conn, "Unable to check up-to-date for " + rsrc.getRemote());
return conn.getContentLength();
// if we get a satisfactory response code, return a size; ignore errors as we'll report
// those when we actually attempt to download the resource
int code = _conn.checkConnectStatus(conn);
return code == HttpURLConnection.HTTP_OK ? conn.getContentLength() : 0;
} finally {
// let it be known that we're done with this connection
@@ -232,7 +238,13 @@ public class Downloader
protected void download (Resource rsrc) throws IOException {
URLConnection conn = _conn.open(rsrc.getRemote(), 0, 0);
// make sure we got a satisfactory response code
_conn.checkConnectOK(conn, "Unable to download resource " + rsrc.getRemote());
int code = _conn.checkConnectStatus(conn);
if (code == HttpURLConnection.HTTP_NOT_FOUND) {
resourceMissing(rsrc);
} else if (code != HttpURLConnection.HTTP_OK) {
throw new IOException(
"Resource returned HTTP error " + rsrc.getRemote() + " [code=" + code + "]");
}
// TODO: make FileChannel download impl (below) robust and allow apps to opt-into it via a
// system property