如何在Spring Boot中限制`application/octet-stream`请求的主体?

huangapple go评论71阅读模式
英文:

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.93.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(&quot;save&quot;)
	public ResponseEntity&lt;Map&lt;String, Object&gt;&gt; save(@RequestBody byte[] data) {
		return ResponseEntity.ok(Map.of(&quot;size&quot;, data.length));
	}
}

To test my endpoint I tried this curl command:

curl -X POST -H &quot;Content-Type: application/octet-stream&quot; --data-binary &quot;@my_big_binary_file.whatever&quot; 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) &amp;&amp; request.getContentLengthLong() &gt; 10000) {
            throw new IOException(&quot;请求内容超过了 10000 字节的限制&quot;);
        }
        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) &amp;&amp; request.getContentLengthLong() &gt; 10000) {
            throw new IOException(&quot;Request content exceeded limit of 10000 bytes&quot;);
        }
        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.

huangapple
  • 本文由 发表于 2023年3月10日 00:00:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75687109.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定