5353import java.net.URI;
5454import java.net.URISyntaxException;
5555import java.net.URL;
56+ import java.net.URLDecoder;
57+ import java.util.regex.Matcher;
58+ import java.util.regex.Pattern;
5659import java.nio.channels.Channels;
5760import java.nio.channels.ReadableByteChannel;
5861import java.util.function.BiConsumer;
@@ -78,9 +81,42 @@ public static File download(String name, String urlPath)
7881 public static File download(String name, String urlPath, @Nullable BiConsumer<Long, Long> progressConsumer)
7982 throws IOException, InterruptedException, URISyntaxException
8083 {
81- final File tempFile = File.createTempFile(name + "-", FilePaths.fileType(urlPath));
82- tempFile.deleteOnExit();
84+ // Resolve redirects and get final URL
8385 URL url = Downloads.redirectedURL(new URL(urlPath));
86+
87+ // Try to get file extension from final URL (after redirects)
88+ String fileExt = FilePaths.fileType(url.toString());
89+ if (fileExt.isEmpty()) {
90+ // Try to extract filename from query parameters (e.g., ?response-content-disposition=...)
91+ String query = url.getQuery();
92+ if (query != null) {
93+ // Parse query parameters
94+ String[] params = query.split("&");
95+ for (String param : params) {
96+ String[] keyValue = param.split("=", 2);
97+ if (keyValue.length == 2 && keyValue[0].equals("response-content-disposition")) {
98+ // Parse Content-Disposition header value
99+ String contentDisp = URLDecoder.decode(keyValue[1], "UTF-8");
100+ // Extract filename from 'filename="..."' or filename*=UTF-8''...
101+ Pattern pattern = Pattern.compile("filename[*]?=(?:UTF-8'')?[\"']?([^\"';&#]+)");
102+ Matcher matcher = pattern.matcher(contentDisp);
103+ if (matcher.find()) {
104+ String filename = URLDecoder.decode(matcher.group(1), "UTF-8");
105+ fileExt = FilePaths.fileType(filename);
106+ }
107+ break;
108+ }
109+ }
110+ }
111+
112+ // Fallback to original URL if still no extension
113+ if (fileExt.isEmpty()) {
114+ fileExt = FilePaths.fileType(urlPath);
115+ }
116+ }
117+
118+ final File tempFile = File.createTempFile(name + "-", fileExt);
119+ tempFile.deleteOnExit();
84120 long size = Downloads.getFileSize(url);
85121 Thread currentThread = Thread.currentThread();
86122 IOException[] ioe = {null};
0 commit comments