Nguon: Microsoft Learn · .NET 8.0

YARP — Transform (biến đổi) Request và Response

Nguồn: YARP Request and Response Transforms

Giới thiệu

Khi proxy (ủy quyền) một request, thường cần sửa đổi một số phần của request hoặc response để phù hợp với yêu cầu của máy chủ đích, hoặc để chuyển tiếp thêm thông tin như địa chỉ IP gốc của client. Quá trình này được thực hiện thông qua Transforms (các biến đổi). Các loại transform được định nghĩa toàn cục cho ứng dụng, sau đó mỗi route cung cấp tham số để bật và cấu hình các transform đó. Các đối tượng request gốc không bị sửa đổi bởi transform — chỉ có proxy request mới bị thay đổi.

Transform cho body của request và response không được YARP cung cấp sẵn, nhưng bạn có thể viết middleware để thực hiện điều này.

Mặc định

Các transform sau được bật mặc định cho tất cả các route. Chúng có thể được cấu hình hoặc tắt như được mô tả ở phần sau trong tài liệu này.

Ví dụ, request đến http://IncomingHost:5000/path:

code
GET /path HTTP/1.1
Host: IncomingHost:5000
Accept: */*
header1: foo

sẽ được transform và proxy tới máy chủ đích https://DestinationHost:6000/ như sau khi dùng các giá trị mặc định:

code
GET /path HTTP/1.1
Host: DestinationHost:6000
Accept: */*
header1: foo
X-Forwarded-For: 5.5.5.5
X-Forwarded-Proto: http
X-Forwarded-Host: IncomingHost:5000

Phân loại Transform

Transform được chia thành một số loại: Request, Response, và Response Trailers (xem trang transforms-response). Request trailers không được hỗ trợ vì HttpClient bên dưới không hỗ trợ chúng.

Nếu bộ transform tích hợp sẵn không đủ, có thể thêm transform tùy chỉnh thông qua extensibility (khả năng mở rộng).

Thêm Transform

Transform có thể được thêm vào route thông qua cấu hình hoặc bằng code.

Từ cấu hình (Configuration)

Transform có thể được cấu hình trên RouteConfig.Transforms và liên kết từ phần Routes của file cấu hình. Chúng có thể được sửa đổi và tải lại mà không cần khởi động lại proxy. Một transform được cấu hình bằng một hoặc nhiều cặp chuỗi key-value.

Dưới đây là ví dụ về các transform phổ biến:

json
{
  "ReverseProxy": {
    "Routes": {
      "route1" : {
        "ClusterId": "cluster1",
        "Match": {
          "Hosts": [ "localhost" ]
        },
        "Transforms": [
          { "PathPrefix": "/apis" },
          {
            "RequestHeader": "header1",
            "Append": "bar"
          },
          {
            "ResponseHeader": "header2",
            "Append": "bar",
            "When": "Always"
          },
          { "ClientCert": "X-Client-Cert" },
          { "RequestHeadersCopy": "true" },
          { "RequestHeaderOriginalHost": "true" },
          {
            "X-Forwarded": "Append",
            "HeaderPrefix": "X-Forwarded-"
          }
        ]
      },
      "route2" : {
        "ClusterId": "cluster1",
        "Match": {
          "Path": "/api/{plugin}/stuff/{**remainder}"
        },
        "Transforms": [
          { "PathPattern": "/foo/{plugin}/bar/{**remainder}" },
          {
            "QueryValueParameter": "q",
            "Append": "plugin"
          }
        ]
      }
    },
    "Clusters": {
      "cluster1": {
        "Destinations": {
          "cluster1/destination1": {
            "Address": "https://localhost:10001/Path/Base"
          }
        }
      }
    }
  }
}

Tất cả các mục cấu hình được xử lý không phân biệt chữ hoa/thường, mặc dù máy chủ đích có thể xử lý các giá trị kết quả theo cách phân biệt hoặc không phân biệt (ví dụ như path).

Nhà phát triển muốn tích hợp transform tùy chỉnh của mình với phần Transforms của cấu hình có thể làm điều đó bằng ITransformFactory được mô tả bên dưới.

Từ Code

Transform có thể được thêm vào route bằng code bằng cách gọi phương thức AddTransforms.

AddTransforms có thể được gọi sau AddReverseProxy để cung cấp một callback để cấu hình transform. Callback này được gọi mỗi khi một route được xây dựng hoặc xây dựng lại, và cho phép nhà phát triển kiểm tra thông tin RouteConfig và thêm transform có điều kiện cho route đó.

Callback AddTransforms cung cấp một TransformBuilderContext nơi các transform có thể được thêm hoặc cấu hình. Hầu hết các transform cung cấp các extension method cho TransformBuilderContext để dễ dàng thêm hơn.

TransformBuilderContext cũng bao gồm một IServiceProvider để truy cập bất kỳ service nào cần thiết.

csharp
services.AddReverseProxy()
    .LoadFromConfig(_configuration.GetSection("ReverseProxy"))
    .AddTransforms(builderContext =>
    {
        // Thêm vào tất cả các route.
        builderContext.AddPathPrefix("/prefix");

        // Thêm transform có điều kiện cho các route yêu cầu xác thực.
        if (!string.IsNullOrEmpty(builderContext.Route.AuthorizationPolicy))
        {
            builderContext.AddRequestTransform(async transformContext =>
            {
                transformContext.ProxyRequest.Headers.Add("CustomHeader", "CustomValue");
            });
        }
    });

Để kiểm soát nâng cao hơn, xem ITransformProvider được mô tả bên dưới.