From eda211934ba2865103c90e701537efe57c7f2ebb Mon Sep 17 00:00:00 2001 From: Joe Baker-Malone Date: Wed, 16 Mar 2022 16:01:30 -0700 Subject: Make StudioDownloader work with symlinks Test: added a test Fixes: 213935705 Change-Id: I035bf816d9ef4ae166aa6165ef53f9a3867b25db --- .../src/com/android/tools/idea/sdk/StudioDownloader.java | 13 ++++++++++--- .../com/android/tools/idea/sdk/StudioDownloaderTest.java | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) (limited to 'android') diff --git a/android/src/com/android/tools/idea/sdk/StudioDownloader.java b/android/src/com/android/tools/idea/sdk/StudioDownloader.java index 8b3a8ec2d47..5c21f708bc2 100644 --- a/android/src/com/android/tools/idea/sdk/StudioDownloader.java +++ b/android/src/com/android/tools/idea/sdk/StudioDownloader.java @@ -38,6 +38,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.nio.file.Files; +import java.nio.file.OpenOption; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; @@ -125,12 +126,18 @@ public class StudioDownloader implements Downloader { @Override @Nullable public InputStream downloadAndStream(@NotNull URL url, @NotNull ProgressIndicator indicator) + throws IOException { + return downloadAndStreamWithOptions(url, indicator, StandardOpenOption.DELETE_ON_CLOSE); + } + + @Nullable + public InputStream downloadAndStreamWithOptions(@NotNull URL url, @NotNull ProgressIndicator indicator, OpenOption... streamOpenOptions) throws IOException { Path file = downloadFully(url, indicator); if (file == null) { return null; } - return CancellableFileIo.newInputStream(file, StandardOpenOption.DELETE_ON_CLOSE); + return CancellableFileIo.newInputStream(file, streamOpenOptions); } @Override @@ -206,7 +213,7 @@ public class StudioDownloader implements Downloader { long contentLength = startOffset + request.getConnection().getContentLengthLong(); DownloadProgressIndicator downloadProgressIndicator = new DownloadProgressIndicator(indicator, target.getFileName().toString(), contentLength, startOffset); - Files.createDirectories(interimDownload.getParent()); + Files.createDirectories(interimDownload.getParent().toRealPath()); try (OutputStream out = new BufferedOutputStream(Files.newOutputStream(interimDownload, StandardOpenOption.APPEND, StandardOpenOption.CREATE))) { NetUtils.copyStreamContent(downloadProgressIndicator, request.getInputStream(), out, @@ -214,7 +221,7 @@ public class StudioDownloader implements Downloader { } try { - Files.createDirectories(target.getParent()); + Files.createDirectories(target.getParent().toRealPath()); Files.move(interimDownload, target, StandardCopyOption.REPLACE_EXISTING); if (CancellableFileIo.exists(target) && checksum != null) { if (!checksum.getValue().equals(Downloader.hash(new BufferedInputStream(CancellableFileIo.newInputStream(target)), diff --git a/android/testSrc/com/android/tools/idea/sdk/StudioDownloaderTest.java b/android/testSrc/com/android/tools/idea/sdk/StudioDownloaderTest.java index 9a9590ee101..94c20df87b4 100644 --- a/android/testSrc/com/android/tools/idea/sdk/StudioDownloaderTest.java +++ b/android/testSrc/com/android/tools/idea/sdk/StudioDownloaderTest.java @@ -319,4 +319,20 @@ public class StudioDownloaderTest { assertThat(InMemoryFileSystems.getExistingFolders(fs)).containsExactly(tmpPath.toString(), InMemoryFileSystems.getDefaultWorkingDirectory()); } + + @Test + public void testTemporaryFilesWithSymlink() throws Exception { + FileSystem fs = InMemoryFileSystems.createInMemoryFileSystem(); + Path realTmpPath = Files.createDirectory(InMemoryFileSystems.getSomeRoot(fs).resolve("realTmp")); + Path tmpPath = Files.createSymbolicLink(InMemoryFileSystems.getSomeRoot(fs).resolve("tmp"), realTmpPath); + createServerContextThatReturnsCustomContent("blah"); + StudioDownloader downloader = new StudioDownloader(new FakeSettingsController(false)); + downloader.setDownloadIntermediatesLocation(tmpPath); + byte[] bytes = new byte[10]; + try (BufferedInputStream is = new BufferedInputStream( + downloader.downloadAndStreamWithOptions(new URL(myUrl), new FakeProgressIndicator()))) { + assertEquals(4, is.read(bytes)); + assertEquals("blah", new String(bytes).trim()); + } + } } -- cgit v1.2.3