Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTP/HTTPS client, "connection reset" on HTTPS requests

I'm trying to make a simple HTTP/HTTPS client using java. What i have done as of now in my Client.java file is here.

Everything is working good when i try to access www.google.com:80. I'm getting the full HTML content in my response BufferedReader.

But, when i try to access www.google.com:443, there is no data coming through BufferedReader

For www.facebook.com:80,

HTTP/1.1 302 Found

Also, when i try with www.facebook.com:443, Getting the following error:

Exception in thread "main" java.net.SocketException: Connection reset

Where am i going wrong? Why am i not able to get any response for the HTTPS sites?

public class Client {

    public static void main(String[] args) throws IOException {

        //String host = args[0];
        //int port = Integer.parseInt(args[1]);
        //String path = args[2];

        int port = 80;
        String host = "www.google.com";
        String path = "/";

        //Opening Connection
        Socket clientSocket = new Socket(host, port);
        System.out.println("======================================");
        System.out.println("Connected");
        System.out.println("======================================");

        //Declare a writer to this url
        PrintWriter request = new PrintWriter(clientSocket.getOutputStream(),true);

        //Declare a listener to this url
        BufferedReader response = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

        //Sending request to the server
        //Building HTTP request header
        request.print("GET "+path+" HTTP/1.1\r\n"); //"+path+"
        request.print("Host: "+host+"\r\n");
        request.print("Connection: close\r\n");
        request.print("\r\n");
        request.flush();

        System.out.println("Request Sent!");
        System.out.println("======================================");

        //Receiving response from server
        String responseLine;
        while ((responseLine = response.readLine()) != null) {
            System.out.println(responseLine);
        }
        System.out.println("======================================"); 
        System.out.println("Response Recieved!!");
        System.out.println("======================================");
        request.close();
        response.close();
        clientSocket.close();
    }
}
like image 991
iamprem Avatar asked Sep 28 '22 14:09

iamprem


1 Answers

HTTPS is encrypted; it's HTTP via SSL. You can't just send raw HTTP requests. The server will drop your connection immediately if you start sending data without establishing a secure connection first (hence the connection reset error). You have to establish an SSL connection first. You'd want to use an SSLSocket (via SSLSocketFactory, see also example) instead of a Socket in that case.

It's as simple as changing one line of your code for the HTTPS case (well, three if you count the exception specification and the port number change to 443):

Socket clientSocket = SSLSocketFactory.getDefault().createSocket(host, port);

Note that clientSocket will be an instance of SSLSocket (which is derived from Socket) in this case.

However, if you're doing this as part of a larger application (as opposed to just a learning experience), consider existing libraries, such as Apache's HttpClient (which supports HTTPS as well) or the built-in HttpURLConnection and HttpsURLConnection if you need something more basic. If you need to embed a server in an application you can use the built-in HttpServer or HttpsServer.

Also issues that EJP mentioned in his comment.

like image 53
Jason C Avatar answered Oct 05 '22 06:10

Jason C