400 要求無效 - 重複標頭

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

問題

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

錯誤訊息

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

HTTP/1.1 400 Bad Request

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

{
   "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 要求中,發現特定標頭出現超過一次 (不允許重複) ,就會傳回 400 Bad Request 和錯誤代碼 protocol.http.DuplicateHeader

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

原因 說明 適用於以下裝置的疑難排解說明
要求中的重複標頭 用戶端應用程式傳送至 Apigee 的 HTTP 要求包含重複的標頭。 Edge 公有和私有雲使用者

常見的診斷步驟

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

API Monitoring

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

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

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

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

  9. 按一下「查看記錄」,然後展開失敗要求所在的資料列。
  10. 在「記錄」視窗中,記下下列詳細資料:
    1. 狀態碼: 400
    2. 錯誤來源: apigee
    3. 故障代碼: protocol.http.DuplicateHeader
  11. 如果「Fault Source」的值為 apigeeMP ,且「Fault Code」的值為 protocol.http.DuplicateHeader,表示來自用戶端的 HTTP 要求含有重複的標頭。

追蹤工具

NGINX

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

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

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

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

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

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

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

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

原因:要求中的標頭重複

診斷

  1. 使用 API 監控或 NGINX 存取記錄,判斷所觀察到錯誤的錯誤代碼錯誤來源,如常見診斷步驟所述。
  2. 如果「Fault Source」的值為 apigeeMP,表示用戶端應用程式傳送至 Apigee 的要求含有重複的標頭。
  3. 如要判斷要求中多次傳送的實際標頭,請使用下列其中一種方法:

    錯誤訊息

    使用錯誤訊息

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

      錯誤訊息範例:

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

    實際要求

    使用實際要求

    1. 如果您可以存取用戶端應用程式發出的實際要求,請執行下列步驟:

      1. 確認要求中傳遞的標頭清單。
      2. 如果發現特定標頭在要求中出現多次,且值相同或不同,就是造成這項錯誤的原因。

      要求範例:

      curl https://HOST_ALIAS/duplicateheadertest -v -H "Expires: Mon, 21 June 2021 07:28:00 GMT" -H "Expires: Mon, 21 June 2021 07:28:00 GMT"
      

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

    2. 或者,如果您可以存取用戶端記錄,就能查看是否擁有向 Apigee Edge 提出的實際要求相關資訊,並判斷重複傳送的標頭。

解析度

修正重複問題

選項 1 (建議):修正用戶端應用程式,避免重複加入標頭

  1. 分析特定用戶端傳送重複標頭的原因。例如上述案例中的 Expires。確認 API Proxy 可以接受重複的標頭。根據 HTTP 規格 RFC7230,這通常不是理想做法。
  2. 如果不是,請修改用戶端應用程式,不要傳送重複的標頭。

    在上述範例中,我們發現標頭 Expires 傳送了兩次,且值相同,這並非我們所樂見。如要修正這個問題,請只傳遞一次 Expires 標頭,如下所示:

    curl https://HOST_ALIAS/duplicateheadertest -v -H "Expires: Mon, 21 June 2021 07:28:00 GMT"
    
  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 產生 400 Bad Request 錯誤,即使要求包含重複的標頭也一樣。如要瞭解如何設定訊息處理器來使用重複的標頭,請參閱 設定訊息處理器以使用重複標頭使用指南。
  2. 如果您是公有雲使用者,請與 Apigee Edge 支援團隊聯絡,為貴機構設定這項屬性。

規格

根據下列 RFC 規格,Apigee 預期用戶端應用程式不會在要求中傳送重複的標頭:

規格
RFC 7230 的 3.2.2 節:欄位順序
RFC 7230 的 3.2 節「Header Fields」

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

必須收集診斷資訊

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

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

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

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

  • 失敗要求顯示的完整錯誤訊息
  • 環境名稱
  • API Proxy 套裝組合
  • 完成用於重現 400 錯誤的 curl 指令
  • 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