您正在查看 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 格式。 |
| 单次编码 | deflate | 此格式使用 |
| 多重编码 | 多重编码 例如,如果编码执行两次,则可能出现以下情况:
|
按标头中显示的顺序对载荷应用了多种编码。 |
造成此错误的可能原因如下:
| 原因 | 说明 | 适用的问题排查说明 |
|---|---|---|
| 请求载荷格式与 Content-Encoding 标头中指定的编码不匹配 | 客户端发送的请求载荷的格式未经过编码,或者与 Content-Encoding 标头中指定的编码不匹配。 |
Edge Public 和 Private Cloud 用户 |
常见诊断步骤
您可以使用以下工具/方法来诊断此错误:
API 监控
如需使用 API 监控功能诊断错误,请执行以下操作:
- 以具有 适当角色的用户身份 登录 Apigee Edge 界面。
切换到您要调查问题的组织。
- 前往分析 > API 监控 > 调查页面。
- 选择您发现错误的具体时间范围。
- 确保将代理过滤条件设置为全部。
- 绘制故障代码与时间的对比图。
选择具有故障代码
messaging.adaptors.http.flow.DecompressionFailureAtRequest的电池,如下所示:( 查看放大图片)
系统会显示有关故障代码
messaging.adaptors.http.flow.DecompressionFailureAtRequest的信息,如下所示:( 查看放大图片)
点击查看日志,然后展开因
400错误而失败的行。( 查看放大图片)
- 在日志窗口中,记下以下详细信息:
- 状态代码:
400 - 故障来源:
proxy - 故障代码:
messaging.adaptors.http.flow.DecompressionFailureAtRequest。
- 状态代码:
- 如果 Fault Source 的值为
proxy,则表示请求载荷格式与Content-Encoding标头中指定的 支持的编码不匹配。
Trace 工具
如需使用 Trace 工具诊断错误,请执行以下操作:
- 启用跟踪会话,然后执行以下任一操作:
- 等待
400 Bad Request错误发生,或 - 如果您可以重现该问题,请进行 API 调用并重现
400 Bad Request。
- 等待
确保已启用显示所有 FlowInfo:
- 选择一个失败的请求,然后检查轨迹。
- 浏览轨迹的不同阶段,找到发生故障的位置。
您通常会在收到来自客户端的请求阶段之后的流程中发现该错误,如下所示:
( 查看放大图片)
-
请记下轨迹中属性的值:
- 错误:
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 返回的状态代码和错误消息,方法是前往
到轨迹中的发送给客户端的响应阶段,如下所示:
( 查看放大图片)
请注意轨迹中的以下详细信息:
- 状态代码:
400 Bad Request。 - 错误内容:
{"fault":{"faultstring":"Decompression failure at request","detail":{"errorcode":"messaging.adaptors.http.flow.DecompressionFailureAtRequest"}}}
- 状态代码:
在轨迹中找到 AX(记录的分析数据)阶段,然后点击它。
- 向下滚动到阶段详情、错误标头部分,并确定 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.DecompressionFailureAtRequestX-Apigee-fault-source policy
NGINX
如需使用 NGINX 访问日志诊断错误,请执行以下操作:
- 如果您是私有云用户,则可以使用 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-source 值:
响应标头 值 X-Apigee-fault-code messaging.adaptors.http.flow.DecompressionFailureAtRequestX-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 进行验证,请执行以下操作:
- 使用 Trace 确定请求标头 Content-Encoding 和属性 error.cause 的值,如常见诊断步骤中所述。
示例轨迹中的值如下所示:
- Content-Encoding:
gzip - error.cause::
Not in GZIP format
请求标头 Content-Encoding 中的值为 gzip;但是,请求载荷不是 GZIP 格式(如 error.cause 所示)。因此,Apigee Edge 会返回
400 Bad Request和错误代码messaging.adaptors.http.flow.DecompressionFailureAtRequest。- Content-Encoding:
实际请求
如需使用实际请求进行验证,请执行以下操作:
如果您有权访问客户端应用发出的实际请求,请执行以下步骤:
- 确定传递给请求标头
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。
消息处理器日志
如需使用消息处理器日志进行验证,请执行以下操作:
如果您是私有云用户,则可以使用消息处理器日志来确定有关 HTTP
400错误的关键信息。- 使用 API 监控、Trace 工具或 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() : Exceptionjava.util.zip.ZipException: Not in GZIP formatoccurred 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 会抛出异常,并向客户端应用返回400状态代码和故障代码messaging.adaptors.http.flow.DecompressionFailureAtRequest。情景 #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 会抛出异常,并向客户端应用返回400状态代码和故障代码messaging.adaptors.http.flow.DecompressionFailureAtRequest。
-
分辨率
- 如果 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 请求的轨迹文件
如果您是私有云用户,请提供以下信息:
- 失败请求的完整错误消息
- 环境名称
- 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