Remove uv_shutdown because FIN is already sent during uv_close (#1811)

* Remove uv_shutdown because FIN is already sent during uv_close

#1808
This commit is contained in:
David Fowler 2017-05-05 12:52:10 -07:00 committed by GitHub
parent 5ea9981cdb
commit cd1568d7f4
5 changed files with 29 additions and 102 deletions

View File

@ -88,6 +88,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal
// Now, complete the input so that no more reads can happen
Input.Complete(new ConnectionAbortedException());
// Send a FIN
Log.ConnectionWriteFin(ConnectionId);
// We're done with the socket now
_socket.Dispose();

View File

@ -67,18 +67,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal
if (result.IsCancelled)
{
// Send a FIN
_log.ConnectionWriteFin(_connectionId);
using (var shutdownReq = new UvShutdownReq(_log))
{
shutdownReq.Init(_thread);
var shutdownResult = await shutdownReq.ShutdownAsync(_socket);
_log.ConnectionWroteFin(_connectionId, shutdownResult.Status);
}
// Ensure no data is written after uv_shutdown
break;
}

View File

@ -42,7 +42,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal.Networkin
_uv_write = NativeMethods.uv_write;
_uv_write2 = NativeMethods.uv_write2;
}
_uv_shutdown = NativeMethods.uv_shutdown;
_uv_err_name = NativeMethods.uv_err_name;
_uv_strerror = NativeMethods.uv_strerror;
_uv_loop_size = NativeMethods.uv_loop_size;
@ -312,16 +311,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal.Networkin
ThrowIfErrored(_uv_write2(req, handle, bufs, nbufs, sendHandle, cb));
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void uv_shutdown_cb(IntPtr req, int status);
protected Func<UvShutdownReq, UvStreamHandle, uv_shutdown_cb, int> _uv_shutdown;
public void shutdown(UvShutdownReq req, UvStreamHandle handle, uv_shutdown_cb cb)
{
req.Validate();
handle.Validate();
ThrowIfErrored(_uv_shutdown(req, handle, cb));
}
protected Func<int, IntPtr> _uv_err_name;
public string err_name(int err)
{
@ -572,9 +561,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal.Networkin
[DllImport("libuv", CallingConvention = CallingConvention.Cdecl)]
unsafe public static extern int uv_write2(UvRequest req, UvStreamHandle handle, uv_buf_t* bufs, int nbufs, UvStreamHandle sendHandle, uv_write_cb cb);
[DllImport("libuv", CallingConvention = CallingConvention.Cdecl)]
public static extern int uv_shutdown(UvShutdownReq req, UvStreamHandle handle, uv_shutdown_cb cb);
[DllImport("libuv", CallingConvention = CallingConvention.Cdecl)]
public extern static IntPtr uv_err_name(int err);

View File

@ -1,76 +0,0 @@
// 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 Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal.Networking
{
/// <summary>
/// Summary description for UvShutdownRequest
/// </summary>
public class UvShutdownReq : UvRequest
{
private readonly static LibuvFunctions.uv_shutdown_cb _uv_shutdown_cb = UvShutdownCb;
private Action<UvShutdownReq, int, Exception, object> _callback;
private object _state;
private LibuvAwaitable<UvShutdownReq> _awaitable = new LibuvAwaitable<UvShutdownReq>();
public UvShutdownReq(ILibuvTrace logger) : base(logger)
{
}
public override void Init(LibuvThread thread)
{
var loop = thread.Loop;
CreateMemory(
loop.Libuv,
loop.ThreadId,
loop.Libuv.req_size(LibuvFunctions.RequestType.SHUTDOWN));
base.Init(thread);
}
public LibuvAwaitable<UvShutdownReq> ShutdownAsync(UvStreamHandle handle)
{
Shutdown(handle, LibuvAwaitable<UvShutdownReq>.Callback, _awaitable);
return _awaitable;
}
public void Shutdown(UvStreamHandle handle, Action<UvShutdownReq, int, Exception, object> callback, object state)
{
_callback = callback;
_state = state;
_uv.shutdown(this, handle, _uv_shutdown_cb);
}
private static void UvShutdownCb(IntPtr ptr, int status)
{
var req = FromIntPtr<UvShutdownReq>(ptr);
var callback = req._callback;
req._callback = null;
var state = req._state;
req._state = null;
Exception error = null;
if (status < 0)
{
req.Libuv.Check(status, out error);
}
try
{
callback(req, status, error, state);
}
catch (Exception ex)
{
req._log.LogError(0, ex, "UvShutdownCb");
throw;
}
}
}
}

View File

@ -522,6 +522,32 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
}
}
[Fact]
public void AbortingTheConnectionSendsFIN()
{
var builder = new WebHostBuilder()
.UseKestrel()
.UseUrls("http://127.0.0.1:0")
.Configure(app => app.Run(context =>
{
context.Abort();
return Task.CompletedTask;
}));
using (var host = builder.Build())
{
host.Start();
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
socket.Connect(new IPEndPoint(IPAddress.Loopback, host.GetPort()));
socket.Send(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost:\r\n\r\n"));
int result = socket.Receive(new byte[32]);
Assert.Equal(0, result);
}
}
}
[Theory]
[InlineData("http://localhost/abs/path", "/abs/path", null)]
[InlineData("https://localhost/abs/path", "/abs/path", null)] // handles mismatch scheme