3

In an ASP.NET Core 2.0 project, I'm trying to initiate a new request to the server itself. Since Kestrel is a managed web server, I assume this should be easy to do, but I couldn't find the answer.

This is particularly useful when you need the results from other actions to produce the result (possibly multiple actions), but you want to run the whole pipeline for each. (eg. logging, authorization, or routing)


No, I don't think this is an XY problem, I'll edit to clarify, and provide usecases at the end.

What I want to achieve is to avoid the network layer, otherwise HttpClient was the way to go, and it was easy. But if I interact with the network, overheads aside, I'd also need to know the hosting URL and Port of the server, which makes it ugly.

I'll elaborate by an example: I have used patterns like this for in-process hosting of the web server (mainly for unit-tests)

var server = TestServer.Create(appBuilder =>
{
    var startup = new TestStartup();
    startup.Configuration(appBuilder);
});

var client = server.HttpClient;
// Use the client to send requests

This test server allows an in-memory stream to be processed without any binding on the network. I want to achieve similar results using Kestrel. Or, if possible, construct a Request object and pass a reference for it to be processed by the web host and pipeline.

I can think of a few use cases for this:

  • Batching multiple requests to the server (via request body) and avoid transport latency
  • Late-running the routing after some action-specific logic, where the best and easiest key to explain what to expect from the server is the URL itself
  • The effect of server-side redirects (Server.Transfer in old days)

I am aware of the security risks and the smell, but in some cases this can be a good solution. My case, specifically, is batching plus some calculations on the results for small monitoring stubs that are limited in access and only perform read-only operations, so no risks.

Iravanchi
  • 5,139
  • 9
  • 40
  • 56
  • 1
    Can you provide some code to better explain what it is you are trying to achieve. So far this looks like an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – Nkosi Mar 09 '18 at 11:37
  • So, HttpClient? What have you tried? – CodeCaster Mar 09 '18 at 11:45
  • Any of these maybe? https://stackoverflow.com/a/41320302/5397642 – alsami Mar 09 '18 at 12:27
  • @SamiAl90 I actually saw that, I'm looking for the last option. But couldn't find a concrete solution and the answer above states that "I believe this is possible". I do believe it too, but couldn't find how! – Iravanchi Mar 09 '18 at 13:00
  • I think this very much *is* an XY problem. What you are wanting to do is very much an anti-pattern, and there's probably *much* better ways to actually go about achieving what you need, if only we knew what those needs were. – Chris Pratt Mar 09 '18 at 13:59

1 Answers1

0

The only way to reliably run the whole pipeline again with the correct client context is to round-trip through the client, generally with a Redirect return-type.

If there were a way to initiate a new request entirely on the server-side, this would effectively make your server the new client, and it would have to do very insecure things to "impersonate" the client. You're basically talking about a man-in-the-middle attack on yourself.

(I disagree with SamiAI90's answer since you didn't specifically ask about APIs, and there are a lot of other possible scenarios that have nothing to do with API-style access, bearer tokens, etc.)

McGuireV10
  • 9,572
  • 5
  • 48
  • 64
  • What scenarios? Why would you combine actions that return views instead of object data? How would this end up being merged together? But yeah ofc it must not be a bearer token and can be smth else, was just an example. – alsami Mar 09 '18 at 11:48
  • For one thing, you'd want to reproduce _all_ cookies. You may have to reproduce complex payloads. And logging would still be wrong, it wouldn't represent the original client if he's doing typical stuff like IP logging. It's just a bad idea in general (without `Redirect`) if the intent is to run the pipeline as the original caller. – McGuireV10 Mar 09 '18 at 11:52
  • Yeah you can attach cookies to the httpclient request too so that argument is invalid. – alsami Mar 09 '18 at 11:53
  • 1
    Bottom line, no matter what he does, `HttpClient` isn't going to run the pipeline in some way that actually impersonates the original client request. You can get close but it will still be a different client. – McGuireV10 Mar 09 '18 at 11:56
  • Why would it not run through the whole pipline? When you write end-to-end test using an HttpClient the request would run through the whole pipeline. All the filters will be executed, same as you would do it using a front-end to call the server end-points. – alsami Mar 09 '18 at 12:00
  • I didn't say it wouldn't run the pipeline, I said it won't be doing all those useful pipeline-things like logging in any way that represents the original client. – McGuireV10 Mar 09 '18 at 12:05
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/166531/discussion-between-samial90-and-mcguirev10). – alsami Mar 09 '18 at 12:06