React to aspnet/HttpAbstractions#160 - Implemented OnResponseCompleted
This commit is contained in:
parent
b761e7d8c2
commit
39b8d204fd
|
|
@ -360,6 +360,11 @@ namespace Microsoft.AspNet.Server.WebListener
|
||||||
Response.OnSendingHeaders(callback, state);
|
Response.OnSendingHeaders(callback, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IHttpResponseFeature.OnResponseCompleted(Action<object> callback, object state)
|
||||||
|
{
|
||||||
|
Response.OnResponseCompleted(callback, state);
|
||||||
|
}
|
||||||
|
|
||||||
string IHttpResponseFeature.ReasonPhrase
|
string IHttpResponseFeature.ReasonPhrase
|
||||||
{
|
{
|
||||||
get { return Response.ReasonPhrase; }
|
get { return Response.ReasonPhrase; }
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ namespace Microsoft.Net.Http.Server
|
||||||
private BoundaryType _boundaryType;
|
private BoundaryType _boundaryType;
|
||||||
private UnsafeNclNativeMethods.HttpApi.HTTP_RESPONSE_V2 _nativeResponse;
|
private UnsafeNclNativeMethods.HttpApi.HTTP_RESPONSE_V2 _nativeResponse;
|
||||||
private IList<Tuple<Action<object>, object>> _onSendingHeadersActions;
|
private IList<Tuple<Action<object>, object>> _onSendingHeadersActions;
|
||||||
|
private IList<Tuple<Action<object>, object>> _onResponseCompletedActions;
|
||||||
|
|
||||||
private RequestContext _requestContext;
|
private RequestContext _requestContext;
|
||||||
|
|
||||||
|
|
@ -63,6 +64,7 @@ namespace Microsoft.Net.Http.Server
|
||||||
_nativeResponse.Response_V1.Version.MinorVersion = 1;
|
_nativeResponse.Response_V1.Version.MinorVersion = 1;
|
||||||
_responseState = ResponseState.Created;
|
_responseState = ResponseState.Created;
|
||||||
_onSendingHeadersActions = new List<Tuple<Action<object>, object>>();
|
_onSendingHeadersActions = new List<Tuple<Action<object>, object>>();
|
||||||
|
_onResponseCompletedActions = new List<Tuple<Action<object>, object>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum ResponseState
|
private enum ResponseState
|
||||||
|
|
@ -284,6 +286,7 @@ namespace Microsoft.Net.Http.Server
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
NotifyOnResponseCompleted();
|
||||||
// TODO: Verbose log
|
// TODO: Verbose log
|
||||||
EnsureResponseStream();
|
EnsureResponseStream();
|
||||||
_nativeStream.Dispose();
|
_nativeStream.Dispose();
|
||||||
|
|
@ -829,6 +832,17 @@ namespace Microsoft.Net.Http.Server
|
||||||
actions.Add(new Tuple<Action<object>, object>(callback, state));
|
actions.Add(new Tuple<Action<object>, object>(callback, state));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnResponseCompleted(Action<object> callback, object state)
|
||||||
|
{
|
||||||
|
var actions = _onResponseCompletedActions;
|
||||||
|
if (actions == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Response already completed");
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.Add(new Tuple<Action<object>, object>(callback, state));
|
||||||
|
}
|
||||||
|
|
||||||
private void NotifyOnSendingHeaders()
|
private void NotifyOnSendingHeaders()
|
||||||
{
|
{
|
||||||
var actions = Interlocked.Exchange(ref _onSendingHeadersActions, null);
|
var actions = Interlocked.Exchange(ref _onSendingHeadersActions, null);
|
||||||
|
|
@ -845,6 +859,30 @@ namespace Microsoft.Net.Http.Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void NotifyOnResponseCompleted()
|
||||||
|
{
|
||||||
|
var actions = Interlocked.Exchange(ref _onResponseCompletedActions, null);
|
||||||
|
if (actions == null)
|
||||||
|
{
|
||||||
|
// Something threw the first time, do not try again.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var actionPair in actions)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
actionPair.Item1(actionPair.Item2);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
RequestContext.Logger.LogWarning(
|
||||||
|
String.Format(Resources.Warning_ExceptionInOnResponseCompletedAction, nameof(OnResponseCompleted)),
|
||||||
|
ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class SendResponseLogContext : ReflectionBasedLogValues
|
private class SendResponseLogContext : ReflectionBasedLogValues
|
||||||
{
|
{
|
||||||
private readonly Response _response;
|
private readonly Response _response;
|
||||||
|
|
|
||||||
|
|
@ -166,5 +166,13 @@ namespace Microsoft.Net.Http.Server {
|
||||||
return ResourceManager.GetString("Exception_WrongIAsyncResult", resourceCulture);
|
return ResourceManager.GetString("Exception_WrongIAsyncResult", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An exception occured while running an action registered with {0}.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Warning_ExceptionInOnResponseCompletedAction
|
||||||
|
{
|
||||||
|
get { return ResourceManager.GetString("Warning_ExceptionInOnResponseCompletedAction"); }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -147,4 +147,7 @@
|
||||||
<data name="Exception_WrongIAsyncResult" xml:space="preserve">
|
<data name="Exception_WrongIAsyncResult" xml:space="preserve">
|
||||||
<value>The given IAsyncResult does not match this opperation.</value>
|
<value>The given IAsyncResult does not match this opperation.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Warning_ExceptionInOnResponseCompletedAction" xml:space="preserve">
|
||||||
|
<value>An exception occured while running an action registered with {0}.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
Loading…
Reference in New Issue