AWS Api代理压缩“无效块类型”
我有一个Api网关端点设置为HTTP_PROXY
,并且它按预期工作 - 只要您不提供Accept-Encoding: gzip
标头即可。然后它失败了。看来,Api Gateway对响应做了“某些事情”,这使得它在接收端无法解读。AWS Api代理压缩“无效块类型”
这是我所看到的:
- 直接将请求发送到代理服务器后端按预期工作(例如
curl --compressed
成功完成)。 - 通过Api Gateway以
curl --compressed
(以及其他方式)发送请求会导致“无效块类型”。 - 来自代理服务器的响应是17514字节,而通过Api网关,它已被炸至31506字节。这反映在
Content-Length
标题中。 - Api网关包括
x-amzn-Remapped-Content-Length
标题与旧(正确)值,所以它似乎知道它做了东西到响应。
的API方法被配置为HTTP代理,并且看起来是这样的:
aws apigateway get-method --rest-api-id xxxxx --resource-id yyyyy --http-method POST
{
"requestModels": {
"application/json": "MyRequestModel"
},
"authorizationType": "CUSTOM",
"apiKeyRequired": false,
"httpMethod": "POST",
"methodIntegration": {
"passthroughBehavior": "WHEN_NO_MATCH",
"cacheKeyParameters": [],
"requestParameters": {},
"uri": "http://myproxy/api/v1/resource",
"httpMethod": "POST",
"requestTemplates": {},
"cacheNamespace": "zzzzz",
"type": "HTTP_PROXY"
},
"requestValidatorId": "xyxyxyxy",
"authorizerId": "zyzyzyzyz"
}
据我所知,没有什么在这里表示代表API网关的任何映射。用户界面也不会显示任何响应映射。
测试API的,我看到以下内容:
- 响应头包括
"Content-Length":"17514"
,这是预期值 - 从中似乎像端点响应主体和方法响应主体是日志同样,尽管手动比较两个gzip数据的乱码ascii表示有点困难。两个
Content-Length
标题都是一样的。
测试期间,重新映射的内容长度值在任何地方都不可见,也不是x-amzn-Remapped-Content-Length
标头。这让我怀疑这可能是由Cloudfront完成的?
我通过“execute-api”和这个API的自定义域映射获得了相同的结果。
任何指针?
由于Michael在他的一个(非常有帮助的)评论中怀疑 - 这确实是API Gateway将我的gzip流视为UTF-8编码文本的情况,并对其进行了重新编码。鉴于这是一个未设置集成响应映射的端点,API网关会以任何方式处理我的响应,但似乎非常不直观,但在文档中提到了它。
解决方案是告诉API网关,对于此REST API,application/json
内容类型是“二进制数据”。这会导致API网关传递未处理的响应。指示REST API然而,随着Cloudformation要做到这一点,是有点本身就是一个兔子洞,这里的解决方案:
RestApi:
Type: 'AWS::ApiGateway::RestApi'
Properties:
Name: !Sub 'agraNcdx${Environment}'
BinaryMediaTypes:
- 'application~1json'
>“但它在文档中提到”。你能把我指向那个文档页面吗?我想我遇到了同样的问题 – spg
实际上,我不确定它的特色有多显着 - 它们只是提到“默认情况下,RestApi只支持utf-8文本”作为binaryMediaTypes文档的旁注,例如: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings.html和https://docs.aws.amazon.com/apigateway/api-reference/resource/rest- api /(搜索“UTF-8编码文本”) –
我不相信CloudFront的做任何转换,在这里,但你可以把它完全脱离通过将API部署为区域而不是边缘优化来实现循环。有一点,API网关不支持'Transfer-Encoding:chunked'响应,当你看到'Accept-Encoding:gzip'时,你的起源可能会切换到这个响应,因为分块传输编码会允许你的源流传输gzip响应而不是缓冲直到gzip响应的“Content-Length”已知。什么是'无效块类型' - 在实际响应体中,curl的控制台错误或错误消息? –
“无效块类型”是当无法有效解压缩响应时curl对“curl --compressed”所说的内容。将结果配置为'gunzip'也不起作用。 –
我认为我之前确定的解决方法是在集成请求中设置“Accept-Encoding:identity”的静态请求标头,但我一直未能找到答案,我不确定当前状态事务就像API网关和流式响应一样。您所描述的行为听起来并不熟悉,即使这样做达到了目的,也可能不是最佳解决方案,因为事情可能已经改变。 –