## HTTP頭部操作
HTTP連接管理器在解碼期間(當接收到請求時)以及在編碼期間(當響應被發送時)處理多個HTTP頭部。
### user-agent
如果啟用了`add_user_agent`選項,則連接管理器在解碼過程中,會設置`user-agent`頭部。這個頭部只有未設置的情況下才會被修改。如果連接管理器確實設置了該字段,則該值由命令行選項`--service-cluster`確定。
### server
`server`頭部將在編碼時設置為選項[server_name](../../v1APIreference/Networkfilters/HTTPconnectionmanager.md)中的值。
### x-client-trace-id
如果一個外部客戶端設置了這個頭部,Envoy會將客戶端提供的跟蹤ID和內部生成的`x-request-id`關聯起來。`x-client-trace-id`需要全局唯一性,建議生成一個uuid4。如果設置了此標志,它將具有與`x-envoy-force-trace`相似的效果。 請參閱`[tracing.client_enabled](../../Configurationreference/HTTPconnectionmanager/Runtime.md)`運行時配置設置。
### x-envoy-downstream-service-cluster
內部服務通常想知道哪個服務正在調用它們。從外部的請求中這個頭部會被清除,但是對于內部請求,將包含調用者的服務集群信息。請注意,在當前的實現中,這應該被認為是一個潛規則,因為它是由調用者設置的,并且很容易被任何內部實體欺騙。將來,Envoy將支持相互認證的TLS網格,這將使這個頭部完全安全。與`user-agent`一樣,該值由`--service-cluster`命令行選項確定。為了啟用此功能,您需要將`user_agent`選項設置為`true`。
### x-envoy-downstream-service-node
內部服務可能想知道下游節點請求來自哪里。這個頭與`x-envoy-downstream-service-cluster`非常相似,除了從`--service-node`選項中取值。
### x-envoy-external-address
服務端想要根據客戶端IP地址,執行分析是很常見的情況。在XFF(`x-forwarded-for`)漫長的討論中,這可能會變得相當復雜。一個正確的實現需涉及轉發XFF,然后從右邊選擇第一個非RFC1918地址。由于這個常用的功能,Envoy通過在解碼過程中設置`x-envoy-external-address`來簡化這種實現,當且僅當請求從外部進入(即它來自外部客戶端)。對于內部請求,`x-envoy-external-address`不會設置或覆蓋。為了分析需要,可以在內部服務之間安全地轉發該頭部,而不必關心XFF的復雜性。
### x-envoy-force-trace
如果一個內部請求設置了這個頭部,Envoy會修改生成的`x-request-id`,使得它強制收集跟蹤信息。這也迫使`x-request-id`在響應頭中返回。如果這個請求標識隨后被傳播到其他主機,那么這些主機上的跟蹤也將被收集,這將為整個請求流提供一致的跟蹤。請參閱[tracing.global_enabled](Configurationreference/HTTPconnectionmanager/Runtime.md)和[tracing.random_sampling](Configurationreference/HTTPconnectionmanager/Runtime.md)運行時配置設置。
### x-envoy-internal
一個常見的情況就是服務想要知道請求是否來自內部。Envoy使用XFF來明確這一點,然后將頭部的值設置為`true`。
這是就避免了需要解析和理解XFF的好處。
### x-forwarded-client-cert
x-forward-client-cert(XFCC)是一個代理頭,在從客戶端到服務器的所經過的路徑上,表示請求已經流經的部分或全部客戶端或代理的證書信息。代理可以在請求代理之前選擇清除/追加/轉發XFCC頭。
XFCC頭部值是以逗號(“,”)為分隔的字符串。每個子字符串都是XFCC元素,它保存著由一個代理所添加的信息。代理可以將當前客戶端證書信息作為XFCC元素,追加到請求的XFCC頭部中。
每個XFCC元素都是一個分號“;”分隔的字符串。每個子字符串都是一個鍵值對,由一個等號(“=”)組成。`key`不區分大小寫,`value`區分大小寫。如果“,”,“;”或“=”出現在一個值中,則該`value`應該用雙引號。`value`中的雙引號應該被反斜杠雙引號(“)替換。
以下鍵支持:
1. `By` 當前代理證書的主題備用名稱(SAN:Subject Alternative Name)。
2. `Hash` 當前客戶端證書的SHA256摘要。
3. `SAN` 當前客戶端證書的SAN字段(URI類型)。
4. `Subject` 當前客戶端證書的主題字段。這個值總是雙引號。
以下是兩個XFCC頭部的例子:
1.
```
x-forwarded-client-cert: By=http://frontend.lyft.com;Hash=468ed33be74eee6556d90c0149c1309e9ba61d6425303443c0748a02dd8de688;Subject="/C=US/ST=CA/L=San Francisco/OU=Lyft/CN=Test Client";SAN=http://testclient.lyft.com
```
2.
```
x-forwarded-client-cert: By=http://frontend.lyft.com;Hash=468ed33be74eee6556d90c0149c1309e9ba61d6425303443c0748a02dd8de688;SAN=http://testclient.lyft.com,By=http://backend.lyft.com;Hash=9ba61d6425303443c0748a02dd8de688468ed33be74eee6556d90c0149c1309e;SAN=http://frontend.lyft.com
```
Envoy處理XFCC的方式由HTTP連接管理器選項`forward_client_cert`和`set_current_client_cert_details` 指定。如果未設置`forward_client_cert`,則默認會對XFCC頭部進行清除。
### x-forwarded-for
x-forwarded-for(XFF)是一個標準的代理頭,它表示請求在從客戶端到服務器的過程中,所經過的IP地址。一個兼容的代理服務,應在代理請求之前將最近客戶端的IP地址附加到XFF列表中。XFF的一些例子是:
1. `x-forwarded-for: 50.0.0.1` (單個客戶端)
2. `x-forwarded-for: 50.0.0.1, 40.0.0.1` (外部代理跳轉)
3. `x-forwarded-for: 50.0.0.1, 10.0.0.1` (內部代理跳轉)
如果HTTP連接管理器選項`use_remote_address`設置為true,Envoy將只附加到XFF。這意味著如果`use_remote_address`為`false`,則連接管理器將透明模式運行,不修改XFF的內容。這對于特定的網格部署類型是必需的,具體取決于Envoy是在邊緣節點還是作為內部服務節點。
最終Envoy會根據的XFF內容來確定請求是從外部還是從內部發起的。這會影響`x-envoy-internal`頭部是否會被設置。
關于XFF的一些非常重要的注意事項:
1. 由于IP地址被附加到XFF,只有最后一個地址(最右邊)可以被信任。更具體地說,右邊的第一個外部(非RFC1918)地址是唯一可信的地址。左邊的任何東西都可能被欺騙。為了方便處理分析,在前面Envoy還將設置`x-envoy-external-address`頭部。
2. XFF是Envoy用來確定請求是來自內部還是外部。它通過檢查XFF是否包含一個單一的IP地址(RFC1918地址)來做到這一點。
- **注意**:如果內部服務代理到另一個內部服務的外部請求,并且包含原始的XFF頭,如果`use_remote_address`被設置,Envoy將在出口附加它。這會導致對方認為請求是外部的。一般來說,這是XFF被轉發的目的。如果沒有打算,不要轉發XFF,而是轉發`x-envoy-internal`。
- **注意**:如果內部服務保留XFF并轉發到另一個內部服務,Envoy不會將其視為內部服務。這是一個已知的“BUG”,因為簡化XFF的解析處理,以確定請求是否是內部的。在這種情況下,不要轉發XFF,并允許Envoy使用一個內部原始IP生成一個新的。
### x-forwarded-proto
一個服務若想要知道前端Envoy代理的處理的始發協議類型(HTTP或HTTPS)。這是一個常見的情況。`x-forward-proto`包含這個信息。它將會被設置為`http`或`https`。
### x-request-id
Envoy使用`x-request-id`頭來標識請求,并執行訪問日志記錄和跟蹤。Envoy將為所有來自的外部請求(頭部被清理)生成一個`x-request-id`頭。它還會為內部請求生成一個`x-request-id`頭,這意味著`x-request-id`可以并應該在客戶端應用程序之間傳遞,以便在整個網格中有穩定的ID。由于Envoy是外置進程架構,頭部不能由Envoy自動轉發。這是少數幾個需要瘦客戶端庫就可以完成的要求之一,關于如何完成這個,不在本文檔范圍。如果`x-request-id`跨所有主機傳遞,則可以使用以下功能:
- 通過[v1 API 過濾器](../../v1APIreference/Accesslogging.md)或[v2 API過濾器](../../v2APIreference/Filters/Commonaccesslogtypes.md)進行穩定的訪問[日志記錄](../../Configurationreference/Accesslogging.md)。
- 當通過運行時設置`tracing.random_sampling`或通過使用`x-envoy-force-trace`和`x-client-trace-id`頭強制使能跟蹤,來執行隨機跟蹤采樣。
### x-ot-span-context
Envoy使用`x-ot-span-context`HTTP頭在span跟蹤之間建立適當的父子關系。這個頭可以用于LightStep和Zipkin跟蹤服務。例如,出口span是入口span(如果存在入口span)的子關系。Envoy在入口請求上注入`x-ot-span-context`頭并將其轉發給本地服務。Envoy依靠應用程序在出口調用時傳播`x-ot-span-context`到上游。在這里查看[更多信息](../../Introduction/Architectureoverview/Tracing.md)。
### x-b3-traceid
Zipkin跟蹤會使用Envoy中的`x-b3-traceid`HTTP頭。TraceId長度為64位,表示跟蹤的總體ID。跟蹤中的每個span都共享此ID。點擊這里查看更多關于[zipkin信息](https://github.com/openzipkin/b3-propagation)。
### x-b3-spanid
Zipkin跟蹤會用到Envoy中的`x-b3-spanid`HTTP頭。SpanId的長度是64位,表示當前操作在跟蹤樹中的位置。該值不應該被解釋:它可以或不可以從TraceId的值中派生出來。點擊這里查看更多關于[zipkin信息](https://github.com/openzipkin/b3-propagation)。
### x-b3-parentspanid
Zipkin跟蹤使用Envoy中的`x-b3-parentspanid`HTTP頭。ParentSpanId的長度為64位,表示父操作在跟蹤樹中的位置。當span是跟蹤樹的根時,ParentSpanId不存在。點擊這里查看更多關于[zipkin信息](https://github.com/openzipkin/b3-propagation)。
### x-b3-sampled
Zipkin跟蹤會使用Envoy中的`x-b3-sampled`HTTP頭。當采樣標志為1時,這個索引將被報告給跟蹤系統。一旦采樣設置為0或1,相同的值應始終向下游發送。點擊這里查看更多關于[zipkin信息](https://github.com/openzipkin/b3-propagation)。
### x-b3-flags
Zipkin跟蹤會使用Envoy中的`x-b3-flags`HTTP頭。編碼一個或多個選項。例如,Debug被編碼為`X-B3-Flags:1`。請[參閱](https://github.com/openzipkin/b3-propagation)上的更多關于zipkin跟蹤的信息。
### Custom request/response headers
自定義添加請求/響應頭,與特定請求/響應路由相匹配,關于虛擬主機和全局路由配置。請參閱相關的v1和v2 API文檔。
**注意**:將按照以下順序附加到請求/響應中:路由級別頭標,虛擬主機級別頭標以及最終全局級別頭標。
Envoy還支持將動態值添加到請求頭域。支持的動態值是:
**%CLIENT_IP%**
- 由Envoy添加原始客戶端IP作為`x-forwarded-for`的請求頭。
**%PROTOCOL%**
- 原來的協議已由Envoy添加`x-forward-proto`作為請求頭。
## 返回
- [上一級](../HTTPconnectionmanager.md)
- [首頁目錄](../../README.md)
- 首頁
- 簡介
- Envoy是什么
- 架構介紹
- 術語
- 線程模型
- 監聽器
- L3/L4網絡過濾器
- HTTP連接管理
- HTTP過濾器
- HTTP路由
- gRPC
- WebSocket支持
- 集群管理
- 服務發現
- 健康檢查
- 連接池
- 負載均衡
- 異常檢測
- 熔斷
- 全局限速
- TLS
- 統計
- 運行時配置
- 跟蹤
- TCP代理
- 訪問日志
- MongoDB
- DynamoDB
- Redis
- 熱重啟
- 動態配置
- 初始化
- 逐出
- 腳本
- 部署
- 業界對比
- 獲得幫助
- 歷史版本
- 編譯安裝
- 編譯
- 參考配置
- 演示沙箱
- 前端代理
- Zipkin跟蹤
- Jaeger跟蹤
- gRPC橋接
- 構建Envoy Docker鏡像
- 工具
- 配置參考
- V1 API 概述
- V2 API 概述
- 監聽器
- 網絡過濾器
- TLS客戶端身份認證
- Echo
- Mongo代理
- 速率限制
- Redis代理
- TCP代理
- HTTP連接管理器
- 路由匹配
- 流量轉移/分流
- HTTP頭部操作
- HTTP頭部清理
- 統計
- 運行時設置
- 路由發現服務
- HTTP過濾器
- 緩存
- CORS過濾器
- 故障注入
- DynamoDB
- gRPC HTTP/1.1 橋接
- gRPC-JSON 轉碼過濾器
- gRPC-Web 過濾器
- 健康檢查
- 速率限制
- 路由
- Lua
- 集群管理
- 統計
- 運行時設置
- 集群發現服務
- 健康檢查
- 熔斷
- 訪問日志
- 限速服務
- 運行時配置
- 路由表檢查工具
- 運維管理
- 命令行選項
- 熱重啟
- 管理接口
- 統計概述
- 運行時配置
- 文件系統
- 自定義擴展示例
- V1 API參考
- 監聽器
- 網絡過濾器
- TLS客戶端身份認證
- Echo
- HTTP連接管理
- Mongo代理
- 速率限制
- Redis代理
- TCP代理
- HTTP路由配置
- 虛擬主機
- 路由
- 虛擬集群
- 速率限制配置
- 路由發現服務
- HTTP過濾器
- 緩存
- CORS過濾器
- DynamoDB
- 故障注入
- gRPC HTTP/1.1 橋接
- gRPC-JSON 轉碼過濾器
- gRPC-Web 過濾器
- 健康檢查
- Lua
- 速率限制
- 路由
- 集群管理
- 集群
- 健康檢查
- 熔斷
- TLS上下文
- 異常值檢測
- HASH環負載均衡配置
- 異常檢測
- 集群發現服務
- 服務發現服務
- 訪問日志
- 管理接口
- 限速服務
- 運行時配置
- 跟蹤
- V2 API參考
- 啟動引導
- 監聽&監聽發現
- 集群&集群發現
- 服務發現
- 健康檢查
- HTTP路由管理&發現
- TLS配置
- 通用的類型
- 網絡地址
- 協議選項
- 發現API
- 限速組件
- 過濾器
- 網絡過濾器
- TLS客戶端身份認證
- HTTP連接管理
- Mongo代理
- 速率限制
- Redis代理
- TCP代理
- HTTP過濾器
- 緩存
- 故障注入
- 健康檢查
- Lua
- 速率限制
- 路由
- gRPC-JSON轉碼器
- 常見訪問日志類型
- 常見故障注入類型
- FAQ
- Envoy有多快?
- 我在哪里獲得二進制文件?
- 我如何設置SNI?
- 如何設置區域感知路由?
- 我如何設置Zipkin跟蹤?