400 要求無效 - 傳送至 HTTPS 通訊埠的純 HTTP 要求

您目前查看的是 Apigee Edge 說明文件。
前往 Apigee X 說明文件
info

問題

用戶端應用程式會收到 HTTP 400 Bad Request 回應,其中包含訊息 The plain HTTP request was sent to HTTPS port

錯誤訊息

用戶端應用程式會取得下列回應代碼:

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 要求 用戶端將 HTTP 要求傳送至已設定 TLS 的虛擬主機 Edge 公有和私有雲使用者
對已設定 TLS 的目標端點發出 HTTP 要求 向目標端點中啟用 TLS 的後端伺服器發出 HTTP 要求。 Edge 公有和私有雲使用者
目標伺服器設定不正確 目標伺服器已設定安全通訊埠 443,但未啟用 SSL。 Edge 公有和私有雲使用者

原因:對已設定 TLS 的虛擬主機發出 HTTP 要求

當用戶端嘗試連線至 Apigee 上的 API,且上述虛擬主機已設定為使用 SSL,但收到的是 HTTP 要求時,就會發生這項錯誤。

診斷

由於這個問題發生在北向端點,且 API 要求在用戶端應用程式和路由器之間的進入點互動失敗,因此 NGINX 路由器存取記錄不會記錄這些錯誤訊息。因此,API Monitoring 和 Trace 工具等不會擷取這些要求。

  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 Proxy 的目標端點中,對啟用 TLS 的後端伺服器設定 HTTP 要求時發生錯誤,就會出現這項錯誤。

診斷

請按照下列步驟使用「追蹤」工具診斷錯誤:

  1. 在 Apigee 使用者介面中,為受影響的 API Proxy 啟用「追蹤」
  2. 對 API Proxy 提出要求。
  3. 選取其中一個失敗的 API 要求 (回應代碼為 400)。
  4. 瀏覽各個階段,找出發生失敗的位置。
  5. 通常您會看到後端伺服器傳回 400 錯誤回應。 也就是說,您會在「Response received from target server」(從目標伺服器收到回應) 階段看到 400 錯誤回應,如下所示:

  6. 在追蹤記錄中按一下「AX」(記錄的 Analytics 資料) 圖示 AX,即可判斷要求發送的目標端點。

  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 Proxy 啟用「追蹤」
  2. 對 API Proxy 提出要求。
  3. 選取其中一個失敗的 API 要求 (回應代碼為 400)。
  4. 瀏覽各個階段,找出發生失敗的位置。
  5. 通常您會看到後端伺服器傳回 400 錯誤回應。 也就是說,您會在「Response received from target server」階段看到 400 錯誤回應,如下所示:

  6. 在追蹤記錄中按一下「AX」(記錄的 Analytics 資料) 圖示 AX,即可判斷要求發送的目標端點。

  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 UI
    • Management API

Edge UI

  1. 依序前往「Apigee Edge」>「管理」>「環境」>「目標伺服器」
  2. 選擇從 API Proxy 識別出的特定目標伺服器,然後按一下「編輯」
  3. 確認目標伺服器指定的通訊埠和 SSL 資訊。
  4. 如果目標伺服器已設定安全通訊埠 (例如:443),但未啟用 SSL,這就是造成問題的原因。

    如上方的螢幕截圖所示,使用的通訊埠為 443,但目標伺服器設定中未啟用該通訊埠的 SSL。這會導致 Apigee Edge 的訊息處理器將 HTTP 要求傳送至安全通訊埠 443。因此,您會收到錯誤 400 Bad Request,並顯示訊息 The plain HTTP request was sent to HTTPS port

Management API

  1. 執行「Get target server」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 Request 錯誤,訊息為 The plain HTTP request was sent to HTTPS port

解析度

如果目標伺服器安全無虞或已設定傳輸層安全標準 (TLS),則必須為特定目標伺服器啟用 SSL。

您可以透過下列任一方式完成這項操作:

  • Edge UI
  • Management API

Edge UI

  1. 依序前往 Edge UI >「管理」>「環境」>「目標伺服器」,然後找到目標伺服器。
  2. 選擇特定目標伺服器,然後按一下「編輯」
  3. 如果目標伺服器安全無虞,且使用 443 等通訊埠,請選取 SSL 選項旁的核取方塊,啟用 SSL。
  4. 設定「Truststore」(信任儲存區)、「Ciphers」(密碼) 和「Protocols」(通訊協定)。(僅限必要時)

Management API

如要設定目標伺服器,請使用管理 API,詳情請參閱「 更新目標伺服器設定」說明文件。

必須收集診斷資訊

如果按照上述指示操作後問題仍未解決,請收集下列診斷資訊,然後與 Apigee Edge 支援團隊聯絡。

  1. 如果您是 Public Cloud 使用者,請提供下列資訊:
    • 機構名稱
    • 環境名稱
    • API Proxy 名稱
    • 完成 curl 指令,重現錯誤
    • 追蹤工具輸出內容 (如果可以擷取失敗要求)
  2. 如果您是 Private Cloud 使用者,請提供下列資訊:
    • 出現的完整錯誤訊息
    • 環境名稱
    • API Proxy 套裝組合
    • 目標伺服器定義 (如果您在端點中使用目標伺服器)
    • 追蹤工具輸出內容 (如果可以擷取失敗要求)