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

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

根據 HTTP 規格 RFC 7230,第 3.2.2 節:欄位順序,Apigee Edge 認為來自用戶端或後端伺服器的 HTTP 要求,不會包含以相同或不同的值傳送多次的相同標頭,除非特定的標頭有例外狀況,且允許具有重複值。

根據預設,Apigee Edge 允許將重複和多個值傳遞至大部分的 HTTP 標頭。但是,這項政策不允許使用不允許重複和多個值的標頭中列出的特定標頭。 因此:

  • 如果用戶端多次傳送含有特定標頭的 HTTP 要求,或是 HTTP 標頭含有多個值,而這些要求不得在 Apigee Edge 中使用重複/多個值,您會收到 400 Bad Request 和錯誤代碼 protocol.http.DuplicateHeader
  • 同樣地,如果後端伺服器多次傳送含有特定標頭的 HTTP 回應,或是 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, allowDuplicate,

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

HTTPHeader.HEADER_NAME

這個屬性可用來覆寫特定標頭的行為 (從 HTTPHeader.ANY 指定的內容)

同上。

標頭不可包含重複項目和多個值

如先前所述,Apigee Edge 預設會允許多數 HTTP 標頭的重複值和多個值。這是因為 HTTPHeader.ANY 屬性已設定為 multivalued, allowDuplicate. 值。

已覆寫設定

系統會以下列其中一種方法覆寫某些特定標頭的預設設定:

  • HTTPHeader.HEADER_NAME=multivalued, allowDuplicate

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

  • HTTPHeader.HEADER_NAME=

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

決定不允許包含重複項目和多個值的標頭

本節將說明如何識別下列資訊:

  • 在 Apigee Edge Private Cloud 設定中不得含有重複和多個值 的特定標頭。以及
  • 包含現有設定的特定標頭
  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 屬性在訊息處理器上設定 HTTPHeader 範例 test-header 的情況。

要求 傳出標頭 (根據 conf/http.properties+HTTPHeader.test-header= 的值)
<空白> allowDuplicate multiValued allowDuplicate, multiValued (DEFAULT)
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

事前準備

開始按照本文件的步驟操作之前,請務必確認您已按照 如何設定 Edge 的說明,為 Edge on Private Cloud 設定屬性。

設定 allowDuplicates 和標頭的多個值

HTTP 標頭屬性允許重複項目和多個值所述,HTTPHeader.ANY = allowDuplicates, multivalued 屬性的值意味著所有標頭都允許在 Apigee Edge 中具有重複值和多個值。不過,有些標頭的值已明確覆寫,因此無法使用 HTTPHeader.HEADER_NAME 屬性重複覆寫值或多個值。

本節會說明如何根據「如何設定邊緣」一文所述的語法,將 HTTPHeader.HEADER_NAME 屬性設定為允許訊息處理器上任何這類 HTTP 標頭的重複值和多個值。

在本節中,我們將使用 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. 該屬性會設為空白,即代表該值遭到覆寫 (且為含有既有設定的標頭),以「不」允許重複的標頭和多個值。也就是說,您只能透過 HTTP 要求或 HTTP 回應向 Apigee 傳送 Expires 標頭超過一次。
    2. 特定資源沒有任何命中,這表示該值「不會覆寫」 (也「不是」現有設定的標頭)。這表示該標頭可在對 Apigee Edge 的 HTTP 要求或 HTTP 回應中多次傳送 (可以重複)。
    3. 如果屬性設定了 allowDuplicates, multivalued 值,表示該值會明確覆寫 (且這是包含現有設定的標頭)。這代表特定標頭可在 HTTP 要求或 HTTP 回應中傳送給 Apigee 時多次傳送 (可以重複)。

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

    /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. 請注意,在上方的輸出範例中,http.properties 中的新值 allowDuplicates, multiValued 已設為 HTTPHeader.Expires 屬性。這表示允許重複的行為,且 HTTPHeader 中的多個值已在訊息處理器上成功設定。
  5. 如果還是看到屬性 HTTPHeader.HEADER_NAME 的舊值,請確認您已正確遵循設定 allowDuplicates 和標頭的多個值一文所述的所有步驟。如果您錯過任何步驟,請再次正確重複所有步驟。

    請確認您的 Proxy 能正常運作,尤其是在 Proxy 中有取得及設定標頭的功能邏輯時,

  6. 如果仍無法修改房源,請與 Apigee Edge 支援團隊聯絡

停用標頭的 allowDuplicates

本節說明如何按照「如何設定 Edge」一節所述的語法,將屬性 HTTPHeader.{Headername} 設為不允許重複和多個值,對訊息處理器上的特定 HTTP 標頭使用。

在本節中,我們將使用 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 以允許重複的標頭和多個值。這表示您無法在 HTTP 要求或 HTTP 回應中,多次傳送 Expires 標頭給 Apigee。
    2. 特定資源沒有任何命中,這表示該值「不會覆寫」,而這是包含現有設定的「NOT」標頭。這表示該標頭可做為 HTTP 要求或 Apigee Edge 的 HTTP 回應的一部分,多次傳送 (可以重複)。
    3. 屬性的值設定為 allowDuplicates, multivalued,表示該值已明確覆寫,而這是存在的設定。 不過,這代表特定標頭可做為 HTTP 要求或 HTTP 回應的一部分傳送給 Apigee 多次 (可以重複傳送)。

    輸出範例 #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 後,上述指令的範例結果如下:

    現有設定

    情境 1有效期限 (標頭含有 pre-Existing config)

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

    沒有現有設定

    情境 #2:myheader 標頭 (不是現有設定的標頭)

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

    請確認您的 Proxy 能正常運作,尤其是在 Proxy 中有取得及設定標頭的功能邏輯時,

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