#896 Have TestHost populate features before calling IHttpContextFactory.Create
This commit is contained in:
parent
af953b4883
commit
60c45c382b
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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)")]
|
||||
|
|
|
|||
Loading…
Reference in New Issue