-
Notifications
You must be signed in to change notification settings - Fork 10k
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
Added support for unix domain sockets to the sockets transport #10560
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Buffers; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Net.Sockets; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Builder; | ||
using Microsoft.AspNetCore.Connections; | ||
using Microsoft.AspNetCore.Connections.Features; | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.AspNetCore.Testing; | ||
using Microsoft.AspNetCore.Testing.xunit; | ||
using Xunit; | ||
|
||
namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests | ||
{ | ||
public class UnixDomainSocketsTest : TestApplicationErrorLoggerLoggedTest | ||
{ | ||
#if LIBUV | ||
[OSSkipCondition(OperatingSystems.Windows, SkipReason = "Libuv does not support unix domain sockets on Windows.")] | ||
#else | ||
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win8, WindowsVersions.Win81, WindowsVersions.Win2008R2, SkipReason = "UnixDomainSocketEndPoint is not supported on older versions of Windows")] | ||
#endif | ||
[ConditionalFact] | ||
public async Task TestUnixDomainSocket() | ||
{ | ||
var path = Path.GetTempFileName(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to be creating the file. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah this is a bit jank. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Especially when you're using it just to get a name and then immediately deleting it. This is a bit of a flake-farm waiting to happen... why not just use |
||
|
||
Delete(path); | ||
|
||
try | ||
{ | ||
async Task EchoServer(ConnectionContext connection) | ||
{ | ||
// For graceful shutdown | ||
var notificationFeature = connection.Features.Get<IConnectionLifetimeNotificationFeature>(); | ||
|
||
try | ||
{ | ||
while (true) | ||
{ | ||
var result = await connection.Transport.Input.ReadAsync(notificationFeature.ConnectionClosedRequested); | ||
|
||
if (result.IsCompleted) | ||
{ | ||
break; | ||
} | ||
|
||
await connection.Transport.Output.WriteAsync(result.Buffer.ToArray()); | ||
|
||
connection.Transport.Input.AdvanceTo(result.Buffer.End); | ||
} | ||
} | ||
catch (OperationCanceledException) | ||
{ | ||
|
||
} | ||
} | ||
|
||
var hostBuilder = TransportSelector.GetWebHostBuilder() | ||
.UseKestrel(o => | ||
{ | ||
o.ListenUnixSocket(path, builder => | ||
{ | ||
builder.Run(EchoServer); | ||
}); | ||
}) | ||
.ConfigureServices(AddTestLogging) | ||
.Configure(c => { }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Out of curiosity, is this line necessary? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea, the webhost throws without it. |
||
|
||
using (var host = hostBuilder.Build()) | ||
{ | ||
await host.StartAsync(); | ||
|
||
using (var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified)) | ||
{ | ||
await socket.ConnectAsync(new UnixDomainSocketEndPoint(path)); | ||
|
||
var data = Encoding.ASCII.GetBytes("Hello World"); | ||
await socket.SendAsync(data, SocketFlags.None); | ||
|
||
var buffer = new byte[data.Length]; | ||
var read = 0; | ||
while (read < data.Length) | ||
{ | ||
read += await socket.ReceiveAsync(buffer.AsMemory(read, buffer.Length - read), SocketFlags.None); | ||
} | ||
|
||
Assert.Equal(data, buffer); | ||
} | ||
|
||
await host.StopAsync(); | ||
} | ||
} | ||
finally | ||
{ | ||
Delete(path); | ||
} | ||
} | ||
|
||
private static void Delete(string path) | ||
{ | ||
try | ||
{ | ||
File.Delete(path); | ||
} | ||
catch (FileNotFoundException) | ||
{ | ||
|
||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
endpoint != null
is still a valid assert I believe.