通过Java REST API处理HTTP 302响应时无法下载Zip文件
问题:302重定向后curl无法下载Server B的文件
场景:访问Server A的Java REST API下载文件,当文件不存在时,Server A返回302重定向到同负载均衡下的Server B API,但执行curl命令后仅生成空的test.zip文件,verbose输出显示已收到302响应,但未发起对Server B的请求。
Server A的重定向代码:
String destinationUri = "https://serverB_IP/68629e2f-5157-4c0c-8ba8"; Response.ok().header("AuthToken", authToken).header("Access-Control-Allow-Origin", "https://"+serverA_IP).header("Access-Control-Allow-Method", HttpMethod.GET).header("Access-Control-Allow-Headers",ContentType.APPLICATION_OCTET_STREAM).status(302).location(destinationUri).build();
curl命令及响应:
curl -v -s -k -o test.zip -H "AuthToken: testToken" "https://serverA_IP/68629e2f-5157-4c0c-8ba8"
* Trying 1xx.xx.xx.xxx:443... * Connected to 1xx.xx.xx.xxx port 443 * schannel: disabled automatic use of client certificate * schannel: using IP address, SNI is not supported by OS. * ALPN: curl offers http/1.1 * ALPN: server did not agree on a protocol. Uses default. * using HTTP/1.x > GET /serverA_IP/68629e2f-5157-4c0c-8ba8 HTTP/1.1 > Host: 1xx.xx.xx.xxx > User-Agent: curl/8.4.0 > Accept: */* > AuthToken: testToken > < HTTP/1.1 302 < Date: Tue, 05 Mar 2024 16:18:27 GMT < Server: Acme < X-Content-Type-Options: nosniff < Cache-Control: no-cache, no-store, must-revalidate < Pragma: no-cache < Expires: 0 < Strict-Transport-Security: max-age=631138519; includeSubDomains < AuthToken: testToken < Access-Control-Allow-Origin: https://serverA_IP < Access-Control-Allow-Method: GET < Access-Control-Allow-Headers: application/octet-stream < Location: https://serverB_IP/68629e2f-5157-4c0c-8ba8 < Content-Type: application/octet-stream < Content-Length: 0 < X-Frame-Options: DENY < X-XSS-Protection: 1; mode=block < Content-Security-Policy: default-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; frame-ancestors 'none'; form-action 'self'; upgrade-insecure-requests; block-all-mixed-content; < * Connection #0 to host 1xx.xx.xx.xxx left intact
核心原因
curl默认不会自动跟随HTTP 3xx重定向,因此只会接收Server A返回的302响应(内容长度为0),不会主动请求Location头指向的Server B地址,最终生成空文件。
解决方案
1. 强制curl跟随重定向
添加-L(或--location)参数,让curl自动处理3xx重定向:
curl -v -s -k -L -o test.zip -H "AuthToken: testToken" "https://serverA_IP/68629e2f-5157-4c0c-8ba8"
2. 确保AuthToken传递到Server B
如果Server B的API同样需要AuthToken验证,curl默认不会将自定义头传递到重定向后的请求,需添加--location-trusted参数,允许将自定义头发送到重定向目标地址:
curl -v -s -k -L --location-trusted -o test.zip -H "AuthToken: testToken" "https://serverA_IP/68629e2f-5157-4c0c-8ba8"
代码优化建议(非当前问题直接原因)
Server A的重定向代码中,Response.ok().status(302)存在逻辑矛盾:ok()默认对应200状态码,后续手动设置302会覆盖,但规范写法应直接使用Response.status(302):
String destinationUri = "https://serverB_IP/68629e2f-5157-4c0c-8ba8"; Response.status(302) .header("AuthToken", authToken) .header("Access-Control-Allow-Origin", "https://"+serverA_IP) .header("Access-Control-Allow-Method", HttpMethod.GET) .header("Access-Control-Allow-Headers", ContentType.APPLICATION_OCTET_STREAM) .location(destinationUri) .build();
内容的提问来源于stack exchange,提问作者Code Trickle
相关产品推荐
相关产品推荐

