Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -269,5 +269,42 @@ await LoopbackServer.CreateServerAsync(async (origServer, origUrl) =>
});
}
}

[Theory]
[InlineData("ftp://ftp.example.com/file.txt")]
[InlineData("file:///etc/passwd")]
[InlineData("gopher://gopher.example.com")]
[InlineData("telnet://telnet.example.com")]
public async Task GetAsync_AllowAutoRedirectTrue_UnsupportedRedirectScheme_ReturnsOriginalResponse(string redirectLocation)
{
HttpClientHandler handler = CreateHttpClientHandler();
handler.AllowAutoRedirect = true;
using (HttpClient client = CreateHttpClient(handler))
{
await LoopbackServer.CreateServerAsync(async (server, url) =>
{
Task<HttpResponseMessage> getTask = client.GetAsync(url);
Task<List<string>> serverTask = server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.Found, $"Location: {redirectLocation}\r\n");

if (IsWinHttpHandler)
{
// WinHttpHandler throws HttpRequestException for unsupported redirect schemes
await Assert.ThrowsAsync<HttpRequestException>(async () => await getTask);
await serverTask;
}
else
{
// SocketsHttpHandler refuses to follow the redirect and returns the original response
await TestHelper.WhenAllCompletedOrAnyFailed(getTask, serverTask);

using (HttpResponseMessage response = await getTask)
{
Assert.Equal(302, (int)response.StatusCode);
Assert.Equal(url, response.RequestMessage.RequestUri);
}
}
});
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,17 @@ internal override async ValueTask<HttpResponseMessage> SendAsync(HttpRequestMess
return null;
}

// Disallow automatic redirection to unsupported schemes
if (!HttpUtilities.IsSupportedScheme(location.Scheme))
{
if (NetEventSource.Log.IsEnabled())
{
TraceError($"Redirect from '{requestUri}' to '{location}' blocked due to unsupported scheme '{location.Scheme}'.", response.RequestMessage!.GetHashCode());
}

return null;
}

return location;
}

Expand Down
Loading