Lorsque j'envoie une requête HTTP normale via un socket, le serveur ne répond pas par une réponse OK. J'ai copié l'en-tête HTTP de FireFox. Voici le code:
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();
Cependant, voici la réponse que j'ai reçue:
HTTP/1.0 408 Request Time-out
Cache-Control: no-cache
Connection: close
Content-Type: text/html
<html><body><h1>408 Request Time-out</h1>
Your browser didn't send a complete request in time.
</body></html>
Je sais que je peux le faire en utilisant URL.openStream()
, mais pourquoi le serveur n'identifie-t-il pas la requête HTTP lorsque je l'envoie manuellement?
Deux choses:
println
au lieu de print
pour imprimer vos entrées sur des lignes séparées.pw.println("");
Vous ne suivez pas le HTTP RFC .
0x0d
plus 0x0a
).En règle générale, vous devriez toujours essayer d'utiliser les bibliothèques HTTP existantes. Bien que HTTP semble être un protocole simple (et comparé à d’autres), il a des règles syntaxiques et sémantiques assez strictes. Si vous essayez d'implémenter cela vous-même, vous devriez avoir lu et compris les parties pertinentes de la RFC 2616 (et les textes associés).
Malheureusement, il existe déjà trop d'implémentations HTTP de mauvaise qualité qui ne respectent pas les normes, ce qui rend la vie de tout le monde misérable. Économisez de l'argent et utilisez les bibliothèques HTTP de la langue de votre choix.
Le correct correctif qui fonctionne vraiment et c'est multi-plateforme:
pw.print("GET / HTTP/1.1\r\n");
pw.print("Host: stackoverflow.com\r\n\r\n");
Le correctif suivant, comme mentionné dans les réponses précédentes, résout le problème;
pw.print("GET / HTTP/1.1\n\r\n");
pw.print("Host: stackoverflow.com\n\r\n");