@@ -9,7 +9,7 @@ import "package:expect/expect.dart";
99import "dart:async" ;
1010import "dart:io" ;
1111
12- Future <HttpServer > setupServer () {
12+ Future <HttpServer > setupServer ({ Uri targetServer} ) {
1313 Completer completer = new Completer <HttpServer >();
1414 HttpServer .bind ("127.0.0.1" , 0 ).then ((server) {
1515 var handlers = new Map <String , Function >();
@@ -130,16 +130,33 @@ Future<HttpServer> setupServer() {
130130 // Setup redirect checking headers.
131131 addRequestHandler ("/src" , (HttpRequest request, HttpResponse response) {
132132 Expect .equals ("value" , request.headers.value ("X-Request-Header" ));
133+ Expect .isNotNull (request.headers.value ("Authorization" ),
134+ "expected 'Authorization' header to be set" );
133135 response.headers.set (
134136 HttpHeaders .locationHeader, "http://127.0.0.1:${server .port }/target" );
135137 response.statusCode = HttpStatus .movedPermanently;
136138 response.close ();
137139 });
138140 addRequestHandler ("/target" , (HttpRequest request, HttpResponse response) {
139141 Expect .equals ("value" , request.headers.value ("X-Request-Header" ));
142+ Expect .isNotNull (request.headers.value ("Authorization" ),
143+ "expected 'Authorization' header to be set" );
140144 response.close ();
141145 });
142146
147+ if (targetServer != null ) {
148+ addRequestHandler ("/src-crossdomain" ,
149+ (HttpRequest request, HttpResponse response) {
150+ Expect .equals ("value" , request.headers.value ("X-Request-Header" ));
151+ Expect .isNotNull (request.headers.value ("Authorization" ),
152+ "expected 'Authorization' header to be set" );
153+ response.headers
154+ .set (HttpHeaders .locationHeader, targetServer.toString ());
155+ response.statusCode = HttpStatus .movedPermanently;
156+ response.close ();
157+ });
158+ }
159+
143160 // Setup redirect for 301 where POST should not redirect.
144161 addRequestHandler ("/301src" , (HttpRequest request, HttpResponse response) {
145162 Expect .equals ("POST" , request.method);
@@ -185,6 +202,36 @@ Future<HttpServer> setupServer() {
185202 return completer.future;
186203}
187204
205+ // A second HTTP server used to validate that redirect requests accross domains
206+ // do *not* include security-related headers.
207+ Future <HttpServer > setupTargetServer () {
208+ Completer completer = new Completer <HttpServer >();
209+ HttpServer .bind ("127.0.0.1" , 0 ).then ((server) {
210+ var handlers = new Map <String , Function >();
211+ addRequestHandler (
212+ String path, void handler (HttpRequest request, HttpResponse response)) {
213+ handlers[path] = handler;
214+ }
215+
216+ server.listen ((HttpRequest request) {
217+ if (request.uri.path == "/target" ) {
218+ Expect .equals ("value" , request.headers.value ("X-Request-Header" ));
219+ Expect .isNull (request.headers.value ("Authorization" ),
220+ "expected 'Authorization' header to be removed on redirect" );
221+ request.response.close ();
222+ } else {
223+ request.listen ((_) {}, onDone: () {
224+ request.response.statusCode = 404 ;
225+ request.response.close ();
226+ });
227+ }
228+ });
229+
230+ completer.complete (server);
231+ });
232+ return completer.future;
233+ }
234+
188235void checkRedirects (int redirectCount, HttpClientResponse response) {
189236 if (redirectCount < 2 ) {
190237 Expect .isTrue (response.redirects.isEmpty);
@@ -252,6 +299,7 @@ void testManualRedirectWithHeaders() {
252299 .then ((HttpClientRequest request) {
253300 request.followRedirects = false ;
254301 request.headers.add ("X-Request-Header" , "value" );
302+ request.headers.add ("Authorization" , "Basic ..." );
255303 return request.close ();
256304 }).then (handleResponse);
257305 });
@@ -284,6 +332,7 @@ void testAutoRedirectWithHeaders() {
284332 .getUrl (Uri .parse ("http://127.0.0.1:${server .port }/src" ))
285333 .then ((HttpClientRequest request) {
286334 request.headers.add ("X-Request-Header" , "value" );
335+ request.headers.add ("Authorization" , "Basic ..." );
287336 return request.close ();
288337 }).then ((HttpClientResponse response) {
289338 response.listen ((_) => Expect .fail ("Response data not expected" ),
@@ -296,6 +345,33 @@ void testAutoRedirectWithHeaders() {
296345 });
297346}
298347
348+ void testCrossDomainAutoRedirectWithHeaders () {
349+ setupTargetServer ().then ((targetServer) {
350+ setupServer (
351+ targetServer:
352+ Uri .parse ("http://127.0.0.1:${targetServer .port }/target" ))
353+ .then ((server) {
354+ HttpClient client = new HttpClient ();
355+
356+ client
357+ .getUrl (Uri .parse ("http://127.0.0.1:${server .port }/src-crossdomain" ))
358+ .then ((HttpClientRequest request) {
359+ request.headers.add ("X-Request-Header" , "value" );
360+ request.headers.add ("Authorization" , "Basic ..." );
361+ return request.close ();
362+ }).then ((HttpClientResponse response) {
363+ response.listen ((_) => Expect .fail ("Response data not expected" ),
364+ onDone: () {
365+ Expect .equals (1 , response.redirects.length);
366+ targetServer.close ();
367+ server.close ();
368+ client.close ();
369+ });
370+ });
371+ });
372+ });
373+ }
374+
299375void testAutoRedirect301POST () {
300376 setupServer ().then ((server) {
301377 HttpClient client = new HttpClient ();
@@ -443,6 +519,7 @@ main() {
443519 testManualRedirectWithHeaders ();
444520 testAutoRedirect ();
445521 testAutoRedirectWithHeaders ();
522+ testCrossDomainAutoRedirectWithHeaders ();
446523 testAutoRedirect301POST ();
447524 testAutoRedirect303POST ();
448525 testAutoRedirectLimit ();
0 commit comments