您正在查看 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 工具等工具不會擷取這些要求。
-
驗證您的 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>
- 請注意,在上述要求範例中,系統透過安全通訊埠
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 的後端伺服器,就會發生這個錯誤。
診斷
請按照下列步驟使用追蹤記錄工具診斷錯誤:
- 在 Apigee UI 中,為受影響的 API Proxy 啟用「Trace」。
- 向 API Proxy 發出要求。
- 請選取其中一個傳回
400
回應代碼失敗的 API 要求。 - 瀏覽各個階段,並判斷錯誤發生的位置。
-
一般來說,您會看見來自後端伺服器的
400
錯誤回應。也就是說,您會在「Responsereceive from target server」階段中看到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 UI 中,為受影響的 API Proxy 啟用「Trace」。
- 向 API Proxy 發出要求。
- 請選取其中一個失敗的 API 要求 (傳回
400
回應代碼)。 - 瀏覽各個階段,並判斷錯誤發生的位置。
-
一般來說,您會看到來自後端伺服器的
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 UI
- Management API
Edge UI
- 依序前往「Apigee Edge」>「管理員」>「環境」>「目標伺服器」。
- 選擇 API Proxy 識別的特定目標伺服器,然後按一下 「Edit」(編輯)。
- 驗證目標伺服器的通訊埠和 SSL 資訊。
-
如果目標伺服器設定了安全通訊埠 (例如:
443
),但未啟用 SSL,這就是這個問題的原因。如以上螢幕截圖所示,使用的通訊埠是
443
,但在目標伺服器設定中,該通訊埠未啟用 SSL。這會使 Apigee Edge 的訊息處理器將 HTTP 要求傳送至安全通訊埠「443
」。因此,您會收到400 Bad Request
錯誤與The plain HTTP request was sent to HTTPS port
訊息。
Management API
-
執行 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"
- 驗證目標伺服器的通訊埠和 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 UI
- Management API
Edge UI
- 在「Edge UI」>「Admin」>「Environments」>「Target Servers」上前往目標伺服器。
- 選擇特定的目標伺服器,然後按一下 「Edit」(編輯)。
- 如果目標伺服器安全無虞,且使用
443
等通訊埠,請勾選「SSL」選項旁的核取方塊來啟用 SSL。 - 設定「Truststore」、「Ciphers」和「Protocols」(通訊協定)。(僅限必要時)
Management API
按照 更新目標伺服器設定說明文件的說明,使用 Management API 設定目標伺服器。
必須收集診斷資訊
如果按照上述指示操作後仍無法解決問題,請收集下列診斷資訊,然後與 Apigee Edge 支援團隊聯絡。
- 如果您是公有雲使用者,請提供下列資訊:
- 機構組織名稱
- 環境名稱
- API Proxy 名稱
- 完成 curl 指令即可重現錯誤
- 追蹤工具輸出 (如果您能夠針對失敗的要求擷取資料)
- 如果您是 Private Cloud 使用者,請提供下列資訊:
- 偵測到完整錯誤訊息
- 環境名稱
- API Proxy 套裝組合
- 目標伺服器定義 (若您在端點中使用目標伺服器)
- 追蹤工具輸出 (如果您能夠針對失敗的要求擷取資料)