Merge branch 'bug/JAL-4397_failing_idWidth_tests' into improvement/JAL-4409_implement...
[jalview.git] / src / 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.ProtocolException;
27 import java.net.URL;
28
29 import javax.ws.rs.HttpMethod;
30
31 import jalview.bin.Cache;
32
33 public class HttpUtils
34 {
35
36   /**
37    * Returns true if it is possible to open an input stream at the given URL,
38    * else false. The input stream is closed.
39    * 
40    * @param url
41    * @return
42    */
43   public static boolean isValidUrl(String url)
44   {
45     InputStream is = null;
46     try
47     {
48       is = HttpUtils.openStream(new URL(url));
49       if (is != null)
50       {
51         return true;
52       }
53     } catch (IOException x)
54     {
55       // MalformedURLException, FileNotFoundException
56       return false;
57     } finally
58     {
59       if (is != null)
60       {
61         try
62         {
63           is.close();
64         } catch (IOException e)
65         {
66           // ignore
67         }
68       }
69     }
70     return false;
71   }
72
73   public static boolean startsWithHttpOrHttps(String file)
74   {
75     return file.startsWith("http://") || file.startsWith("https://");
76   }
77
78   /**
79    * wrapper to get/post to a URL or check headers
80    * 
81    * @param url
82    * @param ids
83    * @param readTimeout
84    * @return
85    * @throws IOException
86    * @throws ProtocolException
87    */
88   public static boolean checkUrlAvailable(URL url, int readTimeout)
89           throws IOException, ProtocolException
90   {
91     // jalview.bin.Console.outPrintln(System.currentTimeMillis() + " " + url);
92
93     HttpURLConnection connection = (HttpURLConnection) url.openConnection();
94     connection.setRequestMethod(HttpMethod.HEAD);
95     connection.setDoInput(true);
96     connection.setUseCaches(false);
97     connection.setConnectTimeout(300);
98     connection.setReadTimeout(readTimeout);
99
100     // HttpURLConnection doesn't follow redirects from http to https. It should!
101     HttpURLConnection conn = followConnection(connection);
102     return conn.getResponseCode() == 200;
103   }
104
105   /**
106    * wrapper to follow a URL connection ALLOWING redirects from http to https
107    * 
108    * @param HttpURLConnection
109    *          conn0
110    * @return HttpUrlConnection conn
111    */
112   public static HttpURLConnection followConnection(HttpURLConnection conn0)
113           throws IOException
114   {
115     URL url = conn0.getURL();
116     if (url == null)
117     {
118       return null;
119     }
120     HttpURLConnection conn = null;
121     int response = conn0.getResponseCode();
122     boolean followed = false;
123     if (response >= 300 && response < 400 && conn0.getFollowRedirects())
124     {
125       // we are only checking for a redirect from http to https
126       if ("http".equals(url.getProtocol()))
127       {
128         URL loc = new URL(conn0.getHeaderField("Location"));
129         if (loc != null && "https".equals(loc.getProtocol()))
130         {
131           conn = (HttpURLConnection) loc.openConnection();
132           conn.setRequestMethod(conn0.getRequestMethod());
133           conn.setDoInput(conn0.getDoInput());
134           conn.setUseCaches(conn0.getUseCaches());
135           conn.setConnectTimeout(conn0.getConnectTimeout());
136           conn.setReadTimeout(conn0.getReadTimeout());
137           conn.setInstanceFollowRedirects(
138                   conn0.getInstanceFollowRedirects());
139           followed = true;
140         }
141       }
142     }
143     return followed && conn != null ? conn : conn0;
144   }
145
146   /**
147    * wrapper to follow a URL connection ALLOWING redirects from http to https
148    * 
149    * @param URL
150    *          url
151    * @return HttpUrlConnection conn
152    */
153   public static HttpURLConnection openConnection(URL url) throws IOException
154   {
155     if (url == null)
156     {
157       return null;
158     }
159     HttpURLConnection conn = null;
160     String protocol = url.getProtocol();
161     if ("http".equals(protocol) || "https".equals(protocol))
162     {
163       HttpURLConnection conn0 = (HttpURLConnection) url.openConnection();
164       if (conn0 != null)
165       {
166         conn = HttpUtils.followConnection(conn0);
167       }
168       else
169       {
170         conn = conn0;
171       }
172     }
173     return conn;
174   }
175
176   /**
177    * wrapper to follow a URL connection ALLOWING redirects from http to https
178    * and return the followed InputStream
179    * 
180    * @param URL
181    *          url
182    * @return HttpUrlConnection conn
183    */
184   public static InputStream openStream(URL url) throws IOException
185   {
186     if (url == null)
187     {
188       return null;
189     }
190     InputStream is = null;
191     String protocol = url.getProtocol();
192     if ("http".equals(protocol) || "https".equals(protocol))
193     {
194       HttpURLConnection conn = HttpUtils
195               .followConnection((HttpURLConnection) url.openConnection());
196       if (conn != null)
197       {
198         is = conn.getInputStream();
199       }
200     }
201     else
202     {
203       is = url.openStream();
204     }
205     return is;
206   }
207
208   public static String getUserAgent()
209   {
210     return getUserAgent(null);
211   }
212
213   public static String getUserAgent(String className)
214   {
215     StringBuilder sb = new StringBuilder();
216     sb.append("Jalview");
217     sb.append('/');
218     sb.append(Cache.getDefault("VERSION", "Unknown"));
219     sb.append(" (");
220     sb.append(System.getProperty("os.name"));
221     sb.append("; ");
222     sb.append(System.getProperty("os.arch"));
223     sb.append(' ');
224     sb.append(System.getProperty("os.name"));
225     sb.append(' ');
226     sb.append(System.getProperty("os.version"));
227     sb.append("; ");
228     sb.append("java/");
229     sb.append(System.getProperty("java.version"));
230     sb.append("; ");
231     sb.append("jalview/");
232     sb.append(ChannelProperties.getProperty("channel"));
233     if (className != null)
234     {
235       sb.append("; ");
236       sb.append(className);
237     }
238     String installation = Cache.applicationProperties
239             .getProperty("INSTALLATION");
240     if (installation != null)
241     {
242       sb.append("; ");
243       sb.append(installation);
244     }
245     sb.append(')');
246     sb.append(" help@jalview.org");
247     return sb.toString();
248   }
249
250 }