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

您正在查看 Apigee Edge 說明文件。
查看 Apigee X 說明文件
資訊

問題

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

錯誤訊息

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

HTTP/1.1 400 Bad Request

如下所示:

<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 Public and Private Cloud 使用者
傳送至 TLS 設定的目標端點的 HTTP 要求 對目標端點中已啟用 TLS 的後端伺服器傳送 HTTP 要求。 Edge Public and Private Cloud 使用者
目標伺服器設定不正確 目標伺服器已設定安全通訊埠 443,但未啟用 SSL。 Edge Public and Private Cloud 使用者

原因:傳送至 TLS 設定的虛擬主機的 HTTP 要求

如果用戶端嘗試在 Apigee 上連線至 API,且上述虛擬主機已設為使用 SSL 並收到 HTTP 要求,就會發生這個錯誤。

診斷

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

  1. 驗證您的 API 要求,查看您是否為主機別名發出 HTTP 要求,該要求已設為僅接受安全通訊埠 443 的要求。如果有,這就是問題的原因。

    不正確的 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 的目標端點中,將 HTTP 要求設為傳送到已啟用 TLS 的後端伺服器,就會發生這個錯誤。

診斷

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

  1. 在 Apigee UI 中,為受影響的 API Proxy 啟用「Trace」
  2. 向 API Proxy 發出要求。
  3. 請選取其中一個傳回 400 回應代碼失敗的 API 要求。
  4. 瀏覽各個階段,並判斷錯誤發生的位置。
  5. 一般來說,您會看見來自後端伺服器的 400 錯誤回應。也就是說,您會在「Responsereceive from target server」階段中看到 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 UI 中,為受影響的 API Proxy 啟用「Trace」
  2. 向 API Proxy 發出要求。
  3. 請選取其中一個失敗的 API 要求 (傳回 400 回應代碼)。
  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 UI
    • Management API

Edge UI

  1. 依序前往「Apigee Edge」>「管理員」>「環境」>「目標伺服器」
  2. 選擇 API Proxy 識別的特定目標伺服器,然後按一下 「Edit」(編輯)
  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」>「Admin」>「Environments」>「Target Servers」上前往目標伺服器。
  2. 選擇特定的目標伺服器,然後按一下 「Edit」(編輯)
  3. 如果目標伺服器安全無虞,且使用 443 等通訊埠,請勾選「SSL」選項旁的核取方塊來啟用 SSL。
  4. 設定「Truststore」、「Ciphers」和「Protocols」(通訊協定)。(僅限必要時)

Management API

按照 更新目標伺服器設定說明文件的說明,使用 Management API 設定目標伺服器。

必須收集診斷資訊

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

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