YARP — Transform Request
Nguồn: YARP Request Transforms
Transform request bao gồm path, query, phiên bản HTTP, phương thức và header. Trong code, chúng được đại diện bởi đối tượng RequestTransformContext và được xử lý bởi các lớp kế thừa từ lớp trừu tượng RequestTransform.
Lưu ý:
- Scheme (http/https), authority và path base của proxy request được lấy từ địa chỉ máy chủ đích (ví dụ
https://localhost:10001/Path/Base) và không nên bị sửa đổi bởi transform. - Header Host có thể được ghi đè bởi transform độc lập với authority, xem RequestHeader bên dưới.
- Thuộc tính PathBase gốc của request không được dùng khi tạo proxy request, xem X-Forwarded.
- Tất cả header của request đến được sao chép sang proxy request theo mặc định, ngoại trừ header Host. Header X-Forwarded cũng được thêm theo mặc định. Các hành vi này có thể được cấu hình bằng các transform sau. Có thể chỉ định thêm header hoặc loại trừ header bằng cách đặt giá trị rỗng.
Dưới đây là các transform tích hợp sẵn được nhận dạng qua key cấu hình chính. Các transform này được áp dụng theo thứ tự được chỉ định trong cấu hình route.
PathPrefix
Sửa đổi path của request bằng cách thêm tiền tố
| Key | Value | Bắt buộc |
|---|---|---|
| PathPrefix | Một path bắt đầu bằng '/' | có |
Cấu hình:
{ "PathPrefix": "/prefix" }Code:
routeConfig = routeConfig.WithTransformPathPrefix(prefix: "/prefix");
transformBuilderContext.AddPathPrefix(prefix: "/prefix");
Ví dụ: /request/path trở thành /prefix/request/path
PathRemovePrefix
Sửa đổi path của request bằng cách xóa tiền tố
| Key | Value | Bắt buộc |
|---|---|---|
| PathRemovePrefix | Một path bắt đầu bằng '/' | có |
Cấu hình:
{ "PathRemovePrefix": "/prefix" }Code:
routeConfig = routeConfig.WithTransformPathRemovePrefix(prefix: "/prefix");
transformBuilderContext.AddPathRemovePrefix(prefix: "/prefix");
Ví dụ: /prefix/request/path trở thành /request/path; /prefix2/request/path không bị thay đổi.
Transform này xóa tiền tố khớp khỏi path của request. Việc khớp được thực hiện trên ranh giới path segment (/). Nếu tiền tố không khớp thì không có thay đổi nào được thực hiện.
PathSet
Thay thế path của request bằng giá trị được chỉ định
| Key | Value | Bắt buộc |
|---|---|---|
| PathSet | Một path bắt đầu bằng '/' | có |
Cấu hình:
{ "PathSet": "/newpath" }Code:
routeConfig = routeConfig.WithTransformPathSet(path: "/newpath");
transformBuilderContext.AddPathSet(path: "/newpath");
Ví dụ: /request/path trở thành /newpath
PathPattern
Thay thế path của request bằng một template pattern
| Key | Value | Bắt buộc |
|---|---|---|
| PathPattern | Một path template bắt đầu bằng '/' | có |
Cấu hình:
{ "PathPattern": "/my/{plugin}/api/{**remainder}" }Code:
routeConfig = routeConfig.WithTransformPathRouteValues(
pattern: new PathString("/my/{plugin}/api/{**remainder}"));transformBuilderContext.AddPathRouteValues(
pattern: new PathString("/my/{plugin}/api/{**remainder}"));Transform này đặt path của request với giá trị đã cho và thay thế bất kỳ segment {} nào bằng giá trị route tương ứng. Các segment {} không có giá trị route khớp sẽ bị xóa. Segment {} cuối cùng có thể được đánh dấu là {**remainder} để chỉ ra đây là segment catch-all có thể chứa nhiều path segment.
Ví dụ:
| Bước | Giá trị |
|---|---|
| Định nghĩa route | /api/{plugin}/stuff/{**remainder} |
| Path request | /api/v1/stuff/more/stuff |
| Giá trị plugin | v1 |
| Giá trị remainder | more/stuff |
| PathPattern | /my/{plugin}/api/{**remainder} |
| Kết quả | /my/v1/api/more/stuff |
QueryValueParameter
Thêm hoặc thay thế tham số trong query string của request
| Key | Value | Bắt buộc |
|---|---|---|
| QueryValueParameter | Tên tham số query string | có |
| Set/Append | Giá trị tĩnh | có |
Cấu hình:
{
"QueryValueParameter": "foo",
"Append": "bar"
}Code:
routeConfig = routeConfig.WithTransformQueryValue(
queryKey: "foo", value: "bar", append: true);transformBuilderContext.AddQueryValue(
queryKey: "foo", value: "bar", append: true);Ví dụ:
| Bước | Giá trị |
|---|---|
| Query | ?a=b |
| QueryValueParameter | foo |
| Append | remainder |
| Kết quả | ?a=b&foo=remainder |
QueryRouteParameter
Thêm hoặc thay thế tham số query string bằng giá trị từ cấu hình route
| Key | Value | Bắt buộc |
|---|---|---|
| QueryRouteParameter | Tên tham số query string | có |
| Set/Append | Tên của một giá trị route | có |
Cấu hình:
{
"QueryRouteParameter": "foo",
"Append": "remainder"
}Code:
routeConfig = routeConfig.WithTransformQueryRouteValue(
queryKey: "foo", routeValueKey: "remainder", append: true);transformBuilderContext.AddQueryRouteValue(
queryKey: "foo", routeValueKey: "remainder", append: true);Ví dụ:
| Bước | Giá trị |
|---|---|
| Định nghĩa route | /api/{*remainder} |
| Path request | /api/more/stuff |
| Giá trị remainder | more/stuff |
| QueryRouteParameter | foo |
| Append | remainder |
| Kết quả | ?foo=more/stuff |
QueryRemoveParameter
Xóa tham số được chỉ định khỏi query string của request
| Key | Value | Bắt buộc |
|---|---|---|
| QueryRemoveParameter | Tên tham số query string | có |
Cấu hình:
{ "QueryRemoveParameter": "foo" }Code:
routeConfig = routeConfig.WithTransformQueryRemoveKey(queryKey: "foo");
transformBuilderContext.AddQueryRemoveKey(queryKey: "foo");
Ví dụ:
| Bước | Giá trị |
|---|---|
| Path request | ?a=b&foo=c |
| QueryRemoveParameter | foo |
| Kết quả | ?a=b |
HttpMethodChange
Thay đổi HTTP method được dùng trong request
| Key | Value | Bắt buộc |
|---|---|---|
| HttpMethodChange | HTTP method cần thay thế | có |
| Set | HTTP method mới | có |
Cấu hình:
{
"HttpMethodChange": "PUT",
"Set": "POST"
}Code:
routeConfig = routeConfig.WithTransformHttpMethodChange(
fromHttpMethod: HttpMethods.Put, toHttpMethod: HttpMethods.Post);transformBuilderContext.AddHttpMethodChange(
fromHttpMethod: HttpMethods.Put, toHttpMethod: HttpMethods.Post);Transform này sẽ đổi các request PUT thành POST.
RequestHeadersCopy
Đặt có sao chép header của request đến sang request đi hay không
| Key | Value | Mặc định | Bắt buộc |
|---|---|---|---|
| RequestHeadersCopy | true/false | true | có |
Cấu hình:
{ "RequestHeadersCopy": "false" }Code:
routeConfig = routeConfig.WithTransformCopyRequestHeaders(copy: false);
transformBuilderContext.CopyRequestHeaders = false;
Đặt xem có sao chép tất cả header của request đến vào proxy request không. Cài đặt này được bật mặc định và có thể tắt bằng cách cấu hình transform với giá trị false. Các transform tham chiếu đến header cụ thể vẫn sẽ chạy nếu cài đặt này bị tắt.
RequestHeaderOriginalHost
Chỉ định xem header Host của request đến có nên được sao chép sang proxy request không
| Key | Value | Mặc định | Bắt buộc |
|---|---|---|---|
| RequestHeaderOriginalHost | true/false | false | có |
Cấu hình:
{ "RequestHeaderOriginalHost": "true" }Code:
routeConfig = routeConfig.WithTransformUseOriginalHostHeader(useOriginal: true);
transformBuilderContext.AddOriginalHost(true);
Cài đặt này bị tắt mặc định và có thể bật bằng cách cấu hình transform với giá trị true. Các transform tham chiếu trực tiếp đến header Host sẽ ghi đè transform này.
RequestHeader
Thêm hoặc thay thế header của request
| Key | Value | Bắt buộc |
|---|---|---|
| RequestHeader | Tên header | có |
| Set/Append | Giá trị header | có |
Cấu hình:
{
"RequestHeader": "MyHeader",
"Set": "MyValue"
}Code:
routeConfig = routeConfig.WithTransformRequestHeader(
headerName: "MyHeader", value: "MyValue", append: false);transformBuilderContext.AddRequestHeader(
headerName: "MyHeader", value: "MyValue", append: false);Ví dụ:
MyHeader: MyValue
Transform này đặt hoặc nối thêm giá trị cho header được đặt tên. Set thay thế bất kỳ header hiện có nào. Append thêm một header bổ sung với giá trị đã cho. Lưu ý: việc đặt "" làm giá trị header không được khuyến nghị và có thể gây ra hành vi không xác định.
RequestHeaderRouteValue
Thêm hoặc thay thế header bằng giá trị từ cấu hình route
| Key | Value | Bắt buộc |
|---|---|---|
| RequestHeaderRouteValue | Tên header | có |
| Set/Append | Tên của một giá trị route | có |
Cấu hình:
{
"RequestHeaderRouteValue": "MyHeader",
"Set": "MyRouteKey"
}Code:
routeConfig = routeConfig.WithTransformRequestHeaderRouteValue(
headerName: "MyHeader", routeValueKey: "key", append: false);transformBuilderContext.AddRequestHeaderRouteValue(
headerName: "MyHeader", routeValueKey: "key", append: false);Ví dụ:
| Bước | Giá trị |
|---|---|
| Định nghĩa route | /api/{*remainder} |
| Path request | /api/more/stuff |
| Giá trị remainder | more/stuff |
| RequestHeaderFromRoute | foo |
| Append | remainder |
| Kết quả | foo: more/stuff |
RequestHeaderRemove
Xóa header của request
| Key | Value | Bắt buộc |
|---|---|---|
| RequestHeaderRemove | Tên header | có |
Cấu hình:
{
"RequestHeaderRemove": "MyHeader"
}Code:
routeConfig = routeConfig.WithTransformRequestHeaderRemove(headerName: "MyHeader");
transformBuilderContext.AddRequestHeaderRemove(headerName: "MyHeader");
Transform này xóa header có tên được chỉ định.
RequestHeadersAllowed
| Key | Value | Bắt buộc |
|---|---|---|
| RequestHeadersAllowed | Danh sách tên header được phép, phân tách bằng dấu chấm phẩy. | có |
Cấu hình:
{
"RequestHeadersAllowed": "Header1;header2"
}Code:
routeConfig = routeConfig.WithTransformRequestHeadersAllowed("Header1", "header2");transformBuilderContext.AddRequestHeadersAllowed("Header1", "header2");YARP sao chép hầu hết header request sang proxy request theo mặc định (xem RequestHeadersCopy). Một số mô hình bảo mật chỉ cho phép proxy các header cụ thể. Transform này tắt RequestHeadersCopy và chỉ sao chép các header được chỉ định.
Lưu ý rằng có một số header YARP không sao chép mặc định vì chúng đặc thù cho kết nối hoặc nhạy cảm về bảo mật (ví dụ Connection, Alt-Svc). Việc đặt những tên header đó vào danh sách cho phép sẽ bỏ qua hạn chế đó nhưng rất không được khuyến khích.
Ví dụ: chỉ header1 và header2 được sao chép vào proxy request.
X-Forwarded
Thêm header với thông tin về request gốc của client
| Key | Value | Mặc định | Bắt buộc |
|---|---|---|---|
| X-Forwarded | Hành động mặc định (Set, Append, Remove, Off) áp dụng cho tất cả X-Forwarded-\* | Set | có |
| For | Hành động áp dụng cho header này | \* Xem X-Forwarded | không |
| Proto | Hành động áp dụng cho header này | \* Xem X-Forwarded | không |
| Host | Hành động áp dụng cho header này | \* Xem X-Forwarded | không |
| Prefix | Hành động áp dụng cho header này | \* Xem X-Forwarded | không |
| HeaderPrefix | Tiền tố tên header | "X-Forwarded-" | không |
Hành động "Off" hoàn toàn tắt transform.
Cấu hình:
{
"X-Forwarded": "Set",
"For": "Remove",
"Proto": "Append",
"Prefix": "Off",
"HeaderPrefix": "X-Forwarded-"
}Code:
routeConfig = routeConfig.WithTransformXForwarded( headerPrefix = "X-Forwarded-", ForwardedTransformActions xDefault = ForwardedTransformActions.Set, ForwardedTransformActions? xFor = null, ForwardedTransformActions? xHost = null, ForwardedTransformActions? xProto = null, ForwardedTransformActions? xPrefix = null);
transformBuilderContext.AddXForwarded(ForwardedTransformActions.Set); transformBuilderContext.AddXForwardedFor(headerName: "X-Forwarded-For", ForwardedTransformActions.Append); transformBuilderContext.AddXForwardedHost(headerName: "X-Forwarded-Host", ForwardedTransformActions.Append); transformBuilderContext.AddXForwardedProto(headerName: "X-Forwarded-Proto", ForwardedTransformActions.Off); transformBuilderContext.AddXForwardedPrefix(headerName: "X-Forwarded-Prefix", ForwardedTransformActions.Remove);
Ví dụ:
X-Forwarded-For: 5.5.5.5 X-Forwarded-Proto: https X-Forwarded-Host: IncomingHost:5000 X-Forwarded-Prefix: /path/base
Tắt header mặc định:
{ "X-Forwarded": "Off" }transformBuilderContext.UseDefaultForwarders = false;
Khi proxy kết nối đến máy chủ đích, kết nối đó độc lập với kết nối client đã tạo tới proxy. Máy chủ đích có thể cần thông tin kết nối gốc để kiểm tra bảo mật và tạo URI tuyệt đối cho các liên kết và chuyển hướng đúng cách.
Transform này được bật mặc định ngay cả khi không được chỉ định trong cấu hình route.
{Prefix}For: Giá trị header được lấy từ HttpContext.Connection.RemoteIpAddress — địa chỉ IP của caller trước đó.
{Prefix}Proto: Giá trị header được lấy từ HttpContext.Request.Scheme — cho biết caller trước đó đã sử dụng HTTP hay HTTPS.
{Prefix}Host: Giá trị header được lấy từ header Host của request đến. Điều này độc lập với RequestHeaderOriginalHost.
{Prefix}Prefix: Giá trị header được lấy từ HttpContext.Request.PathBase.
Forwarded
Thêm header với thông tin về request gốc của client (theo chuẩn RFC)
| Key | Value | Mặc định | Bắt buộc |
|---|---|---|---|
| Forwarded | Danh sách phân tách bằng dấu phẩy có thể chứa: for, by, proto, host | (none) | có |
| ForFormat | Random/RandomAndPort/RandomAndRandomPort/Unknown/UnknownAndPort/UnknownAndRandomPort/Ip/IpAndPort/IpAndRandomPort | Random | không |
| ByFormat | Random/RandomAndPort/RandomAndRandomPort/Unknown/UnknownAndPort/UnknownAndRandomPort/Ip/IpAndPort/IpAndRandomPort | Random | không |
| Action | Hành động áp dụng (Set, Append, Remove, Off) | Set | không |
Cấu hình:
{
"Forwarded": "by,for,host,proto",
"ByFormat": "Random",
"ForFormat": "IpAndPort",
"Action": "Append"
}Code:
routeConfig = routeConfig.WithTransformForwarded(
useHost: true, useProto: true, forFormat: NodeFormat.IpAndPort,
ByFormat: NodeFormat.Random, action: ForwardedTransformAction.Append);Ví dụ:
Forwarded: proto=https;host="localhost:5001";for="[::1]:20173";by=_YQuN68tm6
Header Forwarded được định nghĩa bởi RFC 7239. Nó hợp nhất nhiều chức năng giống với các header X-Forwarded không chính thức.
Bật transform này sẽ tắt các transform X-Forwarded mặc định vì chúng mang thông tin tương tự ở định dạng khác. Các transform X-Forwarded vẫn có thể được bật tường minh.
Định dạng ByFormat và ForFormat:
| Định dạng | Mô tả | Ví dụ |
|---|---|---|
| Random | Định danh bị làm mờ được tạo ngẫu nhiên mỗi request | by=_YQuN68tm6 |
| RandomAndPort | Định danh Random cộng với port | by="_YQuN68tm6:80" |
| RandomAndRandomPort | Định danh Random cộng với định danh ngẫu nhiên cho port | by="_YQuN68tm6:_jDw5Cf3tQ" |
| Unknown | Dùng khi không biết danh tính của thực thể trước | by=unknown |
| UnknownAndPort | Unknown cộng với port nếu có | by="unknown:80" |
| UnknownAndRandomPort | Unknown cộng với định danh ngẫu nhiên cho port | by="unknown:_jDw5Cf3tQ" |
| Ip | Địa chỉ IPv4 hoặc IPv6 kèm ngoặc vuông | by="[::1]" |
| IpAndPort | Địa chỉ IP cộng với port | by="[::1]:80" |
| IpAndRandomPort | Địa chỉ IP cộng với định danh ngẫu nhiên cho port | by="[::1]:_jDw5Cf3tQ" |
ClientCert
Chuyển tiếp chứng chỉ client được dùng trên kết nối đến như một header tới đích
| Key | Value | Bắt buộc |
|---|---|---|
| ClientCert | Tên header | có |
Cấu hình:
{ "ClientCert": "X-Client-Cert" }Code:
routeConfig = routeConfig.WithTransformClientCertHeader(headerName: "X-Client-Cert");
transformBuilderContext.AddClientCertHeader(headerName: "X-Client-Cert");
Ví dụ:
X-Client-Cert: SSdtIGEgY2VydGlmaWNhdGU...
Vì kết nối đến và đi là độc lập, cần có cách truyền chứng chỉ client đến sang máy chủ đích. Transform này khiến chứng chỉ client (lấy từ HttpContext.Connection.ClientCertificate) được mã hóa Base64 và đặt làm giá trị cho tên header đã cho.
Transform này chỉ áp dụng nếu chứng chỉ client đã có trên kết nối.