当URL包含特殊字符

时间:2018-06-17 03:50:00

标签: java url character httpsurlconnection

我正在尝试使用基于HttpsURLConnection的实现替换基于SSLSocket的工作。当我使用包含特殊字符的有效URL时,我尝试过的每个HTTPS请求都会使用我的HttpsURLConnection实现返回状态403。同时,相同的URL使用我的SSLSocket实现返回状态200。

任何人都可以看到HTTPS请求使用SSLSocket返回200的任何原因,但是使用HttpsURLConnection返回403?

以下是 SSLSocket 实施:

import com.sun.net.ssl.internal.ssl.Provider;

import javax.net.ssl.*;
import java.io.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.X509Certificate;

public class UseSslSocket
{
    public static void main(String[] args) throws NoSuchAlgorithmException, KeyManagementException, IOException
    {
        String host = "www.google.com";
        String resource = "/search?q=weather";

        TrustManager[] trustAllCert = new TrustManager[]
                {
                        new X509TrustManager()
                        {
                            public X509Certificate[] getAcceptedIssuers()
                            {
                                return null;
                            }
                            public void checkClientTrusted(X509Certificate[] certs, String authType){}
                            public void checkServerTrusted(X509Certificate[] certs, String authType){}
                        }
                };
        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCert, new SecureRandom());
        Security.addProvider(new Provider());
        SSLSocketFactory sslFactory = sslContext.getSocketFactory();
        SSLSocket sslSocket = (SSLSocket) sslFactory.createSocket(host, 443);

        Writer streamWriter = new OutputStreamWriter(sslSocket.getOutputStream());
        String rn = System.getProperty("line.separator");
        streamWriter.write("GET "+ resource +" HTTP/1.1"+ rn +"Connection:close"+ rn +"Host:"+ host + rn + rn);
        streamWriter.flush();

        InputStreamReader streamReader = new InputStreamReader(sslSocket.getInputStream());
        BufferedReader bufferedReader = new BufferedReader(streamReader);
        String response = new String();
        for (String line; (line = bufferedReader.readLine()) != null; response += line + rn);

        streamWriter.close();
        bufferedReader.close();
        sslSocket.close();

        System.out.println("https://"+ host + resource +" >> "+ response.substring(0, response.indexOf(rn)));
//        System.out.println(response);
    }
}

以下是 HttpsURLConnection 实施:

import javax.net.ssl.*;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

public class UseUrlConnect
{
    public static void main(String[] args) throws NoSuchAlgorithmException, KeyManagementException, URISyntaxException, IOException
    {
        String host = "www.google.com";
        String resource = "/search?q=weather";

        TrustManager[] trustAllCerts = new TrustManager[]
                {
                        new X509TrustManager()
                        {
                            public X509Certificate[] getAcceptedIssuers()
                            {
                                return null;
                            }
                            public void checkClientTrusted(X509Certificate[] certs, String authType){}
                            public void checkServerTrusted(X509Certificate[] certs, String authType){}
                        }
                };
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HostnameVerifier allHostsValid = new HostnameVerifier()
        {
            public boolean verify(String hostname, SSLSession session)
            {
                return true;
            }
        };
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
        URL url = new URI("https://"+ host + resource).toURL();
        HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
        urlConnection.setRequestMethod("GET");

        InputStreamReader streamReader = new InputStreamReader(urlConnection.getInputStream());
        BufferedReader bufferedReader = new BufferedReader(streamReader);
        String response = new String();
        for (String line; (line = bufferedReader.readLine()) != null; response += line + System.getProperty("line.separator"));
        bufferedReader.close();

        System.out.println(response);
    }
}

PS:存在 trustAllCert 内容,以便可以接受自签名证书。

0 个答案:

没有答案