1 /*
   2  * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package jnlp.converter;
  25 
  26 import java.io.File;
  27 import java.io.FileInputStream;
  28 import java.io.FileNotFoundException;
  29 import java.io.FileOutputStream;
  30 import java.io.IOException;
  31 import java.io.InputStream;
  32 import java.io.OutputStream;
  33 import java.net.HttpURLConnection;
  34 import java.net.MalformedURLException;
  35 import java.net.URI;
  36 import java.net.URL;
  37 import java.nio.file.Files;
  38 import java.nio.file.Path;
  39 import java.nio.file.Paths;
  40 import jnlp.converter.parser.GeneralUtil;
  41 
  42 public class HTTPHelper {
  43 
  44     public static final int BUFFER_SIZE = 4096;
  45 
  46     public static String downloadFile(String url, String destFolder, String destFileName) throws MalformedURLException, IOException {
  47         HttpURLConnection connection = null;
  48         String destFile = null;
  49 
  50         try {
  51             if (url.contains(" ")) {
  52                 url = url.replace(" ", "%20");
  53             }
  54             if (url.contains("\\")) {
  55                 url = url.replace("\\", "/");
  56             }
  57 
  58             URL resource = new URL(url);
  59             connection = (HttpURLConnection) resource.openConnection();
  60 
  61             int responseCode = connection.getResponseCode();
  62             if (responseCode == HttpURLConnection.HTTP_OK) {
  63                 destFile = destFolder + File.separator + destFileName;
  64                 Log.verbose("Downloading " + url + " to " + destFile);
  65 
  66                 try (InputStream inputStream = connection.getInputStream();
  67                      OutputStream outputStream = new FileOutputStream(destFile)) {
  68                     byte[] buffer = new byte[BUFFER_SIZE];
  69 
  70                     int length;
  71                     do {
  72                         length = inputStream.read(buffer);
  73                         if (length > 0) {
  74                             outputStream.write(buffer, 0, length);
  75                         }
  76                     } while (length > 0);
  77                 }
  78             } else {
  79                 HTTPHelperException e = new HTTPHelperException("Error: Cannot download " + url + ". Server response code: " + responseCode);
  80                 e.setResponseCode(responseCode);
  81                 throw e;
  82             }
  83         } catch (IOException e) {
  84             if (e instanceof HTTPHelperException) {
  85                 throw e;
  86             } else {
  87                 throw new HTTPHelperException("Error: Cannot download " + url + ". " + e.getClass().getSimpleName() + ": " + e.getMessage());
  88             }
  89         } finally {
  90             if (connection != null) {
  91                 connection.disconnect();
  92             }
  93         }
  94 
  95         return destFile;
  96     }
  97 
  98     public static String copyFile(String url, String destFolder, String destFileName) throws Exception {
  99         if (url.contains(" ")) {
 100             url = url.replace(" ", "%20");
 101         }
 102 
 103         URI sourceURI = new URI(url);
 104 
 105         String sourceFile = sourceURI.getPath();
 106         File file = new File(sourceFile);
 107         if (!file.exists()) {
 108             throw new FileNotFoundException("Error: " + sourceFile + " does not exist.");
 109         }
 110 
 111         String destFile = destFolder + File.separator + destFileName;
 112         file = new File(destFile);
 113         if (file.exists()) {
 114             file.delete();
 115         }
 116 
 117         Path sourcePath = Paths.get(sourceURI);
 118         Path destPath = Paths.get(destFile);
 119         Log.verbose("Copying " + url + " to " + destFile);
 120         Files.copy(sourcePath, destPath);
 121 
 122         return destFile;
 123     }
 124 
 125     public static boolean isHTTPUrl(String url) {
 126         return (url.startsWith("http://") || url.startsWith("https://"));
 127     }
 128 
 129     public static byte[] getJNLPBits(String versionedJNLP, String jnlp) throws Exception {
 130         String jnlpFilePath = null;
 131         byte[] bits = null;
 132 
 133         if (isHTTPUrl(jnlp)) {
 134             try {
 135                 jnlpFilePath = downloadFile(versionedJNLP, JNLPConverter.getJnlpDownloadFolderStatic(), getFileNameFromURL(jnlp));
 136             } catch (HTTPHelperException ex) {
 137                 if (ex.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND &&
 138                        !versionedJNLP.equals(jnlp)) {
 139                     Log.warning("Downloading versioned JNLP from " + versionedJNLP + " failed.");
 140                     Log.warning(ex.getMessage());
 141                     Log.warning("Downloading " + jnlp + " instead.");
 142                     jnlpFilePath = downloadFile(jnlp, JNLPConverter.getJnlpDownloadFolderStatic(), getFileNameFromURL(jnlp));
 143                 } else {
 144                     throw ex;
 145                 }
 146             }
 147             JNLPConverter.markFileToDelete(jnlpFilePath);
 148         } else {
 149             try {
 150                 jnlpFilePath = copyFile(versionedJNLP, JNLPConverter.getJnlpDownloadFolderStatic(), getFileNameFromURL(jnlp));
 151             } catch (FileNotFoundException ex) {
 152                 System.out.println("Error copying versioned JNLP from " + versionedJNLP);
 153                 System.out.println(ex.getMessage());
 154                 System.out.println("Copying " + jnlp + " instead.");
 155                 jnlpFilePath = HTTPHelper.copyFile(jnlp, JNLPConverter.getJnlpDownloadFolderStatic(), getFileNameFromURL(jnlp));
 156             }
 157             JNLPConverter.markFileToDelete(jnlpFilePath);
 158         }
 159 
 160         File jnlpFile = new File(jnlpFilePath);
 161         if (jnlpFile.exists()) {
 162             bits = GeneralUtil.readBytes(new FileInputStream(jnlpFile), jnlpFile.length());
 163         }
 164 
 165         return bits;
 166     }
 167 
 168     public static String getFileNameFromURL(String url) throws IOException {
 169         int index;
 170         int index1 = url.lastIndexOf('/');
 171         int index2 = url.lastIndexOf('\\');
 172 
 173         if (index1 >= index2) {
 174             index = index1;
 175         } else {
 176             index = index2;
 177         }
 178 
 179         if (index != -1) {
 180             String name = url.substring(index + 1, url.length());
 181             name = name.replace("%20", " ");
 182             if (name.endsWith(".jnlp") || name.endsWith(".jar")) { // JNLP or JAR
 183                 return name;
 184             } else if (name.endsWith(".ico")) { // Icons
 185                 return name;
 186             } else {
 187                 throw new IOException("Error: Unsupported file extension for " + url);
 188             }
 189         } else {
 190             throw new IOException("Error: URL (" + url + ") should end with file name.");
 191         }
 192     }
 193 }