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 錯誤網頁操作:

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

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

當用戶端嘗試在 Apigee 上連線至 API,且 虛擬主機設定為使用 SSL,並改為接收 HTTP 要求。

診斷

因為這個問題發生在 Northbound 端點和 API 要求在 用戶端應用程式和路由器,這些錯誤訊息都不會記錄在 NGINX 路由器中 存取記錄檔因此,這些要求不會擷取到 API Monitoring 與 追蹤工具

  1. 驗證您的 API 要求,並查看您是否為 已設為僅接受安全通訊埠 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. 在上方的要求範例中,請注意,系統會將 HTTP 要求傳送至主機別名 「myorg-test.apigee.net」位於安全通訊埠 443 上。這就是導致 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 要求

如果 HTTP 要求對已啟用 TLS 的後端設定錯誤,就會發生這個錯誤 伺服器中的執行個體。

診斷

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

  1. 在 Apigee UI 中為受影響的 API Proxy 啟用 Trace
  2. 向 API Proxy 發出要求。
  3. 請選取一項失敗的 API 要求 (回應代碼為 400)。
  4. 瀏覽各個階段,判斷失敗發生的位置。
  5. 一般來說,您會看到來自後端伺服器的 400 錯誤回應。 換句話說,您會在已收到回應的階段中看到 400 錯誤回應 ,如下所示:

  6. 按一下 [AX]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) 卻未啟用 導致 Apigee Edge 的訊息處理器將 HTTP 要求傳送至 這是基於 TLS 設定的目標伺服器所致。

診斷

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

  1. 在 Apigee UI 中為受影響的 API Proxy 啟用 Trace
  2. 向 API Proxy 發出要求。
  3. 請選取一項失敗的 API 要求 (回應代碼為 400)。
  4. 瀏覽各個階段,判斷失敗發生的位置。
  5. 一般來說,您會看到來自後端伺服器的 400 錯誤回應。 這表示您會在已收到回應的階段中看到 400 錯誤回應 ,如下所示:

  6. 按一下 [AX]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 識別的特定目標伺服器,然後按一下 「編輯」。
  3. 驗證針對目標伺服器指定的通訊埠和 SSL 資訊。
  4. 如果目標伺服器設有安全通訊埠 (例如 443), 但未啟用 SSL,就會造成這項問題。

    如以上螢幕截圖所示,使用的通訊埠是 443,但 SSL 不是 SSL 已為該通訊埠啟用。這會導致 Apigee Edge 的訊息 將 HTTP 要求傳送至安全通訊埠 443 的處理器。因此,您得到的 錯誤 400 Bad Request,錯誤訊息 The 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 設定,您就必須為 目標伺服器

您可以使用下列其中一個選項執行這項動作:

  • Edge UI
  • Management API

Edge UI

  1. 前往「Edge UI >」中的目標伺服器管理 >環境 >目標伺服器
  2. 選擇特定的目標伺服器,然後按一下 「Edit」(編輯)
  3. 如果您的目標伺服器安全無虞,且使用通訊埠 (例如 443),請經由以下方式啟用 SSL: 勾選 SSL 選項旁邊的核取方塊。
  4. 設定「Truststore」Truststore、「Ciphers」Truststore和「Protocols」Truststore。(僅限必要時)

Management API

使用 Management API 設定目標伺服器,方法如 更新目標伺服器設定說明文件。

必須收集診斷資訊

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

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