Skip to content
This repository has been archived by the owner on Dec 19, 2018. It is now read-only.

TestServer should call IHttpContextFactory.Create with valid featureCollection #896

Closed
cortex93 opened this issue Dec 5, 2016 · 4 comments
Assignees

Comments

@cortex93
Copy link

cortex93 commented Dec 5, 2016

Hi,

I'm trying to set the TraceIdentifier from request headers early in the request processing before HostingApplication begins the scope and logs it.
To do so, I’m reading HttpContext.Request.Headers in a custom HttpContextFactory.Create method. While it works with Kestrel, it doesn't with TestServer.

From what I understand, TestServer do not populate HttpContext from the IFeatureCollection but it calls IHttpApplication.CreateContext with a fake RequestFeature and modify the returned HttpContext before calling IHttpApplication.ProcessRequestAsync.

If that's not a bug, what is the correct usage and how could I achieve my requirement

@cortex93
Copy link
Author

cortex93 commented Dec 5, 2016

In RequestState, setting the RequestFeature properties directly with the one from given request.
I do the same with response,and finally create the Context to set the abortedSource token on it.

This make it works but I really don't know the implication.

@Tratcher
Copy link
Member

Tratcher commented Dec 8, 2016

Yes, we could do that. The only reason it hadn't been done that way was that it was more convenient to set fields via the HttpContext. See

var contextFeatures = new FeatureCollection();
contextFeatures.Set<IHttpRequestFeature>(new RequestFeature());
_responseFeature = new ResponseFeature();
contextFeatures.Set<IHttpResponseFeature>(_responseFeature);
Context = application.CreateContext(contextFeatures);
var httpContext = Context.HttpContext;
var serverRequest = httpContext.Request;
serverRequest.Protocol = "HTTP/" + request.Version.ToString(2);
serverRequest.Scheme = request.RequestUri.Scheme;
serverRequest.Method = request.Method.ToString();

@cortex93
Copy link
Author

cortex93 commented Dec 9, 2016

In fact, using the feature is also that convenient. Just replacing

Context = application.CreateContext(contextFeatures);
var httpContext = Context.HttpContext;
var serverRequest = httpContext.Request

with
var serverRequest = contextFeatures.Get<IHttpRequestFeature>();

does the trick. QueryString is of different type so .Value will be required for QueryString.FromUriComponent

At the end,

httpContext.Response.Body = _responseStream;
httpContext.Response.StatusCode = 200;
httpContext.RequestAborted = _requestAbortedSource.Token;

may be replace with

var responseFeature = contextFeatures.Get<IHttpResponseFeature>()
responseFeature.Body = _responseStream;
responseFeature.StatusCode = 200;
Context = application.CreateContext(contextFeatures);
Context.HttpContext.RequestAborted = _requestAbortedSource.Token;

@davidfowl
Copy link
Member

@Tratcher let's make this change.

/cc @muratg

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants