400 要求無效 - 重複標頭

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

問題

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

錯誤訊息

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

HTTP/1.1 400 Bad Request

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

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

可能原因

如果特定 HTTP 標頭不得在 Apigee Edge 中重複,且在用戶端傳送至 Apigee Edge 的 HTTP 要求中重複出現與相同或不同的值,就會發生這個錯誤。

根據 RFC 7230 的第 3.2.2 節:欄位順序寄件者「不得」在郵件中產生具有相同欄位名稱的多個標頭欄位,除非該標頭欄位的完整欄位值定義為以半形逗號分隔的清單 (即#(values)] 或標頭欄位是已知的例外狀況。如果 Apigee Edge 找到不得含有重複項目的特定標頭,在用戶端傳送的 HTTP 要求 中超過一次,就會傳回 400 Bad Request 和錯誤代碼 protocol.http.DuplicateHeader

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

原因 說明 適用的疑難排解指示
要求中的標頭重複 用戶端應用程式傳送至 Apigee 的 HTTP 要求包含重複的標頭。 Edge Public and Private Cloud 使用者

常見診斷步驟

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

API Monitoring

如何使用 API Monitoring 診斷錯誤:

  1. 適當角色的身分 登入 Apigee Edge UI
  2. 切換至您想要調查問題的機構。

  3. 前往「分析」>「API 監控」>「調查」頁面。
  4. 請選取你發現錯誤的特定時間範圍。
  5. 確認 Proxy 篩選器已設為「All」
  6. 將「Fault Code」與「Time」進行比較。
  7. 選取含有錯誤代碼 protocol.http.DuplicateHeader 的儲存格,如下所示:

  8. 錯誤代碼 protocol.http.DuplicateHeader 的相關資訊如下所示:

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

追蹤工具

NGINX

如何使用 NGINX 存取記錄檔診斷錯誤:

  1. 如果您是 Private Cloud 使用者,即可使用 NGINX 存取記錄檔來判斷 HTTP 400 錯誤的相關重要資訊。
  2. 查看 NGINX 存取記錄檔:

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

    其中: ORGENVPORT# 會替換為實際值。

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

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

    以上 NGINX Access 記錄中的範例項目,有下列「X-Apigee- error-code」和「X-Apigee-fault-source」的值:

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

原因:要求中的標頭重複

診斷

  1. 使用 API 監控或 NGINX 存取記錄檔,按照常見診斷步驟說明觀察到錯誤的「Fault Code」和「Fault Source」
  2. 如果「Fault Source」的值為 apigeeMP,就表示用戶端應用程式傳送至 Apigee 的要求包含重複的標頭。
  3. 您可以使用下列任一方法,判斷在要求中傳送多次的實際標頭:

    錯誤訊息

    使用錯誤訊息

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

      錯誤訊息示例:

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

    實際要求

    使用實際的要求

    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

舉例來說,您可以在訊息處理器上設定下列屬性,允許重複項目及標頭 Expires 的多個值。

HTTPHeader.Expires=allowDuplicates, multiValued
  1. 如果您是私人 Cloud 使用者,可以按照 設定訊息處理器使用重複標頭教學指南的說明,設定屬性來避免 Apigee Edge 引發 400 Bad Request 錯誤。
  2. 如果您是公開雲端使用者,請與 Apigee Edge 支援團隊聯絡,為貴機構設定這項屬性。

規格

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

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

如果仍需要 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