Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Provide an (at least temporary) non-global ManagedHandler opt-in mechanism #24173

Merged
merged 3 commits into from
Sep 22, 2017
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 @@ -134,6 +134,7 @@ protected RemoteExecutorTestBase() { }
public static System.Diagnostics.RemoteExecutorTestBase.RemoteInvokeHandle RemoteInvoke(System.Func<string, string, string, string, int> method, string arg1, string arg2, string arg3, string arg4, System.Diagnostics.RemoteInvokeOptions options=null) { throw null; }
public static System.Diagnostics.RemoteExecutorTestBase.RemoteInvokeHandle RemoteInvoke(System.Func<string, string, string, string, string, int> method, string arg1, string arg2, string arg3, string arg4, string arg5, System.Diagnostics.RemoteInvokeOptions options=null) { throw null; }
public static System.Diagnostics.RemoteExecutorTestBase.RemoteInvokeHandle RemoteInvoke(System.Func<System.Threading.Tasks.Task<int>> method, System.Diagnostics.RemoteInvokeOptions options=null) { throw null; }
public static System.Diagnostics.RemoteExecutorTestBase.RemoteInvokeHandle RemoteInvoke(System.Func<string, System.Threading.Tasks.Task<int>> method, string arg, System.Diagnostics.RemoteInvokeOptions options=null) { throw null; }
public static System.Diagnostics.RemoteExecutorTestBase.RemoteInvokeHandle RemoteInvokeRaw(System.Delegate method, string unparsedArg, System.Diagnostics.RemoteInvokeOptions options=null) { throw null; }
public sealed partial class RemoteInvokeHandle : System.IDisposable
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ public static RemoteInvokeHandle RemoteInvoke(
return RemoteInvoke(GetMethodInfo(method), Array.Empty<string>(), options);
}

/// <summary>Invokes the method from this assembly in another process using the specified arguments.</summary>
/// <param name="method">The method to invoke.</param>
/// <param name="options">Options to use for the invocation.</param>
public static RemoteInvokeHandle RemoteInvoke(
Func<string, Task<int>> method,
string arg,
RemoteInvokeOptions options = null)
{
return RemoteInvoke(GetMethodInfo(method), new[] { arg }, options);
}

/// <summary>Invokes the method from this assembly in another process using the specified arguments.</summary>
/// <param name="method">The method to invoke.</param>
/// <param name="arg1">The first argument to pass to the method.</param>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public void DataShared()
acc.Flush();

// Spawn and then wait for the other process, which will verify the data and write its own known pattern
RemoteInvoke(DataShared_OtherProcess, file.Path).Dispose();
RemoteInvoke(new Func<string, int>(DataShared_OtherProcess), file.Path).Dispose();

// Now verify we're seeing the data from the other process
for (int i = 0; i < capacity; i++)
Expand Down
1 change: 1 addition & 0 deletions src/System.Net.Http/src/System.Net.Http.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@
<Reference Include="System.Text.Encoding" />
<Reference Include="System.Text.Encoding.Extensions" />
<Reference Include="System.Threading" />
<Reference Include="System.Threading.Thread" />
<Reference Include="System.Threading.Tasks" />
<Reference Include="System.Threading.Tasks.Extensions" />
<Reference Include="System.Threading.Timer" />
Expand Down
40 changes: 38 additions & 2 deletions src/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,52 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Diagnostics;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Threading;

namespace System.Net.Http
{
public partial class HttpClientHandler : HttpMessageHandler
{
// This partial implementation contains members common to all HttpClientHandler implementations.

private static bool UseManagedHandler => Environment.GetEnvironmentVariable("COMPlus_UseManagedHttpClientHandler") == "true";
private const string ManagedHandlerSettingName = "COMPlus_UseManagedHttpClientHandler";

private static LocalDataStoreSlot s_useManagedHandlerSlot;

private static bool UseManagedHandler
{
get
{
// Check the environment variable to see if it's been set to true. If it has, use the managed handler.
if (Environment.GetEnvironmentVariable(ManagedHandlerSettingName) == "true")
{
return true;
}

// Then check whether a thread local has been set with the same name.
// If it's been set to a Boolean true, also use the managed handler.
LocalDataStoreSlot slot = LazyInitializer.EnsureInitialized(ref s_useManagedHandlerSlot, () =>
{
LocalDataStoreSlot local = Thread.GetNamedDataSlot(ManagedHandlerSettingName);
if (local == null)
{
try
{
local = Thread.AllocateNamedDataSlot(ManagedHandlerSettingName);
}
catch (ArgumentException)
{
local = Thread.GetNamedDataSlot(ManagedHandlerSettingName);
}
}
return local;
});
Debug.Assert(slot != null);
return Thread.GetData(slot) is bool result && result;
}
}

public static Func<HttpRequestMessage, X509Certificate2, X509Chain, SslPolicyErrors, bool> DangerousAcceptAnyServerCertificateValidator { get; } = delegate { return true; };
}
Expand Down
8 changes: 5 additions & 3 deletions src/System.Net.Http/tests/FunctionalTests/CancellationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace System.Net.Http.Functional.Tests
{
public class CancellationTest
public class CancellationTest : HttpClientTestBase
{
private readonly ITestOutputHelper _output;

Expand All @@ -37,8 +37,10 @@ public async Task GetAsync_ResponseContentRead_CancelUsingTimeoutOrToken_TaskCan
TimeSpan timeout = useTimeout ? new TimeSpan(0, 0, 1) : Timeout.InfiniteTimeSpan;
CancellationToken cancellationToken = useTimeout ? CancellationToken.None : cts.Token;

using (var client = new HttpClient() { Timeout = timeout })
using (HttpClient client = CreateHttpClient())
{
client.Timeout = timeout;

var triggerResponseWrite = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
var triggerRequestCancel = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);

Expand Down Expand Up @@ -107,7 +109,7 @@ public Task ReadAsStreamAsync_ReadAsync_Cancel_BodyNeverStarted_TaskCanceledQuic
[InlineData(true)]
public async Task ReadAsStreamAsync_ReadAsync_Cancel_TaskCanceledQuickly(bool startResponseBody)
{
using (var client = new HttpClient())
using (HttpClient client = CreateHttpClient())
{
await LoopbackServer.CreateServerAsync(async (server, url) =>
{
Expand Down
33 changes: 19 additions & 14 deletions src/System.Net.Http/tests/FunctionalTests/DefaultCredentialsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Net.Test.Common;
using System.Security.Principal;
using System.Threading.Tasks;

Expand All @@ -16,7 +15,7 @@ namespace System.Net.Http.Functional.Tests
// TODO: #2383 - Consolidate the use of the environment variable settings to Common/tests.
[SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "dotnet/corefx #20010")]
[PlatformSpecific(TestPlatforms.Windows)]
public class DefaultCredentialsTest
public class DefaultCredentialsTest : HttpClientTestBase
{
private static string DomainJoinedTestServer => Configuration.Http.DomainJoinedHttpHost;
private static bool DomainJoinedTestsEnabled => !string.IsNullOrEmpty(DomainJoinedTestServer);
Expand Down Expand Up @@ -51,7 +50,7 @@ public DefaultCredentialsTest(ITestOutputHelper output)
[InlineData(true)]
public async Task UseDefaultCredentials_DefaultValue_Unauthorized(bool useProxy)
{
var handler = new HttpClientHandler();
HttpClientHandler handler = CreateHttpClientHandler();
handler.UseProxy = useProxy;

using (var client = new HttpClient(handler))
Expand All @@ -68,7 +67,9 @@ public async Task UseDefaultCredentials_DefaultValue_Unauthorized(bool useProxy)
[InlineData(true)]
public async Task UseDefaultCredentials_SetFalse_Unauthorized(bool useProxy)
{
var handler = new HttpClientHandler { UseProxy = useProxy, UseDefaultCredentials = false };
HttpClientHandler handler = CreateHttpClientHandler();
handler.UseProxy = useProxy;
handler.UseDefaultCredentials = false;

using (var client = new HttpClient(handler))
using (HttpResponseMessage response = await client.GetAsync(s_authenticatedServer))
Expand All @@ -84,7 +85,9 @@ public async Task UseDefaultCredentials_SetFalse_Unauthorized(bool useProxy)
[InlineData(true)]
public async Task UseDefaultCredentials_SetTrue_ConnectAsCurrentIdentity(bool useProxy)
{
var handler = new HttpClientHandler { UseProxy = useProxy, UseDefaultCredentials = true };
HttpClientHandler handler = CreateHttpClientHandler();
handler.UseProxy = useProxy;
handler.UseDefaultCredentials = true;

using (var client = new HttpClient(handler))
using (HttpResponseMessage response = await client.GetAsync(s_authenticatedServer))
Expand All @@ -105,7 +108,9 @@ public async Task UseDefaultCredentials_SetTrue_ConnectAsCurrentIdentity(bool us
[InlineData(true)]
public async Task UseDefaultCredentials_SetTrueAndServerOffersMultipleSchemes_Ok(bool useProxy)
{
var handler = new HttpClientHandler { UseProxy = useProxy, UseDefaultCredentials = true };
HttpClientHandler handler = CreateHttpClientHandler();
handler.UseProxy = useProxy;
handler.UseDefaultCredentials = true;

using (var client = new HttpClient(handler))
using (HttpResponseMessage response = await client.GetAsync(s_multipleSchemesAuthenticatedServer))
Expand All @@ -126,10 +131,10 @@ public async Task UseDefaultCredentials_SetTrueAndServerOffersMultipleSchemes_Ok
[InlineData(true)]
public async Task Credentials_SetToSpecificCredential_ConnectAsSpecificIdentity(bool useProxy)
{
var handler = new HttpClientHandler {
UseProxy = useProxy,
UseDefaultCredentials = false,
Credentials = _specificCredential };
HttpClientHandler handler = CreateHttpClientHandler();
handler.UseProxy = useProxy;
handler.UseDefaultCredentials = false;
handler.Credentials = _specificCredential;

using (var client = new HttpClient(handler))
using (HttpResponseMessage response = await client.GetAsync(s_authenticatedServer))
Expand All @@ -148,7 +153,7 @@ public async Task Credentials_SetToSpecificCredential_ConnectAsSpecificIdentity(
[InlineData(true)]
public async Task Credentials_SetToWrappedDefaultCredential_ConnectAsCurrentIdentity(bool useProxy)
{
var handler = new HttpClientHandler();
HttpClientHandler handler = CreateHttpClientHandler();
handler.UseProxy = useProxy;
handler.Credentials = new CredentialWrapper
{
Expand All @@ -172,7 +177,7 @@ public async Task Credentials_SetToWrappedDefaultCredential_ConnectAsCurrentIden
[ConditionalFact(nameof(DomainProxyTestsEnabled))]
public async Task Proxy_UseAuthenticatedProxyWithNoCredentials_ProxyAuthenticationRequired()
{
var handler = new HttpClientHandler();
HttpClientHandler handler = CreateHttpClientHandler();
handler.Proxy = new AuthenticatedProxy(null);

using (var client = new HttpClient(handler))
Expand All @@ -187,7 +192,7 @@ public async Task Proxy_UseAuthenticatedProxyWithNoCredentials_ProxyAuthenticati
[ConditionalFact(nameof(DomainProxyTestsEnabled))]
public async Task Proxy_UseAuthenticatedProxyWithDefaultCredentials_OK()
{
var handler = new HttpClientHandler();
HttpClientHandler handler = CreateHttpClientHandler();
handler.Proxy = new AuthenticatedProxy(CredentialCache.DefaultCredentials);

using (var client = new HttpClient(handler))
Expand All @@ -206,7 +211,7 @@ public async Task Proxy_UseAuthenticatedProxyWithWrappedDefaultCredentials_OK()
InnerCredentials = CredentialCache.DefaultCredentials
};

var handler = new HttpClientHandler();
HttpClientHandler handler = CreateHttpClientHandler();
handler.Proxy = new AuthenticatedProxy(wrappedCreds);

using (var client = new HttpClient(handler))
Expand Down
Loading