From 3c55dd1eb6d5596d9dec13a07d29ea9b88fff4df Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 26 Nov 2014 11:46:32 +0100 Subject: [PATCH] IDEA-130853 (HTTP redirects in library downloader) --- .../download/impl/FileDownloaderImpl.java | 92 ++++++++----------- .../src/messages/IdeBundle.properties | 3 +- 2 files changed, 38 insertions(+), 57 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/util/download/impl/FileDownloaderImpl.java b/platform/lang-impl/src/com/intellij/util/download/impl/FileDownloaderImpl.java index f192ab314865..2c0919ae77c7 100644 --- a/platform/lang-impl/src/com/intellij/util/download/impl/FileDownloaderImpl.java +++ b/platform/lang-impl/src/com/intellij/util/download/impl/FileDownloaderImpl.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.util.download.impl; import com.google.common.base.Throwables; @@ -38,22 +37,19 @@ import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.*; +import com.intellij.util.io.HttpRequests; import com.intellij.util.concurrency.BoundedTaskExecutor; import com.intellij.util.containers.hash.LinkedHashMap; import com.intellij.util.download.DownloadableFileDescription; import com.intellij.util.download.FileDownloader; -import com.intellij.util.io.UrlConnectionUtil; import com.intellij.util.net.IOExceptionDialog; import com.intellij.util.net.NetUtils; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.ide.PooledThreadExecutor; import javax.swing.*; import java.io.*; -import java.net.HttpURLConnection; -import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; @@ -66,9 +62,7 @@ import java.util.concurrent.atomic.AtomicLong; */ public class FileDownloaderImpl implements FileDownloader { private static final Logger LOG = Logger.getInstance(FileDownloaderImpl.class); - private static final int CONNECTION_TIMEOUT = 60*1000; - private static final int READ_TIMEOUT = 60*1000; - @NonNls private static final String LIB_SCHEMA = "lib://"; + private static final String LIB_SCHEMA = "lib://"; private final List myFileDescriptions; private final JComponent myParentComponent; @@ -77,7 +71,7 @@ public class FileDownloaderImpl implements FileDownloader { private final String myDialogTitle; public FileDownloaderImpl(@NotNull List fileDescriptions, - @Nullable final Project project, + @Nullable Project project, @Nullable JComponent parentComponent, @NotNull String presentableDownloadName) { myProject = project; @@ -145,7 +139,7 @@ public class FileDownloaderImpl implements FileDownloader { return null; } - Exception exception = exceptionRef.get(); + @SuppressWarnings("ThrowableResultOfMethodCallIgnored") Exception exception = exceptionRef.get(); if (exception != null) { final boolean tryAgain = IOExceptionDialog.showErrorDialog(myDialogTitle, exception.getMessage()); if (tryAgain) { @@ -252,9 +246,10 @@ public class FileDownloaderImpl implements FileDownloader { @Nullable private static VirtualFile chooseDirectoryForFiles(Project project, JComponent parentComponent) { - final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor(); - descriptor.setTitle(IdeBundle.message("dialog.directory.for.downloaded.files.title")); - final VirtualFile baseDir = project != null ? project.getBaseDir() : null; + FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor() + .withTitle(IdeBundle.message("dialog.directory.for.downloaded.files.title")) + .withDescription(IdeBundle.message("dialog.directory.for.downloaded.files.description")); + VirtualFile baseDir = project != null ? project.getBaseDir() : null; return FileChooser.chooseFile(descriptor, parentComponent, project, baseDir); } @@ -284,7 +279,7 @@ public class FileDownloaderImpl implements FileDownloader { final File ioFile = pair.getFirst(); VirtualFile libraryRootFile = new WriteAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull Result result) { final String url = VfsUtil.getUrlForLibraryRoot(ioFile); LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioFile); result.setResult(VirtualFileManager.getInstance().refreshAndFindFileByUrl(url)); @@ -305,54 +300,39 @@ public class FileDownloaderImpl implements FileDownloader { } @NotNull - private static File downloadFile(@NotNull final DownloadableFileDescription fileDescription, @NotNull final File existingFile, + private static File downloadFile(@NotNull final DownloadableFileDescription description, + @NotNull final File existingFile, @NotNull final ProgressIndicator indicator) throws IOException { - final String presentableUrl = fileDescription.getPresentableDownloadUrl(); + final String presentableUrl = description.getPresentableDownloadUrl(); indicator.setText2(IdeBundle.message("progress.connecting.to.download.file.text", presentableUrl)); indicator.setIndeterminate(true); - HttpURLConnection connection = (HttpURLConnection)new URL(fileDescription.getDownloadUrl()).openConnection(); - connection.setConnectTimeout(CONNECTION_TIMEOUT); - connection.setReadTimeout(READ_TIMEOUT); - - InputStream input = null; - BufferedOutputStream output = null; - - boolean deleteFile = true; - File tempFile = null; - try { - final int responseCode = connection.getResponseCode(); - if (responseCode != HttpURLConnection.HTTP_OK) { - throw new IOException(IdeBundle.message("error.connection.failed.with.http.code.N", responseCode)); - } - final int size = connection.getContentLength(); - if (existingFile.exists() && size == existingFile.length()) { - return existingFile; - } - - tempFile = FileUtil.createTempFile("downloaded", "file"); - input = UrlConnectionUtil.getConnectionInputStreamWithException(connection, indicator); - output = new BufferedOutputStream(new FileOutputStream(tempFile)); - indicator.setText2(IdeBundle.message("progress.download.file.text", fileDescription.getPresentableFileName(), presentableUrl)); - indicator.setIndeterminate(size == -1); - - NetUtils.copyStreamContent(indicator, input, output, size); + return HttpRequests.request(description.getDownloadUrl()).connect(new HttpRequests.RequestProcessor() { + @Override + public File process(@NotNull HttpRequests.Request request) throws IOException { + int size = request.getConnection().getContentLength(); + if (existingFile.exists() && size == existingFile.length()) { + return existingFile; + } - deleteFile = false; - return tempFile; - } - finally { - if (input != null) { - input.close(); - } - if (output != null) { - output.close(); - } - if (deleteFile && tempFile != null) { - FileUtil.delete(tempFile); + File tempFile = FileUtil.createTempFile("download.", ".tmp"); + boolean deleteFile = true; + OutputStream out = new BufferedOutputStream(new FileOutputStream(tempFile)); + try { + indicator.setText2(IdeBundle.message("progress.download.file.text", description.getPresentableFileName(), presentableUrl)); + indicator.setIndeterminate(size == -1); + NetUtils.copyStreamContent(indicator, request.getInputStream(), out, size); + deleteFile = false; + return tempFile; + } + finally { + out.close(); + if (deleteFile) { + FileUtil.delete(tempFile); + } + } } - connection.disconnect(); - } + }); } @NotNull diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index 0eb3fbde6b09..842ae3c5c1f1 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -1007,7 +1007,8 @@ progress.download.file.text=Downloading ''{0}'' from ''{1}''... progress.connecting.to.download.file.text=Connecting to ''{0}''... progress.locate.file.text=Locating ''{0}''... progress.downloading.0.files.text=Downloading {0} {0, choice, 1#file|2#files}... -dialog.directory.for.downloaded.files.title=Downloaded files will be copied to selected directory +dialog.directory.for.downloaded.files.title=Download Directory +dialog.directory.for.downloaded.files.description=Downloaded files will be copied to selected directory error.file.download.failed=Failed to download ''{0}'': {1} maven.repository.presentable.name=Maven repository -- 2.32.0