JAL-4409 Adjust usage of HttpUtils.equivalentJalviewURLString() and pass jalviewX...
[jalview.git] / getdown / src / getdown / core / src / main / java / jalview / util / HttpUtils.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.util;
22
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.net.HttpURLConnection;
26 import java.net.MalformedURLException;
27 import java.net.ProtocolException;
28 import java.net.URI;
29 import java.net.URISyntaxException;
30 import java.net.URL;
31
32 public class HttpUtils
33 {
34
35   /**
36    * Returns true if it is possible to open an input stream at the given URL,
37    * else false. The input stream is closed.
38    * 
39    * @param url
40    * @return
41    */
42   public static boolean isValidUrl(String url)
43   {
44     InputStream is = null;
45     try
46     {
47       is = HttpUtils.openStream(new URL(url));
48       if (is != null)
49       {
50         return true;
51       }
52     } catch (IOException x)
53     {
54       // MalformedURLException, FileNotFoundException
55       return false;
56     } finally
57     {
58       if (is != null)
59       {
60         try
61         {
62           is.close();
63         } catch (IOException e)
64         {
65           // ignore
66         }
67       }
68     }
69     return false;
70   }
71
72   public static boolean startsWithHttpOrHttps(String file)
73   {
74     return file.startsWith("http://") || file.startsWith("https://");
75   }
76
77   /**
78    * wrapper to get/post to a URL or check headers
79    * 
80    * @param url
81    * @param ids
82    * @param readTimeout
83    * @return
84    * @throws IOException
85    * @throws ProtocolException
86    */
87   public static boolean checkUrlAvailable(URL url, int readTimeout)
88           throws IOException, ProtocolException
89   {
90     // jalview.bin.Console.outPrintln(System.currentTimeMillis() + " " + url);
91
92     HttpURLConnection connection = (HttpURLConnection) url.openConnection();
93     connection.setRequestMethod("HEAD");
94     connection.setDoInput(true);
95     connection.setUseCaches(false);
96     connection.setConnectTimeout(300);
97     connection.setReadTimeout(readTimeout);
98
99     // HttpURLConnection doesn't follow redirects from http to https. It should!
100     HttpURLConnection conn = followConnection(connection);
101     return conn.getResponseCode() == 200;
102   }
103
104   /**
105    * wrapper to follow a URL connection ALLOWING redirects from http to https
106    * 
107    * @param HttpURLConnection
108    *          conn0
109    * @return HttpUrlConnection conn
110    */
111   public static HttpURLConnection followConnection(HttpURLConnection conn0)
112           throws IOException
113   {
114     URL url = conn0.getURL();
115     if (url == null)
116     {
117       return null;
118     }
119     HttpURLConnection conn = null;
120     int response = conn0.getResponseCode();
121     boolean followed = false;
122     if (response >= 300 && response < 400 && conn0.getFollowRedirects())
123     {
124       // we are only checking for a redirect from http to https
125       if ("http".equals(url.getProtocol()))
126       {
127         URL loc = new URL(conn0.getHeaderField("Location"));
128         if (loc != null && "https".equals(loc.getProtocol()))
129         {
130           conn = (HttpURLConnection) loc.openConnection();
131           conn.setRequestMethod(conn0.getRequestMethod());
132           conn.setDoInput(conn0.getDoInput());
133           conn.setUseCaches(conn0.getUseCaches());
134           conn.setConnectTimeout(conn0.getConnectTimeout());
135           conn.setReadTimeout(conn0.getReadTimeout());
136           conn.setInstanceFollowRedirects(
137                   conn0.getInstanceFollowRedirects());
138           followed = true;
139         }
140       }
141     }
142     return followed && conn != null ? conn : conn0;
143   }
144
145   /**
146    * wrapper to follow a URL connection ALLOWING redirects from http to https
147    * 
148    * @param URL
149    *          url
150    * @return HttpUrlConnection conn
151    */
152   public static HttpURLConnection openConnection(URL url) throws IOException
153   {
154     if (url == null)
155     {
156       return null;
157     }
158     HttpURLConnection conn = null;
159     String protocol = url.getProtocol();
160     if ("http".equals(protocol) || "https".equals(protocol))
161     {
162       HttpURLConnection conn0 = (HttpURLConnection) url.openConnection();
163       if (conn0 != null)
164       {
165         conn = HttpUtils.followConnection(conn0);
166       }
167       else
168       {
169         conn = conn0;
170       }
171     }
172     return conn;
173   }
174
175   /**
176    * wrapper to follow a URL connection ALLOWING redirects from http to https
177    * and return the followed InputStream
178    * 
179    * @param URL
180    *          url
181    * @return HttpUrlConnection conn
182    */
183   public static InputStream openStream(URL url) throws IOException
184   {
185     if (url == null)
186     {
187       return null;
188     }
189     InputStream is = null;
190     String protocol = url.getProtocol();
191     if ("http".equals(protocol) || "https".equals(protocol))
192     {
193       HttpURLConnection conn = HttpUtils
194               .followConnection((HttpURLConnection) url.openConnection());
195       if (conn != null)
196       {
197         is = conn.getInputStream();
198       }
199     }
200     else
201     {
202       is = url.openStream();
203     }
204     return is;
205   }
206
207   /**
208    * check if a jalview:// scheme URL is given
209    * 
210    * @param String
211    *          uri
212    * @return boolean
213    */
214   public static boolean isJalviewSchemeUri(String jalviewUriString)
215   {
216     URI jalviewUri;
217     try
218     {
219       jalviewUri = new URI(jalviewUriString);
220     } catch (URISyntaxException e)
221     {
222       return false;
223     }
224     String scheme = jalviewUri.getScheme();
225     if (scheme == null || !scheme.startsWith("jalview"))
226     {
227       return false;
228     }
229     return scheme.length() == 7 // jalview
230             || scheme.length() == 8 // jalviewX
231             || scheme.substring(7).equals("http") // jalviewhttp
232             || scheme.substring(7).equals("https"); // jalviewhttps
233   }
234
235   /**
236    * convert a jalview scheme URI to its equivalent URL or path
237    * 
238    * @param String
239    *          uri
240    * @return String
241    */
242   public static String equivalentJalviewUrl(String jalviewUriString)
243   {
244     if (!isJalviewSchemeUri(jalviewUriString))
245     {
246       // not a jalviewUriString, hand it back
247       return jalviewUriString;
248     }
249     URI jalviewUri;
250     try
251     {
252       jalviewUri = new URI(jalviewUriString);
253     } catch (URISyntaxException e)
254     {
255       return null;
256     }
257     String scheme = jalviewUri.getScheme();
258     String host = jalviewUri.getHost();
259     if (host != null && host.length() > 0
260             || scheme.substring(7).startsWith("http"))
261     {
262       URI newUri;
263       try
264       {
265         newUri = new URI(scheme.equals("jalviewhttp") ? "http" : "https",
266                 jalviewUri.getUserInfo(), host, jalviewUri.getPort(),
267                 jalviewUri.getPath(), jalviewUri.getQuery(),
268                 jalviewUri.getFragment());
269         // return a URL
270         return newUri.toURL().toString();
271       } catch (URISyntaxException | MalformedURLException e)
272       {
273         ErrorLog.errPrintln("Trying to convert '" + jalviewUriString
274                 + "' to URL failed");
275       }
276     }
277     else
278     {
279       // return a file path (not a file URI)
280       return jalviewUri.getPath();
281     }
282     return null;
283   }
284 }