您正在查看的是 Apigee Edge 文档。
转到 Apigee X 文档。 信息
问题
客户端应用收到包含消息 The plain HTTP request was sent to HTTPS port
的 HTTP 400 Bad Request
响应。
错误消息
客户端应用会获得以下响应代码:
HTTP/1.1 400 Bad Request
后跟以下 HTML 错误页面:
<html> <head><title>400 The plain HTTP request was sent to HTTPS port</title></head> <body> <center><h1>400 Bad Request</h1></center> <center>The plain HTTP request was sent to HTTPS port</center> </body> </html>
可能的原因
原因 | 说明 | 适用的问题排查说明 |
---|---|---|
向配置了 TLS 的虚拟主机的 HTTP 请求 | 客户端向配置了 TLS 的虚拟主机发送 HTTP 请求 | Edge 公有云和私有云用户 |
向已配置 TLS 的目标端点的 HTTP 请求 | 向目标端点中已启用 TLS 的后端服务器发出的 HTTP 请求。 | Edge 公有云和私有云用户 |
目标服务器配置不正确 | 目标服务器配置了安全端口 443 ,但未启用 SSL。 |
Edge 公有云和私有云用户 |
原因:向配置了 TLS 的虚拟主机发出 HTTP 请求
当客户端尝试连接到 Apigee 上的 API 时,如果上述虚拟主机配置为使用 SSL 并接收 HTTP 请求,就会出现此错误。
诊断
由于此问题发生在 北向端点上,并且 API 请求在客户端应用与路由器之间的入口点交互时失败,因此这些错误消息不会记录在 NGINX 路由器访问日志中。因此,API 监控和跟踪工具等工具不会捕获这些请求。
-
验证您的 API 请求,看看您是否针对配置为仅接受安全端口
443
上的请求的主机别名发出 HTTP 请求。如果是,这就是导致问题的原因。错误 API 请求示例:
curl http://org-test.apigee.net:443/400-demo
<html> <head><title>400 The plain HTTP request was sent to HTTPS port</title></head> <body> <center><h1>400 Bad Request</h1></center> <center>The plain HTTP request was sent to HTTPS port</center> <hr><center>server</center> </body> </html>
- 请注意,在上述示例请求中,系统会对安全端口
443
上的主机别名myorg-test.apigee.net
发出 HTTP 请求。这就是导致400 Bad Request
错误的原因。
分辨率
您需要验证客户端使用的是 HTTP 而不是 HTTPS,然后发出正确的请求,如下所示:
示例 API 请求:
curl https://org-test.apigee.net:443/400-demo
或
curl https://org-test.apigee.net/400-demo
< HTTP/1.1 200 OK < Date: Thu, 25 Feb 2021 13:01:43 GMT < Content-Type: text/xml;charset=UTF-8 < Content-Length: 403 < Connection: keep-alive < Server: gunicorn/19.9.0 < Access-Control-Allow-Origin: * < Access-Control-Allow-Credentials: true
原因:向已配置 TLS 的目标端点的 HTTP 请求
如果您在 API 代理的目标端点中错误地配置了向已启用 TLS 的后端服务器的 HTTP 请求,就会出现此错误。
诊断
请按照以下步骤使用跟踪工具诊断错误:
- 在 Apigee 界面中为受影响的 API 代理启用 Trace。
- 向 API 代理发出请求。
- 选择其中一个失败并返回
400
响应代码的 API 请求。 - 浏览各个阶段,确定发生故障的位置。
-
通常,您将看到来自后端服务器的
400
错误响应。也就是说,您会在从目标服务器接收到的响应阶段中看到400
错误响应,如下所示: -
通过点击跟踪记录中的 AX(已记录的 Analytics 数据)图标,确定为其发出请求的目标端点。
- 注意 target.url,其中包含协议、后端服务器主机别名,有时还包括端口号。目标网址使用的端口是
443
,但协议是 HTTP。 - 查看目标端点的定义以了解配置。
-
验证后端服务器主机是否安全,并监听安全端口(例如
443
)。如果您在<URL>
元素中将协议用作http
,这就是导致此问题的原因。目标端点配置示例:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <TargetEndpoint name="default"> <Description/> <FaultRules/> <PreFlow name="PreFlow"> <Request/> <Response/> </PreFlow> <PostFlow name="PostFlow"> <Request/> <Response/> </PostFlow> <Flows/> <HTTPTargetConnection> <Properties/> <URL>http://somehost.org:443/get</URL> </HTTPTargetConnection> </TargetEndpoint>
上面的示例显示您使用的是 HTTP 协议,但使用的端口是安全端口
443
。这会导致后端服务器返回400 Bad Request
和错误消息The plain HTTP request was sent to HTTPS port
。
分辨率
-
如果您的后端服务器已启用安全/TLS,请确保在目标端点的
<URL>
元素中使用https
作为协议,如以下示例所示:目标端点配置示例:
<HTTPTargetConnection> <Properties/> <URL>https://somehost.org:443/get</URL> </HTTPTargetConnection>
-
如果您的后端服务器不安全,则:
- 请勿提及安全端口号,例如
443
。 - 如果您的后端服务器监听标准非安全端口,则您根本不必提及端口号
- 如果您使用的是任何其他不安全的端口,请注明端口号,例如:
9080
目标端点配置示例:
<HTTPTargetConnection> <Properties/> <URL>http://somehost.org/get</URL> </HTTPTargetConnection> or <HTTPTargetConnection> <Properties/> <URL>http://somehost.org:9080/get</URL> </HTTPTargetConnection>
- 请勿提及安全端口号,例如
原因:目标服务器配置不正确
如果目标服务器配置了安全端口(例如 443
)但未启用 SSL,则会导致 Apigee Edge 的消息处理器将 HTTP 请求发送到安全或已配置 TLS 的目标服务器,从而导致此问题。
诊断
请按照以下步骤使用跟踪工具诊断错误:
- 在 Apigee 界面中为受影响的 API 代理启用 Trace。
- 向 API 代理发出请求。
- 选择其中一个失败并返回
400
响应代码的 API 请求。 - 浏览各个阶段,确定发生故障的位置。
-
通常,您将看到来自后端服务器的
400
错误响应。也就是说,您会在从目标服务器接收到的响应阶段中看到400
错误响应,如下所示: -
通过点击跟踪记录中的 AX(已记录的 Analytics 数据)图标,确定为其发出请求的目标端点。
-
请注意 target.name,它表示目标端点名称。
在上述跟踪文件示例中,target.name 为 default。这表示用于此请求的目标端点是默认端点。
-
查看目标端点的定义以了解配置。
目标端点配置示例:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <TargetEndpoint name="default"> <Description/> <FaultRules/> <PreFlow name="PreFlow"> <Request/> <Response/> </PreFlow> <PostFlow name="PostFlow"> <Request/> <Response/> </PostFlow> <Flows/> <HTTPTargetConnection> <Properties/> <LoadBalancer> <Server name="faulty-target"/> </LoadBalancer> </HTTPTargetConnection> </TargetEndpoint>
上面的目标端点配置示例显示,您正在使用名为
faulty-target
的目标服务器。 -
获得目标服务器名称后,您可以使用以下任一方法检查目标服务器配置:
- Edge 界面
- Management API
Edge 界面
- 依次转到 Apigee Edge > 管理 > 环境 > 目标服务器。
- 选择从 API 代理中标识的特定目标服务器,然后点击 修改。
- 请验证为目标服务器指定的端口和 SSL 信息。
-
如果目标服务器配置了安全端口(例如:
443
),但未启用 SSL,则这就是导致此问题的原因。如上面的屏幕截图所示,使用的端口为
443
,但在目标服务器配置中未为该端口启用 SSL。这会使 Apigee Edge 的消息处理器将 HTTP 请求发送到安全端口443
。因此,您会收到错误400 Bad Request
和The plain HTTP request was sent to HTTPS port
消息。
Management API
-
执行 获取目标服务器 API,以获取有关特定目标服务器配置的详细信息,如下所示:
公有云用户:
curl -v 'https://api.enterprise.apigee.com/v1/organizations/ORG_NAME/environments/ENV_NAME>/targetservers/TARGET_SERVER_NAME' \ -H "Content-Type:application/xml" \ -H "Authorization:Bearer $TOKEN"
Private Cloud 用户:
curl -v 'http://MANAGEMENT_IP:8080/v1/organizations/ORG_NAME/environments/ENV_NAME/targetservers/TARGET_SERVER_NAME' \ -H "Content-Type:application/xml" \ -H "Authorization:Bearer $TOKEN"
- 请验证为目标服务器指定的端口和 SSL 信息。
-
如果目标服务器配置了安全端口(例如:
443
),但未定义SSLInfo
部分或未启用该部分,则这就是导致此问题的原因。目标服务器配置示例:
{ "host" : "somehost.org", "isEnabled" : true, "name" : "faulty-target", "port" : 443 }
在上面的示例输出中,我们可以看到用于目标连接的端口是
443
,但没有SSLInfo
配置块。这会使 Apigee Edge 的消息处理器将 HTTP 请求发送到安全端口
443
。因此,您会收到错误400 Bad Request
和The plain HTTP request was sent to HTTPS port
消息。
分辨率
如果您的目标服务器是安全的或配置了 TLS,则需要为特定目标服务器启用 SSL。
您可以使用以下选项之一执行此操作:
- Edge 界面
- Management API
Edge 界面
- 通过 Edge UI > Admin > Environments > Target Servers 导航到目标服务器。
- 选择特定的目标服务器,然后点击 Edit。
- 如果您的目标服务器是安全的且使用
443
等端口,请选中 SSL 选项旁边的复选框以启用 SSL。 - 配置 Truststore、Ciphers 和 Protocol。(仅在必要时)
Management API
使用 Management API 按照 更新目标服务器配置文档中的说明配置目标服务器。
必须收集的诊断信息
如果按照上述说明操作后,问题仍然存在,请收集以下诊断信息,然后联系 Apigee Edge 支持团队。
- 如果您是公有云用户,请提供以下信息:
- 组织名称
- 环境名称
- API 代理名称
- 完成 curl 命令以重现错误
- 跟踪工具输出(如果您已捕获失败请求)
- 如果您是 Private Cloud 用户,请提供以下信息:
- 观察到完整的错误消息
- 环境名称
- API 代理软件包
- 目标服务器定义(如果您在端点中使用目标服务器)
- 跟踪工具输出(如果您已捕获失败请求)