Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unix domain socket binding on WCF Client #5172

Merged
merged 4 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
20 changes: 20 additions & 0 deletions System.ServiceModel.sln
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ServiceModel.NetTcp"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ServiceModel.NetTcp.Tests", "src\System.ServiceModel.NetTcp\tests\System.ServiceModel.NetTcp.Tests.csproj", "{95C6CD71-6965-44E1-8F05-01F2F150B1E0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ServiceModel.UnixDomainSocket.Tests", "src\System.ServiceModel.UnixDomainSocket\tests\System.ServiceModel.UnixDomainSocket.Tests.csproj", "{58918456-A2B2-431F-BB95-BAAD2818BFC7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Binding.Custom.IntegrationTests", "src\System.Private.ServiceModel\tests\Scenarios\Binding\Custom\Binding.Custom.IntegrationTests.csproj", "{D878F354-E120-476A-A90A-9E601A7E7580}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Binding.Http.IntegrationTests", "src\System.Private.ServiceModel\tests\Scenarios\Binding\Http\Binding.Http.IntegrationTests.csproj", "{2789D52D-9C17-4FCE-B81C-41B65C3FAFF9}"
Expand Down Expand Up @@ -83,6 +85,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ServiceModel.NetFram
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ServiceModel.NetNamedPipe", "src\System.ServiceModel.NetNamedPipe\src\System.ServiceModel.NetNamedPipe.csproj", "{5ECB8887-D7EE-449F-9439-35D0BBBB1E07}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ServiceModel.UnixDomainSocket", "src\System.ServiceModel.UnixDomainSocket\src\System.ServiceModel.UnixDomainSocket.csproj", "{1664DB18-8451-43C0-8A85-2DD9189C3897}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Binding.UDS.IntegrationTests", "src\System.Private.ServiceModel\tests\Scenarios\Binding\UDS\Binding.UDS.IntegrationTests.csproj", "{B7C7D4F1-DE4D-421B-9CE9-C7320A503D58}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -117,6 +123,10 @@ Global
{95C6CD71-6965-44E1-8F05-01F2F150B1E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{95C6CD71-6965-44E1-8F05-01F2F150B1E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95C6CD71-6965-44E1-8F05-01F2F150B1E0}.Release|Any CPU.Build.0 = Release|Any CPU
{58918456-A2B2-431F-BB95-BAAD2818BFC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{58918456-A2B2-431F-BB95-BAAD2818BFC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{58918456-A2B2-431F-BB95-BAAD2818BFC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{58918456-A2B2-431F-BB95-BAAD2818BFC7}.Release|Any CPU.Build.0 = Release|Any CPU
{D878F354-E120-476A-A90A-9E601A7E7580}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D878F354-E120-476A-A90A-9E601A7E7580}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D878F354-E120-476A-A90A-9E601A7E7580}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -241,6 +251,14 @@ Global
{5ECB8887-D7EE-449F-9439-35D0BBBB1E07}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5ECB8887-D7EE-449F-9439-35D0BBBB1E07}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5ECB8887-D7EE-449F-9439-35D0BBBB1E07}.Release|Any CPU.Build.0 = Release|Any CPU
{1664DB18-8451-43C0-8A85-2DD9189C3897}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1664DB18-8451-43C0-8A85-2DD9189C3897}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1664DB18-8451-43C0-8A85-2DD9189C3897}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1664DB18-8451-43C0-8A85-2DD9189C3897}.Release|Any CPU.Build.0 = Release|Any CPU
{B7C7D4F1-DE4D-421B-9CE9-C7320A503D58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B7C7D4F1-DE4D-421B-9CE9-C7320A503D58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B7C7D4F1-DE4D-421B-9CE9-C7320A503D58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7C7D4F1-DE4D-421B-9CE9-C7320A503D58}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -249,6 +267,7 @@ Global
{10C03A32-1B1F-4EF8-8041-92C34DAD221E} = {DFDC71CF-6E65-481D-99D7-C35ED7EF6D4E}
{7805E0FD-3320-432B-91E1-D7BB7ABB781E} = {DFDC71CF-6E65-481D-99D7-C35ED7EF6D4E}
{95C6CD71-6965-44E1-8F05-01F2F150B1E0} = {DFDC71CF-6E65-481D-99D7-C35ED7EF6D4E}
{58918456-A2B2-431F-BB95-BAAD2818BFC7} = {DFDC71CF-6E65-481D-99D7-C35ED7EF6D4E}
{D878F354-E120-476A-A90A-9E601A7E7580} = {D6302510-AB10-4775-BCE9-98FA96FDEB76}
{2789D52D-9C17-4FCE-B81C-41B65C3FAFF9} = {D6302510-AB10-4775-BCE9-98FA96FDEB76}
{B38A2272-F260-4303-964C-ACDC9BADEB79} = {D6302510-AB10-4775-BCE9-98FA96FDEB76}
Expand Down Expand Up @@ -276,6 +295,7 @@ Global
{A3F8C509-AAE7-4391-9272-2221055CC17E} = {DFDC71CF-6E65-481D-99D7-C35ED7EF6D4E}
{E8E40B62-E737-4768-82C2-039E90ED9A39} = {D6302510-AB10-4775-BCE9-98FA96FDEB76}
{88918456-A2B2-431F-BB95-BAAD2818BFC7} = {DFDC71CF-6E65-481D-99D7-C35ED7EF6D4E}
{B7C7D4F1-DE4D-421B-9CE9-C7320A503D58} = {D6302510-AB10-4775-BCE9-98FA96FDEB76}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E0638FAC-BA6B-4E18-BAE6-468C3191BE58}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ public static bool Is_Windows()
ConditionalTestDetectors.IsWindows);
}

public static bool IsNotWindows()
{
return !Is_Windows();
}

// Returns 'true' if both the server and the client are domain-joined.
public static bool Domain_Joined()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(ScenarioTestTargetFrameworks)</TargetFrameworks>
<CLSCompliant>false</CLSCompliant>
<IsTestProject>true</IsTestProject>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CoreWCF.UnixDomainSocket" Version="1.5.0-preview1" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="$(WcfInfrastructureCommonProj)" />
<ProjectReference Include="$(WcfScenarioTestCommonProj)" />
<ProjectReference Include="..\..\..\..\..\System.ServiceModel.UnixDomainSocket\src\System.ServiceModel.UnixDomainSocket.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using CoreWCF;

namespace Binding.UDS.IntegrationTests.ServiceContract
{
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
public class EchoService : IEchoService
{
public string Echo(string echo)
{
return echo;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.ServiceModel;

namespace Binding.UDS.IntegrationTests.ServiceContract
{
internal static partial class Constants
{
public const string NS = "http://tempuri.org/";
public const string TESTSERVICE_NAME = nameof(IEchoService);
public const string OPERATION_BASE = NS + TESTSERVICE_NAME + "/";
}

[ServiceContract(Namespace = Constants.NS, Name = Constants.TESTSERVICE_NAME)]
public interface IEchoService
{
[OperationContract(Name = "Echo", Action = Constants.OPERATION_BASE + "Echo",
ReplyAction = Constants.OPERATION_BASE + "EchoResponse")]
string Echo(string echo);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using CoreWCF.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace Binding.UDS.IntegrationTests
{
internal class ServiceHelper
{
public static IHost CreateWebHostBuilder<TStartup>(string linuxSocketFilepath = "", [CallerMemberName] string callerMethodName = "") where TStartup : class
{
var startupType = typeof(TStartup);
var configureServicesMethod = startupType.GetMethod("ConfigureServices", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, new Type[] { typeof(IServiceCollection) });
var configureMethod = startupType.GetMethod("Configure", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, new Type[] { typeof(IHost) });
var startupInstance = Activator.CreateInstance(startupType);
var hostBuilder = Host.CreateDefaultBuilder(Array.Empty<string>());
hostBuilder.UseUnixDomainSocket(options =>
{
options.Listen(new Uri("net.uds://" + linuxSocketFilepath));
});
if (configureServicesMethod != null)
{
var configureServiceAction = (Action<IServiceCollection>)configureServicesMethod.CreateDelegate(typeof(Action<IServiceCollection>), startupInstance);
hostBuilder.ConfigureServices(configureServiceAction);
}

IHost host = hostBuilder.Build();
if (configureMethod != null)
{
var configureAction = (Action<IHost>)configureMethod.CreateDelegate(typeof(Action<IHost>), startupInstance);
configureAction(host);
}

return host;
}


//only for test, don't use in production code
public static X509Certificate2 GetServiceCertificate()
{
string AspNetHttpsOid = "1.3.6.1.4.1.311.84.1.1";
X509Certificate2 foundCert = null;
using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
{
// X509Store.Certificates creates a new instance of X509Certificate2Collection with
// each access to the property. The collection needs to be cleaned up correctly so
// keeping a single reference to fetched collection.
store.Open(OpenFlags.ReadOnly);
var certificates = store.Certificates;
foreach (var cert in certificates)
{
foreach (var extension in cert.Extensions)
{
if (AspNetHttpsOid.Equals(extension.Oid?.Value))
{
// Always clone certificate instances when you don't own the creation
foundCert = new X509Certificate2(cert);
break;
}
}

if (foundCert != null)
{
break;
}
}
// Cleanup
foreach (var cert in certificates)
{
cert.Dispose();
}
}

if (foundCert == null)
{
foundCert = ServiceUtilHelper.ClientCertificate;
}

return foundCert;
}

public static void CloseServiceModelObjects(params System.ServiceModel.ICommunicationObject[] objects)
{
foreach (System.ServiceModel.ICommunicationObject comObj in objects)
{
try
{
if (comObj == null)
{
continue;
}
// Only want to call Close if it is in the Opened state
if (comObj.State == System.ServiceModel.CommunicationState.Opened)
{
comObj.Close();
}
// Anything not closed by this point should be aborted
if (comObj.State != System.ServiceModel.CommunicationState.Closed)
{
comObj.Abort();
}
}
catch (TimeoutException)
{
comObj.Abort();
}
catch (System.ServiceModel.CommunicationException)
{
comObj.Abort();
}
}
}
}
}
Loading
Loading