internal async Task ReturnResponseMessageAsync() { // Check if the response has already started because the TrySetResult below could happen a bit late // (as it happens on a different thread) by which point the CompleteResponseAsync could run and calls this // method again. if (!_responseFeature.HasStarted) { // Sets HasStarted try { await _responseFeature.FireOnSendingHeadersAsync(); } catch (Exception ex) { Abort(ex); return; } // Copy the feature collection so we're not multi-threading on the same collection. var newFeatures = new FeatureCollection(); foreach (var pair in _httpContext.Features) { newFeatures[pair.Key] = pair.Value; } _responseTcs.TrySetResult(new DefaultHttpContext(newFeatures)); } }
private async Task <HttpResponseMessage> GenerateResponseAsync() { await _responseFeature.FireOnSendingHeadersAsync(); var httpContext = Context.HttpContext; var response = new HttpResponseMessage(); response.StatusCode = (HttpStatusCode)httpContext.Response.StatusCode; response.ReasonPhrase = httpContext.Features.Get <IHttpResponseFeature>().ReasonPhrase; response.RequestMessage = _request; // response.Version = owinResponse.Protocol; response.Content = new StreamContent(_responseStream); foreach (var header in httpContext.Response.Headers) { if (!response.Headers.TryAddWithoutValidation(header.Key, (IEnumerable <string>)header.Value)) { bool success = response.Content.Headers.TryAddWithoutValidation(header.Key, (IEnumerable <string>)header.Value); Contract.Assert(success, "Bad header"); } } return(response); }
public async Task StatusCode_DefaultsTo200() { // Arrange & Act var responseInformation = new ResponseFeature(); // Assert Assert.Equal(200, responseInformation.StatusCode); Assert.False(responseInformation.HasStarted); await responseInformation.FireOnSendingHeadersAsync(); Assert.True(responseInformation.HasStarted); }
internal async Task ReturnResponseMessageAsync() { // Check if the response is already returning because the TrySetResult below could happen a bit late // (as it happens on a different thread) by which point the CompleteResponseAsync could run and calls this // method again. if (!_returningResponse) { _returningResponse = true; try { await _responseFeature.FireOnSendingHeadersAsync(); } catch (Exception ex) { Abort(ex); return; } // Copy the feature collection so we're not multi-threading on the same collection. var newFeatures = new FeatureCollection(); foreach (var pair in _httpContext.Features) { newFeatures[pair.Key] = pair.Value; } var serverResponseFeature = _httpContext.Features.Get <IHttpResponseFeature>() !; // The client gets a deep copy of this so they can interact with the body stream independently of the server. var clientResponseFeature = new HttpResponseFeature() { StatusCode = serverResponseFeature.StatusCode, ReasonPhrase = serverResponseFeature.ReasonPhrase, Headers = serverResponseFeature.Headers, Body = _responseReaderStream }; newFeatures.Set <IHttpResponseFeature>(clientResponseFeature); newFeatures.Set <IHttpResponseBodyFeature>(new StreamResponseBodyFeature(_responseReaderStream)); _responseTcs.TrySetResult(new DefaultHttpContext(newFeatures)); } }