#896 Have TestHost populate features before calling IHttpContextFactory.Create

This commit is contained in:
Chris R 2017-02-28 15:10:42 -08:00
parent af953b4883
commit 60c45c382b
2 changed files with 73 additions and 17 deletions

View File

@ -126,49 +126,51 @@ namespace Microsoft.AspNetCore.TestHost
}
var contextFeatures = new FeatureCollection();
contextFeatures.Set<IHttpRequestFeature>(new RequestFeature());
var requestFeature = new RequestFeature();
contextFeatures.Set<IHttpRequestFeature>(requestFeature);
_responseFeature = new ResponseFeature();
contextFeatures.Set<IHttpResponseFeature>(_responseFeature);
Context = application.CreateContext(contextFeatures);
var httpContext = Context.HttpContext;
var requestLifetimeFeature = new HttpRequestLifetimeFeature();
contextFeatures.Set<IHttpRequestLifetimeFeature>(requestLifetimeFeature);
var serverRequest = httpContext.Request;
serverRequest.Protocol = "HTTP/" + request.Version.ToString(2);
serverRequest.Scheme = request.RequestUri.Scheme;
serverRequest.Method = request.Method.ToString();
requestFeature.Protocol = "HTTP/" + request.Version.ToString(fieldCount: 2);
requestFeature.Scheme = request.RequestUri.Scheme;
requestFeature.Method = request.Method.ToString();
var fullPath = PathString.FromUriComponent(request.RequestUri);
PathString remainder;
if (fullPath.StartsWithSegments(pathBase, out remainder))
{
serverRequest.PathBase = pathBase;
serverRequest.Path = remainder;
requestFeature.PathBase = pathBase.Value;
requestFeature.Path = remainder.Value;
}
else
{
serverRequest.PathBase = PathString.Empty;
serverRequest.Path = fullPath;
requestFeature.PathBase = string.Empty;
requestFeature.Path = fullPath.Value;
}
serverRequest.QueryString = QueryString.FromUriComponent(request.RequestUri);
requestFeature.QueryString = QueryString.FromUriComponent(request.RequestUri).Value;
foreach (var header in request.Headers)
{
serverRequest.Headers.Append(header.Key, header.Value.ToArray());
requestFeature.Headers.Append(header.Key, header.Value.ToArray());
}
var requestContent = request.Content;
if (requestContent != null)
{
foreach (var header in request.Content.Headers)
{
serverRequest.Headers.Append(header.Key, header.Value.ToArray());
requestFeature.Headers.Append(header.Key, header.Value.ToArray());
}
}
_responseStream = new ResponseStream(ReturnResponseMessageAsync, AbortRequest);
httpContext.Response.Body = _responseStream;
httpContext.Response.StatusCode = 200;
httpContext.RequestAborted = _requestAbortedSource.Token;
_responseFeature.Body = _responseStream;
_responseFeature.StatusCode = 200;
requestLifetimeFeature.RequestAborted = _requestAbortedSource.Token;
Context = application.CreateContext(contextFeatures);
}
public Context Context { get; private set; }

View File

@ -49,6 +49,31 @@ namespace Microsoft.AspNetCore.TestHost
return httpClient.GetAsync("https://example.com/A/Path/and/file.txt?and=query");
}
[Fact]
public Task ExpectedKeysAreInFeatures()
{
var handler = new ClientHandler(new PathString("/A/Path/"), new InspectingApplication(features =>
{
// TODO: Assert.True(context.RequestAborted.CanBeCanceled);
Assert.Equal("HTTP/1.1", features.Get<IHttpRequestFeature>().Protocol);
Assert.Equal("GET", features.Get<IHttpRequestFeature>().Method);
Assert.Equal("https", features.Get<IHttpRequestFeature>().Scheme);
Assert.Equal("/A/Path", features.Get<IHttpRequestFeature>().PathBase);
Assert.Equal("/and/file.txt", features.Get<IHttpRequestFeature>().Path);
Assert.Equal("?and=query", features.Get<IHttpRequestFeature>().QueryString);
Assert.NotNull(features.Get<IHttpRequestFeature>().Body);
Assert.NotNull(features.Get<IHttpRequestFeature>().Headers);
Assert.NotNull(features.Get<IHttpResponseFeature>().Headers);
Assert.NotNull(features.Get<IHttpResponseFeature>().Body);
Assert.Equal(200, features.Get<IHttpResponseFeature>().StatusCode);
Assert.Null(features.Get<IHttpResponseFeature>().ReasonPhrase);
Assert.Equal("example.com", features.Get<IHttpRequestFeature>().Headers["host"]);
Assert.NotNull(features.Get<IHttpRequestLifetimeFeature>());
}));
var httpClient = new HttpClient(handler);
return httpClient.GetAsync("https://example.com/A/Path/and/file.txt?and=query");
}
[Fact]
public Task SingleSlashNotMovedToPathBase()
{
@ -274,6 +299,35 @@ namespace Microsoft.AspNetCore.TestHost
}
}
private class InspectingApplication : IHttpApplication<Context>
{
Action<IFeatureCollection> _inspector;
public InspectingApplication(Action<IFeatureCollection> inspector)
{
_inspector = inspector;
}
public Context CreateContext(IFeatureCollection contextFeatures)
{
_inspector(contextFeatures);
return new Context()
{
HttpContext = new DefaultHttpContext(contextFeatures)
};
}
public void DisposeContext(Context context, Exception exception)
{
}
public Task ProcessRequestAsync(Context context)
{
return Task.FromResult(0);
}
}
[ConditionalFact]
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]