46 * and a chunked response body greater than |
46 * and a chunked response body greater than |
47 * sun.net.http.errorstream.bufferSize, 4K + 10 bytes. |
47 * sun.net.http.errorstream.bufferSize, 4K + 10 bytes. |
48 * 2) Client sends request to server and tries to |
48 * 2) Client sends request to server and tries to |
49 * getErrorStream(). 4K + 10 bytes must be read from |
49 * getErrorStream(). 4K + 10 bytes must be read from |
50 * the errorStream. |
50 * the errorStream. |
|
51 * |
|
52 * Part 3: 6993490 |
|
53 * Reuse persistent connection from part 2, the error stream |
|
54 * buffering will have set a reduced timeout on the socket and |
|
55 * tried to reset it to the default, infinity. Client must not |
|
56 * throw a timeout exception. If it does, it indicates that the |
|
57 * default timeout was not reset correctly. |
|
58 * If no timeout exception is thrown, it does not guarantee that |
|
59 * the timeout was reset correctly, as there is a potential race |
|
60 * between the sleeping server and the client thread. Typically, |
|
61 * 1000 millis has been enought to reliable reproduce this problem |
|
62 * since the error stream buffering sets the timeout to 60 millis. |
51 */ |
63 */ |
52 |
64 |
53 public class ChunkedErrorStream |
65 public class ChunkedErrorStream |
54 { |
66 { |
55 com.sun.net.httpserver.HttpServer httpServer; |
67 com.sun.net.httpserver.HttpServer httpServer; |
73 } catch (IOException ioe) { |
85 } catch (IOException ioe) { |
74 ioe.printStackTrace(); |
86 ioe.printStackTrace(); |
75 } finally { |
87 } finally { |
76 httpServer.stop(1); |
88 httpServer.stop(1); |
77 } |
89 } |
78 |
|
79 } |
90 } |
80 |
91 |
81 void doClient() { |
92 void doClient() { |
82 for (int times=0; times<2; times++) { |
93 for (int times=0; times<3; times++) { |
83 HttpURLConnection uc = null; |
94 HttpURLConnection uc = null; |
84 try { |
95 try { |
85 InetSocketAddress address = httpServer.getAddress(); |
96 InetSocketAddress address = httpServer.getAddress(); |
86 String URLStr = "http://localhost:" + address.getPort() + "/test/"; |
97 String URLStr = "http://localhost:" + address.getPort() + "/test/"; |
87 if (times == 0) { |
98 if (times == 0) { |
88 URLStr += 6488669; |
99 URLStr += "first"; |
89 } else { |
100 } else { |
90 URLStr += 6595324; |
101 URLStr += "second"; |
91 } |
102 } |
92 |
103 |
93 System.out.println("Trying " + URLStr); |
104 System.out.println("Trying " + URLStr); |
94 URL url = new URL(URLStr); |
105 URL url = new URL(URLStr); |
95 uc = (HttpURLConnection)url.openConnection(); |
106 uc = (HttpURLConnection)url.openConnection(); |
96 uc.getInputStream(); |
107 uc.getInputStream(); |
97 |
108 |
98 throw new RuntimeException("Failed: getInputStream should throw and IOException"); |
109 throw new RuntimeException("Failed: getInputStream should throw and IOException"); |
99 } catch (IOException e) { |
110 } catch (IOException e) { |
|
111 if (e instanceof SocketTimeoutException) { |
|
112 e.printStackTrace(); |
|
113 throw new RuntimeException("Failed: SocketTimeoutException should not happen"); |
|
114 } |
|
115 |
100 // This is what we expect to happen. |
116 // This is what we expect to happen. |
101 InputStream es = uc.getErrorStream(); |
117 InputStream es = uc.getErrorStream(); |
102 byte[] ba = new byte[1024]; |
118 byte[] ba = new byte[1024]; |
103 int count = 0, ret; |
119 int count = 0, ret; |
104 try { |
120 try { |
110 } |
126 } |
111 |
127 |
112 if (count == 0) |
128 if (count == 0) |
113 throw new RuntimeException("Failed: ErrorStream returning 0 bytes"); |
129 throw new RuntimeException("Failed: ErrorStream returning 0 bytes"); |
114 |
130 |
115 if (times == 1 && count != (4096+10)) |
131 if (times >= 1 && count != (4096+10)) |
116 throw new RuntimeException("Failed: ErrorStream returning " + count + |
132 throw new RuntimeException("Failed: ErrorStream returning " + count + |
117 " bytes. Expecting " + (4096+10)); |
133 " bytes. Expecting " + (4096+10)); |
118 |
134 |
119 System.out.println("Read " + count + " bytes from the errorStream"); |
135 System.out.println("Read " + count + " bytes from the errorStream"); |
120 } |
136 } |
126 */ |
142 */ |
127 void startHttpServer() throws IOException { |
143 void startHttpServer() throws IOException { |
128 httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0); |
144 httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0); |
129 |
145 |
130 // create HttpServer context |
146 // create HttpServer context |
131 HttpContext ctx1 = httpServer.createContext("/test/6488669", new Handler6488669()); |
147 httpServer.createContext("/test/first", new FirstHandler()); |
132 HttpContext ctx2 = httpServer.createContext("/test/6595324", new Handler6595324()); |
148 httpServer.createContext("/test/second", new SecondHandler()); |
133 |
149 |
134 httpServer.start(); |
150 httpServer.start(); |
135 } |
151 } |
136 |
152 |
137 class Handler6488669 implements HttpHandler { |
153 class FirstHandler implements HttpHandler { |
138 public void handle(HttpExchange t) throws IOException { |
154 public void handle(HttpExchange t) throws IOException { |
139 InputStream is = t.getRequestBody(); |
155 InputStream is = t.getRequestBody(); |
140 byte[] ba = new byte[1024]; |
156 byte[] ba = new byte[1024]; |
141 while (is.read(ba) != -1); |
157 while (is.read(ba) != -1); |
142 is.close(); |
158 is.close(); |
154 os.close(); |
170 os.close(); |
155 t.close(); |
171 t.close(); |
156 } |
172 } |
157 } |
173 } |
158 |
174 |
159 class Handler6595324 implements HttpHandler { |
175 static class SecondHandler implements HttpHandler { |
|
176 /* count greater than 0, slow response */ |
|
177 static int count = 0; |
|
178 |
160 public void handle(HttpExchange t) throws IOException { |
179 public void handle(HttpExchange t) throws IOException { |
161 InputStream is = t.getRequestBody(); |
180 InputStream is = t.getRequestBody(); |
162 byte[] ba = new byte[1024]; |
181 byte[] ba = new byte[1024]; |
163 while (is.read(ba) != -1); |
182 while (is.read(ba) != -1); |
164 is.close(); |
183 is.close(); |
165 |
184 |
|
185 if (count > 0) { |
|
186 System.out.println("server sleeping..."); |
|
187 try { Thread.sleep(1000); } catch(InterruptedException e) {} |
|
188 } |
|
189 count++; |
|
190 |
166 t.sendResponseHeaders(404, 0); |
191 t.sendResponseHeaders(404, 0); |
167 OutputStream os = t.getResponseBody(); |
192 OutputStream os = t.getResponseBody(); |
168 |
193 |
169 // actual data doesn't matter. Just send more than 4K worth |
194 // actual data doesn't matter. Just send more than 4K worth |
170 byte b = 'a'; |
195 byte b = 'a'; |