我们有一个带有接收文件上传请求的端点的 REST 服务。所有请求都使用具有 5 分钟超时时间的身份验证令牌。
问题是 Jetty 似乎在调用我们的任何代码之前加载了整个文件。这意味着我们要等到完整上传完成后才能检查身份验证令牌,这会导致大文件因身份验证超时而失败。
我们假设增加身份验证超时不是一个选项。 (文书工作、繁文缛节、客户签字等)。
最初我们使用 JAX-RS 来上传文件,如下所示:
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response fileUpload (MultipartFormDataInput input) {
...
}
在过滤器中检查身份验证:
@Priority(Priorities.AUTHENTICATION)
public class AuthFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
<check token>
chain.doFilter(request, response);
}
}
我们一直在使用带有速率限制的 CURL 进行本地测试:
curl -v --cookie $TOKEN -F "[email protected]" http://localhost:8080/file --limit-rate 10k
我们的所有代码中都有日志消息。 CURL 命令挂起一段时间,直到最后(令牌过期很久之后)才打印任何日志。
我们还尝试了
ContainerRequestFilter
并得到了完全相同的结果。即使有 PreMatching
注释。
@Priority(Priorities.AUTHENTICATION)
@PreMatching
public class AuthFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) {
<check token>
}
}
我们尝试重写端点以使用 Servlet 和 Apache Commons FileUpload 库,根据我在此处阅读的内容,这应该可以解决此问题。
import org.apache.commons.fileupload.servlet.ServletFileUpload;
@WebServlet("file")
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
print("Upload started");
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
print("Upload finished");
}
}
但是,我仍然得到相同的结果。直到 CURL 命令完成上传文件后,才会打印来自 servlet 的日志消息。
任何指点表示赞赏。
我可以回答 Jetty 行为,但不能回答您特定的 REST 库。
Jetty 正在按照 REST 库的指示进行操作。
您已在 REST 库中声明...
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response fileUpload (MultipartFormDataInput input) {
这就是告诉 Jetty 将整个
multipart/form-data
请求正文加载到名为 MultipartFormDataInput
的对象中,然后在完全发送后,将该对象提供给您的端点。
问题是,REST 库调用 Servlet API 来访问该 MultiPart 信息(例如:
HttpServletRequest.getParameter
或 HttpServletRequest.getPart/getParts
),这导致基于 javax.servlet.MultipartConfigElement
的 REST 库配置读取整个多部分表单。
至于为什么您的 REST 身份验证未触发,这超出了我的帮助范围。
最后,commons-fileupload 不应该在现代 Servlet 容器中使用。
查看过去的答案: