Search code examples
spring-webfluxspring-webclientreactor-netty

How to access to request body using WebFlux and Netty HttpClient


I need to calculate some kind of digest of the request body using the WebClient of Webflux and this digest must be set into a HTTP header. Using the good old Spring MVC ClientHttpRequestInterceptor is easy because the request body is provided as an array of bytes.

The ExchangeFilterFunction does not provide access to the request body.

The body is sent as JSon and Spring uses Jackson in order to serialize Java objects, so an option could be serialize my Object into Json and calculate the digest on it, but this strategy has two drawbacks:

  • my code would repeat what Spring will do when the request is actually sent
  • there's no guarantee that the acutal bytes sent by Spring as a request are equal to what I've passed to the digest function

I suppose that I should use some low level API of Netty, but I can't find any example.


Solution

  • I implemented the solution proposed by @rewolf and it worked, but I encountered an issue because of the multi-threading nature of WebFlux.

    In fact, it's possible that the client request is saved into the thread-local map by one thread, but a different thread tries to get it, so a null value is returned.

    For example, it happens if the request to be signed is created inside a Rest controller method which has a Mono as a request body parameter:

    @PostMapping
    public String execute(@RequestBody Mono<MyBody> body){
    
        Mono<OtherBody> otherBody = body.map(this::transformBodyIntoOtherBody);
    
        ...
        webClient.post()
        .body(otherBody)
        .exchange();
        ...
        
    }
    

    According to Reactor specs, the Reactor Context should be used instead of Thread Local.

    I forked @rewolf project and implemented a solution based on Reactor Context: https://github.com/taxone/blog-hmac-auth-webclient