Ik ben bezig met een kleine HTTP responder in java, maar ik heb wat probleempjes met de chunked encoding. Meerdere browsers accepteren de output niet. Enkel Firefox en Opera lijken de output van mijn app. te pakken, terwijl IE8 en chrome de reactie niet graag ontvangen. Chrome is de enige die een beetje een nuttige foutmelding geeft:
Error 321 (net::ERR_INVALID_CHUNKED_ENCODING): Unknown error.
Die zegt dus netjes dat er een fout zit in mijn chunky encoding, maar ik zou niet weten waar de fout zit.
De output van mijn app is:
Iedere lijn is netjes gescheiden met CRLF, zoals omschreven in de HTTP specificatie. Ook wordt de laatste 0 netjes gevolgd door een dubbele CRLF, wat niet te zien is tussen de code-tags omdat de BBCode parser de code trimt van whitespace.
Ik zou niet weten waar hier de fout in zit: waarom accepteren zowel Chrome als Internet Explorer deze output niet? Klopt de output niet of kloot java met de CRLF tekentjes?
Het platform waar ik deze output laat genereren is op dit moment een Java VM draaiende in Apple.
Om deze post nog even af te maken, het relevante deel van mijn code:
Main.java
HTTP/ResponseWriter.java
HTTP/Response.java
Error 321 (net::ERR_INVALID_CHUNKED_ENCODING): Unknown error.
Die zegt dus netjes dat er een fout zit in mijn chunky encoding, maar ik zou niet weten waar de fout zit.
De output van mijn app is:
code:
1
2
3
4
5
6
7
8
| HTTP/1.1 200 OK Content-Type: text/plain Transfer-Encoding: chunked 22 Deze tekenreeks is 34 tekens lang. 0 |
Iedere lijn is netjes gescheiden met CRLF, zoals omschreven in de HTTP specificatie. Ook wordt de laatste 0 netjes gevolgd door een dubbele CRLF, wat niet te zien is tussen de code-tags omdat de BBCode parser de code trimt van whitespace.
Ik zou niet weten waar hier de fout in zit: waarom accepteren zowel Chrome als Internet Explorer deze output niet? Klopt de output niet of kloot java met de CRLF tekentjes?
Het platform waar ik deze output laat genereren is op dit moment een Java VM draaiende in Apple.
Om deze post nog even af te maken, het relevante deel van mijn code:
Main.java
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
| import java.io.*; import java.net.*; import HTTP.*; public class Main { public static void main(String[] args) throws IOException { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(8080); } catch(IOException exc) { System.err.println(exc); System.exit(1); } Socket clientSocket = null; int count = 1; while(count-- > 0) { System.out.println((count+1)+" connections left..."); try { clientSocket = serverSocket.accept(); } catch(IOException exc) { System.err.println(exc); System.exit(1); } try { RequestReader request = new RequestReader(clientSocket.getInputStream()); ResponseWriter response = new ResponseWriter(clientSocket.getOutputStream()); //response.print("àáèéêëïóöü€×÷"); response.print("Deze tekenreeks is 34 tekens lang."); response.finish(); } catch(Exception e) { System.err.println(e); } clientSocket.close(); } serverSocket.close(); } } |
HTTP/ResponseWriter.java
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
| package HTTP; import HTTP.Exceptions.HttpHeadersAlreadySentException; import java.io.OutputStream; import java.io.PrintWriter; /** * A Response-extension which enables the Response to write itself on a outputStream. * @author tobyhinloopen */ public class ResponseWriter extends Response { protected final PrintWriter outputStream; private boolean headersSend = false; /** * Creates a new ResponseWriter * @param outputStream */ public ResponseWriter(OutputStream outputStream) { this.outputStream = new PrintWriter(outputStream); } /** * Try to send the currently generated output. */ public void flush() { trySendHeaders(); try { outputStream.print(Integer.toHexString(output.length())+"\r\n"); outputStream.print(output+"\r\n\r\n"); output = ""; outputStream.flush(); } catch(Exception e) { System.err.println(e); } } /** * Try to send the headers. * @return TRUE if the headers are sent, FALSE if the headers are already sent. */ public boolean trySendHeaders() { if(headersSend) { return false; } try { sendHeaders(); return true; } catch(HttpHeadersAlreadySentException e) { return false; } } /** * Send all headers. * @throws HttpHeadersAlreadySentException */ public void sendHeaders() throws HttpHeadersAlreadySentException { if(headersSend) { throw new HttpHeadersAlreadySentException(); } outputStream.print("HTTP/1.1 200 OK\r\n"); outputStream.print("Content-Type: "+contentType+"\r\n"); outputStream.print("Transfer-Encoding: chunked\r\n\r\n"); headersSend = true; } /** * Sends the complete response and closes the outputStream. */ public void finish() { flush(); outputStream.print("0\r\n\r\n"); outputStream.flush(); outputStream.close(); } } |
HTTP/Response.java
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| package HTTP; /** * A Class representing a HTTP Response. * @author tobyhinloopen */ public class Response { protected String contentType = "text/plain"; protected String output = ""; /** * Appends <code>String</code> to the output. * @param string The string to append. */ public void print(String string) { output += string; } } |
[ Voor 0% gewijzigd door Gamebuster op 13-01-2010 21:29 . Reden: Typo ]
Let op: Mijn post bevat meningen, aannames of onwaarheden