Configuração do cliente HTTP
Cada cluster recebe seu próprio cliente HTTP para se comunicar com seus destinos - configure a conexão, o TLS e o comportamento por requisição de forma independente para cada cluster.
Um cliente por cluster
Cada cluster tem seu próprio HttpMessageInvoker, usado em toda requisição encaminhada para seus destinos. Na inicialização, cada cluster recebe um novo; se a configuração de um cluster mudar posteriormente, IForwarderHttpClientFactory decide se o cliente existente pode continuar sendo usado ou se um novo é necessário - a implementação padrão cria um novo sempre que o próprio HttpClientConfig tiver mudado.
Configurações de HttpClient
Configuradas em HttpClient em um cluster, usando HttpClientConfig:
JSON"HttpClient": {
"SslProtocols": ["Tls12", "Tls13"],
"MaxConnectionsPerServer": "10",
"DangerousAcceptAnyServerCertificate": "false",
"RequestHeaderEncoding": "utf-8",
"ResponseHeaderEncoding": "utf-8",
"EnableMultipleHttp2Connections": "true",
"WebProxy": {
"Address": "http://myproxy:8080",
"BypassOnLocal": "true",
"UseDefaultCredentials": "false"
}
}SslProtocols— quais versões de protocolo TLS/SSL esse cliente aceita. Nenhum valor é definido por padrão.MaxConnectionsPerServer— número máximo de conexões HTTP/1.1 simultâneas para o mesmo destino. O padrão éint32.MaxValue.DangerousAcceptAnyServerCertificate—truedesabilita toda a validação do certificado TLS do destino. O padrão éfalse; o nome é um aviso deliberado, não uma sugestão.RequestHeaderEncoding/ResponseHeaderEncoding— codificação (por exemplo,"utf-8","iso-8859-1") usada para valores de cabeçalho não ASCII em requisições de saída / respostas de entrada, por meio dos seletores de codificação de cabeçalho doSocketsHttpHandler.EnableMultipleHttp2Connections— permite abrir conexões HTTP/2 adicionais para o mesmo destino quando as existentes atingem seu limite de streams simultâneos. O padrão étrue.WebProxy— encaminha as requisições de saída para os destinos por meio de um proxy HTTP upstream:Addressdo proxy,BypassOnLocalpara ignorá-lo em endereços locais,UseDefaultCredentialspara se autenticar nele usando as próprias credenciais do aplicativo.
Se você definir aqui uma codificação de cabeçalho diferente de ASCII, o servidor que hospeda o YARP também precisa ser instruído a aceitá-la. No caso do Kestrel, isso significa definir KestrelServerOptions.RequestHeaderEncodingSelector/ResponseHeaderEncodingSelector correspondentes - caso contrário, o Kestrel rejeita justamente os cabeçalhos que essa configuração deveria permitir.
C#builder.WebHost.ConfigureKestrel(kestrel =>
{
kestrel.RequestHeaderEncodingSelector = _ => Encoding.Latin1;
kestrel.ResponseHeaderEncodingSelector = _ => Encoding.Latin1;
});Configurações de HttpRequest
Configuradas em HttpRequest em um cluster, usando ForwarderRequestConfig - elas regem a própria requisição de saída, não a conexão subjacente:
JSON"HttpRequest": {
"ActivityTimeout": "00:01:40",
"Version": "2",
"VersionPolicy": "RequestVersionOrLower",
"AllowResponseBuffering": "false"
}ActivityTimeout— por quanto tempo uma requisição pode ficar ociosa entre operações antes de ser cancelada. O padrão é 100 segundos; é reiniciado sempre que os cabeçalhos de resposta chegam ou dados de requisição/resposta/streaming (gRPC, WebSockets) são lidos ou gravados. Keep-alives de TCP e pings de HTTP/2 não o reiniciam; pings de WebSocket, sim.Version— a versão do HTTP de saída:1.0,1.1,2ou3. O padrão é2.VersionPolicy— como a versão final é escolhida:RequestVersionOrLower(padrão),RequestVersionOrHigherouRequestVersionExact.AllowResponseBuffering— permite o buffer de escrita ao enviar a resposta de volta ao cliente, se o host oferecer suporte a isso. Quebra os server-sent events se ativado.
Dois clusters com configurações de HTTP diferentes
JSON{
"Clusters": {
"cluster1": {
"LoadBalancingPolicy": "Random",
"HttpClient": { "SslProtocols": ["Tls12"], "MaxConnectionsPerServer": "10" },
"HttpRequest": { "ActivityTimeout": "00:00:30" },
"Destinations": {
"cluster1/destination1": { "Address": "https://localhost:10000/" }
}
},
"cluster2": {
"HttpClient": { "SslProtocols": ["Tls12"] },
"HttpRequest": { "Version": "1.1", "VersionPolicy": "RequestVersionExact" },
"Destinations": {
"cluster2/destination1": { "Address": "https://localhost:10001/" }
}
}
}
}Configurando no código
As mesmas configurações se aplicam ao construir clusters diretamente em vez de a partir de IConfiguration - atribua um HttpClientConfig a ClusterConfig.HttpClient antes de passar o cluster para LoadFromMemory:
C#var clusters = new[]
{
new ClusterConfig
{
ClusterId = "cluster1",
Destinations = { { "destination1", new DestinationConfig { Address = "https://localhost:10000" } } },
HttpClient = new HttpClientConfig
{
MaxConnectionsPerServer = 10,
SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13,
},
},
};
services.AddReverseProxy().LoadFromMemory(routes, clusters);Para qualquer coisa que o esquema não cubra, ConfigureHttpClient expõe diretamente o SocketsHttpHandler subjacente - ele é executado toda vez que um cluster é adicionado ou alterado, depois que as próprias configurações do cluster já foram aplicadas:
C#services.AddReverseProxy()
.ConfigureHttpClient((context, handler) =>
{
handler.SslOptions.ClientCertificates.Add(clientCert);
});Substituindo completamente a fábrica de clientes
Para controle total, substitua IForwarderHttpClientFactory por uma implementação personalizada - derivar do ForwarderHttpClientFactory padrão cobre a maioria dos casos. Uma fábrica personalizada ainda deve definir as mesmas propriedades de SocketsHttpHandler que a padrão define, para evitar quebrar o comportamento do proxy ou adicionar overhead desnecessário: UseProxy = false, AllowAutoRedirect = false, AutomaticDecompression = DecompressionMethods.None, UseCookies = false.
Sempre retorne um HttpMessageInvoker, não um HttpClient - o HttpClient armazena respostas em buffer por padrão, o que quebra o streaming e adiciona latência e overhead de memória que o proxying simples não precisa.