2

How do I have to chain my HttpMessageHandlers for the HttpClient to reach my following goal.

I am using the SocketsHttpHandler as my inner HttpMessageHandler for HttpClient with cookie support. On top of the handler I wrote my own LoggingHttpHandler to log every request including the cookies.

The cookies are not present in the HttpRequestMessage and the HttpResponseMessage. They are handled by the internal CookieContainer of the SocketsHttpHandler, so I access these cookies inside my LoggingSocketsHttpHandler.

My solution is like so:

public class LoggingSocketsHttpHandler : DelegatingHandler
{       
    private readonly SocketsHttpHandler _httpHandler;           
    
    public LoggingSocketsHttpHandler(SocketsHttpHandler httpHandler)
        : base(httpHandler)
    {
         _httpHandler = httpHandler;                      
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        LogRequestStart(request); // Access SocketsHttpHandler.CookieContainer

        var response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);

        LogRequestEnd(response); // Access SocketsHttpHandler.CookieContainer
    }
}

Works pretty fine. I am writing another HttpMessageHandler which intercepts the response if a special HTTP status code is detected.

When this occurs the HttpMessageInterceptionHandler needs to access the CookieContainer as well and makes another request. This request can be logged if the InnerHandler is a LoggingSocketsHttpHandler but should also work with the plain SocketsHttpHandler.

It seems wrong to me to search inside of those DelegatingHandlers for as long as a SocketsHttpHandler is found to get the CookieContainer. I maybe want to write my own one in the future for example. SocketsHttpHandler is sealed also.

The full pipeline would look like:

HttpMessageInterceptionHandler (1)
-> LoggingSocketsHttpHandler (2)
-> SocketsHttpHandler

where (1) and (2) needs to access the CookieContainer.

Anyone knows how to achieve this?

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
BlackMatrix
  • 474
  • 5
  • 19
  • How are you creating instance of `HttpClient` and injecting these handlers? Something like you can do `HttpClient client = HttpClientFactory.Create(new HttpMessageInterceptionHandler(new LoggingSocketsHttpHandler(new SocketsHttpHandler())));` – user1672994 Jan 23 '21 at 14:32
  • Just like so: ```new HttpClient(new HttpMessageInterceptionHandler(new LoggingSocketsHttpHandler(new SocketsHttpHandler{ ... }))``` – BlackMatrix Jan 23 '21 at 14:35
  • You can also look for `var socketHttpHandler = new SocketsHttpHandler() { ... }; HttpClient client = new HttpClient(new HttpMessageInterceptionHandler(socketHttpHandler), new LoggingSocketsHttpHandler(socketHttpHandler));` These message handlers are chained together. The first handler receives an HTTP request, does some processing, and gives the request to the next handler. [Reference](https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/httpclient-message-handlers) – user1672994 Jan 23 '21 at 14:40
  • I think your last example is not correct. The HttpClient doesn't take multiple HttpMessageHandlers in the constructor. Also keep in mind that the requests made by HttpMessageInterceptionHandler should also be logged (but not a must, the Handler should work without also, decided by the HttpClientFactory how). Even you chain them you would always have iterate through all InnerHandlers till you found one with cookie support. And you need to know the type of the Handler which you are searching in your implementation of the DelegatingHandler. That's in my eyes wrong. – BlackMatrix Jan 23 '21 at 14:51
  • yes, it should use `HttpClientFactory.Create` instead of `new HttpClient` – user1672994 Jan 23 '21 at 15:53
  • Maybe you got me wrong. I want to access the cookies inside of multiple HttpMessageHandlers not how I chain them with the HttpClient or the HttpClientFactory. Additionally it would be good if the HttpMessageHandlers do not the depend on the implemantation of SocketsHttpHandler so I can write my own with cookie support if I want to. – BlackMatrix Jan 23 '21 at 23:30

0 Answers0