spring 云网关,请求大小限制过滤器是否可用
spring cloud gateway, Is Request size limit filter is available
我在 spring-cloud-gateway
的一个项目中工作。我看到请求大小限制过滤器尚不可用。但我需要开发它。任何想法,它来了吗?或者我应该开始自己的开发。
我知道很难得到任何答案,因为除了开发人员外,还有一些人在做这件事。
我已经创建了一个名为 RequestSizeGatewayFilterFactory
的过滤器,它目前在我们的应用程序中运行良好。但不确定这是否可以成为 spring-cloud-gateway
项目的一部分。
package com.api.gateway.somename.filter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* This filter blocks the request, if the request size is more than
* the permissible size.The default request size is 5 MB
*
* @author Arpan
*/
public class RequestSizeGatewayFilterFactory
extends AbstractGatewayFilterFactory<RequestSizeGatewayFilterFactory.RequestSizeConfig> {
private static String PREFIX = "kMGTPE";
private static String ERROR = "Request size is larger than permissible limit." +
"Request size is %s where permissible limit is %s";
public RequestSizeGatewayFilterFactory() {
super(RequestSizeGatewayFilterFactory.RequestSizeConfig.class);
}
@Override
public GatewayFilter apply(RequestSizeGatewayFilterFactory.RequestSizeConfig requestSizeConfig) {
requestSizeConfig.validate();
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
String contentLength = request.getHeaders().getFirst("content-length");
if (!StringUtils.isEmpty(contentLength)) {
Long currentRequestSize = Long.valueOf(contentLength);
if (currentRequestSize > requestSizeConfig.getMaxSize()) {
exchange.getResponse().setStatusCode(HttpStatus.PAYLOAD_TOO_LARGE);
exchange.getResponse().getHeaders().add("errorMessage",
getErrorMessage(currentRequestSize, requestSizeConfig.getMaxSize()));
return exchange.getResponse().setComplete();
}
}
return chain.filter(exchange);
};
}
public static class RequestSizeConfig {
// 5 MB is the default request size
private Long maxSize = 5000000L;
public RequestSizeGatewayFilterFactory.RequestSizeConfig setMaxSize(Long maxSize) {
this.maxSize = maxSize;
return this;
}
public Long getMaxSize() {
return maxSize;
}
public void validate() {
Assert.isTrue(this.maxSize != null && this.maxSize > 0,
"maxSize must be greater than 0");
Assert.isInstanceOf(Long.class, maxSize, "maxSize must be a number");
}
}
private static String getErrorMessage(Long currentRequestSize, Long maxSize) {
return String.format(ERROR,
getHumanReadableByteCount(currentRequestSize),
getHumanReadableByteCount(maxSize));
}
private static String getHumanReadableByteCount(long bytes) {
int unit = 1000;
if (bytes < unit) return bytes + " B";
int exp = (int) (Math.log(bytes) / Math.log(unit));
String pre = Character.toString(PREFIX.charAt(exp - 1));
return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
}
}
过滤器的配置是:
当它用作默认过滤器时:
spring:
application:
name: somename
cloud:
gateway:
default-filters:
- Hystrix=default
- RequestSize=7000000
在某些情况下需要应用API
# ===========================================
- id: request_size_route
uri: ${test.uri}/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
maxSize: 5000000
您还需要在项目中的某些可扫描组件 class 中配置 bean,对于 spring-cloud-gateway-core
项目来说是 GatewayAutoConfiguration
。
@Bean
public RequestSizeGatewayFilterFactory requestSizeGatewayFilterFactory() {
return new RequestSizeGatewayFilterFactory();
}
我在 spring-cloud-gateway
的一个项目中工作。我看到请求大小限制过滤器尚不可用。但我需要开发它。任何想法,它来了吗?或者我应该开始自己的开发。
我知道很难得到任何答案,因为除了开发人员外,还有一些人在做这件事。
我已经创建了一个名为 RequestSizeGatewayFilterFactory
的过滤器,它目前在我们的应用程序中运行良好。但不确定这是否可以成为 spring-cloud-gateway
项目的一部分。
package com.api.gateway.somename.filter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* This filter blocks the request, if the request size is more than
* the permissible size.The default request size is 5 MB
*
* @author Arpan
*/
public class RequestSizeGatewayFilterFactory
extends AbstractGatewayFilterFactory<RequestSizeGatewayFilterFactory.RequestSizeConfig> {
private static String PREFIX = "kMGTPE";
private static String ERROR = "Request size is larger than permissible limit." +
"Request size is %s where permissible limit is %s";
public RequestSizeGatewayFilterFactory() {
super(RequestSizeGatewayFilterFactory.RequestSizeConfig.class);
}
@Override
public GatewayFilter apply(RequestSizeGatewayFilterFactory.RequestSizeConfig requestSizeConfig) {
requestSizeConfig.validate();
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
String contentLength = request.getHeaders().getFirst("content-length");
if (!StringUtils.isEmpty(contentLength)) {
Long currentRequestSize = Long.valueOf(contentLength);
if (currentRequestSize > requestSizeConfig.getMaxSize()) {
exchange.getResponse().setStatusCode(HttpStatus.PAYLOAD_TOO_LARGE);
exchange.getResponse().getHeaders().add("errorMessage",
getErrorMessage(currentRequestSize, requestSizeConfig.getMaxSize()));
return exchange.getResponse().setComplete();
}
}
return chain.filter(exchange);
};
}
public static class RequestSizeConfig {
// 5 MB is the default request size
private Long maxSize = 5000000L;
public RequestSizeGatewayFilterFactory.RequestSizeConfig setMaxSize(Long maxSize) {
this.maxSize = maxSize;
return this;
}
public Long getMaxSize() {
return maxSize;
}
public void validate() {
Assert.isTrue(this.maxSize != null && this.maxSize > 0,
"maxSize must be greater than 0");
Assert.isInstanceOf(Long.class, maxSize, "maxSize must be a number");
}
}
private static String getErrorMessage(Long currentRequestSize, Long maxSize) {
return String.format(ERROR,
getHumanReadableByteCount(currentRequestSize),
getHumanReadableByteCount(maxSize));
}
private static String getHumanReadableByteCount(long bytes) {
int unit = 1000;
if (bytes < unit) return bytes + " B";
int exp = (int) (Math.log(bytes) / Math.log(unit));
String pre = Character.toString(PREFIX.charAt(exp - 1));
return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
}
}
过滤器的配置是: 当它用作默认过滤器时:
spring:
application:
name: somename
cloud:
gateway:
default-filters:
- Hystrix=default
- RequestSize=7000000
在某些情况下需要应用API
# ===========================================
- id: request_size_route
uri: ${test.uri}/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
maxSize: 5000000
您还需要在项目中的某些可扫描组件 class 中配置 bean,对于 spring-cloud-gateway-core
项目来说是 GatewayAutoConfiguration
。
@Bean
public RequestSizeGatewayFilterFactory requestSizeGatewayFilterFactory() {
return new RequestSizeGatewayFilterFactory();
}