From eebd9a0f32f75297d87284060a8eda74bd1f233c Mon Sep 17 00:00:00 2001 From: Simon Rozsival Date: Tue, 3 Jan 2023 18:19:21 +0100 Subject: [PATCH 1/4] Add test --- .../AndroidMessageHandlerTests.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs b/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs index 8d748c47bae..76e0de4350d 100644 --- a/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs +++ b/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs @@ -111,6 +111,26 @@ public async Task ServerCertificateCustomValidationCallback_IgnoresCertificateHo Assert.AreEqual (SslPolicyErrors.RemoteCertificateNameMismatch, reportedErrors & SslPolicyErrors.RemoteCertificateNameMismatch); } + [Test] + public async Task ServerCertificateCustomValidationCallback_Redirects () + { + int callbackCounter = 0; + + var handler = new AndroidMessageHandler { + ServerCertificateCustomValidationCallback = (request, cert, chain, errors) => { + callbackCounter++; + Assert.Contains (request.RequestUri.Host, cert.SubjectName.Name); + return errors == SslPolicyErrors.None; + } + }; + + var client = new HttpClient (handler); + var result = await client.GetAsync ("https://httpbin.org/redirect-to?url=https://microsoft.com/"); + + Assert.AreEqual (3, callbackCounter); // httpbin.org, microsoft.com, www.microsoft.com + Assert.IsTrue (result.IsSuccessStatusCode); + } + private async Task AssertRejectsRemoteCertificate (Func makeRequest) { // there is a difference between the exception that's thrown in the .NET build and the legacy Xamarin From 363a0c1a8d5b847a25291a28794869ffd53166e7 Mon Sep 17 00:00:00 2001 From: Simon Rozsival Date: Tue, 3 Jan 2023 18:20:11 +0100 Subject: [PATCH 2/4] Update the RequestUri after redirect --- src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs b/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs index b990aa50e4f..71d972d0a87 100644 --- a/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs +++ b/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs @@ -425,6 +425,7 @@ string EncodeUrl (Uri url) if (redirectState.NewUrl == null) throw new InvalidOperationException ("Request redirected but no new URI specified"); request.Method = redirectState.Method; + request.RequestUri = redirectState.NewUrl; } catch (Java.Net.SocketTimeoutException ex) when (JNIEnv.ShouldWrapJavaException (ex)) { throw new WebException (ex.Message, ex, WebExceptionStatus.Timeout, null); } catch (Java.Net.UnknownServiceException ex) when (JNIEnv.ShouldWrapJavaException (ex)) { From c126fae57f4d1e52bb3c47bf5d24c1f451d2e835 Mon Sep 17 00:00:00 2001 From: Simon Rozsival Date: Tue, 3 Jan 2023 21:52:33 +0100 Subject: [PATCH 3/4] Fix assert --- .../Xamarin.Android.Net/AndroidMessageHandlerTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs b/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs index 76e0de4350d..f645423d451 100644 --- a/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs +++ b/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs @@ -119,7 +119,6 @@ public async Task ServerCertificateCustomValidationCallback_Redirects () var handler = new AndroidMessageHandler { ServerCertificateCustomValidationCallback = (request, cert, chain, errors) => { callbackCounter++; - Assert.Contains (request.RequestUri.Host, cert.SubjectName.Name); return errors == SslPolicyErrors.None; } }; From 8a505152e206ac7f6ca17fe151b46d9c1afcbe89 Mon Sep 17 00:00:00 2001 From: Simon Rozsival Date: Wed, 4 Jan 2023 15:43:42 +0100 Subject: [PATCH 4/4] Avoid redirects from microsoft.com to www.microsoft.com --- .../AndroidMessageHandlerTests.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs b/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs index f645423d451..2f1517d57c6 100644 --- a/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs +++ b/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs @@ -27,9 +27,9 @@ public async Task ServerCertificateCustomValidationCallback_ApproveRequest () var handler = new AndroidMessageHandler { ServerCertificateCustomValidationCallback = (request, cert, chain, errors) => { Assert.NotNull (request, "request"); - Assert.AreEqual ("microsoft.com", request.RequestUri.Host); + Assert.AreEqual ("www.microsoft.com", request.RequestUri.Host); Assert.NotNull (cert, "cert"); - Assert.True (cert!.Subject.Contains ("microsoft.com"), $"Unexpected certificate subject {cert!.Subject}"); + Assert.True (cert!.Subject.Contains ("www.microsoft.com"), $"Unexpected certificate subject {cert!.Subject}"); Assert.True (cert!.Issuer.Contains ("Microsoft"), $"Unexpected certificate issuer {cert!.Issuer}"); Assert.NotNull (chain, "chain"); Assert.AreEqual (SslPolicyErrors.None, errors); @@ -40,7 +40,7 @@ public async Task ServerCertificateCustomValidationCallback_ApproveRequest () }; var client = new HttpClient (handler); - await client.GetStringAsync ("https://microsoft.com/"); + await client.GetStringAsync ("https://www.microsoft.com/"); Assert.IsTrue (callbackHasBeenCalled, "custom validation callback hasn't been called"); } @@ -58,7 +58,7 @@ public async Task ServerCertificateCustomValidationCallback_RejectRequest () }; var client = new HttpClient (handler); - await AssertRejectsRemoteCertificate (() => client.GetStringAsync ("https://microsoft.com/")); + await AssertRejectsRemoteCertificate (() => client.GetStringAsync ("https://www.microsoft.com/")); Assert.IsTrue (callbackHasBeenCalled, "custom validation callback hasn't been called"); } @@ -124,9 +124,9 @@ public async Task ServerCertificateCustomValidationCallback_Redirects () }; var client = new HttpClient (handler); - var result = await client.GetAsync ("https://httpbin.org/redirect-to?url=https://microsoft.com/"); + var result = await client.GetAsync ("https://httpbin.org/redirect-to?url=https://www.microsoft.com/"); - Assert.AreEqual (3, callbackCounter); // httpbin.org, microsoft.com, www.microsoft.com + Assert.AreEqual (2, callbackCounter); Assert.IsTrue (result.IsSuccessStatusCode); }