beginner
beginner

Reputation: 2032

Java socket gets HTTP/1.1 400 Bad Request

Tried this code from this question. When just requesting stackoverflow.com, it gives the correct reply but when i try https://stackoverflow.com/questions/10673684/send-http-request-manually-via-socket, it returns HTTP/1.1 400 Bad Request. What causes this problem?

Here is the working code i got from the above link which gives that correct response from the server.

Socket s = new Socket(InetAddress.getByName("stackoverflow.com"), 80);
PrintWriter pw = new PrintWriter(s.getOutputStream());
pw.println("GET / HTTP/1.1");
pw.println("Host: stackoverflow.com");
pw.println("");
pw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String t;
while ((t = br.readLine()) != null) {
    System.out.println(t);
}
br.close();

Tried to change it to the following...

Socket s = new Socket(InetAddress.getByName("stackoverflow.com"), 80);
PrintWriter pw = new PrintWriter(s.getOutputStream());
pw.println("GET / HTTP/1.1");
pw.println("Host: https://stackoverflow.com/questions/10673684/send-http-request-manually-via-socket");
pw.println("");
pw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String t;
while ((t = br.readLine()) != null) {
    System.out.println(t);
}

Then the response is HTTP/1.1 400 Bad Request.

P.S. I am not planning to use any http libraries.

Upvotes: 1

Views: 5709

Answers (1)

Alex
Alex

Reputation: 1205

The problem lies within your request, which is not correct. If you replace your call to the PrintWriter with

pw.println ("GET /questions/10673684/send-http-request-manually-via-socket HTTP/1.1");
pw.println ("Host: stackoverflow.com");

it should work.


EDIT: As EJP pointed out in a comment to this answer, you should make sure the line ending is always \r\n. You could either ditch the println-function and instead use

pw.print ("Host: stackoverflow.com\r\n");

or you could change the default line ending to make sure println works correctly, however, this could influence other parts of your program as well.


Furthermore, you could use a try-with-resources to make sure your socket gets closed after you finish reading, which addresses one of Steffen Ullrichs concerns in his comment to your question.

However, in your first example you call br.close();, which should close the underlying input stream, which in turn closes the socket, so that should work too. However, in my opinion it's better to do that explicitly.

Upvotes: 1

Related Questions