HTTP标头不在EC2上返回
我在2个EC2实例(分段和生产环境)上部署了一个Spring Boot应用程序。 我有一个用于下载文件的端点。 它看起来像这样(应用程序是用Kotlin编写的):
@PostMapping("/download") open fun download(@RequestBody request: DownloadRequest, servletResponse: HttpServletResponse) { val file = getByteArray(request.fileId) servletResponse.outputStream.write(file) servletResponse.contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE servletResponse.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"${request.fileId}.zip\"") }
当我在登台机器上执行下载请求时,一切都很好。 我找回文件,响应中设置了标题。 这些是我可以在邮差看到的标题:
Cache-Control →no-cache, no-store, max-age=0, must-revalidate Connection →keep-alive Content-Disposition →attachment; filename="345412.zip" Content-Length →11756 Content-Type →application/octet-stream Date →Tue, 04 Apr 2017 09:04:19 GMT Expires →0 Pragma →no-cache X-Application-Context →application:8081 X-Content-Type-Options →nosniff X-Frame-Options →DENY X-XSS-Protection →1; mode=block
当我在生产上做同样的请求时,响应主体包含文件内容,但我手动设置的2个标题“Content-Type”和“Content-Disposition”缺失:
Cache-Control →no-cache, no-store, max-age=0, must-revalidate Connection →keep-alive Content-Length →56665 Date →Tue, 04 Apr 2017 09:06:45 GMT Expires →0 Pragma →no-cache X-Application-Context →application:8081 X-Content-Type-Options →nosniff X-Frame-Options →DENY X-XSS-Protection →1; mode=block
两台机器在Docker容器中都部署了完全相同的JAR。 这两个调用都是使用它们的私有IP直接针对EC2实例完成的,所以不涉及ELB。 这两个实例的配置是相同的,我可以在AWS控制台中找到不同的区别。
你知道什么可能导致这个? 在EC2中是否有一个设置可以防止一些HTTP头被回送回来? 我找不到任何理由为什么标题被送回一个案件,而不是在另一个。
这个问题是通过首先编写响应头然后响应主体来解决的:
@PostMapping("/download") open fun download(@RequestBody request: DownloadRequest, servletResponse: HttpServletResponse) { val file = getByteArray(request.fileId) servletResponse.contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE servletResponse.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"${request.fileId}.zip\"") servletResponse.outputStream.write(file) }
如果您首先开始写体,则可能无法正确设置标题。 我仍然不确定为什么这只是在生产机器上复制。