Tests for _HttpClient.shouldCopyHeadersOnRedirect.
TESTED=test change
Change-Id: I3fb27e21eaab05fc812b2b888dfea3b29e0c5648
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/230600
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Brian Quinlan <bquinlan@google.com>
diff --git a/sdk/lib/_http/http_impl.dart b/sdk/lib/_http/http_impl.dart
index 80ee3b5..312ca7c 100644
--- a/sdk/lib/_http/http_impl.dart
+++ b/sdk/lib/_http/http_impl.dart
@@ -2723,7 +2723,8 @@
subdomain.host.endsWith("." + domain.host)));
}
- static bool _shouldCopyHeaderOnRedirect(
+ // Only visible for testing.
+ static bool shouldCopyHeaderOnRedirect(
String headerKey, Uri originalUrl, Uri redirectUri) {
if (_isSubdomain(redirectUri, originalUrl)) {
return true;
@@ -2754,7 +2755,7 @@
for (var header in previous.headers._headers.keys) {
if (request.headers[header] == null &&
(!isRedirect ||
- _shouldCopyHeaderOnRedirect(header, resolved, previous.uri))) {
+ shouldCopyHeaderOnRedirect(header, resolved, previous.uri))) {
request.headers.set(header, previous.headers[header]!);
}
}
diff --git a/tests/standalone/io/http_redirect_test.dart b/tests/standalone/io/http_redirect_test.dart
index 1a19222..7ccf54d 100644
--- a/tests/standalone/io/http_redirect_test.dart
+++ b/tests/standalone/io/http_redirect_test.dart
@@ -6,6 +6,7 @@
import "package:expect/expect.dart";
import "dart:async";
import "dart:io";
+import "dart:mirrors";
Future<HttpServer> setupServer({Uri? targetServer}) {
final completer = new Completer<HttpServer>();
@@ -343,6 +344,95 @@
});
}
+void testShouldCopyHeadersOnRedirect() {
+ final clientClass = reflect(HttpClient()).type;
+ final fnName = Symbol("shouldCopyHeaderOnRedirect");
+
+ shouldCopyHeaderOnRedirect(
+ String headerKey, Uri originalUrl, Uri redirectUri) =>
+ clientClass.invoke(
+ fnName, [headerKey, originalUrl, redirectUri]).reflectee as bool;
+
+ checkShouldCopyHeader(
+ String headerKey, String originalUrl, String redirectUri, bool expected) {
+ if (shouldCopyHeaderOnRedirect(
+ headerKey, Uri.parse(originalUrl), Uri.parse(redirectUri)) !=
+ expected) {
+ Expect.fail(
+ "shouldCopyHeaderOnRedirect($headerKey, $originalUrl, $redirectUri) => ${!expected}");
+ }
+ }
+
+ // Redirect on localhost.
+ checkShouldCopyHeader(
+ "authorization", "http://localhost", "http://localhost/foo", true);
+ checkShouldCopyHeader(
+ "cat", "http://localhost", "http://localhost/foo", true);
+
+ // Redirect to same IP address.
+ checkShouldCopyHeader("authorization", "http://192.168.20.20",
+ "http://192.168.20.20/foo", true);
+ checkShouldCopyHeader(
+ "cat", "http://192.168.20.20", "http://192.168.20.20/foo", true);
+
+ // Redirect to different IP address.
+ checkShouldCopyHeader(
+ "authorization", "http://192.168.20.20", "http://192.168.20.99", false);
+ checkShouldCopyHeader(
+ "cat", "http://192.168.20.20", "http://192.168.20.99", true);
+
+ // Redirect to same domain.
+ checkShouldCopyHeader(
+ "authorization", "http://foo.com", "http://foo.com/foo", true);
+ checkShouldCopyHeader("cat", "http://foo.com", "http://foo.com/foo", true);
+
+ // Redirect to same domain with explicit ports.
+ checkShouldCopyHeader(
+ "authorization", "http://foo.com", "http://foo.com:80/foo", true);
+ checkShouldCopyHeader("cat", "http://foo.com", "http://foo.com:80/foo", true);
+
+ // Redirect to subdomain.
+ checkShouldCopyHeader(
+ "authorization", "https://foo.com", "https://www.foo.com", true);
+ checkShouldCopyHeader("cat", "https://foo.com", "https://www.foo.com", true);
+
+ // Redirect to different domain.
+ checkShouldCopyHeader(
+ "authorization", "https://foo.com", "https://wwwfoo.com", false);
+ checkShouldCopyHeader("cat", "https://foo.com", "https://wwwfoo.com", true);
+
+ // Redirect to different port.
+ checkShouldCopyHeader(
+ "authorization", "http://foo.com", "http://foo.com:81", false);
+ checkShouldCopyHeader("cat", "http://foo.com", "http://foo.com:81", true);
+
+ // Redirect from secure to insecure.
+ checkShouldCopyHeader(
+ "authorization", "https://foo.com", "http://foo.com", false);
+ checkShouldCopyHeader("cat", "https://foo.com", "http://foo.com", true);
+
+ // Redirect from secure to insecure, same port.
+ checkShouldCopyHeader(
+ "authorization", "https://foo.com:8888", "http://foo.com:8888", false);
+ checkShouldCopyHeader(
+ "cat", "https://foo.com:8888", "http://foo.com:8888", true);
+
+ // Redirect from insecure to secure.
+ checkShouldCopyHeader(
+ "authorization", "http://foo.com", "https://foo.com", false);
+ checkShouldCopyHeader("cat", "http://foo.com", "https://foo.com", true);
+
+ // Redirect to subdomain, different port.
+ checkShouldCopyHeader(
+ "authorization", "https://foo.com:80", "https://www.foo.com:81", false);
+ checkShouldCopyHeader(
+ "cat", "https://foo.com:80", "https://www.foo.com:81", true);
+
+ // Different header casting:
+ checkShouldCopyHeader(
+ "AuThOrIzAtiOn", "https://foo.com", "https://bar.com", false);
+}
+
void testCrossDomainAutoRedirectWithHeaders() {
setupTargetServer().then((targetServer) {
setupServer(
@@ -517,6 +607,7 @@
testManualRedirectWithHeaders();
testAutoRedirect();
testAutoRedirectWithHeaders();
+ testShouldCopyHeadersOnRedirect();
testCrossDomainAutoRedirectWithHeaders();
testAutoRedirect301POST();
testAutoRedirect303POST();
diff --git a/tests/standalone_2/io/http_redirect_test.dart b/tests/standalone_2/io/http_redirect_test.dart
index e851045..1d4fde8 100644
--- a/tests/standalone_2/io/http_redirect_test.dart
+++ b/tests/standalone_2/io/http_redirect_test.dart
@@ -8,6 +8,7 @@
import "package:expect/expect.dart";
import "dart:async";
import "dart:io";
+import "dart:mirrors";
Future<HttpServer> setupServer({Uri targetServer}) {
Completer completer = new Completer<HttpServer>();
@@ -345,6 +346,95 @@
});
}
+void testShouldCopyHeadersOnRedirect() {
+ final clientClass = reflect(HttpClient()).type;
+ final fnName = Symbol("shouldCopyHeaderOnRedirect");
+
+ shouldCopyHeaderOnRedirect(
+ String headerKey, Uri originalUrl, Uri redirectUri) =>
+ clientClass.invoke(
+ fnName, [headerKey, originalUrl, redirectUri]).reflectee as bool;
+
+ checkShouldCopyHeader(
+ String headerKey, String originalUrl, String redirectUri, bool expected) {
+ if (shouldCopyHeaderOnRedirect(
+ headerKey, Uri.parse(originalUrl), Uri.parse(redirectUri)) !=
+ expected) {
+ Expect.fail(
+ "shouldCopyHeaderOnRedirect($headerKey, $originalUrl, $redirectUri) => ${!expected}");
+ }
+ }
+
+ // Redirect on localhost.
+ checkShouldCopyHeader(
+ "authorization", "http://localhost", "http://localhost/foo", true);
+ checkShouldCopyHeader(
+ "cat", "http://localhost", "http://localhost/foo", true);
+
+ // Redirect to same IP address.
+ checkShouldCopyHeader("authorization", "http://192.168.20.20",
+ "http://192.168.20.20/foo", true);
+ checkShouldCopyHeader(
+ "cat", "http://192.168.20.20", "http://192.168.20.20/foo", true);
+
+ // Redirect to different IP address.
+ checkShouldCopyHeader(
+ "authorization", "http://192.168.20.20", "http://192.168.20.99", false);
+ checkShouldCopyHeader(
+ "cat", "http://192.168.20.20", "http://192.168.20.99", true);
+
+ // Redirect to same domain.
+ checkShouldCopyHeader(
+ "authorization", "http://foo.com", "http://foo.com/foo", true);
+ checkShouldCopyHeader("cat", "http://foo.com", "http://foo.com/foo", true);
+
+ // Redirect to same domain with explicit ports.
+ checkShouldCopyHeader(
+ "authorization", "http://foo.com", "http://foo.com:80/foo", true);
+ checkShouldCopyHeader("cat", "http://foo.com", "http://foo.com:80/foo", true);
+
+ // Redirect to subdomain.
+ checkShouldCopyHeader(
+ "authorization", "https://foo.com", "https://www.foo.com", true);
+ checkShouldCopyHeader("cat", "https://foo.com", "https://www.foo.com", true);
+
+ // Redirect to different domain.
+ checkShouldCopyHeader(
+ "authorization", "https://foo.com", "https://wwwfoo.com", false);
+ checkShouldCopyHeader("cat", "https://foo.com", "https://wwwfoo.com", true);
+
+ // Redirect to different port.
+ checkShouldCopyHeader(
+ "authorization", "http://foo.com", "http://foo.com:81", false);
+ checkShouldCopyHeader("cat", "http://foo.com", "http://foo.com:81", true);
+
+ // Redirect from secure to insecure.
+ checkShouldCopyHeader(
+ "authorization", "https://foo.com", "http://foo.com", false);
+ checkShouldCopyHeader("cat", "https://foo.com", "http://foo.com", true);
+
+ // Redirect from secure to insecure, same port.
+ checkShouldCopyHeader(
+ "authorization", "https://foo.com:8888", "http://foo.com:8888", false);
+ checkShouldCopyHeader(
+ "cat", "https://foo.com:8888", "http://foo.com:8888", true);
+
+ // Redirect from insecure to secure.
+ checkShouldCopyHeader(
+ "authorization", "http://foo.com", "https://foo.com", false);
+ checkShouldCopyHeader("cat", "http://foo.com", "https://foo.com", true);
+
+ // Redirect to subdomain, different port.
+ checkShouldCopyHeader(
+ "authorization", "https://foo.com:80", "https://www.foo.com:81", false);
+ checkShouldCopyHeader(
+ "cat", "https://foo.com:80", "https://www.foo.com:81", true);
+
+ // Different header casting:
+ checkShouldCopyHeader(
+ "AuThOrIzAtiOn", "https://foo.com", "https://bar.com", false);
+}
+
void testCrossDomainAutoRedirectWithHeaders() {
setupTargetServer().then((targetServer) {
setupServer(
@@ -519,6 +609,7 @@
testManualRedirectWithHeaders();
testAutoRedirect();
testAutoRedirectWithHeaders();
+ testShouldCopyHeadersOnRedirect();
testCrossDomainAutoRedirectWithHeaders();
testAutoRedirect301POST();
testAutoRedirect303POST();