blob: 23a7733ab03663927c080927a41cd6f29adbdeab [file] [log] [blame]
/*
* Copyright 2014-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.buck.file;
import com.facebook.buck.event.BuckEventBus;
import com.facebook.buck.util.HumanReadableException;
import com.google.common.base.Optional;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.TimeUnit;
/**
* Download a file over HTTP.
*/
public class HttpDownloader implements Downloader {
public static final int PROGRESS_REPORT_EVERY_N_BYTES = 1000;
private final Optional<Proxy> proxy;
private final Optional<String> mavenRepo;
public HttpDownloader(Optional<Proxy> proxy, Optional<String> mavenRepo) {
this.proxy = proxy;
this.mavenRepo = mavenRepo;
}
@Override
public void fetch(BuckEventBus eventBus, URI uri, Path output) throws IOException {
if ("mvn".equals(uri.getScheme())) {
uri = MavenUrlDecoder.toHttpUrl(mavenRepo, uri);
}
eventBus.post(DownloadEvent.started(uri));
try {
HttpURLConnection connection = createConnection(uri);
if (HttpURLConnection.HTTP_OK != connection.getResponseCode()) {
throw new HumanReadableException(
"Unable to download %s: %s", uri, connection.getResponseMessage());
}
long contentLength = connection.getContentLengthLong();
try (InputStream is = new BufferedInputStream(connection.getInputStream());
OutputStream os = new BufferedOutputStream(Files.newOutputStream(output))) {
long read = 0;
while (true) {
int r = is.read();
read++;
if (r == -1) {
break;
}
if (read % PROGRESS_REPORT_EVERY_N_BYTES == 0) {
eventBus.post(new DownloadProgressEvent(uri, contentLength, read));
}
os.write(r);
}
}
} finally {
eventBus.post(DownloadEvent.finished(uri));
}
}
protected HttpURLConnection createConnection(URI uri) throws IOException {
if (!("http".equals(uri.getScheme()) || "https".equals(uri.getScheme()))) {
throw new HumanReadableException(
"Cowardly refusing to download with unknown scheme: %s", uri);
}
HttpURLConnection connection;
if (proxy.isPresent()) {
connection = (HttpURLConnection) uri.toURL().openConnection(proxy.get());
} else {
connection = (HttpURLConnection) uri.toURL().openConnection();
}
connection.setConnectTimeout((int) TimeUnit.SECONDS.toMillis(20));
connection.setInstanceFollowRedirects(true);
return connection;
}
}