private boolean installIfNecessaryFrom()

in core/src/main/java/hudson/FilePath.java [854:940]


    private boolean installIfNecessaryFrom(@NonNull URL archive, @NonNull TaskListener listener, @NonNull String message, int maxRedirects) throws InterruptedException, IOException {
        try {
            FilePath timestamp = this.child(".timestamp");
            long lastModified = timestamp.lastModified();
            URLConnection con;
            try {
                con = ProxyConfiguration.open(archive);
                if (lastModified != 0) {
                    con.setIfModifiedSince(lastModified);
                }
                con.connect();
            } catch (IOException x) {
                if (this.exists()) {
                    // Cannot connect now, so assume whatever was last unpacked is still OK.
                    listener.getLogger().println("Skipping installation of " + archive + " to " + remote + ": " + x);
                    return false;
                } else {
                    throw x;
                }
            }

            if (con instanceof HttpURLConnection) {
                HttpURLConnection httpCon = (HttpURLConnection) con;
                int responseCode = httpCon.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_MOVED_PERM
                        || responseCode == HttpURLConnection.HTTP_MOVED_TEMP) {
                    // follows redirect
                    if (maxRedirects > 0) {
                        String location = httpCon.getHeaderField("Location");
                        listener.getLogger().println("Following redirect " + archive.toExternalForm() + " -> " + location);
                        return installIfNecessaryFrom(getUrlFactory().newURL(location), listener, message, maxRedirects - 1);
                    } else {
                        listener.getLogger().println("Skipping installation of " + archive + " to " + remote + " due to too many redirects.");
                        return false;
                    }
                }
                if (lastModified != 0) {
                    if (responseCode == HttpURLConnection.HTTP_NOT_MODIFIED) {
                        return false;
                    } else if (responseCode != HttpURLConnection.HTTP_OK) {
                        listener.getLogger().println("Skipping installation of " + archive + " to " + remote + " due to server error: " + responseCode + " " + httpCon.getResponseMessage());
                        return false;
                    }
                }
            }

            long sourceTimestamp = con.getLastModified();

            if(this.exists()) {
                if (lastModified != 0 && sourceTimestamp == lastModified)
                    return false;   // already up to date
                this.deleteContents();
            } else {
                this.mkdirs();
            }

            listener.getLogger().println(message);

            if (isRemote()) {
                // First try to download from the agent machine.
                try {
                    act(new Unpack(archive));
                    timestamp.touch(sourceTimestamp);
                    return true;
                } catch (IOException x) {
                    Functions.printStackTrace(x, listener.error("Failed to download " + archive + " from agent; will retry from master"));
                }
            }

            // for HTTP downloads, enable automatic retry for added resilience
            InputStream in = archive.getProtocol().startsWith("http") ? ProxyConfiguration.getInputStream(archive) : con.getInputStream();
            CountingInputStream cis = new CountingInputStream(in);
            try {
                if(archive.toExternalForm().endsWith(".zip"))
                    unzipFrom(cis);
                else
                    untarFrom(cis,GZIP);
            } catch (IOException e) {
                throw new IOException(String.format("Failed to unpack %s (%d bytes read of total %d)",
                        archive,cis.getByteCount(),con.getContentLength()),e);
            }
            timestamp.touch(sourceTimestamp);
            return true;
        } catch (IOException e) {
            throw new IOException("Failed to install "+archive+" to "+remote,e);
        }
    }