OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 #import("dart:io"); | |
6 #import("dart:uri"); | |
7 | |
8 class Server { | |
9 HttpServer server; | |
10 int proxyHops; | |
11 int requestCount = 0; | |
12 | |
13 Server(this.proxyHops) : server = new HttpServer(); | |
14 | |
15 void start() { | |
16 server.listen("127.0.0.1", 0, 5); | |
17 server.defaultRequestHandler = | |
18 (HttpRequest request, HttpResponse response) { | |
19 requestCount++; | |
20 if (proxyHops > 0) { | |
Anders Johnsen
2012/10/08 11:05:25
Indentation.
Søren Gjesse
2012/10/08 12:17:30
Done.
| |
21 Expect.isNotNull(request.headers[HttpHeaders.VIA]); | |
22 Expect.equals(1, request.headers[HttpHeaders.VIA].length); | |
23 Expect.equals(proxyHops, | |
24 request.headers[HttpHeaders.VIA][0].split(",").length); | |
25 } else { | |
26 Expect.isNull(request.headers[HttpHeaders.VIA]); | |
27 } | |
28 StringInputStream stream = new StringInputStream(request.inputStream); | |
29 StringBuffer body = new StringBuffer(); | |
30 stream.onData = () => body.add(stream.read()); | |
31 stream.onClosed = () { | |
32 String path = request.path.substring(1); | |
33 String content = "$path$path$path"; | |
34 Expect.equals(content, body.toString()); | |
35 response.outputStream.writeString(request.path); | |
36 response.outputStream.close(); | |
37 }; | |
38 }; | |
39 } | |
40 | |
41 void shutdown() { | |
42 server.close(); | |
43 } | |
44 | |
45 int get port => server.port; | |
46 } | |
47 | |
48 Server setupServer(int proxyHops) { | |
49 Server server = new Server(proxyHops); | |
50 server.start(); | |
51 return server; | |
52 } | |
53 | |
54 class ProxyServer { | |
55 HttpServer server; | |
56 HttpClient client; | |
57 int requestCount = 0; | |
58 | |
59 ProxyServer() : server = new HttpServer(), client = new HttpClient(); | |
60 | |
61 void start() { | |
62 server.listen("127.0.0.1", 0, 5); | |
63 server.defaultRequestHandler = | |
64 (HttpRequest request, HttpResponse response) { | |
65 requestCount++; | |
66 // Open the connection from the proxy. | |
67 HttpClientConnection conn = | |
68 client.openUrl(request.method, new Uri.fromString(request.path)); | |
69 conn.onRequest = (HttpClientRequest clientRequest) { | |
70 // Forward all headers. | |
71 request.headers.forEach((String name, List<String> values) { | |
72 values.forEach((String value) { | |
73 if (name != "content-length" && name != "via") { | |
74 clientRequest.headers.add(name, value); | |
75 } | |
76 }); | |
77 }); | |
78 // Special handling of Content-Length and Via. | |
79 clientRequest.contentLength = request.contentLength; | |
80 List<String> via = request.headers[HttpHeaders.VIA]; | |
81 String viaPrefix = via == null ? "" : "${via[0]}, "; | |
82 clientRequest.headers.add( | |
83 HttpHeaders.VIA, "${viaPrefix}1.1 localhost:$port"); | |
84 // Copy all content. | |
85 request.inputStream.pipe(clientRequest.outputStream); | |
86 }; | |
87 conn.onResponse = (HttpClientResponse clientResponse) { | |
88 clientResponse.inputStream.pipe(response.outputStream); | |
89 }; | |
90 }; | |
91 } | |
92 | |
93 void shutdown() { | |
94 server.close(); | |
95 client.shutdown(); | |
96 } | |
97 | |
98 int get port => server.port; | |
99 } | |
100 | |
101 ProxyServer setupProxyServer() { | |
102 ProxyServer proxyServer = new ProxyServer(); | |
103 proxyServer.start(); | |
104 return proxyServer; | |
105 } | |
106 | |
107 testInvalidProxy() { | |
108 HttpClient client = new HttpClient(); | |
109 | |
110 // TODO(sgjesse): This should not throw errors, but call | |
111 // HttpClientConnection onError. | |
112 client.findProxy = (Uri uri) => "XXX"; | |
113 Expect.throws( | |
114 () => client.getUrl(new Uri.fromString("http://www.google.com/test")), | |
115 (e) => e is HttpException); | |
116 | |
117 client.findProxy = (Uri uri) => "PROXY www.google.com"; | |
118 Expect.throws( | |
119 () => client.getUrl(new Uri.fromString("http://www.google.com/test")), | |
120 (e) => e is HttpException); | |
121 | |
122 client.findProxy = (Uri uri) => "PROXY www.google.com:http"; | |
123 Expect.throws( | |
124 () => client.getUrl(new Uri.fromString("http://www.google.com/test")), | |
125 (e) => e is FormatException); | |
126 } | |
127 | |
128 int testDirectDoneCount = 0; | |
Anders Johnsen
2012/10/08 11:05:25
Why is this(and those below) defined outside the f
Søren Gjesse
2012/10/08 12:17:30
Because otherwise its initial value of 0 is captur
Anders Johnsen
2012/10/08 12:27:29
Okay!
| |
129 void testDirectProxy() { | |
130 Server server = setupServer(0); | |
131 HttpClient client = new HttpClient(); | |
132 List<String> proxy = | |
133 ["DIRECT", " DIRECT ", "DIRECT ;", " DIRECT ; ", | |
134 ";DIRECT", " ; DIRECT ", ";;DIRECT;;"]; | |
135 | |
136 client.findProxy = (Uri uri) { | |
137 int index = int.parse(uri.path.substring(1)); | |
138 return proxy[index]; | |
139 }; | |
140 | |
141 for (int i = 0; i < proxy.length; i++) { | |
142 HttpClientConnection conn = | |
143 client.getUrl(new Uri.fromString("http://127.0.0.1:${server.port}/$i")); | |
144 conn.onRequest = (HttpClientRequest clientRequest) { | |
145 String content = "$i$i$i"; | |
146 clientRequest.contentLength = content.length; | |
147 clientRequest.outputStream.writeString(content); | |
148 clientRequest.outputStream.close(); | |
149 }; | |
150 conn.onResponse = (HttpClientResponse response) { | |
151 response.inputStream.onData = () => response.inputStream.read(); | |
152 response.inputStream.onClosed = () { | |
153 testDirectDoneCount++; | |
154 if (testDirectDoneCount == proxy.length) { | |
155 Expect.equals(proxy.length, server.requestCount); | |
156 server.shutdown(); | |
157 client.shutdown(); | |
158 } | |
159 }; | |
160 }; | |
161 } | |
162 } | |
163 | |
164 int testProxyDoneCount = 0; | |
165 void testProxy() { | |
166 ProxyServer proxyServer = setupProxyServer(); | |
167 Server server = setupServer(1); | |
168 HttpClient client = new HttpClient(); | |
169 | |
170 List<String> proxy = | |
171 ["PROXY localhost:${proxyServer.port}", | |
172 "PROXY localhost:${proxyServer.port}; PROXY hede.hule.hest:8080", | |
173 "PROXY localhost:${proxyServer.port}; DIRECT"]; | |
174 | |
175 client.findProxy = (Uri uri) { | |
176 // Pick the proxy configuration based on the request path. | |
177 int index = int.parse(uri.path.substring(1)); | |
178 return proxy[index]; | |
179 }; | |
180 | |
181 for (int i = 0; i < proxy.length; i++) { | |
182 HttpClientConnection conn = | |
183 client.postUrl( | |
184 new Uri.fromString("http://127.0.0.1:${server.port}/$i")); | |
185 conn.onRequest = (HttpClientRequest clientRequest) { | |
186 String content = "$i$i$i"; | |
187 clientRequest.outputStream.writeString(content); | |
188 clientRequest.outputStream.close(); | |
189 }; | |
190 conn.onResponse = (HttpClientResponse response) { | |
191 response.inputStream.onData = () => response.inputStream.read(); | |
192 response.inputStream.onClosed = () { | |
193 testProxyDoneCount++; | |
194 if (testProxyDoneCount == proxy.length) { | |
195 Expect.equals(proxy.length, server.requestCount); | |
196 proxyServer.shutdown(); | |
197 server.shutdown(); | |
198 client.shutdown(); | |
199 } | |
200 }; | |
201 }; | |
202 } | |
203 } | |
204 | |
205 int testProxyChainDoneCount = 0; | |
206 void testProxyChain() { | |
207 // Setup two proxy servers having the first using the second as its proxy. | |
208 ProxyServer proxyServer1 = setupProxyServer(); | |
209 ProxyServer proxyServer2 = setupProxyServer(); | |
210 proxyServer1.client.findProxy = (_) => "PROXY 127.0.0.1:${proxyServer2.port}"; | |
211 | |
212 Server server = setupServer(2); | |
213 HttpClient client = new HttpClient(); | |
214 | |
215 List<String> proxy = | |
216 ["PROXY localhost:${proxyServer1.port}", | |
217 "PROXY localhost:${proxyServer1.port}; PROXY hede.hule.hest:8080", | |
218 "PROXY localhost:${proxyServer1.port}; DIRECT"]; | |
219 | |
220 client.findProxy = (Uri uri) { | |
221 // Pick the proxy configuration based on the request path. | |
222 int index = int.parse(uri.path.substring(1)); | |
223 return proxy[index]; | |
224 }; | |
225 | |
226 for (int i = 0; i < proxy.length; i++) { | |
227 HttpClientConnection conn = | |
228 client.getUrl(new Uri.fromString("http://127.0.0.1:${server.port}/$i")); | |
229 conn.onRequest = (HttpClientRequest clientRequest) { | |
230 String content = "$i$i$i"; | |
231 clientRequest.contentLength = content.length; | |
232 clientRequest.outputStream.writeString(content); | |
233 clientRequest.outputStream.close(); | |
234 }; | |
235 conn.onResponse = (HttpClientResponse response) { | |
236 response.inputStream.onData = () => response.inputStream.read(); | |
237 response.inputStream.onClosed = () { | |
238 testProxyChainDoneCount++; | |
239 if (testProxyChainDoneCount == proxy.length) { | |
240 Expect.equals(proxy.length, server.requestCount); | |
241 proxyServer1.shutdown(); | |
242 proxyServer2.shutdown(); | |
243 server.shutdown(); | |
244 client.shutdown(); | |
245 } | |
246 }; | |
247 }; | |
248 } | |
249 } | |
250 | |
251 int testRealProxyDoneCount = 0; | |
252 void testRealProxy() { | |
253 Server server = setupServer(1); | |
254 HttpClient client = new HttpClient(); | |
255 | |
256 List<String> proxy = | |
257 ["PROXY localhost:8080", | |
258 "PROXY localhost:8080; PROXY hede.hule.hest:8080", | |
259 "PROXY localhost:8080; DIRECT"]; | |
260 | |
261 client.findProxy = (Uri uri) { | |
262 // Pick the proxy configuration based on the request path. | |
263 int index = int.parse(uri.path.substring(1)); | |
264 return proxy[index]; | |
265 }; | |
266 | |
267 for (int i = 0; i < proxy.length; i++) { | |
268 HttpClientConnection conn = | |
269 client.getUrl(new Uri.fromString("http://127.0.0.1:${server.port}/$i")); | |
270 conn.onRequest = (HttpClientRequest clientRequest) { | |
271 String content = "$i$i$i"; | |
272 clientRequest.contentLength = content.length; | |
273 clientRequest.outputStream.writeString(content); | |
274 clientRequest.outputStream.close(); | |
275 }; | |
276 conn.onResponse = (HttpClientResponse response) { | |
277 response.inputStream.onData = () => response.inputStream.read(); | |
278 response.inputStream.onClosed = () { | |
279 testRealProxyDoneCount++; | |
280 if (testRealProxyDoneCount == proxy.length) { | |
281 Expect.equals(proxy.length, server.requestCount); | |
282 server.shutdown(); | |
283 client.shutdown(); | |
284 } | |
285 }; | |
286 }; | |
287 } | |
288 } | |
289 | |
290 main() { | |
291 testInvalidProxy(); | |
292 testDirectProxy(); | |
293 testProxy(); | |
294 testProxyChain(); | |
295 // This test is not normally run. It can be used for locally testing | |
296 // with a real proxy server (e.g. Apache). | |
297 // testRealProxy(); | |
298 } | |
OLD | NEW |