import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
import java.net.ProtocolException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
-
-import javax.ws.rs.HttpMethod;
-
-import jalview.bin.Cache;
+import java.net.URLConnection;
public class HttpUtils
{
+ public final static String JALVIEWSCHEMEPREFIX = "jalview";
+
+ public static boolean isPlausibleUri(String s)
+ {
+ if (s == null)
+ {
+ return false;
+ }
+ if (startsWithHttpOrHttps(s) || isJalviewSchemeUri(s))
+ {
+ return true;
+ }
+ try
+ {
+ URI u = new URI(s);
+ // allow file:/home/... as well as file:///home... as java copes
+ if (s.startsWith("file:/"))
+ {
+ return true;
+ }
+ } catch (URISyntaxException e)
+ {
+ return false;
+ }
+ return false;
+ }
/**
* Returns true if it is possible to open an input stream at the given URL,
InputStream is = null;
try
{
- is = new URL(url).openStream();
+ is = HttpUtils.openStream(new URL(url));
if (is != null)
{
return true;
// jalview.bin.Console.outPrintln(System.currentTimeMillis() + " " + url);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
-
- connection.setRequestMethod(HttpMethod.HEAD);
-
+ connection.setRequestMethod("HEAD");
connection.setDoInput(true);
-
connection.setUseCaches(false);
connection.setConnectTimeout(300);
connection.setReadTimeout(readTimeout);
- return connection.getResponseCode() == 200;
+
+ // HttpURLConnection doesn't follow redirects from http to https. It should!
+ HttpURLConnection conn = followConnection(connection);
+ return conn.getResponseCode() == 200;
+ }
+
+ /**
+ * wrapper to follow a URL connection ALLOWING redirects from http to https
+ *
+ * @param HttpURLConnection
+ * conn0
+ * @return HttpUrlConnection conn
+ */
+ public static HttpURLConnection followConnection(HttpURLConnection conn0)
+ throws IOException
+ {
+ URL url = conn0.getURL();
+ if (url == null)
+ {
+ return null;
+ }
+ HttpURLConnection conn = null;
+ int response = conn0.getResponseCode();
+ boolean followed = false;
+ if (response >= 300 && response < 400 && conn0.getFollowRedirects())
+ {
+ // we are only checking for a redirect from http to https
+ if ("http".equals(url.getProtocol()))
+ {
+ URL loc = new URL(conn0.getHeaderField("Location"));
+ if (loc != null && "https".equals(loc.getProtocol()))
+ {
+ conn = (HttpURLConnection) loc.openConnection();
+ conn.setRequestMethod(conn0.getRequestMethod());
+ conn.setDoInput(conn0.getDoInput());
+ conn.setUseCaches(conn0.getUseCaches());
+ conn.setConnectTimeout(conn0.getConnectTimeout());
+ conn.setReadTimeout(conn0.getReadTimeout());
+ conn.setInstanceFollowRedirects(
+ conn0.getInstanceFollowRedirects());
+ followed = true;
+ }
+ }
+ }
+ return followed && conn != null ? conn : conn0;
+ }
+
+ /**
+ * wrapper to follow a URL connection ALLOWING redirects from http to https
+ *
+ * @param URL
+ * url
+ * @return HttpUrlConnection conn
+ */
+ public static URLConnection openConnection(URL url) throws IOException
+ {
+ if (url == null)
+ {
+ return null;
+ }
+ URLConnection conn = null;
+ String protocol = url.getProtocol();
+ if ("http".equals(protocol) || "https".equals(protocol))
+ {
+ HttpURLConnection conn0 = (HttpURLConnection) url.openConnection();
+ if (conn0 != null)
+ {
+ conn = HttpUtils.followConnection(conn0);
+ }
+ else
+ {
+ conn = conn0;
+ }
+ }
+ else
+ {
+ conn = url.openConnection();
+ }
+ return conn;
}
- public static String getUserAgent()
+ /**
+ * wrapper to follow a URL connection ALLOWING redirects from http to https
+ * and return the followed InputStream
+ *
+ * @param URL
+ * url
+ * @return HttpUrlConnection conn
+ */
+ public static InputStream openStream(URL url) throws IOException
{
- return getUserAgent(null);
+ if (url == null)
+ {
+ return null;
+ }
+ InputStream is = null;
+ String protocol = url.getProtocol();
+ if ("http".equals(protocol) || "https".equals(protocol))
+ {
+ HttpURLConnection conn = HttpUtils
+ .followConnection((HttpURLConnection) url.openConnection());
+ if (conn != null)
+ {
+ is = conn.getInputStream();
+ }
+ }
+ else
+ {
+ is = url.openStream();
+ }
+ return is;
}
- public static String getUserAgent(String className)
+ /**
+ * check if a jalview:// scheme URL is given
+ *
+ * @param String
+ * uri
+ * @return boolean
+ */
+ public static boolean isJalviewSchemeUri(String jalviewUriString)
{
- StringBuilder sb = new StringBuilder();
- sb.append("Jalview");
- sb.append('/');
- sb.append(Cache.getDefault("VERSION", "Unknown"));
- sb.append(" (");
- sb.append(System.getProperty("os.name"));
- sb.append("; ");
- sb.append(System.getProperty("os.arch"));
- sb.append(' ');
- sb.append(System.getProperty("os.name"));
- sb.append(' ');
- sb.append(System.getProperty("os.version"));
- sb.append("; ");
- sb.append("java/");
- sb.append(System.getProperty("java.version"));
- sb.append("; ");
- sb.append("jalview/");
- sb.append(ChannelProperties.getProperty("channel"));
- if (className != null)
- {
- sb.append("; ");
- sb.append(className);
- }
- String installation = Cache.applicationProperties
- .getProperty("INSTALLATION");
- if (installation != null)
- {
- sb.append("; ");
- sb.append(installation);
- }
- sb.append(')');
- sb.append(" help@jalview.org");
- return sb.toString();
+ URI jalviewUri;
+ try
+ {
+ jalviewUri = new URI(jalviewUriString);
+ } catch (URISyntaxException e)
+ {
+ return false;
+ }
+ String scheme = jalviewUri.getScheme();
+ if (scheme == null || !scheme.startsWith(JALVIEWSCHEMEPREFIX))
+ {
+ return false;
+ }
+ int jspl = JALVIEWSCHEMEPREFIX.length();
+ return scheme.length() == jspl // jalview
+ || scheme.length() == jspl + 1 // jalviewX
+ || scheme.substring(jspl).equals("http") // jalviewhttp
+ || scheme.substring(jspl).equals("https"); // jalviewhttps
}
+ /**
+ * convert a jalview scheme URI to its equivalent URL or path
+ *
+ * @param String
+ * uri
+ * @return String
+ */
+ public static String equivalentJalviewUrl(String jalviewUriString)
+ {
+ if (!isJalviewSchemeUri(jalviewUriString))
+ {
+ // not a jalviewUriString, hand it back
+ return jalviewUriString;
+ }
+ URI jalviewUri;
+ try
+ {
+ jalviewUri = new URI(jalviewUriString);
+ } catch (URISyntaxException e)
+ {
+ return null;
+ }
+ String scheme = jalviewUri.getScheme();
+ String host = jalviewUri.getHost();
+ if (host != null && host.length() > 0 || scheme
+ .substring(JALVIEWSCHEMEPREFIX.length()).startsWith("http"))
+ {
+ URI newUri;
+ try
+ {
+ newUri = new URI(
+ scheme.equals(JALVIEWSCHEMEPREFIX + "http") ? "http"
+ : "https",
+ jalviewUri.getUserInfo(), host, jalviewUri.getPort(),
+ jalviewUri.getPath(), jalviewUri.getQuery(),
+ jalviewUri.getFragment());
+ // return a URL
+ return newUri.toURL().toString();
+ } catch (URISyntaxException | MalformedURLException e)
+ {
+ ErrorLog.errPrintln("Trying to convert '" + jalviewUriString
+ + "' to URL failed");
+ }
+ }
+ else
+ {
+ // return a file path (not a file URI)
+ return jalviewUri.getPath();
+ }
+ return null;
+ }
}