'Why does Spring Cloud Gateway not process request further after changing body?

I have to write a filter, that will replace token on user login. Here is the code:

    @Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    ServerHttpRequest request = exchange.getRequest();
    String path = request.getURI().getPath();
    log.info("AuthenticationFilterOne: path - {}, if predicate - {}",
            path,
            !loggingFilterProperties.getIgnoredUris().contains(path)
                    && noAuthProperties.checkNoAuthEndpoint(path)
    );
    if (!loggingFilterProperties.getIgnoredUris().contains(path)
            && noAuthProperties.checkNoAuthEndpoint(path)) {
        log.info("AuthenticationFilterOne: in if block, path - {}, predicate - {}, ignoredUris - {}, NoAuthEndpoints - {}",
                path,
                !loggingFilterProperties.getIgnoredUris().contains(path)
                        && noAuthProperties.checkNoAuthEndpoint(path),
                Arrays.toString(loggingFilterProperties.getIgnoredUris().toArray()),
                Arrays.toString(noAuthProperties.getNoAuthEndpoints().toArray())
        );
        GatewayContext gatewayContext = new GatewayContext();
        gatewayContext.setPath(path);
        exchange.getAttributes().put(GatewayContext.CACHE_GATEWAY_CONTEXT, gatewayContext);
        HttpHeaders headers = request.getHeaders();
        MediaType contentType = headers.getContentType();
        if (contentType != null && "application/x-thrift".equals(contentType.toString())) {
            return readBody(exchange, chain, gatewayContext);
        }
    }
    return chain.filter(exchange);
}

@SuppressWarnings({"AnonInnerLength", "MultipleStringLiterals", "LineLength", "CommentsIndentation"})
private Mono<Void> readBody(
        ServerWebExchange exchange,
        GatewayFilterChain chain,
        GatewayContext gatewayContext) {
    /**
     * join the body
     */
    return DataBufferUtils.join(exchange.getRequest().getBody())
            .flatMap(dataBuffer -> {
                byte[] bytes = new byte[dataBuffer.readableByteCount()];
                dataBuffer.read(bytes);
                DataBufferUtils.release(dataBuffer);
                TProtocol protocol = protocolFactory.getProtocol(new TMemoryInputTransport(bytes));
                int startPosition = findStartPosition(protocol);
                UserData userData = null;
                try {
                    userData = authenticationGateway.verify();
                    userData = authenticationGateway.verify(extractAuthToken(protocol, new AuthenticationTokenAuthEntity()));
                } catch (TException e) {
                    log.error("In AuthenticationFilterOne: error get user data");
                }
                AuthenticationTokenAuthEntity authenticationTokenAuthEntity = extractAuthToken(protocol, new AuthenticationTokenAuthEntity());
                int endPosition = findEndPosition(protocol);
                byte[] processed = ArrayUtils.addAll(
                        ArrayUtils.addAll(
                                getSkippedPart(protocol, startPosition),
                                serializeUserData(protocolFactory, userData)
                        ),
                        getAfterTokenPart(protocol, endPosition, bytes.length)
                );
                log.info("AuthenticationFilterOne: userData - {}", userData);
                Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
                    DataBuffer buffer =
                            exchange.getResponse().bufferFactory().wrap(processed);
                    DataBufferUtils.retain(buffer);
                    return Mono.just(buffer);
                });
                /**
                 * repackage ServerHttpRequest
                 */
                ServerHttpRequest mutatedRequest =
                        new ServerHttpRequestDecorator(exchange.getRequest()) {
                            @Override
                            public Flux<DataBuffer> getBody() {
                                return cachedFlux;
                            }
                        };
                /**
                 * mutate exchage with new ServerHttpRequest
                 */
                ServerWebExchange mutatedExchange =
                        exchange.mutate().request(mutatedRequest).build();
                HttpHeaders headers = mutatedExchange.getRequest().getHeaders();
                StringBuilder builder = new StringBuilder("{");
                for (Map.Entry<String, List<String>> e: headers.entrySet()) {
                    builder.append("[key - ").append(e.getKey()).append(": value - ")
                    .append(Arrays.toString(e.getValue().toArray())).append("]");
                }
                builder.append("}");
                /**
                 * read body string with default messageReaders
                 */
                return ServerRequest.create(mutatedExchange, MESSAGE_READERS)
                        .bodyToMono(String.class)
                        .doOnNext(objectValue -> {
                            log.info("PostBody:{}, headers - {}", objectValue, builder.toString());
                            gatewayContext.setCacheBody(objectValue);
                    /*  log.debug("[GatewayContext]Read JsonBody:{}",
                          objectValue);*/
                        }).then(chain.filter(mutatedExchange));
            });
}

It replaces the token, but it doesn't process the request further to an application and I cannot understand why. I have tried RewriteFunction<String, String> but, it doesn't work, because there is issue when I tried convert string to array of bytes and then to thrift structure.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source