您正在查看的是 Apigee Edge 文档。
转到 Apigee X 文档。 信息
问题
客户端应用收到 HTTP 状态代码 400 Bad Request
且错误代码为 messaging.adaptors.http.flow.DecompressionFailureAtRequest
,作为对 API 调用的响应。
错误消息
客户端应用会获得以下响应代码:
HTTP/1.1 400 Bad Request
此外,您可能还会看到类似于如下所示的错误消息:
{ "fault":{ "faultstring":"Decompression failure at request", "detail":{ "errorcode":"messaging.adaptors.http.flow.DecompressionFailureAtRequest" } } }
可能的原因
只有在以下情况下,才会发生此错误:
- HTTP 请求标头
Content-Encoding
中指定的编码有效且 受 Apigee Edge 支持, - 客户端作为 HTTP 请求的一部分发送的载荷格式与
Content-Encoding
标头中指定的编码格式不匹配
但是
这是因为 Apigee Edge 无法使用指定编码对载荷进行解码,因为载荷格式与 Content-Encoding
标头中指定的编码格式不同。
下面列举了一些示例来说明支持的 Content-Encoding
值,以及 Apigee Edge 在这些情况下预期载荷格式:
场景 | Content-Encoding | 预期的载荷格式 |
---|---|---|
单一编码 | gzip | Unix 请参阅 RFC1952 GZIP 格式。 |
单一编码 | 压缩 | 此格式搭配使用 |
多种编码 | 多种编码 例如,如果编码进行了两次,则可能发生以下情况:
|
按照标头中显示的指定顺序对载荷应用多种编码。 |
导致此错误的可能原因如下:
原因 | 说明 | 适用的问题排查说明 |
---|---|---|
请求载荷格式与 Content-Encoding 标头中指定的编码不匹配 | 客户端发送的请求载荷的格式未编码,或与 Content-Encoding 标头中指定的编码不匹配。 |
Edge 公有云和私有云用户 |
常见诊断步骤
使用以下工具/技巧之一来诊断此错误:
API 监控
要使用 API Monitoring 诊断错误,请执行以下操作:
- 以拥有 适当角色的用户身份 登录 Apigee Edge 界面。
切换到您要调查问题的组织。
- 前往 Analyze > API Monitoring > Investigate 页面。
- 选择您发现错误的具体时间范围。
- 确保将代理过滤器设置为全部。
- 根据时间绘制故障代码。
选择具有错误代码
messaging.adaptors.http.flow.DecompressionFailureAtRequest
的单元格,如下所示:( 查看大图)
错误代码
messaging.adaptors.http.flow.DecompressionFailureAtRequest
的相关信息如下所示:( 查看大图)
点击查看日志,然后展开失败并显示
400
错误的行。( 查看大图)
- 在日志窗口中,请注意以下详细信息:
- 状态代码:
400
- 错误来源:
proxy
- 错误代码:
messaging.adaptors.http.flow.DecompressionFailureAtRequest
。
- 状态代码:
- 如果故障来源的值为
proxy
,则表示请求载荷格式与Content-Encoding
标头中指定的 支持的编码不匹配。
跟踪工具
如需使用跟踪工具诊断错误,请执行以下操作:
- 启用跟踪会话,并执行以下任一操作:
- 等待
400 Bad Request
错误发生,或者 - 如果您可以重现问题,请发出 API 调用并重现
400 Bad Request
。
- 等待
确保已启用 Show all FlowInfos:
- 选择其中一个失败的请求并检查跟踪记录。
- 浏览跟踪记录的不同阶段,并找到发生故障的位置。
您通常会在 Request Received from Client 阶段后立即在流程中发现错误,如下所示:
( 查看大图)
-
请注意跟踪记录中的属性值:
- 错误:
Decompression failure at request
- error.class:
com.apigee.rest.framework.BadRequestException
- error.cause::
Not in GZIP format
error.cause 声明请求负载不是 GZIP 格式。这意味着 Apigee Edge 期望请求载荷采用 GZIP 格式,因为它在
Content-Encoding
标头中已指定。 - 错误:
确定请求标头
Content-Encoding
的值。 为此,请转到 Request Received from Client 阶段,如下所示:( 查看大图)
请注意,请求标头
Content-Encoding
的值确实是gzip
。上面的示例轨迹显示,请求标头
Content-Encoding
中指定的编码为gzip
;但是,请求载荷未采用 GZIP 格式。因此,Apigee 无法使用 gzip 解压缩载荷,并返回错误Decompression failure at request
。- 查看 Apigee Edge 返回的状态代码和错误消息。
进入跟踪记录中的 Response Sent to Client 阶段,如下所示:
( 查看大图)
请注意跟踪记录中的以下详细信息:
- 状态代码:
400 Bad Request
。 - 错误内容:
{"fault":{"faultstring":"Decompression failure at request","detail":{"errorcode":"messaging.adaptors.http.flow.DecompressionFailureAtRequest"}}}
- 状态代码:
进入跟踪记录中的 AX(已记录的 Analytics 数据)阶段并点击该阶段。
- 向下滚动到 Phase Details(阶段详细信息)和 Error Headers(错误标头)部分,并确定 X-Apigee-fault-code 和 X-Apigee-fault-source 的值,如下所示:
( 查看大图)
- 您将看到 X-Apigee-fault-code 和 X-Apigee-fault-source 的值为
messaging.adaptors.http.flow.DecompressionFailureAtRequest
和policy
,这表明请求载荷格式与Content-Encoding
标头中指定的编码不匹配。响应标头 值 X-Apigee-fault-code messaging.adaptors.http.flow.DecompressionFailureAtRequest
X-Apigee-fault-source policy
NGINX
如需使用 NGINX 访问日志诊断错误,请执行以下操作:
- 如果您是 Private Cloud 用户,则可以使用 NGINX 访问日志来确定有关 HTTP
400
错误的关键信息。 检查 NGINX 访问日志:
/opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log
其中:将 ORG、ENV 和 PORT# 替换为实际值。
- 搜索以查看在特定持续时间内是否存在任何
400
错误(如果问题是在过去发生的),或者是否有任何请求仍然失败并显示400
。 如果您确实发现任何
400
错误且 X-Apigee-fault-code 与messaging.adaptors.http.flow.DecompressionFailureAtRequest
的值匹配,请确定 X-Apigee-fault-source 的值。NGINX 访问日志中的 400 错误示例:
NGINX 访问日志中的上述示例条目具有 X-Apigee-fault-code 和 X-Apigee-fault-code 的以下值:
响应标头 值 X-Apigee-fault-code messaging.adaptors.http.flow.DecompressionFailureAtRequest
X-Apigee-fault-source policy
原因:请求载荷格式与 Content-Encoding 标头中指定的编码不匹配
默认情况下,如果请求标头 Content-Encoding
包含有效且
支持的编码,则 Apigee Edge 始终会解压缩载荷。因此,请求载荷的格式应与请求标头 Content-Encoding
中指定的编码匹配。如果不相符,会收到此错误。
诊断
- 按照常见诊断步骤中所述,使用 API 监控、Trace 工具或 NGINX 访问日志确定观察到的错误的故障代码和故障来源。
- 如果故障代码为
messaging.adaptors.http.flow.DecompressionFailureAtRequest
且故障来源的值为policy
或proxy
,则表示客户端应用发送的请求所包含的载荷与请求标头Content-Encoding
中指定的 支持的编码不匹配。 您可以使用以下方法之一确定 HTTP 请求中的不匹配情况:
错误消息
如需使用错误消息进行验证,请执行以下操作:
-
如果您有权访问从 Apigee Edge 收到的完整错误消息,请参阅
faultstring
。示例错误消息:
"faultstring":"Decompression failure at request"
- 在上述错误消息中,它显示了
"Decompression failure at request"
,这意味着无法使用Content-Encoding
标头中指定的编码解压缩请求。
跟踪记录
如需使用 Trace 进行验证,请执行以下操作:
实际请求
如需使用实际请求进行验证,请执行以下操作:
如果您有权访问客户端应用发出的实际请求,请执行以下步骤:
- 确定传递给请求标头
Content-Encoding
的值。 - 确定作为请求一部分发送的载荷格式。
如果
Content-Encoding
标头的值包含在 支持的编码列表中,但请求载荷的格式与Content-Encoding
标头中指定的编码不匹配,那么这就是导致问题的原因。示例请求:
curl -v "http://HOSTALIAS/v1/testgzip"
-H "Content-Encoding: gzip"
-X POST -d @request_payload.zip上面的示例请求将值
gzip
发送到Content-Encoding
标头,该标头是 Apigee Edge 中 支持的编码。但是,请求载荷request_payload.zip
采用 ZIP 格式。因此,此请求将失败,并显示400 Bad Request
状态代码和错误代码:messaging.adaptors.http.flow.DecompressionFailureAtRequest
。
消息处理器日志
如需使用消息处理器日志进行验证,请执行以下操作:
如果您是 Private Cloud 用户,则可以使用消息处理器日志来确定有关 HTTP
400
错误的关键信息。- 使用 API 监控、跟踪工具或 NGINX 访问日志来确定失败请求的消息 ID,如常见诊断步骤中所述。
在消息处理器日志中搜索消息 ID:
/opt/apigee/var/log/edge-message-processor/logs/system.log
您会看到以下例外情况之一:
情景 #1
场景 1:当 API 请求的标头包含 Content-Encoding: gzip 时
2021-07-28 10:21:16,861 NIOThread@0 ERROR HTTP.SERVER - HTTPServer$Context.onInputException() : Message id:rt-57-1 SSLClientChannel[Accepted: Remote:192.168.199.8:8443 Local:192.168.80.234:44284]@28469 useCount=1 bytesRead=0 bytesWritten=28764 age=2739893ms lastIO=0ms isOpen=true.onExceptionRead exception: {} java.util.zip.ZipException: Not in GZIP format 2021-07-28 10:21:16,862 NIOThread@0 ERROR ADAPTORS.HTTP.FLOW - AbstractRequestListener.onException() : Request:POST, uri:/test, message Id:rt-57-1, exception:java.util.zip.ZipException: Not in GZIP format, context:Context@71ea5ac input=ClientInputChannel(SSLClientChannel[Accepted: Remote:192.168.199.8:8443 Local:192.168.80.234:44284]@28469 useCount=1 bytesRead=0 bytesWritten=28764 age=2739894ms lastIO=0ms isOpen=true) 2021-07-28 10:21:16,862 NIOThread@0 INFO HTTP.SERVICE - ExceptionHandler.handleException() : Exception
java.util.zip.ZipException: Not in GZIP format
occurred while writing to channel null 2021-07-28 10:21:16,863 NIOThread@0 INFO HTTP.SERVICE - ExceptionHandler.handleException() : Exception trace: java.util.zip.ZipException: Not in GZIP format上述错误消息中的
java.util.zip.ZipException: Not in GZIP format
行表示虽然Content-Encoding
指定为 gzip,但请求载荷却没有以 GZIP 格式发送。因此,Apigee Edge 会抛出异常,并向客户端应用返回包含错误代码messaging.adaptors.http.flow.DecompressionFailureAtRequest
的400
状态代码。情景 #2
场景 2:当 API 请求的标头包含 Content-Encoding: deflate 时
2021-07-28 15:26:31,893 NIOThread@1 ERROR HTTP.SERVER - HTTPServer$Context.onInputException() : Message id:rt-47875-1 SSLClientChannel[Accepted: Remote:192.168.199.8:8443 Local:192.168.81.72:45954]@29276 useCount=1 bytesRead=0 bytesWritten=37230 age=3498856ms lastIO=1ms isOpen=true.onExceptionRead exception: {}
java.util.zip.ZipException: incorrect header check
….Caused by: java.util.zip.DataFormatException: incorrect header check
.. 2021-07-28 15:26:31,894 NIOThread@1 ERROR ADAPTORS.HTTP.FLOW - AbstractRequestListener.onException() : Request:POST, uri:/test, message Id:rrt-47875-1, exception:java.util.zip.ZipException: incorrect header check, context:Context@69b3ac45 input=ClientInputChannel(SSLClientChannel[Accepted: Remote:192.168.199.8:8443 Local:192.168.81.72:45954]@29276 useCount=1 byt esRead=0 bytesWritten=37230 age=3498856ms lastIO=1ms isOpen=true)上述错误消息中的
java.util.zip.ZipException: incorrect header check
和Caused by: java.util.zip.DataFormatException: incorrect header check
行表示请求载荷不是以 deflate 格式发送的,并且与 deflate 的Content-Encoding
标头中指定的编码不匹配。因此,Apigee Edge 会抛出异常,并向客户端应用返回包含错误代码messaging.adaptors.http.flow.DecompressionFailureAtRequest
的400
状态代码。
-
分辨率
- 如果 Apigee Edge 和后端服务器中的 API 代理流程不需要压缩的请求载荷,则不要传递标头
Content-Encoding
。如果需要压缩请求载荷,请转到第 2 步。 - 确保客户端应用始终发送以下内容:
- 任何
支持的编码作为请求中
Content-Encoding
标头的值 - 向 Apigee Edge 发送的请求载荷采用支持的格式与
Content-Encoding
标头中指定的编码格式一致
- 任何
支持的编码作为请求中
- 在上述示例中,请求载荷采用 ZIP 格式,但请求标头指定了
Content-Encoding: gzip
。如需解决此问题,您能够以Content-Encoding: gzip
的形式发送请求,并且请求载荷也以gzip
格式发送:curl -v "https://HOSTALIAS/v1/testgzip" -H "Content-Encoding: gzip" -X POST -d @request_payload.gz
规范
根据以下 RFC 规范,Apigee Edge 返回状态代码 400 Bad Request
和错误代码 messaging.adaptors.http.flow.DecompressionFailureAtRequest
:
规范 |
---|
RFC 7231,第 6.5.1 节 |
RFC 7231,第 3.1.2.2 节 |
如果您仍然需要 Apigee 支持部门的任何帮助,请参阅 必须收集诊断信息。
必须收集的诊断信息
收集以下诊断信息,然后联系 Apigee Edge 支持团队:
如果您是公有云用户,请提供以下信息:
- 组织名称
- 环境名称
- API 代理名称
- 完成用于重现
400
错误的curl
命令 - API 请求的跟踪文件
如果您是 Private Cloud 用户,请提供以下信息:
- 观察到失败请求的完整错误消息
- 环境名称
- API 代理软件包
- API 请求的跟踪文件
NGINX 访问日志
/opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log
其中:将 ORG、ENV 和 PORT# 替换为实际值。
- 消息处理器系统日志
/opt/apigee/var/log/edge-message-processor/logs/system.log