502 閘道錯誤 - 重複標頭

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

問題

用戶端應用程式會收到 HTTP 狀態碼 502 Bad Gateway,以及錯誤碼 protocol.http.DuplicateHeader ,做為 API 呼叫的回應。

錯誤訊息

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

HTTP/1.1 502 Bad Gateway

此外,您可能會看到類似下方的錯誤訊息:

{
   "fault":{
      "faultstring":"Duplicate Header \"Expires\"",
      "detail":{
         "errorcode":"protocol.http.DuplicateHeader"
      }
   }
}

可能原因

如果後端伺服器傳送至 Apigee Edge 的 HTTP 回應中,出現 Apigee Edge 不允許重複的特定 HTTP 標頭,且這些標頭的值相同或不同,就會發生這項錯誤。

根據 RFC 7230 第 3.2.2 節:欄位順序 ,寄件者「不得」在郵件中產生多個具有相同欄位名稱的標頭欄位,除非該標頭欄位的整個欄位值定義為半形逗號分隔的清單,[即 #(values)],或標頭欄位是已知的例外狀況。如果 Apigee Edge 發現特定相同標頭 (不允許重複) 在目標/後端伺服器傳送的 HTTP 回應 中傳送超過一次,就會傳回 502 Bad Gateway 和錯誤代碼 protocol.http.DuplicateHeader

這項錯誤的可能原因如下:

原因 說明 適用於以下裝置的疑難排解說明
回應中的重複標頭 後端伺服器的回應包含重複的標頭。 Edge 公有和私有雲使用者

常見的診斷步驟

請使用下列其中一種工具/技術診斷這項錯誤:

API Monitoring

如要使用 API 監控功能診斷錯誤,請按照下列步驟操作:

  1. 以具備 適當角色的使用者身分登入 Apigee Edge UI
  2. 切換至要調查問題的機構。

  3. 前往「Analyze」>「API Monitoring」>「Investigate」頁面。
  4. 選取您觀察到錯誤的特定時間範圍。
  5. 確認「Proxy」篩選器已設為「All」
  6. 繪製「錯誤代碼」與「時間」的關係圖。
  7. 選取含有故障代碼 protocol.http.DuplicateHeader 的儲存格,如下所示:

    (查看較大圖片)

  8. 故障代碼 protocol.http.DuplicateHeader 的相關資訊會顯示如下:

    (查看較大圖片)

  9. 確認「狀態碼」502,如上例所示。
  10. 按一下「查看記錄」,然後展開失敗要求所在的資料列。
  11. 在「記錄」視窗中,請注意下列詳細資料:

    • 狀態碼: 502
    • 錯誤來源: target
    • 故障代碼: protocol.http.DuplicateHeader
  12. 「Fault Source」(錯誤來源) 為 target,表示後端伺服器的回應含有重複的標頭。

追蹤工具

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

  1. 啟用「追蹤工作階段」,並選擇下列任一選項:
    1. 等待發生 502 Bad Gateway 錯誤,或
    2. 如果可以重現問題,請發出 API 呼叫並重現 502 Bad Gateway 錯誤
  2. 確認已啟用「Show all Flow Infos」(顯示所有流程資訊)

  3. 選取其中一個失敗的要求,然後檢查追蹤記錄。
  4. 瀏覽追蹤記錄的不同階段,找出發生失敗的位置。
  5. 通常在「Request sent to target server」(已將要求傳送至目標伺服器)階段之後的流程中,就會出現錯誤,如下所示:

    (查看較大圖片)

  6. 請記下追蹤記錄中的錯誤值。

    上述範例追蹤記錄會將錯誤顯示為 Duplicate Header "Expires"。由於 Apigee 是在將要求傳送至後端伺服器後引發錯誤,因此表示後端伺服器傳送標頭 Expires 的次數超過一次。

  7. 在追蹤記錄中前往「AX」(記錄的 Analytics 資料) 階段,然後按一下。AX
  8. 向下捲動至「Phase Details - Response Headers」部分,然後判斷「X-Apigee-fault-code」和「X-Apigee-fault-source」的值,如下所示:

    (查看較大圖片)

  9. 您會看到 X-Apigee-fault-codeX-Apigee-fault-source 的值為 protocol.http.DuplicateHeadertarget,表示這項錯誤是因為後端伺服器為回應標頭 Expires 傳遞重複標頭所致。
    回應標頭
    X-Apigee-fault-code protocol.http.DuplicateHeader
    X-Apigee-fault-source target
  10. 檢查您是否使用Proxy 鏈結,也就是目標伺服器或目標端點是否在 Apigee 中叫用另一個 Proxy。

    1. 如要判斷這一點,請返回「Request sent to target」(傳送至目標的要求) 伺服器階段。 按一下「顯示 Curl」

    2. 「Curl for Request Sent to Target Server」(傳送至目標伺服器的 Curl 要求) 視窗隨即開啟,您可以在這個視窗中判斷目標伺服器主機別名。

    3. 如果目標伺服器主機別名指向虛擬主機別名,則為 Proxy 鏈結。在這種情況下,您需要針對鏈結的 Proxy 重複上述所有步驟,直到找出實際導致 502 Bad Gateway 錯誤的原因為止。
    4. 如果目標伺服器主機別名指向後端伺服器,表示後端伺服器在傳送給 Apigee 的回應中,含有重複的標頭。

NGINX

如要使用 NGINX 存取記錄診斷錯誤,請按照下列步驟操作:

  1. 如果您是私有雲使用者,可以透過 NGINX 存取記錄判斷 HTTP 502 錯誤的相關金鑰資訊。
  2. 檢查 NGINX 存取記錄:

    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

    說明: ORGENVPORT# 會替換為實際值。

  3. 搜尋特定時間範圍內是否有任何502錯誤 (如果問題發生在過去),或是否有任何要求仍502失敗。
  4. 如果發現任何 502 錯誤,且 X-Apigee-fault-code protocol.http.DuplicateHeader 的值相符,請判斷 X-Apigee-fault-source 的值。

    NGINX 存取記錄檔中的 502 錯誤範例:

    上述 NGINX 存取記錄檔的範例項目,X-Apigee-fault-codeX-Apigee-fault-source 的值如下:

    回應標頭
    X-Apigee-fault-code protocol.http.DuplicateHeader
    X-Apigee-fault-source target

原因:回應中出現重複標頭

診斷

  1. 常見診斷步驟所述,使用 API 監控或 NGINX 存取記錄,判斷觀察到的錯誤的錯誤代碼錯誤來源
  2. 如果「Fault Source」的值為 target,表示目標伺服器傳送的回應包含重複的標頭。
  3. 如要判斷實際傳送的標頭是否在回應中重複出現,請使用下列其中一種方法:

    錯誤訊息

    使用錯誤訊息:

    1. 如果您可以存取 Apigee Edge 傳送的完整錯誤訊息,請參閱 faultstringfaultstring 包含已傳送多次的標頭名稱。

      錯誤訊息範例:

      "faultstring":"Duplicate Header \"Expires\""
    2. 從上述錯誤訊息中,您可以看到標頭 Expires 傳送超過一次,如 faultstring 所示。

    實際要求

    使用實際要求:

    1. 如果無法存取向目標伺服器發出的實際要求,請從「使用 Trace 工具」步驟 10.a 和步驟 10.b 取得對應的 curl 指令。
    2. 如果您可以存取向目標伺服器應用程式發出的實際要求,請執行下列步驟:

      1. 呼叫目標伺服器。

        本範例中使用的目標伺服器要求範例:

        curl -X GET "https://BACKEND_SERVER_HOST/response-headers?Expires=Mon%2C%2021%20June%202021%2007%3A28%3A00%20GMT&Expires=Mon%2C%2021%20June%202021%2007%3A28%3A00%20GMT" -v
        
      2. 確認回應中顯示的標頭清單。

        本範例中目標伺服器的範例回應:

        * ...Trimmed...
        > GET /response-headers?Expires=Mon%2C%2021%20June%202021%2007%3A28%3A00%20GMT&Expires=Mon%2C%2021%20June%202021%2007%3A28%3A00%20GMT HTTP/2
        > Host: BACKEND_SERVER_HOST
        > User-Agent: curl/7.64.1
        > Accept: */*
        >
        * Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
        < HTTP/2 200
        < date: Fri, 02 Jul 2021 05:29:07 GMT
        < content-type: application/json
        < content-length: 166
        < server: gunicorn/19.9.0
        < Expires: Mon, 21 June 2021 07:28:00 GMT
        < Expires: Mon, 21 June 2021 07:28:00 GMT
        < access-control-allow-origin: *
        < access-control-allow-credentials: true
        <
        ----<Response BODY>------
        * Connection #0 to host httpbin.org left intact
        * Closing connection 0

        在上述範例要求中,標頭 Expires 傳送次數超過一次。因此,這項要求會失敗,並傳回 502 Bad Gateway 錯誤和錯誤代碼:protocol.http.DuplicateHeader

      3. 如果名稱顯示在 faultstring 中的標頭在後端伺服器的回應中出現超過一次,就是造成這項錯誤的原因。在上述情況中,標頭 Expires 會傳送多次。

解析度

修正重複問題

方法 1 (建議做法):修正後端伺服器,避免納入重複標頭

  1. 分析特定後端伺服器傳送重複標頭 Expires 的原因,並確認 API Proxy 是否可以接受該標頭。在大多數情況下,根據 HTTP 規格 RFC7230,這並非理想做法。
  2. 如果不希望這樣,請修改目標伺服器應用程式,不要傳送重複的標頭。 在上述範例中,我們發現標頭 Expires 傳送了兩次,且值相同,這並非我們所樂見。如要修正這個問題,請確保目標伺服器只傳遞一次 Expires 標頭。
  3. 如果需要允許重複的標頭,請前往「選項 2:使用 CwC 屬性」。

CwC

選項 2:使用 CwC 資源

Apigee 提供 CwC 屬性 HTTPHeader.<HeaderName>,可讓用戶端應用程式和目標伺服器將重複的標頭傳送至 Apigee Edge 中的 API Proxy。

CwC 資源
HTTPHeader.<HeaderName> allowDuplicates,multivalued

舉例來說,您可以在 Message Processors 上設定下列屬性,允許標頭 Expires 的重複值和多個值。

HTTPHeader.Expires=allowDuplicates, multiValued
  1. 如果您是私有雲使用者,可以設定這個屬性,防止 Apigee Edge 產生 502 Bad Gateway 錯誤,即使要求包含重複的標頭也一樣。如需操作說明,請參閱「 設定訊息處理器以使用重複的標頭」使用指南。
  2. 如果您是公有雲使用者,請與 Apigee Edge 支援團隊聯絡,為貴機構設定這項屬性。

規格

Apigee 會傳回 502 Bad Gateway 錯誤回應,因為 Apigee 預期後端伺服器會根據下列 RFC 規格運作:

規格
RFC 7230 的 3.2.2 節:欄位順序
RFC 7230 的 3.2 節:標頭欄位

如果仍需要 Apigee 支援團隊協助,請參閱「 必須收集診斷資訊」。

必須收集診斷資訊

收集下列診斷資訊,然後聯絡 Apigee Edge 支援團隊

如果您是公有雲使用者,請提供下列資訊:

  • 機構名稱
  • 環境名稱
  • API Proxy 名稱
  • 用於重現 502 錯誤的完整 curl 指令
  • API 要求的追蹤記錄檔

如果您是 Private Cloud 使用者,請提供下列資訊:

  • 失敗要求顯示的完整錯誤訊息
  • 環境名稱
  • API Proxy 套裝組合
  • API 要求的追蹤記錄檔
  • NGINX 存取記錄:

    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

    說明: ORGENVPORT# 會替換為實際值。

  • 訊息處理器系統記錄 /opt/apigee/var/log/edge-message-processor/logs/system.log