英文:
How can I limit the body of a application/octet-stream request in Spring Boot?
问题
我正在开发一个服务,该服务将通过HTTP Post请求接收一个文件。文件通过请求体发送,并带有 Content-Type: application/octet-stream
头部。我想将请求体的大小限制为10MB。以下是我目标的 最小可复现示例(MRE):
@RestController
public class MyController {
@PostMapping("save")
public ResponseEntity<Map<String, Object>> save(@RequestBody byte[] data) {
return ResponseEntity.ok(Map.of("size", data.length));
}
}
为了测试我的端点,我尝试了以下 curl
命令:
curl -X POST -H "Content-Type: application/octet-stream" --data-binary "@my_big_binary_file.whatever" http://localhost:8080/save
我尝试设置了以下属性,但没有成功:
server.tomcat.max-http-form-post-size=10MB
server.tomcat.max-swallow-size=10MB
所以,我的问题是:我将在我的服务上有多个类似这样的请求。如何将它们的大小限制为10MB?还有,我认为这两个属性与此有关:它们的目的是什么?它们不是我期望的吗?
使用Java 17测试,Spring Boot 版本为 2.7.9 和 3.0.4。
附注:我知道有一种方法可以使用以下属性限制 multipart/form-data
请求。那个方法非常好用。但这不是我需要的。
spring.servlet.multipart.max-file-size=10MB
英文:
I'm developing a service that will receive a file through an HTTP Post request. The file is sent by the request body with a Content-Type: application/octet-stream
header. I want to limit the request body to 10MB. Here's a MRE of my goal:
@RestController
public class MyController {
@PostMapping("save")
public ResponseEntity<Map<String, Object>> save(@RequestBody byte[] data) {
return ResponseEntity.ok(Map.of("size", data.length));
}
}
To test my endpoint I tried this curl
command:
curl -X POST -H "Content-Type: application/octet-stream" --data-binary "@my_big_binary_file.whatever" http://localhost:8080/save
I tried to set the following properties, but with no success:
server.tomcat.max-http-form-post-size=10MB
server.tomcat.max-swallow-size=10MB
So, my question is: I'm going have multiple requests like this on my service. How can I limit the size of all of them to 10MB? Also, and I think it's related: what's the purpose of these two properties? Isn't it what I was expecting?
Tested using Java 17 on Spring Boot 2.7.9 and 3.0.4
PS.: I know there's a way to limit multipart/form-data
requests using the properties below. That works just fine. But it's not what I need.
spring.servlet.multipart.max-file-size=10MB
答案1
得分: 1
Chin Huang 插入的回应是有效的!只需要稍微修改一下,将它限制为 octet-stream 类型。
它将会几乎是这样的:
@Component
public class ApplicationJsonRequestSizeLimitFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (isApplicationOctet(request) && request.getContentLengthLong() > 10000) {
throw new IOException("请求内容超过了 10000 字节的限制");
}
filterChain.doFilter(request, response);
}
private boolean isApplicationOctet(HttpServletRequest httpRequest) {
return (MediaType.APPLICATION_OCTET_STREAM.isCompatibleWith(MediaType
.parseMediaType(httpRequest.getHeader(HttpHeaders.CONTENT_TYPE))));
}
}
这个解决方案基于 Chin Huang 的回答,只是调整了数据类型。
英文:
Well, the response that Chin Huang inserted is valid! You would need to change it only a little bit to limit octet-stream only.
It would be almost like that:
@Component
public class ApplicationJsonRequestSizeLimitFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (isApplicationOctet(request) && request.getContentLengthLong() > 10000) {
throw new IOException("Request content exceeded limit of 10000 bytes");
}
filterChain.doFilter(request, response);
}
private boolean isApplicationOctet(HttpServletRequest httpRequest) {
return (MediaType.APPLICATION_OCTET_STREAM.isCompatibleWith(MediaType
.parseMediaType(httpRequest.getHeader(HttpHeaders.CONTENT_TYPE))));
}
}
This solution is based on Chin Huang answer, just adjusting the datatype.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论