1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.owasp.dependencycheck.utils;
19
20 import java.io.BufferedOutputStream;
21 import java.io.File;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.net.HttpURLConnection;
26 import java.net.URISyntaxException;
27 import java.net.URL;
28 import java.util.logging.Level;
29 import java.util.logging.Logger;
30 import java.util.zip.GZIPInputStream;
31 import java.util.zip.InflaterInputStream;
32
33
34
35
36
37
38 public final class Downloader {
39
40
41
42
43 private static final Logger LOGGER = Logger.getLogger(Downloader.class.getName());
44
45
46
47
48 private Downloader() {
49 }
50
51
52
53
54
55
56
57
58 public static void fetchFile(URL url, File outputPath) throws DownloadFailedException {
59 fetchFile(url, outputPath, true);
60 }
61
62
63
64
65
66
67
68
69
70 public static void fetchFile(URL url, File outputPath, boolean useProxy) throws DownloadFailedException {
71 if ("file".equalsIgnoreCase(url.getProtocol())) {
72 File file;
73 try {
74 file = new File(url.toURI());
75 } catch (URISyntaxException ex) {
76 final String msg = String.format("Download failed, unable to locate '%s'", url.toString());
77 throw new DownloadFailedException(msg);
78 }
79 if (file.exists()) {
80 try {
81 org.apache.commons.io.FileUtils.copyFile(file, outputPath);
82 } catch (IOException ex) {
83 final String msg = String.format("Download failed, unable to copy '%s'", url.toString());
84 throw new DownloadFailedException(msg);
85 }
86 } else {
87 final String msg = String.format("Download failed, file does not exist '%s'", url.toString());
88 throw new DownloadFailedException(msg);
89 }
90 } else {
91 HttpURLConnection conn = null;
92 try {
93 conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
94 conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
95 conn.connect();
96 } catch (IOException ex) {
97 try {
98 if (conn != null) {
99 conn.disconnect();
100 }
101 } finally {
102 conn = null;
103 }
104 throw new DownloadFailedException("Error downloading file.", ex);
105 }
106 final String encoding = conn.getContentEncoding();
107
108 BufferedOutputStream writer = null;
109 InputStream reader = null;
110 try {
111 if (encoding != null && "gzip".equalsIgnoreCase(encoding)) {
112 reader = new GZIPInputStream(conn.getInputStream());
113 } else if (encoding != null && "deflate".equalsIgnoreCase(encoding)) {
114 reader = new InflaterInputStream(conn.getInputStream());
115 } else {
116 reader = conn.getInputStream();
117 }
118
119 writer = new BufferedOutputStream(new FileOutputStream(outputPath));
120 final byte[] buffer = new byte[4096];
121 int bytesRead;
122 while ((bytesRead = reader.read(buffer)) > 0) {
123 writer.write(buffer, 0, bytesRead);
124 }
125 } catch (Throwable ex) {
126 throw new DownloadFailedException("Error saving downloaded file.", ex);
127 } finally {
128 if (writer != null) {
129 try {
130 writer.close();
131 } catch (Throwable ex) {
132 LOGGER.log(Level.FINEST,
133 "Error closing the writer in Downloader.", ex);
134 }
135 }
136 if (reader != null) {
137 try {
138 reader.close();
139 } catch (Throwable ex) {
140 LOGGER.log(Level.FINEST,
141 "Error closing the reader in Downloader.", ex);
142 }
143 }
144 try {
145 conn.disconnect();
146 } finally {
147 conn = null;
148 }
149 }
150 }
151 }
152
153
154
155
156
157
158
159
160
161 public static long getLastModified(URL url) throws DownloadFailedException {
162 long timestamp = 0;
163
164 if ("file".equalsIgnoreCase(url.getProtocol())) {
165 File lastModifiedFile;
166 try {
167 lastModifiedFile = new File(url.toURI());
168 } catch (URISyntaxException ex) {
169 final String msg = String.format("Unable to locate '%s'", url.toString());
170 throw new DownloadFailedException(msg);
171 }
172 timestamp = lastModifiedFile.lastModified();
173 } else {
174 HttpURLConnection conn = null;
175 try {
176 conn = URLConnectionFactory.createHttpURLConnection(url);
177 conn.setRequestMethod("HEAD");
178 conn.connect();
179 final int t = conn.getResponseCode();
180 if (t >= 200 && t < 300) {
181 timestamp = conn.getLastModified();
182 } else {
183 throw new DownloadFailedException("HEAD request returned a non-200 status code");
184 }
185 } catch (URLConnectionFailureException ex) {
186 throw new DownloadFailedException("Error creating URL Connection for HTTP HEAD request.", ex);
187 } catch (IOException ex) {
188 throw new DownloadFailedException("Error making HTTP HEAD request.", ex);
189 } finally {
190 if (conn != null) {
191 try {
192 conn.disconnect();
193 } finally {
194 conn = null;
195 }
196 }
197 }
198 }
199 return timestamp;
200 }
201 }