設定郵件處理工具以允許重複的標頭

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

根據 HTTP 規格 RFC 7230 第 3.2.2 節:欄位順序,Apigee Edge 預期來自用戶端的 HTTP 要求或來自後端伺服器的 HTTP 回應,不會包含相同標頭,且傳遞次數超過一次,除非特定標頭有例外狀況,允許重複。

根據預設,Apigee Edge 允許將重複項目和多個值傳遞至大多數 HTTP 標頭。不過,系統不允許使用某些標題,詳情請參閱「不允許重複和多個值的標題」。因此:

  • 如果用戶端傳送的 HTTP 要求含有特定標頭,且該標頭出現多次,或 HTTP 標頭含有多個值,但 Apigee Edge 不允許重複/多個值,您會收到 400 Bad Request 錯誤碼 protocol.http.DuplicateHeader
  • 同樣地,如果後端伺服器傳送的 HTTP 回應包含特定標頭,且該標頭在 Apigee Edge 中不允許重複或有多個值,您也會收到 502 Bad Gateway 錯誤代碼 protocol.http.DuplicateHeader

如要解決這些錯誤,建議的解決方案是修正用戶端應用程式和後端伺服器,避免傳送重複的標頭,並遵守 RFC 7230 第 3.2.2 節:欄位順序的規格,詳情請參閱下列疑難排解手冊:

不過,在某些情況下,您可能會想新增例外狀況,針對某些 HTTP 標頭納入重複值和多個值。在這種情況下,您可以在訊息處理器層級設定 HTTPHeader.HEADER_NAME 屬性,允許特定 HTTP 標頭出現重複標頭和多個值。

本文提供這項屬性的相關資訊,說明如何啟用這項屬性來避免上述錯誤,並分享相關最佳做法。

允許重複和多個值的 HTTP 標頭屬性

Apigee Edge 提供下列兩項屬性,可控管允許 HTTP 標頭重複和多個值的行為。請注意,這些設定只能在訊息處理器上進行,方法是使用「如何設定 Edge」一文說明的符記語法。

屬性名稱 說明 允許的值
HTTPHeader.ANY

這項屬性會指出是否允許所有 HTTP 標頭 (包括自訂標頭) 出現重複或多個值。這些標頭會以用戶端發出的 HTTP 要求或後端伺服器傳送至 Apigee Edge 的 HTTP 回應形式傳送。

預設值:

multiValued, allowDuplicates,

  1. blank:HTTP 標頭不得重複,也不得有多個值。
  2. multiValued:將多值標頭分割成多個標頭。 HTTP 標頭可有多個值,但不得重複。 值 multiValued 已啟用,這表示 test-header=a,b 會轉換為 test-header=atest-header=b.
  3. allowDuplicates:允許使用相同名稱的多個 (重複) HTTP 標頭。
  4. multiValued, allowDuplicates:HTTP 標頭可有多個值,也可以重複。

HTTPHeader.HEADER_NAME

這項屬性可用於覆寫特定標頭的行為,使其與 HTTPHeader.ANY 指定的行為不同。

同上。

不得重複或有多個值的標題

如先前所述,Apigee Edge 預設允許大多數 HTTP 標頭出現重複項目和多個值。這是因為屬性 HTTPHeader.ANY 已設定為值 multiValued, allowDuplicates.

設定已覆寫

對於某些特定標頭,預設設定會透過下列其中一種方法覆寫:

  • HTTPHeader.HEADER_NAME=multiValued, allowDuplicates

    這項設定不會變更預設行為。 也就是說,特定標頭允許重複和多個值

  • HTTPHeader.HEADER_NAME=

    這項設定會變更預設行為。也就是說,特定標頭不得重複,也不得有多個值

判斷不得有重複值和多個值的標題

本節說明如何找出下列項目:

  • 不得重複或有多個值的特定標頭 ,以及
  • 現有設定的特定標頭
  1. 在訊息處理器電腦上,搜尋 /opt/apigee/edge-message-processor/conf 目錄中的 HTTPHeader. 屬性,如下所示:

    grep -ri "HTTPHeader." /opt/apigee/edge-message-processor/conf
    

    輸出內容範例:

    # grep -ri "HTTPHeader" /opt/apigee/edge-message-processor/conf
    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.ANY=allowDuplicates, multiValued
    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.Connection=allowDuplicates, multiValued
    … <snipped>
    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.Host=
    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.Expires=
    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.Date=allowDuplicates
    …
    <snipped>
  2. 如「設定已覆寫」一節所述,請注意上述範例輸出中的下列資訊:
    1. HTTP 標頭 Connection 會遭到覆寫,但允許有重複值和多個值
    2. HTTP 標頭 HostExpires 會遭到覆寫,且不得有重複值和多個值
    3. HTTP 標頭 Date 會遭到覆寫,且允許重複,但不得有多個值
    4. 本文件中會將這裡顯示的所有標頭 (上述範例中的 ConnectionHostExpiresDate) 稱為「具有預先存在設定的標頭」

Apigee Edge

下表說明 Apigee Edge 在標頭以重複形式傳送,以及含有多個值時的行為,具體取決於訊息處理器上 HTTPHeader 屬性的設定方式,並提供 HTTPHeadertest-header 範例。

要求 根據 conf/http.properties+HTTPHeader.test-header= 的值,傳送 HEADERS
<Blank> allowDuplicates multiValued allowDuplicates、multiValued (預設)
test‑header=a,b test‑header=a,b test‑header=a,b

protocol.http.
DuplicateHeader

我們在內部將 test-header=a,b 分成:

  • test-header=a
  • test-header=b

然後擲回 DuplicateHeader 錯誤。

test‑header=a,b

我們在內部將 test-header=a,b 分成:

  • test-header=a
  • test-header=b

但原始表單會傳送至目標。

test‑header=a
test‑header=b
protocol.http.
DuplicateHeader
test‑header=a
test‑header=b
protocol.http.
DuplicateHeader
test‑header=a
test‑header=b

事前準備

使用本文中的步驟前,請務必先瞭解如何為 Private Cloud 上的 Edge 設定屬性,詳情請參閱「 如何設定 Edge」。

設定 allowDuplicates 和標頭的多個值

如「允許重複和多個值的 HTTP 標頭屬性」一文所述,屬性 HTTPHeader.ANY = allowDuplicates, multiValued 的值表示所有標頭都可以在 Apigee Edge 中重複和有多個值。不過,系統會明確覆寫某些標頭的值,以禁止重複的標頭或使用 HTTPHeader.HEADER_NAME 屬性為標頭提供多個值。

本節說明如何設定 HTTPHeader.HEADER_NAME 屬性,允許訊息處理器上任何這類 HTTP 標頭出現重複值和多個值,並根據「如何設定 Edge」一文所述語法,使用對應的權杖。

在本節中,我們會使用 Expires (和 myheader) 做為範例標頭,允許重複和多個值,如下所示:

  1. 判斷屬性 HTTPHeaderHEADER_NAME 的目前值,確保該屬性尚未啟用,可使用下列指令允許重複和多個值:
    grep -ri "HTTPHeader.HEADER_NAME" /opt/apigee/edge-message-processor/conf
    

    舉例來說,如果您要為 Expires 標頭設定屬性,請檢查訊息處理器上 HTTPHeader.Expires 權杖的屬性目前值:

    grep -ri "HTTPHeader.Expires" /opt/apigee/edge-message-processor/conf
    

    上述指令的輸出結果如下:

    1. 如果將屬性設為空白,表示值會遭到覆寫 (這是具有預先存在設定的標頭),因此不允許重複的標頭和多個值。也就是說,您不得在傳送至 Apigee 的 HTTP 要求或 HTTP 回應中,多次傳送 Expires 標頭。
    2. 如果特定屬性沒有任何命中,表示該值未遭覆寫 (且這並非具有預先存在設定的標頭)。也就是說,特定標頭可多次傳送 (允許重複),做為傳送至 Apigee Edge 的 HTTP 要求或 HTTP 回應的一部分。
    3. 如果屬性設為 allowDuplicates, multiValued 值, 表示該值已明確覆寫 (這是具有 現有設定的標頭)。也就是說,特定標頭可多次傳送 (允許重複),做為傳送至 Apigee 的 HTTP 要求或 HTTP 回應的一部分。

    搜尋指令的輸出內容範例:

    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.Expires=

    上述範例輸出內容顯示屬性 HTTPHeader.Expires 設為空白。也就是說,系統會覆寫屬性,針對標頭 Expires禁止重複或多個值

  2. 如果發現與特定標頭對應的屬性明確遭到覆寫,導致不允許重複或多個值 (如上述範例輸出內容所示),請務必執行下列步驟。如果沒有明確覆寫,請略過本節的其餘步驟。
  3. 編輯。如果不存在,您可以建立一個:
    /opt/apigee/customer/application/message-processor.properties

    舉例來說,如要使用 vi 開啟檔案,請輸入下列指令:

    vi /opt/apigee/customer/application/message-processor.properties
    
  4. 新增一行,格式如下:
    conf_http_HTTPHeader.Expires=allowDuplicates, multiValued
  5. 儲存變更。
  6. 確認屬性檔案的擁有者是 apigee 使用者。 如果不是,請執行下列指令:

    chown apigee:apigee /opt/apigee/customer/application/message-processor.properties
    
  7. 重新啟動訊息處理工具:

    /opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart
    

    如要重新啟動但不影響流量,請參閱「重新啟動訊息處理器,但不影響流量」。

  8. 如果您有多個訊息處理器,請在所有訊息處理器上重複上述步驟。

確認標頭已設為重複和多個值

本節說明如何確認特定標頭的屬性HTTPHeader.HEADER_NAME已成功更新,允許訊息處理器上的重複項目。

我們將使用 Expires 做為標題範例,並檢查對應的 HTTPHeader.Expires 屬性是否已更新。

即使您使用權杖 conf_http_HTTPHeader.Expires 更新訊息處理器上的值,仍須確認實際屬性 HTTPHeader.Expires 是否已設為新值。

  1. 在訊息處理器電腦上,搜尋 /opt/apigee/edge-message-processor/conf 目錄中的 HTTPHeader.HEADER_NAME 屬性,並檢查是否已設定新值,如下所示:
    grep -ri "HTTPHeader.HEADER_NAME" /opt/apigee/edge-message-processor/conf
    

    舉例來說,如要確認屬性 HTTPHeader.Expires 已設為新值,請執行下列指令:

    grep -ri "HTTPHeader.Expires" /opt/apigee/edge-message-processor/conf
    
  2. 如果成功為 訊息處理器 上的 HTTPHeader.HEADER_NAME 設定新值,上述指令就會在 http.properties 檔案中顯示新值。
  3. 設定 allowDuplicatesmultiValued 後,上述指令的範例結果如下:

    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.Expires=allowDuplicates, multiValued
  4. 在上述範例輸出內容中,請注意屬性 HTTPHeader.Expires 已在 http.properties 中設定新值 allowDuplicates, multiValued。這表示訊息處理器已成功設定允許重複和多個 HTTPHeader 中的值。
  5. 如果屬性 HTTPHeader.HEADER_NAME 仍顯示舊值,請確認您已正確按照「為標頭設定 allowDuplicates 和多個值」一文中的所有步驟操作。如果遺漏任何步驟,請再次正確執行所有步驟。

    請確認 Proxy 運作正常,特別是 Proxy 中有取得及設定標頭的功能邏輯時。

  6. 如果還是無法修改屬性,請與 Apigee Edge 支援團隊聯絡。

停用標頭的 allowDuplicates

本節說明如何使用 如何設定 Edge 中所述的語法,透過對應的權杖,在 Message Processor 上為特定 HTTP 標頭設定屬性 HTTPHeader.{Headername}禁止重複和多個值

在本節中,我們會使用 Expires (和 myheader) 做為範例標頭,說明我們不允許重複項目的原因,如下所示:

  1. 判斷屬性 HTTPHeaderHEADER_NAME 的目前值,確保未停用,允許重複和多個值,請使用下列指令:
    grep -ri "HTTPHeader.HEADER_NAME" /opt/apigee/edge-message-processor/conf
    

    舉例來說,如果您要為 Expires 標頭設定屬性,請檢查訊息處理器上 HTTPHeader.Expires 權杖的屬性目前值:

    grep -ri "HTTPHeader.Expires" /opt/apigee/edge-message-processor/conf
    

    上述指令的輸出結果如下:

    1. 如果將這項屬性設為空白,則表示值會覆寫為 NOT,以允許重複的標頭和多個值。也就是說,您不得在傳送至 Apigee 的 HTTP 要求或 HTTP 回應中,多次傳送 Expires 標頭。
    2. 如果特定屬性沒有任何命中,表示該值未遭覆寫,且這是具有預先存在設定的 NOT 標頭。也就是說,特定標頭可多次傳送 (允許重複),做為傳送至 Apigee Edge 的 HTTP 要求或 HTTP 回應的一部分。
    3. 如果屬性設為 allowDuplicates, multiValued 值,表示該值已明確覆寫,且這是現有的設定。 不過,這表示特定標頭可多次傳送 (允許重複),做為傳送至 Apigee 的 HTTP 要求或 HTTP 回應的一部分。

    輸出內容範例 #1

    搜尋指令的輸出內容範例 #1:

    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.Expires=allowDuplicates, multiValued

    範例輸出內容顯示屬性 HTTPHeader.Expires 設為 allowDuplicates, multiValued。也就是說,系統會覆寫屬性,允許標頭 Expires 含有重複或多個值

    輸出內容範例 #2

    搜尋指令的指令和輸出內容範例 #2

    grep -ri "HTTPHeader.myheader" /opt/apigee/edge-message-processor/conf
    

    範例輸出內容未顯示任何輸出內容,表示屬性 HTTPHeader.myheader 預設設為 allowDuplicates, multiValued。 這也表示系統不會覆寫 標頭 myheader 的屬性,

  2. 如果發現下列任一情況,請完成本節的其餘步驟:
    1. 對應特定標頭的屬性會遭到覆寫,以允許重複和多個值,如上方的「範例輸出 #1」(具有預先存在的設定的標頭) 所示
    2. 如上方的「範例輸出 #2」所示,特定標頭對應的資源沒有任何命中 (不是具有預先存在設定的標頭)

    否則請略過本節的其餘步驟。

  3. 編輯下列檔案。如果沒有,請建立一個。
    /opt/apigee/customer/application/message-processor.properties

    舉例來說,如要使用 vi 開啟檔案,請輸入下列指令:

    vi /opt/apigee/customer/application/message-processor.properties
    
  4. 在屬性檔案中新增一行,格式如下:

    現有設定

    情境 1:頁首含有預先存在的設定:

    conf_http_HTTPHeader.Expires=

    沒有現有設定

    情境 2:不是具有預先存在設定的標頭:

    conf/http.properties+HTTPHeader.myheader=
  5. 儲存變更。
  6. 確認屬性檔案的擁有者是 apigee 使用者。如果不是,請執行下列指令:
    chown apigee:apigee /opt/apigee/customer/application/message-processor.properties
    
  7. 重新啟動訊息處理器:
    /opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart
    

    如要重新啟動但不影響流量,請參閱「重新啟動訊息處理器,但不影響流量」。

  8. 如果您有多個訊息處理器,請在所有訊息處理器上重複上述步驟。

確認標頭已設定為不允許重複值和多個值

本節說明如何確認特定標頭的屬性HTTPHeader.HEADER_NAME已成功更新,禁止訊息處理器出現重複項目。

我們將使用 Expires (和 myheader) 做為標題範例,並檢查對應的 HTTPHeader.Expires 屬性 (和 HTTPHeader.myheader) 是否已更新。

  1. 在訊息處理器電腦上,搜尋 /opt/apigee/edge-message- processor/conf 目錄中的 HTTPHeader.HEADER_NAME 屬性,並檢查是否已設定新值,如下所示:

    grep -ri "HTTPHeader.HEADER_NAME" /opt/apigee/edge-message-processor/conf
    

    舉例來說,如要檢查屬性 HTTPHeader.Expires 是否已設為新值,可以執行下列指令:

    現有設定

    grep -ri "HTTPHeader.Expires" /opt/apigee/edge-message-processor/conf
    

    沒有現有設定

    grep -ri "HTTPHeader.myheader" /opt/apigee/edge-message-processor/conf
    
  2. 如果已成功為訊息處理器上的 HTTPHeader.HEADER_NAME I 設定新的 HTTP 標頭值,上述指令就會在 http.properties 檔案中顯示新值。
  3. 停用 allowDuplicates 後,上述指令的範例結果如下:

    現有設定

    情境 1Expires 標頭 (標頭具有預先存在的設定)

    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.Expires=

    沒有現有設定

    情境 2:myheader 標題 (不是具有預先存在設定的標題)

    /opt/apigee/edge-message-processor/conf/http.properties:HTTPHeader.myheader=
  4. 在上述範例輸出內容中,請注意屬性 HTTPHeader.Expires ( 和 HTTPHeader.myheader) 已設為新值 {blank} in http.properties。這表示訊息處理器已成功停用允許特定 HTTP 標頭 Expires (和 myheader) 重複和多個值的行為。
  5. 如果屬性 HTTPHeader.Expires (or HTTPHeader.myheader) 仍顯示舊值,請確認您已正確按照「為標頭設定 allowDuplicates 和多個值」一文中的所有步驟操作。如果遺漏任何步驟,請再次正確執行所有步驟。

    請確認 Proxy 運作正常,特別是 Proxy 中有取得及設定標頭的功能邏輯時。

  6. 如果還是無法修改屬性,請聯絡 Apigee Edge 支援團隊