Request and response transformations (2023)

Introduction

When proxiing a request, it is common to change parts of the request or response to fit the needs of the destination server, or to pass additional data, such as the original IP address of the client. This process is implemented through transformations. Transformation types are defined globally for the application, and then individual routes provide the parameters to enable and configure those transformations. These transformations do not modify the original request objects, only the proxy requests.

YARP does not provide the request and response body transformations, but you can write a middleware for them.

predetermined values

The following transformations are enabled by default for all streams. They can be configured or disabled as shown later in this document.

  • Host – Suppresses the Host header from the incoming request. The proxy request defaults to the host name specified in the destination server address. WatchRequestHeaderOriginalHostunder.
  • X-Forwarded-For – Sets the client's IP address in the X-Forwarded-For header. WatchX-forwardedunder.
  • X-Forwarded-Proto – Sets the original scheme of the request (http/https) in the X-Forwarded-Proto header. WatchX-forwardedunder.
  • X-Forwarded-Host – Sets the original host of the request in the X-Forwarded-Host header. WatchX-forwardedunder.
  • X-Forwarded-Prefix – Sets the request's original PathBase, if any, in the X-Forwarded-Prefix header. WatchX-forwardedunder.

For example, the following incoming requesthttp://IncomingHost:5000/Pfad:

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

transformed and forwarded to destination serverhttps://Zielhost:6000/as follows using these default values:

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

transform categories

Transformations fall into a few categories: request, response, and response trailer. Request trailers are not supported because the underlying HttpClient does not support them.

add transformations

Transforms can be added to routes through configuration or programmatically.

from settings

Transformations can be configuredRouteConfig.Transformsand may be subject toroutessections of the configuration file. These can be modified and reloaded without restarting the proxy. A transformation is configured using one or more key-value string pairs.

Here is an example of common transformations:

{ "ReverseProxy": { "Routes": { "route1": { "ClusterId": "cluster1", "Match": { "Hosts": [ "localhost" ] }, "Transformations": [ { "PathPrefix": "/apis" }, { "RequestHeader": "header1", "Append": "bar" }, { "ResponseHeader": "header2", "Append": "bar", "When": "Always" }, { "ClientCert": "X-Client-Cert" }, { "RequestHeadersCopy": "true" }, { "RequestHeaderOriginalHost": "true" }, { "X-Forwarded": "proto,host,for,prefix" , "Add": "true", "Prefix": "X-Forwarded-" } ] }, "route2": { "ClusterId": "cluster1", "Match": { "Route": "/api/{ plugin}/stuff/{**other}" }, "Transformations": [ { "PathPattern": "/foo/{plugin}/bar/{**other}" }, { "QueryValueParameter": "q", "Anhängen": "Plugin" } ] } }, "Cluster": { "Cluster1": { "Ziele": { "Cluster1/Ziel1": { "Address": "https://localhost:10001/Pfad/Basis " } } } } }}

All configuration entries are case sensitive, although the target server may treat the resulting values ​​as case, e.g. B. the way.

The details of these transformations are discussed later in this document.

Developers who want to integrate their custom transformations into thetransformedThe configuration section can do this withITransformFactorydescribed below.

by code

Transformations can be added to routes programmatically by callingadd transformationsMethod.

add transformationscan be calledStart.ConfigureServicesto provide a callback to configure transformations. This callback is called each time a route is created or re-created and allows the developerRouteConfiginformation and conditionally add transformations to it.

Whatadd transformationscallback offers aTransformBuilderContextwhere transformations can be added or configured. Most transformations offerTransformBuilderContextExtension methods for easy addition. These are extensions that are documented below with the individual transform descriptions.

WhatTransformBuilderContextalso includes oneIServiceProviderto access the required services.

services.AddReverseProxy() .LoadFromConfig(_configuration.GetSection("ReverseProxy")).AddTransforms(builderContext => { // Agregado a todas las rutas builderContext.AddPathPrefix("/prefix"); // Agrega condicionalmente una transformación para rutas que Autenticación requerido si (!string.IsNullOrEmpty(builderContext.Route.AuthorizationPolicy)) { builderContext.AddRequestTransform(async transformContext => { transformContext.ProxyRequest.Headers.Add("CustomHeader", "CustomValue"); }); } });

For advanced control seeITransformProviderdescribed below.

Request transformations

Request transformations include the request path, query, HTTP version, method, and headers. In the code, these are represented by theRequestTransformContextObject and processed by abstract class implementationsrequest transformation.

Observations:

  • The proxy request scheme (http/https), authority, and route base are derived from the address of the destination server (https://localhost:10001/ruta/basein the example above) and should not be changed by transforms.
  • The host header can be overridden by transformations regardless of authority, seerequest headerunder.
  • The request's original PathBase property is not used when constructing the proxy request, seeX-forwarded.
  • All incoming request headers are copied to the proxy request by default, except for the host header (seepredetermined values).X-forwardedHeaders are also added by default. These behaviors can be configured using the following transformations. Additional request headers can be specified or request headers can be excluded by setting them to an empty value.

The following are built-in transforms identified by their primary configuration key. These transformations are applied in the order that they are specified in the stream configuration.

route prefix

Change the request path and add a prefix value

GustoWertNecessary
route prefixA path beginning with '/'Yes actually

Setting:

{ "prefixpath": "/prefix" }

Code:

routeConfig = routeConfig.WithTransformPathPrefix(prefix: "/prefix");
transformBuilderContext.AddPathPrefix(prefix: "/prefix");

Example:
/request/pathbecomes/prefix/request/route

This prepends the specified value to the request path.

RutaEliminarPrefijo

Change the request path and remove a prefix value

GustoWertNecessary
RutaEliminarPrefijoA path beginning with '/'Yes actually

Setting:

{ "PathRemovePrefix": "/prefix" }

Code:

routeConfig = routeConfig.WithTransformPathRemovePrefix(prefix: "/prefix");
transformBuilderContext.AddPathRemovePrefix(prefix: "/prefix");

Example:
/prefix/request/routebecomes/request/path
/prefix2/request/routewill not be modified

This removes the matching prefix from the request route. Matches are made at route segment boundaries (/). If the prefix does not match, no changes are made.

PfadSet

Replaces the request path with the specified value

GustoWertNecessary
PfadSetA path beginning with '/'Yes actually

Setting:

{ "PathSet": "/neuerPfad" }

Code:

routeConfig = routeConfig.WithTransformPathSet(ruta: "/nuevaruta");
transformBuilderContext.AddPathSet(ruta: "/nuevaruta");

Example:
/request/pathbecomes/new way

This sets the request path to the specified value.

route pattern

Replace the request path with a sample template

GustoWertNecessary
route patternA route template beginning with "/".Yes actually

Setting:

(Video) Kong Gateway Request & Response Transformation Plugins | #KongBuilders – August 20

{ "PathPattern": "/mi/{complement}/api/{**rest}" }

Code:

routeConfig = routeConfig.WithTransformPathRouteValues(patrón: nueva PathString("/my/{plugin}/api/{**remainder}"));
transformBuilderContext.AddPathRouteValues(patrón: nueva PathString("/my/{plugin}/api/{**remainder}"));

This sets the request path to the specified value and replaces each{}Segments with the associated route value.{}Segments without a matching path value are removed. The end{}The segment can be marked as{**Rest}to indicate that this is a capture segment that can contain multiple route segments. See ASP.NET Corerouting documentsfor more information on route templates.

Example:

PasoWert
route definition/api/{plugin}/stuff/{**rest}
request path/api/v1/stuff/more/stuff
plugin valuev1
valor residualmore things
route pattern/mi/{complement}/api/{**rest}
result/my/v1/api/more/stuff

QueryValueParameter

Add or replace parameters in the request query string

GustoWertNecessary
QueryValueParameterName of a query string parameterYes actually
Set/Appendstatic valueYes actually

Setting:

{ "QueryValueParameter": "foo", "Add": "bar"}

Code:

routeConfig = routeConfig.WithTransformQueryValue(queryKey: "foo", value: "bar", append: true);
transformBuilderContext.AddQueryValue(queryKey: "foo", value: "bar", append: true);

This will add a query string parameter calledFooand sets it to the static valueBar.

Example:

PasoWert
query?a=b
QueryValueParameterFoo
to attachRest
result?a=b&foo=Change

QueryRouteParameter

Add a query string parameter or replace it with a value from the route configuration

GustoWertNecessary
QueryRouteParameterName of a query string parameterYes actually
Set/AppendThe name of a route valueYes actually

Setting:

{ "QueryRouteParameter": "foo", "Agregar": "Rest"}

Code:

routeConfig = routeConfig.WithTransformQueryRouteValue(queryKey: "foo", routeValueKey: "resto", agregar: verdadero);
transformBuilderContext.AddQueryRouteValue(queryKey: "foo", routeValueKey: "rest", add: true);

This will add a query string parameter calledFooand sets it to the value of the associated path value.

Example:

PasoWert
route definition/api/{*Rest}
request path/api/more/stuff
valor residualmore things
QueryRouteParameterFoo
to attachRest
result?foo=more/stuff

QueryRemoveParameter

Removes the specified parameter from the request query string

GustoWertNecessary
QueryRemoveParameterName of a query string parameterYes actually

Setting:

{ "QueryRemoveParameter": "foo" }

Code:

routeConfig = routeConfig.WithTransformQueryRemoveKey(queryKey: "foo");
transformBuilderContext.AddQueryRemoveKey(queryKey: "foo");

This removes a query string parameter namedFooif available upon request.

Example:

PasoWert
request path?a=b&foo=c
QueryRemoveParameterFoo
result?a=b

HttpMethodChange

Changes the HTTP method used in the request.

GustoWertNecessary
HttpMethodChangeThe http method to replaceYes actually
PhraseThe new http methodYes actually

Setting:

{ "HttpMethodChange": "PUT", "Establecer": "POST",}

Code:

routeConfig = routeConfig.WithTransformHttpMethodChange (fromHttpMethod: HttpMethods.Put, toHttpMethod: HttpMethods.Post);
transformBuilderContext.AddHttpMethodChange (desde HttpMethod: HttpMethods.Put, hasta HttpMethod: HttpMethods.Post);

This changes PUT requests to POST.

RequestHeadersCopy

Determines whether headers from incoming requests are copied to the outgoing request

GustoWertStandardNecessary
RequestHeadersCopytrue FalseIt is rightYes actually

Setting:

{ "RequestHeadersCopy": "falso" }

Code:

routeConfig = routeConfig.WithTransformCopyRequestHeaders(copia: falso);
transformBuilderContext.CopyRequestHeaders = falso;

This determines if all incoming request headers are copied to the proxy request. This setting is on by default and can be turned off by configuring the transformation with aINCORRECTWorth. Transformations that reference specific headers will continue to run when this is disabled.

RequestHeaderOriginalHost

Indicates whether the host header of the incoming request should be copied to the proxy request

GustoWertStandardNecessary
RequestHeaderOriginalHosttrue FalseINCORRECTYes actually

Setting:

{ "RequestHeaderOriginalHost": "verdadero" }
routeConfig = routeConfig.WithTransformUseOriginalHostHeader(useOriginal: true);
transformBuilderContext.AddOriginalHost(true);

This specifies whether the host header of the incoming request should be copied to the proxy request. This setting is disabled by default and can be enabled by configuring the transformation with aIt is rightWorth. Transformations that refer directly to thehostThe header overrides this transformation.

request header

Add or replace request headers

GustoWertNecessary
request headerThe name of the headerYes actually
Set/AppendThe header valueYes actually

Setting:

{ "RequestHeader": "MyHeader", "Set": "MyValue",}

Code:

routeConfig = routeConfig.WithTransformRequestHeader(headerName: "MyHeader", value: "MyValue", append: false);
transformBuilderContext.AddRequestHeader(headerName: "MyHeader", value: "MyValue", append: false);

Example:

MiEncabezado: MeinWert

This sets or adds the value for the named header. Set replaces all existing headers. Append adds an additional header with the specified value. Note: Setting "" as the header value is not recommended and may result in undefined behavior.

RequestHeaderRemove

Remove request headers

GustoWertNecessary
RequestHeaderRemoveThe name of the headerYes actually

Setting:

{ "RequestHeaderRemove": "MiEncabezado"}

Code:

(Video) OmniStudio: Integration Procedure - Send and Response Transformations #16 | 0to1Code

routeConfig = routeConfig.WithTransformRequestHeaderRemove(headerName: "MyHeader");
transformBuilderContext.AddRequestHeaderRemove(headerName: "MyHeader");

Example:

MiEncabezado: MiValorOtroEncabezado: OtroValor

This removes the named header.

Allowed Request Headers

GustoWertNecessary
Allowed Request HeadersA semicolon-separated list of allowed header names.Yes actually

Setting:

{ "RequestHeadersAllowed": "Header1;Header2"}

Code:

routeConfig = routeConfig.WithTransformRequestHeadersAllowed("Header1", "header2");
transformBuilderContext.AddRequestHeadersAllowed("Header1", "Header2");

By default, YARP copies most of the request headers into the proxy request (seeRequestHeadersCopy). Some security models only allow certain headers to be forwarded. This transformation disables RequestHeadersCopy and copies only the specified headers. Other transformations that modify or add existing headers may be affected if they are not on the allow list.

Note that there are some headers that YARP does not copy by default because they are connection-specific or security-related (for example,Connection,Alt-Svc). Adding these header names to the allow list bypasses this restriction, but is strongly discouraged as it may break proxy functionality or introduce security vulnerabilities.

Example:

Header1: value1Header2: value2OtherHeader: OtherValue

Only Header1 and Header2 are copied to the proxy request.

X-forwarded

Add headers with information about the original client's request

GustoWertStandardNecessary
X-forwardedDefault Action (Set, Add, Delete, Disable) to be applied to all X-Forwarded-* listed belowPhraseYes actually
TowardsAction to apply to this header* See X-Forwardedno
prototypeAction to apply to this header* See X-Forwardedno
hostAction to apply to this header* See X-Forwardedno
prefixAction to apply to this header* See X-Forwardedno
header prefixThe header name prefix"X-Redirected-"no

The "Off" action disables the transformation completely.

Setting:

{ "X-Forwarded": "Set", "For": "Remove", "Proto": "Add", "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(ForwardedTransformAction.Set);transformBuilderContext.AddXForwardedFor(headerName: "X-Forwarded-For", ForwardedTransformAction.Append);transformBuilderContext.AddXForwardedHost(headerName: "X-Forwarded-Host", ForwardedTransformAction.Append);transformBuilderContext.AddXForwardedProto (headerName: „X-Forwarded-Proto“, ForwardedTransformAction.Off); transformBuilderContext.AddXForwardedPrefix(headerName: „X-Forwarded-Prefix“, ForwardedTransformAction.Remove);

Example:

X-Forwarded-For: 5.5.5.5X-Forwarded-Proto: httpsX-Forwarded-Host: IncomingHost:5000X-Forwarded-Prefix: /ruta/base

Disable standard headers:

{ "X-Forward": "Off" }
transformBuilderContext.UseDefaultForwarders = falso;

When the proxy connects to the target server, the connection is separate from the one the client made to the proxy. The destination server probably needs original connection information for security checks and to correctly generate absolute URIs for bindings and redirects. A set of additional headers can be added to allow information about the client's connection to be passed to the destination. untilresentA standard has been created, a common solution should be usedX-forwarded-*headers There is no official standard that defines this.X-forwarded-*Headers and implementations vary, check your destination server for support.

This transform is enabled by default, even if it is not specified in the stream configuration.

set thoseX-forwardedvalue to a comma-separated list of the headers you need to enable. All headers are enabled by default. All can be disabled by specifying the value"Outside".

The prefix specifies the header name prefix to use for each header. with defaultX-forwarded-The prefix will be the resulting headers.x-forwarded-to,X-Forwarded-Proto,Forwarded Host X, yForwarded Prefix X.

The transform action specifies how each header should be combined with an existing header of the same name. It can be "Set", "Append", "Remove" or "Disable" (disable conversion completely) If the action is "Set" and the associated value is not available in the request (for example, RemoteIpAddress is null), any header is still stripped to prevent spoofing.

Se toma el valor {Prefix}For HeaderHttpContext.Connection.RemoteIpAddresswhich represents the IP address of the previous caller. The port is not included. IPv6 addresses do not contain any limitations.[]supports.

The value of the {Prefix}Proto header is takenHttpContext.Request.SchemeIndicates whether the previous caller used HTTP or HTTPS.

The host header value {Prefix} is taken from the host header of the incoming request. This is independent of the RequestHeaderOriginalHost specified above. Unicode/IDN hosts are encoded with Punycode.

The value of the {Prefix}Prefix header is adoptedHttpContext.Request.PathBase. The PathBase property is not used when generating the proxy request, so the destination server needs the original value to correctly generate bindings and redirects. The value is in percent-encoded Uri format.

resent

Adds a header with information about the original client's request

GustoWertStandardNecessary
resentA comma-separated list containing one of these values: for,by,proto,host(none)Yes actually
for formatRandom/RandomAndPort/RandomAndRandomPort/Unknown/UnknownAndPort/UnknownAndRandomPort/Ip/IpYPort/IpAndRandomPortcasuallyno
By formatRandom/RandomAndPort/RandomAndRandomPort/Unknown/UnknownAndPort/UnknownAndRandomPort/Ip/IpYPort/IpAndRandomPortcasuallyno
actionAction to apply to this header (set, add, remove, disable)Phraseno

Setting:

{ "Forwarded": "by, to, host, prototype", "ByFormat": "Random", "ForFormat": "IpAndPort", "Action": "Add"},

Code:

routeConfig = routeConfig.WithTransformForwarded(useHost: true, useProto: true, forFormat: NodeFormat.IpAndPort, ByFormat: NodeFormat.Random, action: ForwardedTransformAction.Append);
transformBuilderContext.AddForwarded(useHost: true, useProto: true, forFormat: NodeFormat.IpAndPort, ByFormat: NodeFormat.Random, action: ForwardedTransformAction.Append);

Example:

Weitergeleitet: proto=https;host="localhost:5001";for="[::1]:20173";by=_YQuN68tm6

WhatresentThe header is defined byRFC-7239. It consolidates many of the same functions as unofficial X-Forwarded headers and forwards information to the destination server that would otherwise be obfuscated through the use of a proxy.

Enabling this transform disables the standard X-Forwarded transforms, as they contain similar information in a different format. X-Forwarded transforms can still be enabled explicitly.

Action: This specifies how the transformation should handle an existing Forwarded header. It can be "Set", "Append", "Delete" or "Off" (disable conversion completely) as its original value.

Proto: It is worth adoptingHttpContext.Request.SchemeIndicates whether the previous caller used HTTP or HTTPS.

Host – This value is taken from the host header of the incoming request. This is independent of the RequestHeaderOriginalHost specified above. Unicode/IDN hosts are encoded with Punycode.

To: This value identifies the previous caller. IP addresses are extractedHttpContext.Connection.RemoteIpAddress. See ByFormat and ForFormat below for more details.

By: This value indicates where the proxy received the request. IP addresses are extractedHttpContext.Connection.LocalIpAddress. See ByFormat and ForFormat below for more details.

By format and by format:

The RFC allows avariety of formatsfor the From and To fields. Requires the standard format for using an obfuscated identifier, referred to here as random.

Formatdescriptionexample
casuallyA randomly generated obfuscated identifier per request. This enables diagnostic tracking scenarios while limiting the flow of uniquely identifiable information for privacy reasons.by=_YQuN68tm6
RandomAndPortThe random identifier plus the port.by="_YQuN68tm6:80"
RandomAndRandomPortThe random identifier plus another random identifier for the port.por="_YQuN68tm6:_jDw5Cf3tQ"
unknownThis can be used when the identity of the previous entity is not known, but the proxy still wants to signal that the request has been forwarded.from=unknown
UnknownAndPortThe unknown identifier plus the port if available.by = "unknown: 80"
Unknown and random portThe unknown identifier plus a random identifier for the port.by="unknown:_jDw5Cf3tQ"
IPAn IPv4 address or an IPv6 address in parentheses.von="[::1]"
IP y puertoThe IP address plus the port.von="[::1]:80"
random IP and portThe IP address plus a random identifier for the port.por="[::1]:_jDw5Cf3tQ"

client certificate

Forwards the client certificate used for the incoming connection as a header to the destination

(Video) Http Methods

GustoWertNecessary
client certificateThe name of the headerYes actually

Setting:

{ "ClientCert": "X Client Certificate" }

Code:

routeConfig = routeConfig.WithTransformClientCertHeader(headerName: "X-Client-Cert");
transformBuilderContext.AddClientCertHeader(headerName: "X-Client-Cert");

Example:

X client certificate: SSdtIGEgY2VydGlmaWNhdGU...

Since incoming and outgoing connections are independent of each other, there must be a way to forward all incoming client certificates to the destination server. This transformation causes the client certificate to be adoptedHttpContext.Connection.ClientCertificateBase64 encoded and set as the value for the specified header name. The destination server may need this certificate to authenticate the client. There is no standard that defines this header and implementations vary, please check with your destination server for support.

By default, servers perform minimal verification of the incoming client certificate. The certificate must be validated at the proxy or at the destination, seeClient certificate authenticationdocuments for more details.

This transformation only applies if the client certificate already exists for the connection. Watch theoptional doc certificateif it needs to be requested by the customer by route.

Reply and Reply Trailer

All response headers and trailers are copied from the proxy response to the outgoing client response by default. The answer and answer advance transformations can specify whether to apply only to correct answers or to all answers.

In code, these are implemented as derivatives of abstract classes.ResponseTransformyResponseFollowerTransform.

ResponseHeadersCopy

Determines whether destination response headers are copied to the client

GustoWertStandardNecessary
ResponseHeadersCopytrue FalseIt is rightYes actually

Setting:

{ "ResponseHeadersCopy": "falso" }

Code:

routeConfig = routeConfig.WithTransformCopyResponseHeaders(copia: falso);
transformBuilderContext.CopyResponseHeaders = falso;

This determines if all the proxy response headers are copied into the client response. This setting is on by default and can be turned off by configuring the transformation with aINCORRECTWorth. Transformations that reference specific headers will continue to run when this is disabled.

response header

Add or replace response headers

GustoWertStandardNecessary
response headerThe name of the header(none)Yes actually
Set/AppendThe header value(none)Yes actually
WhenSuccess/Always/Failuresuccessno

Setting:

{ "ResponseHeader": "HeaderName", "Add": "value", "When": "Success"}

Code:

routeConfig = routeConfig.WithTransformResponseHeader(headerName: "HeaderName", value: "value", append: true, ResponseCondition.Success);
transformBuilderContext.AddResponseHeader(headerName: "HeaderName", value: "value", append: true, always: ResponseCondition.Success);

Example:

Header Name: Wert

This sets or adds the value for the named response header. Set replaces all existing headers. Append adds an additional header with the specified value. Note: Setting "" as the header value is not recommended and may result in undefined behavior.

Whenspecifies whether to include the response header for all responses, successful or failed. Any response with a status code less than 400 is considered a success.

ResponseHeaderRemove

Remove response headers

GustoWertStandardNecessary
ResponseHeaderRemoveThe name of the header(none)Yes actually
WhenSuccess/Always/Failuresuccessno

Setting:

{ "ResponseHeaderRemove": "HeaderName", "When": "Success"}

Code:

routeConfig = routeConfig.WithTransformResponseHeaderRemove(headerName: "HeaderName", ResponseCondition.Success);
transformBuilderContext.AddResponseHeaderRemove(headerName: "HeaderName", ResponseCondition.Success);

Example:

HeaderName: valueAnotherHeader: otro-valor

This removes the named response header.

WhenSpecifies whether to remove the response header for all responses, successful or failed. Any response with a status code less than 400 is considered a success.

Allowed response headers

GustoWertNecessary
Allowed response headersA semicolon-separated list of allowed header names.Yes actually

Setting:

{ "ResponseHeadersAllowed": "Headers1;Headers2"}

Code:

routeConfig = routeConfig.WithTransformResponseHeadersAllowed("Header1", "header2");
transformBuilderContext.AddResponseHeadersAllowed("Encabezado1", "Encabezado2");

By default, YARP copies most of the response headers from the proxy response (seeResponseHeadersCopy). Some security models only allow certain headers to be forwarded. This transformation disables ResponseHeadersCopy and copies only the specified headers. Other transformations that modify or add existing headers may be affected if they are not on the allow list.

Note that there are some headers that YARP does not copy by default because they are connection-specific or security-related (for example,Connection,Alt-Svc). Adding these header names to the allow list bypasses this restriction, but is strongly discouraged as it may break proxy functionality or introduce security vulnerabilities.

Example:

Header1: value1Header2: value2OtherHeader: OtherValue

Only Header1 and Header2 are copied from the proxy response.

ReplyTrailersCopy

Determines whether destination final response headers are copied to the client

GustoWertStandardNecessary
ReplyTrailersCopytrue FalseIt is rightYes actually

Setting:

{ "ResponseTrailersCopy": "falso" }

Code:

routeConfig = routeConfig.WithTransformCopyResponseTrailers(copia: falso);
transformBuilderContext.CopyResponseTrailers = falso;

This determines if all proxy response feeds are copied to the client response. This setting is on by default and can be turned off by configuring the transformation with aINCORRECTWorth. Transformations that reference specific headers will continue to run when this is disabled.

response trailer

Add or replace trailing response headers

GustoWertStandardNecessary
response trailerThe name of the header(none)Yes actually
Set/AppendThe header value(none)Yes actually
WhenSuccess/Always/Failuresuccessno

Setting:

{ "ResponseTrailer": "HeaderName", "Append": "value", "When": "Success"}

Code:

(Video) 🔥 Boys Transformation After 💔 Rejection || Attitude 🔥 Status Video|| Ek Duje Ke Vaste S2

routeConfig = routeConfig.WithTransformResponseTrailer(headerName: "HeaderName", value: "value", append: true, ResponseCondition.Success);
transformBuilderContext.AddResponseTrailer(headerName: "HeaderName", value: "value", append: true, ResponseCondition.Success);

Example:

Header Name: Wert

Response trailers are headers that are sent at the end of the response body. Trailer support is rare in HTTP/1.1 implementations, but is becoming more common in HTTP/2 implementations. Check your client and server for support.

ResponseTrailer follows the same structure and orientation asresponse header.

Answers Trailer Removed

Remove trailing response headers

GustoWertStandardNecessary
Answers Trailer RemovedThe name of the header(none)Yes actually
WhenSuccess/Always/Failuresuccessno

Setting:

{ "ResponseTrailerRemove": "HeaderName", "When": "Success"}

Code:

routeConfig = routeConfig.WithTransformResponseTrailerRemove(headerName: "HeaderName", ResponseCondition.Success);
transformBuilderContext.AddResponseTrailerRemove(headerName: "HeaderName", ResponseCondition.Success);

Example:

HeaderName: valueAnotherHeader: otro-valor

This removes the final named header.

ResponseTrailerRemove follows the same structure and orientation asResponseHeaderRemove.

AnswerTrailerAllowed

GustoWertNecessary
AnswerTrailerAllowedA semicolon-separated list of allowed header names.Yes actually

Setting:

{ "ResponseTrailersAllowed": "Header1;Header2"}

Code:

routeConfig = routeConfig.WithTransformResponseTrailersAllowed("Header1", "header2");
transformBuilderContext.AddResponseTrailersAllowed("Header1", "Header2");

By default, YARP copies most of the response feeds from the proxy response (seeReplyTrailersCopy). Some security models only allow certain headers to be forwarded. This transform disables ResponseTrailersCopy and copies only the specified headers. Other transformations that modify or add existing headers may be affected if they are not on the allow list.

Note that there are some headers that YARP does not copy by default because they are connection-specific or security-related (for example,Connection,Alt-Svc). Adding these header names to the allow list bypasses this restriction, but is strongly discouraged as it may break proxy functionality or introduce security vulnerabilities.

Example:

Header1: value1Header2: value2OtherHeader: OtherValue

Only Header1 and Header2 are copied from the proxy response.

expandability

AddRequestTransform

AddRequestTransformit's aTransformBuilderContextExtension method that defines a requirements transformation asFunc<RequestTransformContext, ValueTask>. This allows you to create a custom Requirements transformation without implementing arequest transformationderived class.

AddResponseTransform

AddResponseTransformit's aTransformBuilderContextExtension method that defines a response transformation asFunc<ResponseTransformContext, ValueTask>. This allows you to create a custom Response transformation without implementing aResponseTransformderived class.

AddResponseTrailersTransform

AddResponseTrailersTransformit's aTransformBuilderContextExtension method that defines a responsive trailer transformation asFunc<Response TrailersTransformContext, Task Value>. This allows you to create a custom responsive trailer transformation without implementing aResponseFollowerTransformderived class.

request transformation

All request transformations must derive from the abstract base classrequest transformation. They can freely modify the proxyHttpRequestMensaje. Avoid reading or modifying the request body, as this can break the proxy flow. Also consider adding a parameterized extension methodTransformBuilderContextfor discoverability and usability.

ResponseTransform

All response transformations must derive from the abstract base classResponseTransform. Can freely modify the customerHTTPResponse. Avoid reading or modifying the response body, as this can break the proxy flow. Also consider adding a parameterized extension methodTransformBuilderContextfor discoverability and usability.

ResponseFollowerTransform

All responsive trailer transformations must derive from the abstract base classResponseFollowerTransform. They are free to modify the client's HttpResponse trailers. These are executed after the response body and should not attempt to modify response headers or the response body. Also consider adding a parameterized extension methodTransformBuilderContextfor discoverability and usability.

Request body transformations

YARP does not provide built-in transforms to change the request body. However, the text can be changed in custom transformations.

Pay attention to what types of requests are modified, how much data is buffered, applying timeouts, parsing untrusted input, and updating body-related headers, such as:content length.

The following example uses simple and inefficient buffering to transform requests. A more efficient implementation would wrap and replaceHttpContext.Request.Bodywith a flow that made the necessary changes as the data passed from the client to the server. This would also require removing the Content-Length header since the final length would not be known in advance.

This example requires YARP 1.1, seehttps://github.com/microsoft/reverse-proxy/pull/1569.

.AddTransforms(context =>{ context.AddRequestTransform(async requestContext => { using var reader = new StreamReader(requestContext.HttpContext.Request.Body); // TODO: size limits, timeouts var body = await reader.ReadToEndAsync (); if (!string.IsNullOrEmpty(body)) { body = body.Replace("Alpha", "Charlie"); var bytes = Encoding.UTF8.GetBytes(body); // change the length of the content so that match the modified body , or remove it. } });});

transformed reaction corps

YARP does not provide built-in transforms to change the response body. However, the text can be changed in custom transformations.

Pay attention to what types of responses are modified, how much data is buffered, applying timeouts, parsing untrusted input, and updating body-related headers such as:content length. You may need to decompress the content before modifying it, as specified in the content-encoding header, and then recompress it or remove the header.

The following example uses simple and inefficient buffering to convert responses. A more efficient implementation would wrap the stream returned byReadAsStreamAsync()with a flow that made the necessary changes as the data passed from the client to the server. This would also require removing the Content-Length header since the final length would not be known in advance.

.AddTransforms(context =>{ context.AddResponseTransform(async responseContext => { var stream = await responseContext.ProxyResponse.Content.ReadAsStreamAsync(); using var reader = new StreamReader(stream); // TODO: size limits, timeouts expect var body = expect reader.ReadToEndAsync(); if (!string.IsNullOrEmpty(body)) { responseContext.SuppressResponseBody = true; body = body.Replace("Bravo", "Charlie"); var bytes = Encoding.UTF8. GetBytes(body ); // Change the content length to match the modified body or remove it responseContext.HttpContext.Response.ContentLength = bytes.Length; // Response headers are copied before transforms are called, update the required headers in HttpContext.Response .await responseContext.HttpContext.Response.Body.WriteAsync(bytes); } });});

ITransformProvider

ITransformProviderprovides the functionality ofadd transformationsdescribed above, as well as DI integration and validation support.

ITransformProvider's can be registered in DI by callingAddTransformations<T>(). SeveralITransformProviderDeployments can all be registered and run.

ITransformProviderhas two methodsConfirmyApply.Confirmgives you the ability to inspect the stream for any parameters required to configure a transformation, such as: B. Custom metadata and return validation errors for the context when required values ​​are missing or invalid. ThatApplyThe method provides the same functionality as AddTransform as described above, adding and setting transformations per path.

services.AddReverseProxy() .LoadFromConfig(_configuration.GetSection("ReverseProxy")) .AddTransforms<MyTransformProvider>();
inner class MyTransformProvider: ITransformProvider{ public void Validate(TransformValidationContext context) { // Check all paths for a custom property and validate // its transformation data. string value = null; if (context.Route.Metadata?.TryGetValue("CustomMetadata", out value) ?? false) { if (string.IsNullOrEmpty(value)) { context.Errors.Add(new ArgumentException( "A non-empty CustomMetadata value is required ")); } } } public void Apply(TransformBuilderContext transformBuildContext) { // Check all paths for a custom property and add your transform. string value = null; if (transformBuildContext.Route.Metadata?.TryGetValue("CustomMetadata", out value) ?? false) { if (string.IsNullOrEmpty(value)) { throw new ArgumentException( "Non-empty CustomMetadata value required"); } transformBuildContext.AddRequestTransform(transformContext => { transformContext.ProxyRequest.Headers.Add("CustomHeader", value); return default; }); } }}

ITransformFactory

Developers who want to integrate their custom transformations into thetransformedThe configuration section can implement aITransformFactory. This must be registered in DI with theAddTransformFactory<T>()Method. Multiple factories can be registered and all can be used.

ITransformFactoryoffers two methodsConfirmyTo build. Each of these processes a set of transformation values, represented by aIReadOnlyDictionary<string, string>.

WhatConfirmThe method is called when a configuration is loaded to inspect the content and report any errors. Any reported errors prevent the setting from being applied.

WhatTo buildThe method takes the specified configuration and creates the associated transform instances for the stream.

services.AddReverseProxy() .LoadFromConfig(_configuration.GetSection("ReverseProxy")) .AddTransformFactory<MyTransformFactory>();
clase interna MyTransformFactory: ITransformFactory{ public bool Validate(TransformValidationContext context, IReadOnlyDictionary<string, string> transformValues) { if (transformValues.TryGetValue("CustomTransform", out var value)) { if (string.IsNullOrEmpty(value)) { contexto. Errors.Add(new ArgumentException( "Ein nicht leerer CustomTransform-Wert ist erforderlich")); } verdadero zurückgeben; // Abgestimmt } devuelve falso; } public bool Build(TransformBuilderContext context, IReadOnlyDictionary<string, string> transformValues) { if (transformValues.TryGetValue("CustomTransform", out var value)) { if (string.IsNullOrEmpty(value)) { throw new ArgumentException( "A non -Leerer CustomTransform-Wert erforderlich"); } context.AddRequestTransform(transformContext => { transformContext.ProxyRequest.Headers.Add("CustomHeader", value); return default; }); gib verdadero zurück; // Abgestimmt } devuelve falso; }}

ConfirmyTo buildgive backIt is rightwhether they have identified the specified transform configuration as one that they own. AITransformFactorycan implement multiple transformations. noRouteConfig.TransformsEntries that are not edited by anyoneITransformFactorythey are considered configuration errors and prevent the configuration from being applied.

Also consider adding parameterized extension methodsRouteConfigWhatConTransformQueryValueto facilitate the establishment of programmatic routes.

(Video) Amazon API Gateway | Integration and Method Requests & Responses

RouteConfig estático público WithTransformQueryValue (este RouteConfig routeConfig, string queryKey, string value, bool append = true) { var type = append ? QueryTransformFactory.AppendKey : QueryTransformFactory.SetKey; return routeConfig.WithTransform(transform => { transform[QueryTransformFactory.QueryValueParameterKey] = queryKey; transform[type] = value; });}

Videos

1. Python Requests Tutorial: Request Web Pages, Download Images, POST Data, Read JSON, and More
(Corey Schafer)
2. How to use HTTP Transformation to send Webservice Request
(Informatica Support)
3. Sabse Badhkar Hum 2 | Mahesh Babu | Blockbuster Action Hindi Dubbed Movie l Venkatesh, Samantha
(Blockbuster Movies)
4. 😈boy transformation😱😍after breakup💔🔥ll jealous ex GF ll boys attitude 😎🔥status ll Deepesh sai ll
(Deepesh sai)
5. Impulse Response & Transfer Function of a System
(Tutorials Point)
6. Publish-Subscribe Pattern vs Message Queues vs Request Response (Detailed Discussions with Examples)
(Hussein Nasser)

References

Top Articles
Latest Posts
Article information

Author: Catherine Tremblay

Last Updated: 26/08/2023

Views: 6483

Rating: 4.7 / 5 (67 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Catherine Tremblay

Birthday: 1999-09-23

Address: Suite 461 73643 Sherril Loaf, Dickinsonland, AZ 47941-2379

Phone: +2678139151039

Job: International Administration Supervisor

Hobby: Dowsing, Snowboarding, Rowing, Beekeeping, Calligraphy, Shooting, Air sports

Introduction: My name is Catherine Tremblay, I am a precious, perfect, tasty, enthusiastic, inexpensive, vast, kind person who loves writing and wants to share my knowledge and understanding with you.