Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: tests/standalone/io/http_proxy_test.dart

Issue 13915007: Add support for proxies requiing authentication (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« sdk/lib/io/http_impl.dart ('K') | « sdk/lib/io/http_impl.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import "package:expect/expect.dart"; 5 import "package:expect/expect.dart";
6 import "dart:async"; 6 import "dart:async";
7 import 'dart:crypto';
7 import "dart:io"; 8 import "dart:io";
8 import "dart:uri"; 9 import "dart:uri";
10 import 'dart:utf';
9 11
10 class Server { 12 class Server {
11 HttpServer server; 13 HttpServer server;
12 bool secure; 14 bool secure;
13 int proxyHops; 15 int proxyHops;
14 List<String> directRequestPaths; 16 List<String> directRequestPaths;
15 int requestCount = 0; 17 int requestCount = 0;
16 18
17 Server(this.proxyHops, this.directRequestPaths, this.secure); 19 Server(this.proxyHops, this.directRequestPaths, this.secure);
18 20
(...skipping 22 matching lines...) Expand all
41 } else { 43 } else {
42 Expect.isNull(request.headers[HttpHeaders.VIA]); 44 Expect.isNull(request.headers[HttpHeaders.VIA]);
43 } 45 }
44 var body = new StringBuffer(); 46 var body = new StringBuffer();
45 request.listen( 47 request.listen(
46 (data) { 48 (data) {
47 body.write(new String.fromCharCodes(data)); 49 body.write(new String.fromCharCodes(data));
48 }, 50 },
49 onDone: () { 51 onDone: () {
50 String path = request.uri.path.substring(1); 52 String path = request.uri.path.substring(1);
51 String content = "$path$path$path"; 53 if (path != "A") {
52 Expect.equals(content, body.toString()); 54 String content = "$path$path$path";
55 Expect.equals(content, body.toString());
56 }
53 response.write(request.uri.path); 57 response.write(request.uri.path);
54 response.close(); 58 response.close();
55 }); 59 });
56 }); 60 });
57 return x.future; 61 return x.future;
58 }); 62 });
59 } 63 }
60 64
61 void shutdown() { 65 void shutdown() {
62 server.close(); 66 server.close();
63 } 67 }
64 68
65 int get port => server.port; 69 int get port => server.port;
66 } 70 }
67 71
68 Future<Server> setupServer(int proxyHops, 72 Future<Server> setupServer(int proxyHops,
69 {List<String> directRequestPaths: const <String>[], 73 {List<String> directRequestPaths: const <String>[],
70 secure: false}) { 74 secure: false}) {
71 Server server = new Server(proxyHops, directRequestPaths, secure); 75 Server server = new Server(proxyHops, directRequestPaths, secure);
72 return server.start(); 76 return server.start();
73 } 77 }
74 78
75 class ProxyServer { 79 class ProxyServer {
76 HttpServer server; 80 HttpServer server;
77 HttpClient client; 81 HttpClient client;
78 int requestCount = 0; 82 int requestCount = 0;
83 String username;
84 String password;
79 85
80 ProxyServer() : client = new HttpClient(); 86 ProxyServer() : client = new HttpClient();
81 87
88 authenticationRequired(request) {
89 request.fold(null, (x, y) {}).then((_) {
90 var response = request.response;
91 response.headers.set(HttpHeaders.PROXY_AUTHENTICATE,
92 "Basic, realm=realm");
93 response.statusCode = HttpStatus.PROXY_AUTHENTICATION_REQUIRED;
94 response.close();
95 });
96 }
97
82 Future<ProxyServer> start() { 98 Future<ProxyServer> start() {
83 var x = new Completer(); 99 var x = new Completer();
84 HttpServer.bind().then((s) { 100 HttpServer.bind().then((s) {
85 server = s; 101 server = s;
86 x.complete(this); 102 x.complete(this);
87 server.listen((HttpRequest request) { 103 server.listen((HttpRequest request) {
88 requestCount++; 104 requestCount++;
105 if (username != null && password != null) {
106 if (request.headers[HttpHeaders.PROXY_AUTHORIZATION] == null) {
107 authenticationRequired(request);
108 return;
109 } else {
110 Expect.equals(
111 1, request.headers[HttpHeaders.PROXY_AUTHORIZATION].length);
112 String authorization =
113 request.headers[HttpHeaders.PROXY_AUTHORIZATION][0];
114 List<String> tokens = authorization.split(" ");
115 Expect.equals("Basic", tokens[0]);
116 String auth =
117 CryptoUtils.bytesToBase64(encodeUtf8("$username:$password"));
118 if (auth != tokens[1]) {
119 authenticationRequired(request);
120 return;
121 }
122 }
123 }
89 // Open the connection from the proxy. 124 // Open the connection from the proxy.
90 client.openUrl(request.method, request.uri) 125 client.openUrl(request.method, request.uri)
91 .then((HttpClientRequest clientRequest) { 126 .then((HttpClientRequest clientRequest) {
92 // Forward all headers. 127 // Forward all headers.
93 request.headers.forEach((String name, List<String> values) { 128 request.headers.forEach((String name, List<String> values) {
94 values.forEach((String value) { 129 values.forEach((String value) {
95 if (name != "content-length" && name != "via") { 130 if (name != "content-length" && name != "via") {
96 clientRequest.headers.add(name, value); 131 clientRequest.headers.add(name, value);
97 } 132 }
98 }); 133 });
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 } 390 }
356 391
357 test(false); 392 test(false);
358 test(true); 393 test(true);
359 } 394 }
360 }); 395 });
361 }); 396 });
362 }); 397 });
363 } 398 }
364 399
400
401 int testProxyAuthenticateCount = 0;
402 void testProxyAuthenticate() {
403 setupProxyServer().then((proxyServer) {
404 proxyServer.username = "test";
405 proxyServer.password = "test";
406 setupServer(1).then((server) {
407 setupServer(1, secure: true).then((secureServer) {
408 HttpClient client = new HttpClient();
409
410 Completer step1 = new Completer();
411 Completer step2 = new Completer();
412
413 // Test with no authentication.
414 client.findProxy = (Uri uri) {
415 return "PROXY localhost:${proxyServer.port}";
416 };
417
418 const int loopCount = 2;
419 for (int i = 0; i < loopCount; i++) {
420 test(bool secure) {
421 String url = secure
422 ? "https://localhost:${secureServer.port}/$i"
423 : "http://127.0.0.1:${server.port}/$i";
424
425 client.postUrl(Uri.parse(url))
426 .then((HttpClientRequest clientRequest) {
427 String content = "$i$i$i";
428 clientRequest.write(content);
429 return clientRequest.close();
430 })
431 .then((HttpClientResponse response) {
432 response.listen((_) {}, onDone: () {
433 testProxyAuthenticateCount++;
434 Expect.equals(HttpStatus.PROXY_AUTHENTICATION_REQUIRED,
435 response.statusCode);
436 if (testProxyAuthenticateCount == loopCount * 2) {
437 Expect.equals(0, server.requestCount);
438 Expect.equals(0, secureServer.requestCount);
439 step1.complete(null);
440 }
441 });
442 });
443 }
444
445 test(false);
446 test(true);
447 }
448
449 step1.future.then((_) {
450 testProxyAuthenticateCount = 0;
451 client.findProxy = (Uri uri) {
452 return "PROXY test:test@localhost:${proxyServer.port}";
453 };
454
455 for (int i = 0; i < loopCount; i++) {
456 test(bool secure) {
457 String url = secure
458 ? "https://localhost:${secureServer.port}/$i"
459 : "http://127.0.0.1:${server.port}/$i";
460
461 client.postUrl(Uri.parse(url))
462 .then((HttpClientRequest clientRequest) {
463 String content = "$i$i$i";
464 clientRequest.write(content);
465 return clientRequest.close();
466 })
467 .then((HttpClientResponse response) {
468 response.listen((_) {}, onDone: () {
469 testProxyAuthenticateCount++;
470 Expect.equals(HttpStatus.OK, response.statusCode);
471 if (testProxyAuthenticateCount == loopCount * 2) {
472 Expect.equals(loopCount, server.requestCount);
473 Expect.equals(loopCount, secureServer.requestCount);
474 step2.complete(null);
475 }
476 });
477 });
478 }
479
480 test(false);
481 test(true);
482 }
483 });
484
485 step2.future.then((_) {
486 testProxyAuthenticateCount = 0;
487 client.findProxy = (Uri uri) {
488 return "PROXY localhost:${proxyServer.port}";
489 };
490
491 client.authenticateProxy = (host, port, scheme, realm) {
492 client.addProxyCredentials(
493 "localhost",
494 proxyServer.port,
495 "realm",
496 new HttpClientBasicCredentials("test", "test"));
497 return new Future.immediate(true);
498 };
499
500 for (int i = 0; i < loopCount; i++) {
501 test(bool secure) {
502 String url = secure
503 ? "https://localhost:${secureServer.port}/A"
504 : "http://127.0.0.1:${server.port}/A";
505
506 client.postUrl(Uri.parse(url))
507 .then((HttpClientRequest clientRequest) {
508 String content = "$i$i$i";
509 clientRequest.write(content);
510 return clientRequest.close();
511 })
512 .then((HttpClientResponse response) {
513 response.listen((_) {}, onDone: () {
514 testProxyAuthenticateCount++;
515 Expect.equals(HttpStatus.OK, response.statusCode);
516 if (testProxyAuthenticateCount == loopCount * 2) {
517 Expect.equals(loopCount * 2, server.requestCount);
518 Expect.equals(loopCount * 2, secureServer.requestCount);
519 proxyServer.shutdown();
520 server.shutdown();
521 secureServer.shutdown();
522 client.close();
523 }
524 });
525 });
526 }
527 test(false);
528 test(true);
529 }
530 });
531
532 });
533 });
534 });
535 }
536
365 int testRealProxyDoneCount = 0; 537 int testRealProxyDoneCount = 0;
366 void testRealProxy() { 538 void testRealProxy() {
367 setupServer(1).then((server) { 539 setupServer(1).then((server) {
368 HttpClient client = new HttpClient(); 540 HttpClient client = new HttpClient();
541 client.addProxyCredentials("localhost",
542 8080,
543 "test",
544 new HttpClientBasicCredentials("test", "test"));
369 545
370 List<String> proxy = 546 List<String> proxy =
371 ["PROXY localhost:8080", 547 ["PROXY localhost:8080",
372 "PROXY localhost:8080; PROXY hede.hule.hest:8080", 548 "PROXY localhost:8080; PROXY hede.hule.hest:8080",
373 "PROXY hede.hule.hest:8080; PROXY localhost:8080", 549 "PROXY hede.hule.hest:8080; PROXY localhost:8080",
374 "PROXY localhost:8080; DIRECT"]; 550 "PROXY localhost:8080; DIRECT"];
375 551
376 client.findProxy = (Uri uri) { 552 client.findProxy = (Uri uri) {
377 // Pick the proxy configuration based on the request path. 553 // Pick the proxy configuration based on the request path.
378 int index = int.parse(uri.path.substring(1)); 554 int index = int.parse(uri.path.substring(1));
379 return proxy[index]; 555 return proxy[index];
380 }; 556 };
381 557
382 for (int i = 0; i < proxy.length; i++) { 558 for (int i = 0; i < proxy.length; i++) {
383 client.getUrl(Uri.parse("http://127.0.0.1:${server.port}/$i")) 559 client.getUrl(Uri.parse("http://127.0.0.1:${server.port}/$i"))
384 .then((HttpClientRequest clientRequest) { 560 .then((HttpClientRequest clientRequest) {
385 String content = "$i$i$i"; 561 String content = "$i$i$i";
386 clientRequest.contentLength = content.length; 562 clientRequest.contentLength = content.length;
387 clientRequest.write(content); 563 clientRequest.write(content);
388 return clientRequest.close(); 564 return clientRequest.close();
389 }) 565 })
390 .then((HttpClientResponse response) { 566 .then((HttpClientResponse response) {
391 response.listen((_) {}, onDone: () { 567 response.listen((_) {}, onDone: () {
392 testRealProxyDoneCount++; 568 if (++testRealProxyDoneCount == proxy.length) {
393 if (testRealProxyDoneCount == proxy.length) {
394 Expect.equals(proxy.length, server.requestCount); 569 Expect.equals(proxy.length, server.requestCount);
395 server.shutdown(); 570 server.shutdown();
396 client.close(); 571 client.close();
572 }
573 });
574 });
575 }
576 });
577 }
578
579 int testRealProxyAuthDoneCount = 0;
580 void testRealProxyAuth() {
581 setupServer(1).then((server) {
582 HttpClient client = new HttpClient();
583
584 List<String> proxy =
585 ["PROXY test:test@localhost:8080",
586 "PROXY test:test@localhost:8080; PROXY hede.hule.hest:8080",
587 "PROXY hede.hule.hest:8080; PROXY test:test@localhost:8080",
588 "PROXY test:test@localhost:8080; DIRECT"];
589
590 client.findProxy = (Uri uri) {
591 // Pick the proxy configuration based on the request path.
592 int index = int.parse(uri.path.substring(1));
593 return proxy[index];
594 };
595
596 for (int i = 0; i < proxy.length; i++) {
597 client.getUrl(Uri.parse("http://127.0.0.1:${server.port}/$i"))
598 .then((HttpClientRequest clientRequest) {
599 String content = "$i$i$i";
600 clientRequest.contentLength = content.length;
601 clientRequest.write(content);
602 return clientRequest.close();
603 })
604 .then((HttpClientResponse response) {
605 response.listen((_) {}, onDone: () {
606 if (++testRealProxyAuthDoneCount == proxy.length) {
607 Expect.equals(proxy.length, server.requestCount);
608 server.shutdown();
609 client.close();
397 } 610 }
398 }); 611 });
399 }); 612 });
400 } 613 }
401 }); 614 });
402 } 615 }
403 616
404 void InitializeSSL() { 617 void InitializeSSL() {
405 var testPkcertDatabase = 618 var testPkcertDatabase =
406 new Path(new Options().script).directoryPath.append('pkcert/'); 619 new Path(new Options().script).directoryPath.append('pkcert/');
407 SecureSocket.initialize(database: testPkcertDatabase.toNativePath(), 620 SecureSocket.initialize(database: testPkcertDatabase.toNativePath(),
408 password: 'dartdart'); 621 password: 'dartdart');
409 } 622 }
410 623
411 main() { 624 main() {
412 InitializeSSL(); 625 InitializeSSL();
413 testInvalidProxy(); 626 testInvalidProxy();
414 testDirectProxy(); 627 testDirectProxy();
415 testProxy(); 628 testProxy();
416 testProxyChain(); 629 testProxyChain();
417 testProxyFromEnviroment(); 630 testProxyFromEnviroment();
631 testProxyAuthenticate();
418 // This test is not normally run. It can be used for locally testing 632 // This test is not normally run. It can be used for locally testing
419 // with a real proxy server (e.g. Apache). 633 // with a real proxy server (e.g. Apache).
420 //testRealProxy(); 634 //testRealProxy();
635 //testRealProxyAuth();
421 } 636 }
OLDNEW
« sdk/lib/io/http_impl.dart ('K') | « sdk/lib/io/http_impl.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698