Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
runtime
提交
1729ca66
R
runtime
项目概览
dotNET Platform
/
runtime
11 个月 前同步成功
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
runtime
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
1729ca66
编写于
7月 27, 2022
作者:
A
Anton Firszov
提交者:
GitHub
7月 27, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Tear down pending HTTP connection when the originating request completes (#71785)
Resolves #66297
上级
cc7ccfd0
变更
9
展开全部
隐藏空白更改
内联
并排
Showing
9 changed file
with
381 addition
and
125 deletion
+381
-125
src/libraries/Common/src/System/Threading/Tasks/TaskCompletionSourceWithCancellation.cs
...m/Threading/Tasks/TaskCompletionSourceWithCancellation.cs
+1
-1
src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs
...ies/Common/tests/System/Net/Http/GenericLoopbackServer.cs
+3
-0
src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs
src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs
+1
-1
src/libraries/System.Net.Http/src/System.Net.Http.csproj
src/libraries/System.Net.Http/src/System.Net.Http.csproj
+2
-2
src/libraries/System.Net.Http/src/System/Net/Http/GlobalHttpSettings.cs
...System.Net.Http/src/System/Net/Http/GlobalHttpSettings.cs
+4
-0
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
.../src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
+1
-1
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs
.../System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs
+227
-119
src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Cancellation.NonParallel.cs
...lTests/SocketsHttpHandlerTest.Cancellation.NonParallel.cs
+140
-0
src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj
...s/FunctionalTests/System.Net.Http.Functional.Tests.csproj
+2
-1
未找到文件。
src/libraries/Common/src/System/Threading/Tasks/TaskCompletionSourceWithCancellation.cs
浏览文件 @
1729ca66
...
...
@@ -8,7 +8,7 @@ namespace System.Threading.Tasks
/// <seealso cref="OperationCanceledException"/>s contain the relevant <see cref="CancellationToken"/>,
/// while also avoiding unnecessary allocations for closure captures.
/// </summary>
internal
sealed
class
TaskCompletionSourceWithCancellation
<
T
>
:
TaskCompletionSource
<
T
>
internal
class
TaskCompletionSourceWithCancellation
<
T
>
:
TaskCompletionSource
<
T
>
{
public
TaskCompletionSourceWithCancellation
()
:
base
(
TaskCreationOptions
.
RunContinuationsAsynchronously
)
{
...
...
src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs
浏览文件 @
1729ca66
...
...
@@ -152,6 +152,9 @@ public abstract class GenericLoopbackConnection : IAsyncDisposable
/// <summary>Waits for the client to signal cancellation.</summary>
public
abstract
Task
WaitForCloseAsync
(
CancellationToken
cancellationToken
);
/// <summary>Reset the connection's internal state so it can process further requests.</summary>
public
virtual
void
CompleteRequestProcessing
()
{
}
/// <summary>Helper function to make it easier to convert old test with strings.</summary>
public
async
Task
SendResponseBodyAsync
(
string
content
,
bool
isFinal
=
true
)
{
...
...
src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs
浏览文件 @
1729ca66
...
...
@@ -873,7 +873,7 @@ public override async Task<Byte[]> ReadRequestBodyAsync()
return
buffer
;
}
public
void
CompleteRequestProcessing
()
public
override
void
CompleteRequestProcessing
()
{
_contentLength
=
0
;
_bodyRead
=
false
;
...
...
src/libraries/System.Net.Http/src/System.Net.Http.csproj
浏览文件 @
1729ca66
...
...
@@ -138,8 +138,6 @@
Link="Common\System\Net\HttpDateParser.cs" />
<Compile Include="$(CommonPath)System\Text\SimpleRegex.cs"
Link="Common\System\Text\SimpleRegex.cs" />
<Compile Include="$(CommonPath)System\Threading\Tasks\TaskCompletionSourceWithCancellation.cs"
Link="Common\System\Threading\Tasks\TaskCompletionSourceWithCancellation.cs" />
<Compile Include="$(CommonPath)System\HexConverter.cs"
Link="Common\System\HexConverter.cs" />
<Compile Include="$(CommonPath)System\Net\ArrayBuffer.cs"
...
...
@@ -226,6 +224,8 @@
Link="Common\System\Net\DebugSafeHandle.cs" />
<Compile Include="$(CommonPath)System\Net\DebugSafeHandleZeroOrMinusOneIsInvalid.cs"
Link="Common\System\Net\DebugSafeHandleZeroOrMinusOneIsInvalid.cs" />
<Compile Include="$(CommonPath)System\Threading\Tasks\TaskCompletionSourceWithCancellation.cs"
Link="Common\System\Threading\Tasks\TaskCompletionSourceWithCancellation.cs" />
<!-- Header support -->
<Compile Include="$(CommonPath)System\Net\Http\aspnetcore\IHttpStreamHeadersHandler.cs">
<Link>Common\System\Net\Http\aspnetcore\IHttpStreamHeadersHandler.cs</Link>
...
...
src/libraries/System.Net.Http/src/System/Net/Http/GlobalHttpSettings.cs
浏览文件 @
1729ca66
...
...
@@ -45,6 +45,10 @@ internal static class SocketsHttpHandler
// Defaults to 1.0. Higher values result in shorter window, but slower downloads.
public
static
double
Http2StreamWindowScaleThresholdMultiplier
{
get
;
}
=
GetHttp2StreamWindowScaleThresholdMultiplier
();
public
static
int
PendingConnectionTimeoutOnRequestCompletion
{
get
;
}
=
RuntimeSettingParser
.
QueryRuntimeSettingInt32
(
"System.Net.SocketsHttpHandler.PendingConnectionTimeoutOnRequestCompletion"
,
"DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_PENDINGCONNECTIONTIMEOUTONREQUESTCOMPLETION"
,
5000
);
public
const
int
DefaultHttp2MaxStreamWindowSize
=
16
*
1024
*
1024
;
public
const
double
DefaultHttp2StreamWindowScaleThresholdMultiplier
=
1.0
;
...
...
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
浏览文件 @
1729ca66
...
...
@@ -2074,7 +2074,7 @@ private void ReturnConnectionToPool()
_idleSinceTickCount
=
Environment
.
TickCount64
;
// Put connection back in the pool.
_pool
.
Re
turnHttp11Connection
(
this
,
isNewConnection
:
false
);
_pool
.
Re
cycleHttp11Connection
(
this
);
}
}
...
...
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs
浏览文件 @
1729ca66
此差异已折叠。
点击以展开。
src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Cancellation.NonParallel.cs
0 → 100644
浏览文件 @
1729ca66
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using
System.IO
;
using
System.Net.Sockets
;
using
System.Net.Test.Common
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Microsoft.DotNet.RemoteExecutor
;
using
Xunit
;
using
Xunit.Abstractions
;
namespace
System.Net.Http.Functional.Tests
{
[
Collection
(
nameof
(
DisableParallelization
))]
// Reduces chance of timing-related issues
[
ConditionalClass
(
typeof
(
SocketsHttpHandler
),
nameof
(
SocketsHttpHandler
.
IsSupported
))]
public
class
SocketsHttpHandler_Cancellation_Test_NonParallel
:
HttpClientHandlerTestBase
{
public
SocketsHttpHandler_Cancellation_Test_NonParallel
(
ITestOutputHelper
output
)
:
base
(
output
)
{
}
[
OuterLoop
(
"Incurs significant delay."
)]
[
ConditionalTheory
(
typeof
(
RemoteExecutor
),
nameof
(
RemoteExecutor
.
IsSupported
))]
[
InlineData
(
"1.1"
,
10
_000
,
1
_000
,
100
)]
[
InlineData
(
"2.0"
,
10
_000
,
1
_000
,
100
)]
[
InlineData
(
"1.1"
,
20
_000
,
10
_000
,
null
)]
[
InlineData
(
"2.0"
,
20
_000
,
10
_000
,
null
)]
public
static
void
CancelPendingRequest_DropsStalledConnectionAttempt
(
string
versionString
,
int
firstConnectionDelayMs
,
int
requestTimeoutMs
,
int
?
pendingConnectionTimeoutOnRequestCompletion
)
{
RemoteInvokeOptions
options
=
new
RemoteInvokeOptions
();
if
(
pendingConnectionTimeoutOnRequestCompletion
is
not
null
)
{
options
.
StartInfo
.
EnvironmentVariables
[
"DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_PENDINGCONNECTIONTIMEOUTONREQUESTCOMPLETION"
]
=
pendingConnectionTimeoutOnRequestCompletion
.
ToString
();
}
RemoteExecutor
.
Invoke
(
CancelPendingRequest_DropsStalledConnectionAttempt_Impl
,
versionString
,
firstConnectionDelayMs
.
ToString
(),
requestTimeoutMs
.
ToString
(),
options
).
Dispose
();
}
private
static
async
Task
CancelPendingRequest_DropsStalledConnectionAttempt_Impl
(
string
versionString
,
string
firstConnectionDelayMsString
,
string
requestTimeoutMsString
)
{
var
version
=
Version
.
Parse
(
versionString
);
LoopbackServerFactory
factory
=
GetFactoryForVersion
(
version
);
const
int
AttemptCount
=
3
;
int
firstConnectionDelayMs
=
int
.
Parse
(
firstConnectionDelayMsString
);
int
requestTimeoutMs
=
int
.
Parse
(
requestTimeoutMsString
);
bool
firstConnection
=
true
;
using
CancellationTokenSource
cts0
=
new
CancellationTokenSource
(
requestTimeoutMs
);
await
factory
.
CreateClientAndServerAsync
(
async
uri
=>
{
using
var
handler
=
CreateHttpClientHandler
(
version
);
GetUnderlyingSocketsHttpHandler
(
handler
).
ConnectCallback
=
DoConnect
;
using
var
client
=
new
HttpClient
(
handler
)
{
DefaultRequestVersion
=
version
};
await
Assert
.
ThrowsAnyAsync
<
TaskCanceledException
>(
async
()
=>
{
await
client
.
GetAsync
(
uri
,
cts0
.
Token
);
});
for
(
int
i
=
0
;
i
<
AttemptCount
;
i
++)
{
using
var
cts1
=
new
CancellationTokenSource
(
requestTimeoutMs
);
using
var
response
=
await
client
.
GetAsync
(
uri
,
cts1
.
Token
);
Assert
.
Equal
(
HttpStatusCode
.
OK
,
response
.
StatusCode
);
}
},
async
server
=>
{
await
server
.
AcceptConnectionAsync
(
async
connection
=>
{
for
(
int
i
=
0
;
i
<
AttemptCount
;
i
++)
{
await
connection
.
ReadRequestDataAsync
();
await
connection
.
SendResponseAsync
();
connection
.
CompleteRequestProcessing
();
}
});
});
async
ValueTask
<
Stream
>
DoConnect
(
SocketsHttpConnectionContext
ctx
,
CancellationToken
cancellationToken
)
{
if
(
firstConnection
)
{
firstConnection
=
false
;
await
Task
.
Delay
(
100
,
cancellationToken
);
// Wait for the request to be pushed to the queue
cts0
.
Cancel
();
// cancel the first request faster than RequestTimeoutMs
await
Task
.
Delay
(
firstConnectionDelayMs
,
cancellationToken
);
// Simulate stalled connection
}
var
s
=
new
Socket
(
SocketType
.
Stream
,
ProtocolType
.
Tcp
)
{
NoDelay
=
true
};
await
s
.
ConnectAsync
(
ctx
.
DnsEndPoint
,
cancellationToken
);
return
new
NetworkStream
(
s
,
ownsSocket
:
true
);
}
}
[
OuterLoop
(
"Incurs significant delay."
)]
[
ConditionalTheory
(
typeof
(
RemoteExecutor
),
nameof
(
RemoteExecutor
.
IsSupported
))]
[
InlineData
(
20
_000
)]
[
InlineData
(
Timeout
.
Infinite
)]
public
void
PendingConnectionTimeout_HighValue_PendingConnectionIsNotCancelled
(
int
timeout
)
{
RemoteExecutor
.
Invoke
(
async
timoutStr
=>
{
// Setup "infinite" timeout of int.MaxValue milliseconds
AppContext
.
SetData
(
"System.Net.SocketsHttpHandler.PendingConnectionTimeoutOnRequestCompletion"
,
int
.
Parse
(
timoutStr
));
bool
connected
=
false
;
CancellationTokenSource
cts
=
new
CancellationTokenSource
();
await
new
Http11LoopbackServerFactory
().
CreateClientAndServerAsync
(
async
uri
=>
{
using
var
handler
=
CreateHttpClientHandler
(
HttpVersion
.
Version11
);
GetUnderlyingSocketsHttpHandler
(
handler
).
ConnectCallback
=
DoConnect
;
using
var
client
=
new
HttpClient
(
handler
)
{
DefaultRequestVersion
=
HttpVersion
.
Version11
};
await
Assert
.
ThrowsAnyAsync
<
TaskCanceledException
>(()
=>
client
.
GetAsync
(
uri
,
cts
.
Token
));
},
async
server
=>
{
await
server
.
AcceptConnectionAsync
(
_
=>
Task
.
CompletedTask
).
WaitAsync
(
30
_000
);
});
async
ValueTask
<
Stream
>
DoConnect
(
SocketsHttpConnectionContext
ctx
,
CancellationToken
cancellationToken
)
{
var
s
=
new
Socket
(
SocketType
.
Stream
,
ProtocolType
.
Tcp
)
{
NoDelay
=
true
};
await
Task
.
Delay
(
100
,
cancellationToken
);
// Wait for the request to be pushed to the queue
cts
.
Cancel
();
await
Task
.
Delay
(
10
_000
,
cancellationToken
);
await
s
.
ConnectAsync
(
ctx
.
DnsEndPoint
,
cancellationToken
);
connected
=
true
;
return
new
NetworkStream
(
s
,
ownsSocket
:
true
);
}
Assert
.
True
(
connected
);
},
timeout
.
ToString
()).
Dispose
();
}
}
}
src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj
浏览文件 @
1729ca66
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<StringResourcesPath>../../src/Resources/Strings.resx</StringResourcesPath>
<DefineConstants>$(DefineConstants);SYSNETHTTP_NO_OPENSSL;HTTP3</DefineConstants>
...
...
@@ -159,6 +159,7 @@
Link="Common\TestUtilities\System\DisableParallelization.cs" />
<Compile Include="HttpClientHandlerTest.AltSvc.cs" />
<Compile Include="SocketsHttpHandlerTest.Cancellation.cs" />
<Compile Include="SocketsHttpHandlerTest.Cancellation.NonParallel.cs" />
<Compile Include="SocketsHttpHandlerTest.Http2FlowControl.cs" />
<Compile Include="SocketsHttpHandlerTest.Http2KeepAlivePing.cs" />
<Compile Include="HttpClientHandlerTest.Connect.cs" />
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录