public Task <HttpActionStatus> LimitConnectTime(Task <HttpActionStatus> mainTask, Request request, WebRequestState state, TimeSpan?connectTimeout) { if (connectTimeout == null) { return(mainTask); } if (!ConnectTimeoutHelper.CanCheckSocket) { return(mainTask); } if (state.TimeRemaining < connectTimeout.Value) { return(mainTask); } if (request.Url.IsLoopback) { return(mainTask); } if (ConnectTimeoutHelper.IsSocketConnected(state.Request, log)) { return(mainTask); } return(LimitConnectTimeInternal(mainTask, request, state, connectTimeout.Value)); }
private async Task <HttpActionStatus> LimitConnectTimeInternal(Task <HttpActionStatus> mainTask, Request request, WebRequestState state, TimeSpan connectTimeout) { using (var timeoutCancellation = new CancellationTokenSource()) { var completedTask = await Task.WhenAny(mainTask, Task.Delay(connectTimeout, timeoutCancellation.Token)).ConfigureAwait(false); if (completedTask is Task <HttpActionStatus> taskWithResult) { timeoutCancellation.Cancel(); return(taskWithResult.GetAwaiter().GetResult()); } if (!ConnectTimeoutHelper.IsSocketConnected(state.Request, log)) { state.CancelRequestAttempt(); LogConnectionFailure(request, new WebException($"Connection attempt timed out. Timeout = {connectTimeout.ToPrettyString()}.", WebExceptionStatus.ConnectFailure)); return(HttpActionStatus.ConnectionFailure); } return(await mainTask.ConfigureAwait(false)); } }