Coverage Report - org.owasp.dependencycheck.utils.Downloader
 
Classes in this File Line Coverage Branch Coverage Complexity
Downloader
0%
0/84
0%
0/24
4.143
 
 1  
 /*
 2  
  * This file is part of dependency-check-core.
 3  
  *
 4  
  * Dependency-check-core is free software: you can redistribute it and/or modify it
 5  
  * under the terms of the GNU General Public License as published by the Free
 6  
  * Software Foundation, either version 3 of the License, or (at your option) any
 7  
  * later version.
 8  
  *
 9  
  * Dependency-check-core is distributed in the hope that it will be useful, but
 10  
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  
  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 12  
  * details.
 13  
  *
 14  
  * You should have received a copy of the GNU General Public License along with
 15  
  * dependency-check-core. If not, see http://www.gnu.org/licenses/.
 16  
  *
 17  
  * Copyright (c) 2012 Jeremy Long. All Rights Reserved.
 18  
  */
 19  
 package org.owasp.dependencycheck.utils;
 20  
 
 21  
 import java.io.BufferedOutputStream;
 22  
 import java.io.File;
 23  
 import java.io.FileOutputStream;
 24  
 import java.io.IOException;
 25  
 import java.io.InputStream;
 26  
 import java.net.HttpURLConnection;
 27  
 import java.net.InetSocketAddress;
 28  
 import java.net.Proxy;
 29  
 import java.net.SocketAddress;
 30  
 import java.net.URL;
 31  
 import java.util.logging.Level;
 32  
 import java.util.logging.Logger;
 33  
 import java.util.zip.GZIPInputStream;
 34  
 import java.util.zip.InflaterInputStream;
 35  
 
 36  
 /**
 37  
  * A utility to download files from the Internet.
 38  
  *
 39  
  * @author Jeremy Long (jeremy.long@owasp.org)
 40  
  */
 41  
 public final class Downloader {
 42  
 
 43  
     /**
 44  
      * Private constructor for utility class.
 45  
      */
 46  0
     private Downloader() {
 47  0
     }
 48  
 
 49  
     /**
 50  
      * Retrieves a file from a given URL and saves it to the outputPath.
 51  
      *
 52  
      * @param url the URL of the file to download.
 53  
      * @param outputPath the path to the save the file to.
 54  
      * @throws DownloadFailedException is thrown if there is an error
 55  
      * downloading the file.
 56  
      */
 57  
     public static void fetchFile(URL url, String outputPath) throws DownloadFailedException {
 58  0
         fetchFile(url, outputPath, false);
 59  0
     }
 60  
 
 61  
     /**
 62  
      * Retrieves a file from a given URL and saves it to the outputPath.
 63  
      *
 64  
      * @param url the URL of the file to download.
 65  
      * @param outputPath the path to the save the file to.
 66  
      * @param unzip true/false indicating that the file being retrieved is
 67  
      * gzipped and if true, should be uncompressed before writing to the file.
 68  
      * @throws DownloadFailedException is thrown if there is an error
 69  
      * downloading the file.
 70  
      */
 71  
     public static void fetchFile(URL url, String outputPath, boolean unzip) throws DownloadFailedException {
 72  0
         final File f = new File(outputPath);
 73  0
         fetchFile(url, f, unzip);
 74  0
     }
 75  
 
 76  
     /**
 77  
      * Retrieves a file from a given URL and saves it to the outputPath.
 78  
      *
 79  
      * @param url the URL of the file to download.
 80  
      * @param outputPath the path to the save the file to.
 81  
      * @throws DownloadFailedException is thrown if there is an error
 82  
      * downloading the file.
 83  
      */
 84  
     public static void fetchFile(URL url, File outputPath) throws DownloadFailedException {
 85  0
         fetchFile(url, outputPath, false);
 86  0
     }
 87  
 
 88  
     /**
 89  
      * Retrieves a file from a given URL and saves it to the outputPath.
 90  
      *
 91  
      * @param url the URL of the file to download.
 92  
      * @param outputPath the path to the save the file to.
 93  
      * @param unzip true/false indicating that the file being retrieved is
 94  
      * gzipped and if true, should be uncompressed before writing to the file.
 95  
      * @throws DownloadFailedException is thrown if there is an error
 96  
      * downloading the file.
 97  
      */
 98  
     public static void fetchFile(URL url, File outputPath, boolean unzip) throws DownloadFailedException {
 99  0
         HttpURLConnection conn = null;
 100  
         try {
 101  0
             conn = Downloader.getConnection(url);
 102  0
             conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
 103  0
             conn.connect();
 104  0
         } catch (IOException ex) {
 105  
             try {
 106  0
                 if (conn != null) {
 107  0
                     conn.disconnect();
 108  
                 }
 109  
             } finally {
 110  0
                 conn = null;
 111  0
             }
 112  0
             throw new DownloadFailedException("Error downloading file.", ex);
 113  0
         }
 114  0
         final String encoding = conn.getContentEncoding();
 115  
 
 116  0
         BufferedOutputStream writer = null;
 117  0
         InputStream reader = null;
 118  
         try {
 119  0
             if (unzip || (encoding != null && "gzip".equalsIgnoreCase(encoding))) {
 120  0
                 reader = new GZIPInputStream(conn.getInputStream());
 121  0
             } else if (encoding != null && "deflate".equalsIgnoreCase(encoding)) {
 122  0
                 reader = new InflaterInputStream(conn.getInputStream());
 123  
             } else {
 124  0
                 reader = conn.getInputStream();
 125  
             }
 126  
 
 127  0
             writer = new BufferedOutputStream(new FileOutputStream(outputPath));
 128  0
             final byte[] buffer = new byte[4096];
 129  
             int bytesRead;
 130  0
             while ((bytesRead = reader.read(buffer)) > 0) {
 131  0
                 writer.write(buffer, 0, bytesRead);
 132  
             }
 133  0
         } catch (Exception ex) {
 134  0
             throw new DownloadFailedException("Error saving downloaded file.", ex);
 135  
         } finally {
 136  0
             if (writer != null) {
 137  
                 try {
 138  0
                     writer.close();
 139  0
                     writer = null;
 140  0
                 } catch (Exception ex) {
 141  0
                     Logger.getLogger(Downloader.class.getName()).log(Level.FINEST,
 142  
                             "Error closing the writer in Downloader.", ex);
 143  0
                 }
 144  
             }
 145  0
             if (reader != null) {
 146  
                 try {
 147  0
                     reader.close();
 148  0
                     reader = null;
 149  0
                 } catch (Exception ex) {
 150  
 
 151  0
                     Logger.getLogger(Downloader.class.getName()).log(Level.FINEST,
 152  
                             "Error closing the reader in Downloader.", ex);
 153  0
                 }
 154  
             }
 155  
             try {
 156  0
                 conn.disconnect();
 157  
             } finally {
 158  0
                 conn = null;
 159  0
             }
 160  0
         }
 161  0
     }
 162  
 
 163  
     /**
 164  
      * Makes an HTTP Head request to retrieve the last modified date of the
 165  
      * given URL.
 166  
      *
 167  
      * @param url the URL to retrieve the timestamp from
 168  
      * @return an epoch timestamp
 169  
      * @throws DownloadFailedException is thrown if an exception occurs making
 170  
      * the HTTP request
 171  
      */
 172  
     public static long getLastModified(URL url) throws DownloadFailedException {
 173  0
         HttpURLConnection conn = null;
 174  0
         long timestamp = 0;
 175  
         try {
 176  0
             conn = Downloader.getConnection(url);
 177  0
             conn.setRequestMethod("HEAD");
 178  0
             conn.connect();
 179  0
             timestamp = conn.getLastModified();
 180  0
         } catch (Exception ex) {
 181  0
             throw new DownloadFailedException("Error making HTTP HEAD request.", ex);
 182  
         } finally {
 183  0
             if (conn != null) {
 184  
                 try {
 185  0
                     conn.disconnect();
 186  
                 } finally {
 187  0
                     conn = null;
 188  0
                 }
 189  
             }
 190  
         }
 191  0
         return timestamp;
 192  
     }
 193  
 
 194  
     /**
 195  
      * Utility method to get an HttpURLConnection. If the app is configured to
 196  
      * use a proxy this method will retrieve the proxy settings and use them
 197  
      * when setting up the connection.
 198  
      *
 199  
      * @param url the url to connect to
 200  
      * @return an HttpURLConnection
 201  
      * @throws DownloadFailedException thrown if there is an exception
 202  
      */
 203  
     private static HttpURLConnection getConnection(URL url) throws DownloadFailedException {
 204  0
         HttpURLConnection conn = null;
 205  0
         Proxy proxy = null;
 206  0
         final String proxyUrl = Settings.getString(Settings.KEYS.PROXY_URL);
 207  
         try {
 208  0
             if (proxyUrl != null) {
 209  0
                 final int proxyPort = Settings.getInt(Settings.KEYS.PROXY_PORT);
 210  0
                 final SocketAddress addr = new InetSocketAddress(proxyUrl, proxyPort);
 211  0
                 proxy = new Proxy(Proxy.Type.HTTP, addr);
 212  0
                 conn = (HttpURLConnection) url.openConnection(proxy);
 213  0
             } else {
 214  0
                 conn = (HttpURLConnection) url.openConnection();
 215  
             }
 216  
             //added a default timeout of 20000
 217  
             //if (Settings.getString(Settings.KEYS.CONNECTION_TIMEOUT) != null) {
 218  0
             final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 60000);
 219  0
             conn.setConnectTimeout(timeout);
 220  
             //}
 221  0
         } catch (IOException ex) {
 222  0
             if (conn != null) {
 223  
                 try {
 224  0
                     conn.disconnect();
 225  
                 } finally {
 226  0
                     conn = null;
 227  0
                 }
 228  
             }
 229  0
             throw new DownloadFailedException("Error getting connection.", ex);
 230  0
         }
 231  0
         return conn;
 232  
     }
 233  
 }