Enviar solicitud HTTP manualmente a través de socket

Cuando envío una solicitud HTTP normal a través de un socket, el servidor no responde con una respuesta OK. Copié el encabezado HTTP de FireFox. Aquí está el código:

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

Sin embargo, aquí está la respuesta que recibí:

 HTTP/1.0 408 Request Time-out Cache-Control: no-cache Connection: close Content-Type: text/html 

408 Request Time-out

Your browser didn't send a complete request in time.

Sé que puedo hacerlo utilizando URL.openStream() , pero ¿por qué el servidor no identifica la solicitud HTTP cuando la envío de forma manual?

Dos cosas:

  1. Debe usar println lugar de print para imprimir sus entradas en líneas separadas.
  2. La solicitud HTTP debe terminar en una línea en blanco ( enlace ). Así que agrega pw.println("");

No sigues el HTTP RFC .

  • Las líneas de encabezado siempre terminan con un CR LF (es decir, 0x0d más 0x0a ).
  • El encabezado termina después de la primera doble línea nueva. En su caso, no incluye la nueva línea final para que el servidor no reconozca el final de los encabezados de solicitud.

En general, siempre debe intentar usar las bibliotecas HTTP existentes. Aunque HTTP parece ser un protocolo simple (y se lo compara con otros), tiene reglas semánticas y sintácticas bastante estrictas. Si intenta implementarlo usted mismo, debería haber leído y entendido las partes relevantes de RFC 2616 (y relacionadas).

Lamentablemente, ya hay demasiadas implementaciones HTTP defectuosas que no siguen los estándares que hacen la vida imposible para todos. Ahórrese la molestia y use las bibliotecas HTTP del idioma elegido.

La solución correcta que realmente funciona y es multiplataforma:

  pw.print("GET / HTTP/1.1\r\n"); pw.print("Host: stackoverflow.com\r\n\r\n"); 

La siguiente solución, como se menciona en las respuestas anteriores, resuelve el problema;

 pw.print("GET / HTTP/1.1\n\r\n"); pw.print("Host: stackoverflow.com\n\r\n");