/* * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) * Copyright (C) $$Year-Rel$$ The Jalview Authors * * This file is part of Jalview. * * Jalview is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ package jalview.util; 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 java.net.URLConnection; public class HttpUtils { public final static String JALVIEWSCHEMEPREFIX = "jalview"; /** * Returns true if it is possible to open an input stream at the given URL, * else false. The input stream is closed. * * @param url * @return */ public static boolean isValidUrl(String url) { InputStream is = null; try { is = HttpUtils.openStream(new URL(url)); if (is != null) { return true; } } catch (IOException x) { // MalformedURLException, FileNotFoundException return false; } finally { if (is != null) { try { is.close(); } catch (IOException e) { // ignore } } } return false; } public static boolean startsWithHttpOrHttps(String file) { return file.startsWith("http://") || file.startsWith("https://"); } public static boolean startsWithHttpOrHttpsOrJalviewScheme(String file) { if (startsWithHttpOrHttps(file)) { return true; } return isJalviewSchemeUri(file); } /** * wrapper to get/post to a URL or check headers * * @param url * @param ids * @param readTimeout * @return * @throws IOException * @throws ProtocolException */ public static boolean checkUrlAvailable(URL url, int readTimeout) throws IOException, ProtocolException { // jalview.bin.Console.outPrintln(System.currentTimeMillis() + " " + url); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("HEAD"); connection.setDoInput(true); connection.setUseCaches(false); connection.setConnectTimeout(300); connection.setReadTimeout(readTimeout); // 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; } /** * 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 { 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; } /** * check if a jalview:// scheme URL is given * * @param String * uri * @return boolean */ public static boolean isJalviewSchemeUri(String jalviewUriString) { 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; } }