private void Shutdown(Exception shutdownReason) { lock (_shutdownLock) { if (_socketDisposed) { return; } // Make sure to close the connection only after the _aborted flag is set. // Without this, the RequestsCanBeAbortedMidRead test will sometimes fail when // a BadHttpRequestException is thrown instead of a TaskCanceledException. _socketDisposed = true; // shutdownReason should only be null if the output was completed gracefully, so no one should ever // ever observe the nondescript ConnectionAbortedException except for connection middleware attempting // to half close the connection which is currently unsupported. _shutdownReason = shutdownReason ?? new ConnectionAbortedException("The Socket transport's send loop completed gracefully."); _trace.ConnectionWriteFin(ConnectionId, _shutdownReason.Message); try { // Try to gracefully close the socket even for aborts to match libuv behavior. _socket.Shutdown(SocketShutdown.Both); } catch { // Ignore any errors from Socket.Shutdown() since we're tearing down the connection anyway. } _socket.Dispose(); } }
private void Shutdown() { lock (_shutdownLock) { if (!_aborted) { // Make sure to close the connection only after the _aborted flag is set. // Without this, the RequestsCanBeAbortedMidRead test will sometimes fail when // a BadHttpRequestException is thrown instead of a TaskCanceledException. _aborted = true; _trace.ConnectionWriteFin(ConnectionId); try { // Try to gracefully close the socket even for aborts to match libuv behavior. _socket.Shutdown(SocketShutdown.Both); } catch { // Ignore any errors from Socket.Shutdown since we're tearing down the connection anyway. } _socket.Dispose(); } } }
private async Task <Exception> DoSend() { Exception error = null; try { await ProcessSends(); } catch (SocketException ex) when(ex.SocketErrorCode == SocketError.OperationAborted) { error = null; } catch (ObjectDisposedException) { error = null; } catch (IOException ex) { error = ex; } catch (Exception ex) { error = new IOException(ex.Message, ex); } finally { // Make sure to close the connection only after the _aborted flag is set. // Without this, the RequestsCanBeAbortedMidRead test will sometimes fail when // a BadHttpRequestException is thrown instead of a TaskCanceledException. _aborted = true; _trace.ConnectionWriteFin(ConnectionId); _socket.Shutdown(SocketShutdown.Both); } return(error); }
private async Task <Exception> DoSend() { Exception error = null; try { while (true) { // Wait for data to write from the pipe producer var result = await Output.ReadAsync(); var buffer = result.Buffer; if (result.IsCanceled) { break; } try { if (!buffer.IsEmpty) { await _sender.SendAsync(buffer); } else if (result.IsCompleted) { break; } } finally { Output.AdvanceTo(buffer.End); } } } catch (SocketException ex) when(ex.SocketErrorCode == SocketError.OperationAborted) { error = null; } catch (ObjectDisposedException) { error = null; } catch (IOException ex) { error = ex; } catch (Exception ex) { error = new IOException(ex.Message, ex); } finally { // Make sure to close the connection only after the _aborted flag is set. // Without this, the RequestsCanBeAbortedMidRead test will sometimes fail when // a BadHttpRequestException is thrown instead of a TaskCanceledException. _aborted = true; _trace.ConnectionWriteFin(ConnectionId); _socket.Shutdown(SocketShutdown.Both); } return(error); }