Skip to content

Commit 6020fde

Browse files
authored
Add reset support for IIS (#24552)
1 parent 8ba7c7b commit 6020fde

File tree

12 files changed

+759
-18
lines changed

12 files changed

+759
-18
lines changed

src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/managedexports.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,4 +589,16 @@ http_response_set_trailer(
589589
IHttpResponse4* pHttpResponse = (IHttpResponse4*)pInProcessHandler->QueryHttpContext()->GetResponse();
590590
return pHttpResponse->SetTrailer(pszHeaderName, pszHeaderValue, usHeaderValueLength, fReplace);
591591
}
592+
593+
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
594+
VOID
595+
http_reset_stream(
596+
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
597+
ULONG errorCode
598+
)
599+
{
600+
IHttpResponse4* pHttpResponse = (IHttpResponse4*)pInProcessHandler->QueryHttpContext()->GetResponse();
601+
pHttpResponse->ResetStream(errorCode);
602+
}
603+
592604
// End of export

src/Servers/IIS/IIS/src/Core/IISHttpContext.FeatureCollection.cs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ internal partial class IISHttpContext : IFeatureCollection,
3333
ITlsConnectionFeature,
3434
IHttpBodyControlFeature,
3535
IHttpMaxRequestBodySizeFeature,
36-
IHttpResponseTrailersFeature
36+
IHttpResponseTrailersFeature,
37+
IHttpResetFeature
3738
{
3839
// NOTE: When feature interfaces are added to or removed from this HttpProtocol implementation,
3940
// then the list of `implementedFeatures` in the generated code project MUST also be updated.
@@ -394,6 +395,33 @@ IHeaderDictionary IHttpResponseTrailersFeature.Trailers
394395
set => ResponseTrailers = value;
395396
}
396397

398+
internal IHttpResetFeature GetResetFeature()
399+
{
400+
// Check version is above 2.
401+
if (HttpVersion >= System.Net.HttpVersion.Version20 && NativeMethods.HttpSupportTrailer(_pInProcessHandler))
402+
{
403+
return this;
404+
}
405+
406+
return null;
407+
}
408+
409+
void IHttpResetFeature.Reset(int errorCode)
410+
{
411+
if (errorCode < 0)
412+
{
413+
throw new ArgumentOutOfRangeException("'errorCode' cannot be negative");
414+
}
415+
416+
SetResetCode(errorCode);
417+
AbortIO(clientDisconnect: false);
418+
}
419+
420+
internal unsafe void SetResetCode(int errorCode)
421+
{
422+
NativeMethods.HttpResetStream(_pInProcessHandler, (ulong)errorCode);
423+
}
424+
397425
void IHttpResponseBodyFeature.DisableBuffering()
398426
{
399427
NativeMethods.HttpDisableBuffering(_pInProcessHandler);

src/Servers/IIS/IIS/src/Core/IISHttpContext.Features.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ internal partial class IISHttpContext
2929
private static readonly Type IServerVariablesFeature = typeof(global::Microsoft.AspNetCore.Http.Features.IServerVariablesFeature);
3030
private static readonly Type IHttpMaxRequestBodySizeFeature = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpMaxRequestBodySizeFeature);
3131
private static readonly Type IHttpResponseTrailersFeature = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpResponseTrailersFeature);
32+
private static readonly Type IHttpResetFeature = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpResetFeature);
3233

3334
private object _currentIHttpRequestFeature;
3435
private object _currentIHttpResponseFeature;
@@ -50,6 +51,7 @@ internal partial class IISHttpContext
5051
private object _currentIServerVariablesFeature;
5152
private object _currentIHttpMaxRequestBodySizeFeature;
5253
private object _currentIHttpResponseTrailersFeature;
54+
private object _currentIHttpResetFeature;
5355

5456
private void Initialize()
5557
{
@@ -66,6 +68,7 @@ private void Initialize()
6668
_currentIHttpMaxRequestBodySizeFeature = this;
6769
_currentITlsConnectionFeature = this;
6870
_currentIHttpResponseTrailersFeature = GetResponseTrailersFeature();
71+
_currentIHttpResetFeature = GetResetFeature();
6972
}
7073

7174
internal object FastFeatureGet(Type key)
@@ -154,6 +157,10 @@ internal object FastFeatureGet(Type key)
154157
{
155158
return _currentIHttpResponseTrailersFeature;
156159
}
160+
if (key == IHttpResetFeature)
161+
{
162+
return _currentIHttpResetFeature;
163+
}
157164

158165
return ExtraFeatureGet(key);
159166
}
@@ -260,6 +267,10 @@ internal void FastFeatureSet(Type key, object feature)
260267
{
261268
_currentIHttpResponseTrailersFeature = feature;
262269
}
270+
if (key == IHttpResetFeature)
271+
{
272+
_currentIHttpResetFeature = feature;
273+
}
263274
if (key == IISHttpContextType)
264275
{
265276
throw new InvalidOperationException("Cannot set IISHttpContext in feature collection");
@@ -349,6 +360,10 @@ private IEnumerable<KeyValuePair<Type, object>> FastEnumerable()
349360
{
350361
yield return new KeyValuePair<Type, object>(IHttpResponseTrailersFeature, _currentIHttpResponseTrailersFeature as global::Microsoft.AspNetCore.Http.Features.IHttpResponseTrailersFeature);
351362
}
363+
if (_currentIHttpResetFeature != null)
364+
{
365+
yield return new KeyValuePair<Type, object>(IHttpResponseTrailersFeature, _currentIHttpResetFeature as global::Microsoft.AspNetCore.Http.Features.IHttpResetFeature);
366+
}
352367

353368
if (MaybeExtra != null)
354369
{

src/Servers/IIS/IIS/src/Core/IISHttpContextOfT.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ public override async Task<bool> ProcessRequestAsync()
5959
// Dispose
6060
}
6161

62+
if (!success && HasResponseStarted)
63+
{
64+
// HTTP/2 INTERNAL_ERROR = 0x2 https://tools.ietf.org/html/rfc7540#section-7
65+
// Otherwise the default is Cancel = 0x8.
66+
SetResetCode(2);
67+
}
68+
6269
if (_onCompleted != null)
6370
{
6471
await FireOnCompleted();

src/Servers/IIS/IIS/src/NativeMethods.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ private static extern unsafe int http_websockets_write_bytes(
146146
[DllImport(AspNetCoreModuleDll)]
147147
private static extern unsafe int http_response_set_trailer(IntPtr pInProcessHandler, byte* pszHeaderName, byte* pszHeaderValue, ushort usHeaderValueLength, bool replace);
148148

149+
[DllImport(AspNetCoreModuleDll)]
150+
private static extern unsafe int http_reset_stream(IntPtr pInProcessHandler, ulong errorCode);
151+
149152
[DllImport(AspNetCoreModuleDll)]
150153
private static extern unsafe int http_response_set_known_header(IntPtr pInProcessHandler, int headerId, byte* pHeaderValue, ushort length, bool fReplace);
151154

@@ -318,6 +321,11 @@ internal static unsafe void HttpResponseSetTrailer(IntPtr pInProcessHandler, byt
318321
Validate(http_response_set_trailer(pInProcessHandler, pHeaderName, pHeaderValue, length, false));
319322
}
320323

324+
internal static unsafe void HttpResetStream(IntPtr pInProcessHandler, ulong errorCode)
325+
{
326+
Validate(http_reset_stream(pInProcessHandler, errorCode));
327+
}
328+
321329
internal static unsafe bool HttpSupportTrailer(IntPtr pInProcessHandler)
322330
{
323331
bool supportsTrailers;

0 commit comments

Comments
 (0)