Clover icon

Coverage Report

  1. Project Clover database Mon Sep 2 2024 17:57:51 BST
  2. Package jalview.util

File HttpUtils.java

 

Coverage histogram

../../img/srcFileCovDistChart5.png
43% of files have more coverage

Code metrics

40
103
10
1
349
241
46
0.45
10.3
10
4.6

Classes

Class Line # Actions
HttpUtils 35 103 46
0.4771241847.7%
 

Contributing tests

This file is covered by 113 tests. .

Source view

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    import java.net.URLConnection;
32   
33    import jalview.bin.Console;
34   
 
35    public class HttpUtils
36    {
37    public final static String JALVIEWSCHEMEPREFIX = "jalview";
38   
 
39  176 toggle public static boolean isPlausibleUri(String s)
40    {
41  176 if (s == null)
42    {
43  0 return false;
44    }
45  176 if (startsWithHttpOrHttps(s) || isJalviewSchemeUri(s))
46    {
47  0 return true;
48    }
49  176 try
50    {
51  176 URI u = new URI(s);
52    // allow file:/home/... as well as file:///home... as java copes
53  176 if (s.startsWith("file:/"))
54    {
55  0 return true;
56    }
57    } catch (URISyntaxException e)
58    {
59  0 return false;
60    }
61  176 return false;
62    }
63   
64    /**
65    * Returns true if it is possible to open an input stream at the given URL,
66    * else false. The input stream is closed.
67    *
68    * @param url
69    * @return
70    */
 
71  0 toggle public static boolean isValidUrl(String url)
72    {
73  0 InputStream is = null;
74  0 try
75    {
76  0 is = HttpUtils.openStream(new URL(url));
77  0 if (is != null)
78    {
79  0 return true;
80    }
81    } catch (IOException x)
82    {
83    // MalformedURLException, FileNotFoundException
84  0 return false;
85    } finally
86    {
87  0 if (is != null)
88    {
89  0 try
90    {
91  0 is.close();
92    } catch (IOException e)
93    {
94    // ignore
95    }
96    }
97    }
98  0 return false;
99    }
100   
 
101  274 toggle public static boolean startsWithHttpOrHttps(String file)
102    {
103  274 return file.startsWith("http://") || file.startsWith("https://");
104    }
105   
106    /**
107    * wrapper to get/post to a URL or check headers
108    *
109    * @param url
110    * @param ids
111    * @param readTimeout
112    * @return
113    * @throws IOException
114    * @throws ProtocolException
115    */
 
116  0 toggle public static boolean checkUrlAvailable(URL url, int readTimeout)
117    throws IOException, ProtocolException
118    {
119    // jalview.bin.Console.outPrintln(System.currentTimeMillis() + " " + url);
120   
121  0 HttpURLConnection connection = (HttpURLConnection) url.openConnection();
122  0 connection.setRequestMethod("HEAD");
123  0 connection.setDoInput(true);
124  0 connection.setUseCaches(false);
125  0 connection.setConnectTimeout(300);
126  0 connection.setReadTimeout(readTimeout);
127   
128    // HttpURLConnection doesn't follow redirects from http to https. It should!
129  0 HttpURLConnection conn = followConnection(connection);
130  0 return conn.getResponseCode() == 200;
131    }
132   
133    /**
134    * wrapper to return a new HttpURLConnection to a new URL when there is a
135    * redirect from http to https, otherwise return the unused original
136    * HttpURLConnection
137    *
138    * @param HttpURLConnection
139    * conn0
140    * @return HttpUrlConnection conn
141    */
 
142  375 toggle public static HttpURLConnection followConnection(HttpURLConnection conn0)
143    throws IOException
144    {
145  375 URL url = conn0.getURL();
146    // we are only checking for a redirect from http to https otherwise the java
147    // connection will follow when called (if not unset)
148  375 if (url == null || !"http".equals(url.getProtocol())
149    || !conn0.getInstanceFollowRedirects())
150    {
151  310 return conn0;
152    }
153   
154    // check the response code
155  65 HttpURLConnection checkConn = (HttpURLConnection) url.openConnection();
156  65 httpURLConnectionCopyAttributes(conn0, checkConn);
157   
158  65 boolean redirectToHttps = false;
159  65 int response = checkConn.getResponseCode();
160  65 checkConn.disconnect();
161  65 if (response >= 300 && response < 400)
162    {
163    // we are only checking for a redirect from http to https
164  0 URL loc = new URL(conn0.getHeaderField("Location"));
165  0 if (loc != null && "https".equals(loc.getProtocol()))
166    {
167  0 redirectToHttps = true;
168  0 url = loc;
169    }
170    }
171   
172  65 if (!redirectToHttps)
173    {
174  65 return conn0;
175    }
176   
177    // We want to return an HttpURLConnection to the new https URL that is
178    // unconnected in case further manipulation of the request is required
179  0 HttpURLConnection conn = (HttpURLConnection) url.openConnection();
180  0 httpURLConnectionCopyAttributes(conn0, conn);
181  0 return conn;
182    }
183   
 
184  65 toggle private static void httpURLConnectionCopyAttributes(
185    HttpURLConnection conn0, HttpURLConnection conn1)
186    throws ProtocolException
187    {
188  65 conn1.setRequestMethod(conn0.getRequestMethod());
189  65 conn1.setDoInput(conn0.getDoInput());
190  65 conn1.setUseCaches(conn0.getUseCaches());
191  65 conn1.setConnectTimeout(conn0.getConnectTimeout());
192  65 conn1.setReadTimeout(conn0.getReadTimeout());
193  65 conn1.setInstanceFollowRedirects(conn0.getInstanceFollowRedirects());
194    }
195   
196    /**
197    * wrapper to follow a URL connection ALLOWING redirects from http to https
198    *
199    * @param URL
200    * url
201    * @return HttpUrlConnection conn
202    */
 
203  2 toggle public static URLConnection openConnection(URL url) throws IOException
204    {
205  2 if (url == null)
206    {
207  0 Console.debug("HttpUtils.openConnection(url) called with null url");
208  0 return null;
209    }
210  2 Console.debug("HttpUtils.openConnection(url) called with url="
211    + url.toString());
212  2 URLConnection conn = null;
213  2 String protocol = url.getProtocol();
214  2 if ("http".equals(protocol) || "https".equals(protocol))
215    {
216  0 HttpURLConnection conn0 = (HttpURLConnection) url.openConnection();
217  0 if (conn0 != null)
218    {
219  0 conn = HttpUtils.followConnection(conn0);
220    }
221    else
222    {
223  0 conn = conn0;
224    }
225    }
226    else
227    {
228  2 conn = url.openConnection();
229    }
230  2 return conn;
231    }
232   
233    /**
234    * wrapper to follow a URL connection ALLOWING redirects from http to https
235    * and return the followed InputStream
236    *
237    * @param URL
238    * url
239    * @return HttpUrlConnection conn
240    */
 
241  536 toggle public static InputStream openStream(URL url) throws IOException
242    {
243  536 if (url == null)
244    {
245  0 return null;
246    }
247  536 InputStream is = null;
248  536 String protocol = url.getProtocol();
249  536 if ("http".equals(protocol) || "https".equals(protocol))
250    {
251  375 HttpURLConnection conn = HttpUtils
252    .followConnection((HttpURLConnection) url.openConnection());
253  375 if (conn != null)
254    {
255  375 is = conn.getInputStream();
256    }
257    }
258    else
259    {
260  161 is = url.openStream();
261    }
262  431 return is;
263    }
264   
265    /**
266    * check if a jalview:// scheme URL is given
267    *
268    * @param String
269    * uri
270    * @return boolean
271    */
 
272  352 toggle public static boolean isJalviewSchemeUri(String jalviewUriString)
273    {
274  352 if (jalviewUriString == null)
275    {
276  0 return false;
277    }
278  352 URI jalviewUri;
279  352 try
280    {
281  352 jalviewUri = new URI(jalviewUriString);
282    } catch (URISyntaxException e)
283    {
284  0 return false;
285    }
286  352 String scheme = jalviewUri.getScheme();
287  352 if (scheme == null || !scheme.startsWith(JALVIEWSCHEMEPREFIX))
288    {
289  352 return false;
290    }
291  0 int jspl = JALVIEWSCHEMEPREFIX.length();
292  0 return scheme.length() == jspl // jalview
293    || scheme.length() == jspl + 1 // jalviewX
294    || scheme.substring(jspl).equals("http") // jalviewhttp
295    || scheme.substring(jspl).equals("https"); // jalviewhttps
296    }
297   
298    /**
299    * convert a jalview scheme URI to its equivalent URL or path
300    *
301    * @param String
302    * uri
303    * @return String
304    */
 
305  176 toggle public static String equivalentJalviewUrl(String jalviewUriString)
306    {
307  176 if (!isJalviewSchemeUri(jalviewUriString))
308    {
309    // not a jalviewUriString, hand it back
310  176 return jalviewUriString;
311    }
312  0 URI jalviewUri;
313  0 try
314    {
315  0 jalviewUri = new URI(jalviewUriString);
316    } catch (URISyntaxException e)
317    {
318  0 return null;
319    }
320  0 String scheme = jalviewUri.getScheme();
321  0 String host = jalviewUri.getHost();
322  0 if (host != null && host.length() > 0 || scheme
323    .substring(JALVIEWSCHEMEPREFIX.length()).startsWith("http"))
324    {
325  0 URI newUri;
326  0 try
327    {
328  0 newUri = new URI(
329  0 scheme.equals(JALVIEWSCHEMEPREFIX + "http") ? "http"
330    : "https",
331    jalviewUri.getUserInfo(), host, jalviewUri.getPort(),
332    jalviewUri.getPath(), jalviewUri.getQuery(),
333    jalviewUri.getFragment());
334    // return a URL
335  0 return newUri.toURL().toString();
336    } catch (URISyntaxException | MalformedURLException e)
337    {
338  0 ErrorLog.errPrintln("Trying to convert '" + jalviewUriString
339    + "' to URL failed");
340    }
341    }
342    else
343    {
344    // return a file path (not a file URI)
345  0 return jalviewUri.getPath();
346    }
347  0 return null;
348    }
349    }