400 请求错误 - 向 HTTP 端口发送的普通 HTTP 请求

您正在查看的是 Apigee Edge 文档。
转到 Apigee X 文档
信息

问题

客户端应用收到包含消息 The plain HTTP request was sent to HTTPS portHTTP 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 监控和跟踪工具等工具不会捕获这些请求。

  1. 验证您的 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>
    
  2. 请注意,在上述示例请求中,系统会对安全端口 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 请求,就会出现此错误。

诊断

请按照以下步骤使用跟踪工具诊断错误:

  1. 在 Apigee 界面中为受影响的 API 代理启用 Trace
  2. 向 API 代理发出请求。
  3. 选择其中一个失败并返回 400 响应代码的 API 请求。
  4. 浏览各个阶段,确定发生故障的位置。
  5. 通常,您将看到来自后端服务器的 400 错误响应。也就是说,您会在从目标服务器接收到的响应阶段中看到 400 错误响应,如下所示:

  6. 通过点击跟踪记录中的 AX(已记录的 Analytics 数据)图标,确定为其发出请求的目标端点。

  7. 注意 target.url,其中包含协议、后端服务器主机别名,有时还包括端口号。目标网址使用的端口是 443,但协议是 HTTP。
  8. 查看目标端点的定义以了解配置。
  9. 验证后端服务器主机是否安全,并监听安全端口(例如 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

分辨率

  1. 如果您的后端服务器已启用安全/TLS,请确保在目标端点的 <URL> 元素中使用 https 作为协议,如以下示例所示:

    目标端点配置示例

    <HTTPTargetConnection>
        <Properties/>
        <URL>https://somehost.org:443/get</URL>
    </HTTPTargetConnection>
    
  2. 如果您的后端服务器不安全,则:

    • 请勿提及安全端口号,例如 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 的目标服务器,从而导致此问题。

诊断

请按照以下步骤使用跟踪工具诊断错误:

  1. 在 Apigee 界面中为受影响的 API 代理启用 Trace
  2. 向 API 代理发出请求。
  3. 选择其中一个失败并返回 400 响应代码的 API 请求。
  4. 浏览各个阶段,确定发生故障的位置。
  5. 通常,您将看到来自后端服务器的 400 错误响应。也就是说,您会在从目标服务器接收到的响应阶段中看到 400 错误响应,如下所示:

  6. 通过点击跟踪记录中的 AX(已记录的 Analytics 数据)图标,确定为其发出请求的目标端点。

  7. 请注意 target.name,它表示目标端点名称。

    在上述跟踪文件示例中,target.namedefault。这表示用于此请求的目标端点是默认端点。

  8. 查看目标端点的定义以了解配置。

    目标端点配置示例

    <?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 的目标服务器。

  9. 获得目标服务器名称后,您可以使用以下任一方法检查目标服务器配置:

    • Edge 界面
    • Management API

Edge 界面

  1. 依次转到 Apigee Edge > 管理 > 环境 > 目标服务器
  2. 选择从 API 代理中标识的特定目标服务器,然后点击 修改
  3. 请验证为目标服务器指定的端口和 SSL 信息。
  4. 如果目标服务器配置了安全端口(例如:443),但未启用 SSL,则这就是导致此问题的原因。

    如上面的屏幕截图所示,使用的端口为 443,但在目标服务器配置中未为该端口启用 SSL。这会使 Apigee Edge 的消息处理器将 HTTP 请求发送到安全端口 443。因此,您会收到错误 400 Bad RequestThe plain HTTP request was sent to HTTPS port 消息。

Management API

  1. 执行 获取目标服务器 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"
    
  2. 请验证为目标服务器指定的端口和 SSL 信息。
  3. 如果目标服务器配置了安全端口(例如:443),但未定义 SSLInfo 部分或未启用该部分,则这就是导致此问题的原因。

    目标服务器配置示例

    {
      "host" : "somehost.org",
      "isEnabled" : true,
      "name" : "faulty-target",
      "port" : 443
    }
    

    在上面的示例输出中,我们可以看到用于目标连接的端口是 443,但没有 SSLInfo 配置块。

    这会使 Apigee Edge 的消息处理器将 HTTP 请求发送到安全端口 443。因此,您会收到错误 400 Bad RequestThe plain HTTP request was sent to HTTPS port 消息。

分辨率

如果您的目标服务器是安全的或配置了 TLS,则需要为特定目标服务器启用 SSL。

您可以使用以下选项之一执行此操作:

  • Edge 界面
  • Management API

Edge 界面

  1. 通过 Edge UI > Admin > Environments > Target Servers 导航到目标服务器。
  2. 选择特定的目标服务器,然后点击 Edit
  3. 如果您的目标服务器是安全的且使用 443 等端口,请选中 SSL 选项旁边的复选框以启用 SSL。
  4. 配置 TruststoreCiphersProtocol。(仅在必要时)

Management API

使用 Management API 按照 更新目标服务器配置文档中的说明配置目标服务器。

必须收集的诊断信息

如果按照上述说明操作后,问题仍然存在,请收集以下诊断信息,然后联系 Apigee Edge 支持团队

  1. 如果您是公有云用户,请提供以下信息:
    • 组织名称
    • 环境名称
    • API 代理名称
    • 完成 curl 命令以重现错误
    • 跟踪工具输出(如果您已捕获失败请求)
  2. 如果您是 Private Cloud 用户,请提供以下信息:
    • 观察到完整的错误消息
    • 环境名称
    • API 代理软件包
    • 目标服务器定义(如果您在端点中使用目标服务器)
    • 跟踪工具输出(如果您已捕获失败请求)