Amazon web services AWS Api网关代理压缩“;无效的块类型";
我将Api网关端点设置为Amazon web services AWS Api网关代理压缩“;无效的块类型";,amazon-web-services,gzip,aws-api-gateway,Amazon Web Services,Gzip,Aws Api Gateway,我将Api网关端点设置为HTTP\U代理,只要不提供Accept Encoding:gzip头,它就可以正常工作。然后它失败了。似乎Api网关正在对响应执行“某些操作”,使其在接收端无法识别 这就是我所看到的: 将请求直接发送到代理后端会按预期工作(例如,curl--compressed成功完成) 使用curl--compressed(和其他方式)通过Api网关发送请求会导致“无效块类型” 来自代理服务器的响应是17514字节,而通过Api网关,它已被放大到31506字节。这反映在内容长度标题
HTTP\U代理
,只要不提供Accept Encoding:gzip
头,它就可以正常工作。然后它失败了。似乎Api网关正在对响应执行“某些操作”,使其在接收端无法识别
这就是我所看到的:
- 将请求直接发送到代理后端会按预期工作(例如,
成功完成)curl--compressed
- 使用
(和其他方式)通过Api网关发送请求会导致“无效块类型”curl--compressed
- 来自代理服务器的响应是17514字节,而通过Api网关,它已被放大到31506字节。这反映在
标题中内容长度
- Api网关包含带有旧(正确)值的
头,因此它似乎知道它对响应做了什么x-amzn-Remapped-Content-Length
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网关指示任何映射。该UI也不指示任何响应映射
在测试Api时,我看到以下内容:
- 响应标题包括
,这是预期值“内容长度”:“17514”
- 从日志来看,端点响应体和方法响应体似乎是相同的,尽管手动比较gzip数据的两个乱码ascii表示有点困难。两个
标题也相同内容长度
x-amzn-remapped-content-length
标题也不可见。这让我怀疑这可能是Cloudfront做的
我通过“执行api”和这个api的自定义域映射得到了相同的结果
有什么建议吗?正如Michael在他的一条(非常有用的)评论中所怀疑的那样-这确实是API网关将我的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'
我不相信CloudFront会进行任何转换,但您可以通过将API部署为区域而不是边缘优化,将其完全排除在循环之外。API网关一度不支持
传输编码:分块的响应,当看到Accept Encoding:gzip
时,您的源站可能会切换到它,因为分块传输编码将允许您的源站流化gzip响应,而不是缓冲它,直到gzip响应的内容长度
已知为止。什么是invalid block type
——来自curl的控制台错误或实际响应正文中的错误消息?“invalid block type”是当响应无法有效解压缩时curl对curl--compressed
所说的。将结果传送到gunzip
也不起作用。我认为我之前确定的解决方法是在集成请求中设置一个静态请求头Accept Encoding:identity
,但我还没有找到答案,我也不确定API网关和流式响应的当前状态。您所描述的行为听起来并不熟悉,因此即使实现了目的,它也可能不是最佳解决方案,因为事情可能已经发生了变化。它所做的事情听起来像是将二进制有效负载强制转换为UTF-8,这可能会替换任何识别为无效字符的内容(并非所有的八位字节序列都代表有效的UTF-8)使用� Unicode替换字符,具有字节0xEF
0xBF
0xBD
,肯定会扰乱您的gzip流。非常感谢@Michael sqlbot!这确实是响应的utf-8编码-请参阅下面我自己的答案。>“但文档中提到了它”。你能给我指一下那个文档页面吗?我想我也遇到了同样的问题。事实上,我不确定它的功能有多突出-他们只是在binaryMediaTypes文档中提到“默认情况下RestApi只支持utf-8文本”,例如:和(搜索“utf-8编码文本”)