29
29
30
30
package cc .arduino .utils .network ;
31
31
32
- import cc .arduino .net .CustomProxySelector ;
33
- import org .apache .commons .codec .binary .Base64 ;
34
32
import org .apache .commons .compress .utils .IOUtils ;
35
33
36
34
import processing .app .BaseNoGui ;
37
- import processing .app .PreferencesData ;
35
+ import processing .app .helpers . FileUtils ;
38
36
39
37
import java .io .File ;
40
38
import java .io .IOException ;
41
39
import java .io .InputStream ;
42
40
import java .io .RandomAccessFile ;
43
- import java .net .HttpURLConnection ;
44
- import java .net .Proxy ;
45
- import java .net .SocketTimeoutException ;
46
- import java .net .URL ;
41
+ import java .net .*;
47
42
import java .nio .file .Files ;
48
43
import java .nio .file .Paths ;
49
44
import java .util .Observable ;
45
+ import java .util .Optional ;
46
+ import java .util .logging .Level ;
47
+ import java .util .logging .Logger ;
50
48
51
49
public class FileDownloader extends Observable {
50
+ private static Logger log = Logger
51
+ .getLogger (FileDownloader .class .getName ());
52
52
53
53
public enum Status {
54
54
CONNECTING , //
@@ -68,15 +68,12 @@ public enum Status {
68
68
private final File outputFile ;
69
69
private InputStream stream = null ;
70
70
private Exception error ;
71
- private String userAgent ;
72
71
73
72
public FileDownloader (URL url , File file ) {
74
73
downloadUrl = url ;
75
74
outputFile = file ;
76
75
downloaded = 0 ;
77
76
initialSize = 0 ;
78
- userAgent = "ArduinoIDE/" + BaseNoGui .VERSION_NAME + " Java/"
79
- + System .getProperty ("java.version" );
80
77
}
81
78
82
79
public long getInitialSize () {
@@ -144,62 +141,49 @@ private void saveLocalFile() {
144
141
}
145
142
146
143
private void downloadFile (boolean noResume ) throws InterruptedException {
147
- RandomAccessFile file = null ;
144
+ RandomAccessFile randomAccessOutputFile = null ;
148
145
149
146
try {
147
+ setStatus (Status .CONNECTING );
148
+
149
+ final File settingsFolder = BaseNoGui .getPlatform ().getSettingsFolder ();
150
+ final String cacheFolder = Paths .get (settingsFolder .getPath (), "cache" ).toString ();
151
+ final FileDownloaderCache fileDownloaderCache =
152
+ new FileDownloaderCache (cacheFolder , downloadUrl );
153
+
154
+ final boolean isChanged = fileDownloaderCache .checkIfTheFileIsChanged ();
155
+
156
+ if (!isChanged ) {
157
+ try {
158
+ final Optional <File > fileFromCache =
159
+ fileDownloaderCache .getFileFromCache ();
160
+ if (fileFromCache .isPresent ()) {
161
+ FileUtils .copyFile (fileFromCache .get (), outputFile );
162
+ setStatus (Status .COMPLETE );
163
+ return ;
164
+ }
165
+ } catch (Exception e ) {
166
+ log .log (Level .WARNING ,
167
+ "Cannot get the file from the cache, will be downloaded a new one " , e .getCause ());
168
+
169
+ }
170
+ }
171
+
150
172
// Open file and seek to the end of it
151
- file = new RandomAccessFile (outputFile , "rw" );
152
- initialSize = file .length ();
173
+ randomAccessOutputFile = new RandomAccessFile (outputFile , "rw" );
174
+ initialSize = randomAccessOutputFile .length ();
153
175
154
176
if (noResume && initialSize > 0 ) {
155
177
// delete file and restart downloading
156
178
Files .delete (outputFile .toPath ());
157
179
initialSize = 0 ;
158
180
}
159
181
160
- file .seek (initialSize );
161
-
162
- setStatus (Status .CONNECTING );
163
-
164
- Proxy proxy = new CustomProxySelector (PreferencesData .getMap ()).getProxyFor (downloadUrl .toURI ());
165
- if ("true" .equals (System .getProperty ("DEBUG" ))) {
166
- System .err .println ("Using proxy " + proxy );
167
- }
168
-
169
- HttpURLConnection connection = (HttpURLConnection ) downloadUrl .openConnection (proxy );
170
- connection .setRequestProperty ("User-agent" , userAgent );
171
- if (downloadUrl .getUserInfo () != null ) {
172
- String auth = "Basic " + new String (new Base64 ().encode (downloadUrl .getUserInfo ().getBytes ()));
173
- connection .setRequestProperty ("Authorization" , auth );
174
- }
175
-
176
- connection .setRequestProperty ("Range" , "bytes=" + initialSize + "-" );
177
- connection .setConnectTimeout (5000 );
178
- setDownloaded (0 );
179
-
180
- // Connect
181
- connection .connect ();
182
- int resp = connection .getResponseCode ();
183
-
184
- if (resp == HttpURLConnection .HTTP_MOVED_PERM || resp == HttpURLConnection .HTTP_MOVED_TEMP ) {
185
- URL newUrl = new URL (connection .getHeaderField ("Location" ));
182
+ randomAccessOutputFile .seek (initialSize );
186
183
187
- proxy = new CustomProxySelector (PreferencesData .getMap ()).getProxyFor (newUrl .toURI ());
188
-
189
- // open the new connnection again
190
- connection = (HttpURLConnection ) newUrl .openConnection (proxy );
191
- connection .setRequestProperty ("User-agent" , userAgent );
192
- if (downloadUrl .getUserInfo () != null ) {
193
- String auth = "Basic " + new String (new Base64 ().encode (downloadUrl .getUserInfo ().getBytes ()));
194
- connection .setRequestProperty ("Authorization" , auth );
195
- }
196
-
197
- connection .setRequestProperty ("Range" , "bytes=" + initialSize + "-" );
198
- connection .setConnectTimeout (5000 );
199
-
200
- connection .connect ();
201
- resp = connection .getResponseCode ();
202
- }
184
+ final HttpURLConnection connection = new HttpConnectionManager (downloadUrl )
185
+ .makeConnection ((c ) -> setDownloaded (0 ));
186
+ final int resp = connection .getResponseCode ();
203
187
204
188
if (resp < 200 || resp >= 300 ) {
205
189
throw new IOException ("Received invalid http status code from server: " + resp );
@@ -221,11 +205,11 @@ private void downloadFile(boolean noResume) throws InterruptedException {
221
205
if (read == -1 )
222
206
break ;
223
207
224
- file .write (buffer , 0 , read );
208
+ randomAccessOutputFile .write (buffer , 0 , read );
225
209
setDownloaded (getDownloaded () + read );
226
210
227
211
if (Thread .interrupted ()) {
228
- file .close ();
212
+ randomAccessOutputFile .close ();
229
213
throw new InterruptedException ();
230
214
}
231
215
}
@@ -234,6 +218,8 @@ private void downloadFile(boolean noResume) throws InterruptedException {
234
218
if (getDownloaded () < getDownloadSize ())
235
219
throw new Exception ("Incomplete download" );
236
220
}
221
+ // Set the cache whe it finish to download the file
222
+ fileDownloaderCache .fillCache (outputFile );
237
223
setStatus (Status .COMPLETE );
238
224
} catch (InterruptedException e ) {
239
225
setStatus (Status .CANCELLED );
@@ -249,7 +235,7 @@ private void downloadFile(boolean noResume) throws InterruptedException {
249
235
setError (e );
250
236
251
237
} finally {
252
- IOUtils .closeQuietly (file );
238
+ IOUtils .closeQuietly (randomAccessOutputFile );
253
239
254
240
synchronized (this ) {
255
241
IOUtils .closeQuietly (stream );
0 commit comments