Antipadrão: acessar cabeçalhos HTTP de vários valores incorretamente em um proxy de API

Esta é a documentação do Apigee Edge.
Acesse Documentação da Apigee X.
informações

Os cabeçalhos HTTP são os pares de valor de nome que permitem que os aplicativos clientes e os serviços de back-end transmitam informações adicionais sobre solicitações e respostas, respectivamente. Veja alguns exemplos simples:

  • O cabeçalho da solicitação de autorização transmite as credenciais do usuário para o servidor:
    Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
  • O cabeçalho Content-Type indica o tipo do conteúdo da solicitação/resposta que está sendo enviada:
    Content-Type: application/json

Os cabeçalhos HTTP podem ter um ou mais valores, dependendo das definições de campo de cabeçalho (em inglês). Um cabeçalho com vários valores terá valores separados por vírgula. Veja alguns exemplos de cabeçalhos com vários valores:

  • Cache-Control: no-cache, no-store, must-revalidate
  • Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8
  • X-Forwarded-For: 10.125.5.30, 10.125.9.125

O Apigee Edge permite que os desenvolvedores acessem cabeçalhos facilmente usando o variáveis de fluxo em qualquer uma das políticas do Edge ou fluxos condicionais. Aqui está a lista de variáveis que podem ser usadas para acessar um cabeçalho de solicitação ou resposta específico no Edge:

Variáveis de fluxo:

  • message.header.header-name
  • request.header.header-name
  • response.header.header-name
  • message.header.header-name.N
  • request.header.header-name.N
  • response.header.header-name.N

Objetos JavaScript:

  • context.proxyRequest.headers.header-name
  • context.targetRequest.headers.header-name
  • context.proxyResponse.headers.header-name
  • context.targetResponse.headers.header-name

Este é um exemplo de política AssignMessage que mostra como ler o valor de um cabeçalho de solicitação e armazená-lo em uma variável:

<AssignMessage continueOnError="false" enabled="true" name="assign-message-default">
  <AssignVariable>
    <Name>reqUserAgent</Name>
    <Ref>request.header.User-Agent</Ref>
  </AssignVariable>
</AssignMessage>

Antipadrão

Acessar os valores de cabeçalhos HTTP nas políticas do Edge de maneira que retorne apenas o primeiro valor está incorreta e poderá causar problemas se os cabeçalhos HTTP específicos tiverem mais de um valor.

As seções a seguir contêm exemplos de acesso ao cabeçalho.

Exemplo 1: ler um cabeçalho "Accept" com vários valores usando o código JavaScript

Considere que o cabeçalho Accept tem vários valores, conforme mostrado abaixo:

Accept: text/html, application/xhtml+xml, application/xml

Este é o código JavaScript que lê o valor do cabeçalho Accept:

// Read the values from Accept header
var acceptHeaderValues = context.getVariable("request.header.Accept");

O código JavaScript acima retorna apenas o primeiro valor do cabeçalho Accept, como text/html.

Exemplo 2: ler um cabeçalho "Access-Control-Allow-Headers" com vários valores na política "AssignMessage" ou "RaiseFault"

Considere que o cabeçalho Access-Control-Allow-Headers tem vários valores, conforme mostrado abaixo:

Access-Control-Allow-Headers: content-type, authorization

Veja a parte do código das políticas AssignMessage ou RaiseFault definindo o cabeçalho Access-Control-Allow-Headers:

<Set>
  <Headers>
    <Header name="Access-Control-Allow-Headers">{request.header.Access-Control-Request-Headers}</Header>
  </Headers>
</Set>

O código acima define o cabeçalho Access-Control-Allow-Headers com apenas o primeiro valor do cabeçalho de solicitação Access-Control-Allow-Headers, neste exemplo, content-type.

Impacto

  1. Nos dois exemplos acima, observe que apenas o primeiro valor de cabeçalhos com vários valores é retornado. Se esses valores forem usados posteriormente por outra política no fluxo do proxy da API ou pelo serviço de back-end para executar alguma função ou lógica, isso poderá levar a um efeito ou resultado inesperado.
  2. Quando os valores do cabeçalho da solicitação são acessados e transmitidos ao servidor de destino, as solicitações da API podem ser processadas incorretamente pelo back-end, o que pode gerar resultados incorretos.
  3. Se o aplicativo cliente depender de valores de cabeçalho específicos da resposta do Edge, ele também podem ser processadas incorretamente e gerar resultados incorretos.

Prática recomendada

  1. Use as variáveis de fluxo integradas apropriadas: request.header.header_name.values.count, request.header.header_name.N, response.header.header_name.values.count, response.header.header_name.N.

    Em seguida, repita para buscar todos os valores de um cabeçalho específico nas políticas de callout em JavaScript ou Java.

    Exemplo: código JavaScript de amostra para ler um cabeçalho com vários valores

    for (var i = 1; i <=context.getVariable('request.header.Accept.values.count'); i++)
    {
      print(context.getVariable('request.header.Accept.' + i));
    }
    

    Por exemplo, application/xml;q=0.9, */*;q=0.8 aparecerá como um valor com o código acima.

    Se os valores do cabeçalho precisarem ser divididos usando ponto e vírgula como delimitador, use string.split(";") para separá-los em valores.

  2. Use a função substring() na variável de fluxo request.header.header_name.values na política RaiseFault ou AssignMessage para ler todos os valores de um cabeçalho específico.

    Exemplo: política RaiseFault ou AssignMessage de amostra para ler um cabeçalho com vários valores

    <Set>
      <Headers>
       <Header name="Access-Control-Allow-Headers">{substring(request.header.Access-Control-Request-Headers.values,1,-1)}</Header>
      </Headers>
    </Set>
    

Leitura adicional