package com.test.gateway.filter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qs.gateway.filter.xss.EscapeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import space.tryanything.kit.security.oauth.OAuth2Key;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;
@Slf4j
@Component
@Order(3)
public class HttpRequestFilter implements GlobalFilter {
private final ObjectMapper mapper = new ObjectMapper();
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String method = request.getMethodValue().toUpperCase();
if("GET".equalsIgnoreCase(method)){
try {
skyWalkInput(mapper.writeValueAsString(request.getQueryParams()),exchange);
} catch (JsonProcessingException e) {
log.error(e.getMessage(), e);
}
ServerHttpRequest mutateReq = new ServerHttpRequestDecorator(request) {
@Override
public MultiValueMap<String, String> getQueryParams() {
final MultiValueMap<String, String> parent = super.getQueryParams();
final MultiValueMap<String, String> now = new LinkedMultiValueMap<>(parent.size());
parent.forEach((key, value) -> now.addAll(key,
value.stream()
.map(EscapeUtil::clean)
.collect(Collectors.toList())));
return now;
}
};
return chain.filter(exchange.mutate().request(mutateReq).build());
}
return requestDecorator(exchange,chain);
}
private Mono<Void> requestDecorator(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
final HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.putAll(request.getHeaders());
httpHeaders.remove(HttpHeaders.CONTENT_LENGTH);
httpHeaders.set(HttpHeaders.CONTENT_TYPE,MediaType.APPLICATION_JSON_VALUE);
return DataBufferUtils.join(request.getBody()).flatMap(dataBuffer -> {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
String bodyStr = new String(bytes, StandardCharsets.UTF_8);
skyWalkInput(bodyStr,exchange);
exchange.getAttributes().put("POST_BODY", bodyStr);
DataBufferUtils.release(dataBuffer);
Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
DataBuffer buffer = response.bufferFactory().wrap(bytes);
return Mono.just(buffer);
});
ServerHttpRequest mutateReq = new ServerHttpRequestDecorator(request) {
@Override
public Flux<DataBuffer> getBody() {
return cachedFlux;
}
};
return chain.filter(exchange.mutate().request(mutateReq).build());
});
}
private void skyWalkInput(String body,ServerWebExchange exchange){
//构造请求的方法&URL&参数
StringBuilder sb = new StringBuilder("curl")
.append(" -X ").append(exchange.getRequest().getMethod())
.append(" ").append(exchange.getRequest().getPath().pathWithinApplication().value());
if(StringUtils.hasLength(body)){
sb.append("?").append(body);
}
//构造header
HttpHeaders header = exchange.getRequest().getHeaders();
String authorization = header.getFirst(OAuth2Key.AUTHORIZATION_KEY);
sb.append(" -H '").append("authorization:").append(authorization).append("'");
String contentType = header.getFirst(HttpHeaders.CONTENT_TYPE);
sb.append(" -H '").append("Content-Type:").append(contentType).append("'");
}
}版权声明:本文为chenrisheng1原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。