99import java .net .*;
1010import java .nio .file .Files ;
1111import java .nio .file .Path ;
12- import java .nio .file .Paths ;
1312
1413public class FileOperations {
1514 private final SyncSchema syncSchema ;
@@ -38,16 +37,49 @@ public void DownloadFromUri(String uri, Path output, int index) {
3837 }
3938
4039 public void downloadFileWithProgress (String uriString , Path outputPath , ProgressCallback callback ) throws IOException , URISyntaxException {
41- URL url = new URI (uriString ).toURL ();
42- URLConnection connection = url .openConnection ();
40+ // Manually follow redirects so cross-protocol redirects (e.g. http -> https
41+ // from URL shorteners) are handled correctly.
42+ int maxRedirects = 10 ;
43+ String currentUri = uriString ;
44+ URLConnection connection = null ;
45+ boolean resolved = false ;
46+
47+ for (int i = 0 ; i < maxRedirects ; i ++) {
48+ URL url = new URI (currentUri ).toURL ();
49+ connection = url .openConnection ();
50+ connection .setConnectTimeout (10_000 );
51+ connection .setReadTimeout (30_000 );
52+
53+ if (connection instanceof HttpURLConnection httpURLConnection ) {
54+ httpURLConnection .setRequestMethod ("GET" );
55+ httpURLConnection .setRequestProperty ("User-Agent" , "Mozilla/5.0 (compatible; SimpleModSync)" );
56+ httpURLConnection .setInstanceFollowRedirects (false );
57+
58+ int responseCode = httpURLConnection .getResponseCode ();
59+ if (responseCode >= 300 && responseCode < 400 ) {
60+ String location = httpURLConnection .getHeaderField ("Location" );
61+ httpURLConnection .disconnect ();
62+ if (location == null ) {
63+ throw new IOException ("Redirect (HTTP " + responseCode + ") with no Location header" );
64+ }
65+ if (!location .startsWith ("http://" ) && !location .startsWith ("https://" )) {
66+ URL base = new URI (currentUri ).toURL ();
67+ location = new URL (base , location ).toString ();
68+ }
69+ currentUri = location ;
70+ continue ;
71+ }
72+ }
73+ resolved = true ;
74+ break ; // non-HTTP connection or non-redirect response — proceed to download
75+ }
4376
44- if ( connection instanceof HttpURLConnection httpURLConnection ) {
45- httpURLConnection . setRequestMethod ( "GET" );
77+ if (! resolved ) {
78+ throw new IOException ( "Too many redirects while fetching: " + uriString );
4679 }
4780
4881 long fileSize = connection .getContentLengthLong ();
4982 InputStream inputStream = connection .getInputStream ();
50-
5183 OutputStream outputStream = Files .newOutputStream (outputPath );
5284
5385 byte [] buffer = new byte [4096 ];
@@ -79,4 +111,4 @@ public void downloadFileWithProgress(String uriString, Path outputPath, Progress
79111 callback .onProgress (100 );
80112 }
81113 }
82- }
114+ }
0 commit comments