web-dev-qa-db-ja.com

HttpURLConnection-「https://」と「http://」

たとえば、ユーザーが入力したURLのファビコンを取得しようとしています。

_url = "google.com";

HttpUrlConnectionを使用して、ホストURLの/favicon.ico拡張子からファビコンのビットマップを取得します。

        String faviconString = Uri.parse(_url).getHost() + "/favicon.ico";
        URL faviconUrl = null;
        Bitmap favicon = null;
        try
        {
            faviconString = "http://" + faviconString;
            faviconUrl = new URL(faviconString);
            HttpURLConnection connection = (HttpURLConnection) faviconUrl.openConnection();
            connection.setDoInput(true);
            connection.connect();
            favicon = BitmapFactory.decodeStream(connection.getInputStream());
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return favicon;

ただし、ユーザーはおそらくhttp://またはhttps://を指定しないので、自分で追加する必要があります。私が抱えている問題は、URLの前にhttp://を追加すると、すべてが正常に機能することですが、https://の場合、ファビコンを返すサイトもあれば、nullを返すサイトもあります。どのページがhttpsを使用しているかを確認するにはどうすればよいですか?すべての場合にhttp://を追加する必要がありますか?厳密にhttpsに制限し、httpを使用するとnullを返すWebサイトはありますか?

10
Jason Hu

User2558882の idea を使用する場合、またはWebサイトのファビコンを取得するだけのツールが他にある場合を除いて、httpとhttpsの両方のURLを確認する必要があります。これを行う他の方法はありません。それはウェブを使うことの難しさの一部です。

おそらく、コードを別の方法で見て、実行しようとしていることをより小さく、より管理しやすい部分に分解する方が少し良いでしょうか?

public void getFavicon(String Host) {

    URL httpUrl = this.getHttpUrl(Host + "/favicon.ico");

    Bitmap favicon = this.getBitmap(httpUrl);

    if (favicon == null) {

        URL httpsUrl = this.getHttpsUrl(Host + "/favicon.ico");

        favicon = this.getBitmap(httpsUrl);
    }

    if (favicon == null) {

        throw new FaviconMissingException("Unable to find favicon for Host: " + Host);
    }

    return favicon;
}

public URL getHttpUrl(String uri) throws MalformedURLException {

    // There are better ways of building a url then string concationation.
    return new URL("http://" + uri);
}

public URL getHttpsUrl(String uri) throws MalformedURLException {

    // There are better ways of building a url then string concationation.
    return new URL("https://" + uri);
}

public Bitmap getBitmap(URL url) {

    InputStream inputStream = getInputStream(url);

    Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

    return bitmap
}

public InputStream getInputStream(URL url) {

    // Please use a real connection library like HTTPClient here!
    // HttpClient will handle timeouts, redirects, and things like that for you.
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setDoInput(true);
    connection.connect();

    return connection.getInputStream();
}

ところで、1つまたは2つの接続を心配することは、2つの要求を行うためのコードを書くよりも時間がかかります。私はグーグルが必要に応じて2つの要求をしていることをほぼ保証します。そしてそれがグーグルにとって十分であるならば、それは私にとっても十分です。

最後に、2つのリクエストを行うのに本当に時間がかかりすぎることに気付いた場合は、パフォーマンスを改善するために何かをしてください。

4
hooknc

注:私の答えがどれほど役立つかわかりません。

あなたはグーグルを使用してファビコンをつかむことができます:

http://www.google.com/s2/favicons?domain=stackoverflow.com

戻り値:

enter image description here

httpまたはhttpsを指定する必要はありません。

 http://www.google.com/s2/favicons?domain=my.yorku.ca ===>> (https://my.yorku.ca)

戻り値:

enter image description here

しかし、これは https://my.yorku.ca が使用する実際のファビコンではありません。したがって、グーグルはファビコンへのアクセスを提供しないサイトに対してデフォルトのものを返すと思います。

InputStream is = null;

String urlPrefix = "http://www.google.com/s2/favicons?domain=";

String _url = "google.com";

Bitmap favicon = null;

try {

    is = (InputStream) new URL(urlPrefix + _url).getContent();

} catch (MalformedURLException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

favicon = BitmapFactory.decodeStream(is);

実際にデフォルトのファビコンのコピーを保持して、次のことを確認できます。

if (defaultBitmap.sameAs(favicon)) {
    // favicon wasn't available
}
4
Vikram
            URL url = new URL(downloadURL);
            HttpURLConnection urlCon = null;

            URL testUrlHttps = new URL(downloadURL);
            if (testUrlHttps.getProtocol().toLowerCase().equals("https"))
            {
                trustAllHosts();
                HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
                https.setHostnameVerifier(DO_NOT_VERYFY);
                urlCon = https;
            } else
            {
                urlCon = (HttpURLConnection) url.openConnection();
            }




add this method. May be it will help



   private static void trustAllHosts()
    {
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager()
        {
            public Java.security.cert.X509Certificate[] getAcceptedIssuers()
            {
                return new Java.security.cert.X509Certificate[] {};
            }

            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException
            {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException
            {
            }
        } };

        // Install the all-trusting trust manager
        try
        {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new Java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }
3
DropAndTrap

URLが「https」で始まる場合にこれを試してください。

              TrustManager[] trustAllCerts = new TrustManager[]
               {
                 new X509TrustManager()
                  {
                    public Java.security.cert.X509Certificate[] getAcceptedIssuers()  { return null; }
                    public void checkClientTrusted( Java.security.cert.X509Certificate[] certs, String authType)  {}
                    public void checkServerTrusted( Java.security.cert.X509Certificate[] certs, String authType)  {}
                  }
                 };
              try
                {
                  SSLContext sc = SSLContext.getInstance( "SSL"); // "TLS" "SSL"
                  sc.init( null, trustAllCerts, null);
                  HttpsURLConnection.setDefaultSSLSocketFactory( sc.getSocketFactory());
                  HttpsURLConnection.setDefaultHostnameVerifier( 
                   new HostnameVerifier() 
                    {
                      public boolean verify( String hostname, SSLSession session) { return true; }
                    } );
                }
               catch( Exception e)
1
Tapa Save

さらに「簡単」な別の答え。

ユーザーにファビコンのURL(プロトコルを含む)を入力させ、URLがファビコンを返すことを検証するだけです。そうでない場合は、検証エラーをエンドユーザーに表示します。

アジャイルプリンシパルに従って、最小限の作業を行い、何が機能するかを確認します。 1つのプランが機能しない場合は、別のプランを試してください。

1
hooknc

ウェブサイトがnullまたはファビコンを返すかどうかを確認するのはどうですか?

これがお役に立てば幸いです

1
Sebastian Walla