public boolean doGet(int logLevel,
Get.DownloadProgress progress) throws IOException {
checkAttributes();
//dont do any progress, unless asked
if (progress == null) {
progress = new NullProgress();
}
log("Getting: " + source, logLevel);
log("To: " + dest.getAbsolutePath(), logLevel);
//set the timestamp to the file date.
long timestamp = 0;
boolean hasTimestamp = false;
if (useTimestamp && dest.exists()) {
timestamp = dest.lastModified();
if (verbose) {
Date t = new Date(timestamp);
log("local file date : " + t.toString(), logLevel);
}
hasTimestamp = true;
}
//set up the URL connection
URLConnection connection = source.openConnection();
//modify the headers
//NB: things like user authentication could go in here too.
if (hasTimestamp) {
connection.setIfModifiedSince(timestamp);
}
// prepare Java 1.1 style credentials
if (uname != null || pword != null) {
String up = uname + ":" + pword;
String encoding;
//we do not use the sun impl for portability,
//and always use our own implementation for consistent
//testing
Base64Converter encoder = new Base64Converter();
encoding = encoder.encode(up.getBytes());
connection.setRequestProperty ("Authorization",
"Basic " + encoding);
}
//connect to the remote site (may take some time)
connection.connect();
//next test for a 304 result (HTTP only)
if (connection instanceof HttpURLConnection) {
HttpURLConnection httpConnection
= (HttpURLConnection) connection;
long lastModified = httpConnection.getLastModified();
if (httpConnection.getResponseCode()
== HttpURLConnection.HTTP_NOT_MODIFIED
|| (lastModified != 0 && hasTimestamp
&& timestamp >= lastModified)) {
//not modified so no file download. just return
//instead and trace out something so the user
//doesn't think that the download happened when it
//didn't
log("Not modified - so not downloaded", logLevel);
return false;
}
// test for 401 result (HTTP only)
if (httpConnection.getResponseCode()
== HttpURLConnection.HTTP_UNAUTHORIZED) {
String message = "HTTP Authorization failure";
if (ignoreErrors) {
log(message, logLevel);
return false;
} else {
throw new BuildException(message);
}
}
}
//REVISIT: at this point even non HTTP connections may
//support the if-modified-since behaviour -we just check
//the date of the content and skip the write if it is not
//newer. Some protocols (FTP) don't include dates, of
//course.
InputStream is = null;
for (int i = 0; i < NUMBER_RETRIES; i++) {
//this three attempt trick is to get round quirks in different
//Java implementations. Some of them take a few goes to bind
//property; we ignore the first couple of such failures.
try {
is = connection.getInputStream();
break;
} catch (IOException ex) {
log("Error opening connection " + ex, logLevel);
}
}
if (is == null) {
log("Can't get " + source + " to " + dest, logLevel);
if (ignoreErrors) {
return false;
}
throw new BuildException("Can't get " + source + " to " + dest,
getLocation());
}
FileOutputStream fos = new FileOutputStream(dest);
progress.beginDownload();
boolean finished = false;
try {
byte[] buffer = new byte[BIG_BUFFER_SIZE];
int length;
while ((length = is.read(buffer)) >= 0) {
fos.write(buffer, 0, length);
progress.onTick();
}
finished = true;
} finally {
FileUtils.close(fos);
FileUtils.close(is);
// we have started to (over)write dest, but failed.
// Try to delete the garbage we'd otherwise leave
// behind.
if (!finished) {
dest.delete();
}
}
progress.endDownload();
//if (and only if) the use file time option is set, then
//the saved file now has its timestamp set to that of the
//downloaded file
if (useTimestamp) {
long remoteTimestamp = connection.getLastModified();
if (verbose) {
Date t = new Date(remoteTimestamp);
log("last modified = " + t.toString()
+ ((remoteTimestamp == 0)
? " - using current time instead"
: ""), logLevel);
}
if (remoteTimestamp != 0) {
FILE_UTILS.setFileLastModified(dest, remoteTimestamp);
}
}
//successful download
return true;
}
make a get request, with the supplied progress and logging info.
All the other config parameters are set at the task level,
source, dest, ignoreErrors, etc. |
public void setUseTimestamp(boolean v) {
useTimestamp = v;
}
If true, conditionally download a file based on the timestamp
of the local copy.
In this situation, the if-modified-since header is set so
that the file is only fetched if it is newer than the local
file (or there is no local file) This flag is only valid on
HTTP connections, it is ignored in other cases. When the flag
is set, the local copy of the downloaded file will also have
its timestamp set to the remote file time.
Note that remote files of date 1/1/1970 (GMT) are treated as
'no timestamp', and web servers often serve files with a
timestamp in the future by replacing their timestamp with that
of the current time. Also, inter-computer clock differences can
cause no end of grief. |