HAproxy está me dando problemas com regex substituir, Isso é um bug ou estou fazendo algo incorreto?

1

Eu estou tentando corrigir um problema de parâmetro de URL, forçando uma codificação de URL em um nó de um caminho POST que é um pouco uma ocorrência freqüente. Parece melhor, neste momento, consertar isso na camada proxy até que uma solução melhor seja desenvolvida ... mas a Haproxy está me dando problemas com isso, eu também devo mencionar que eu estou preso com a Haproxy v1.5 no momento ( que, pelo que eu posso dizer, também deixa Lua usando a lista de opções .. introduzida na v1.6?).

Um exemplo disso é assim:

Eu recebo uma solicitação POST normalmente na forma como esta ...

http(s)://sub.domain.com/context/{context}/staticPath/location/{location}/material/{material} 

Então, pode parecer mais com isso na prática ...

http://sub.domain.com/context/smith/staticePath/location/columbus/material/abc/123

Precisando do seguinte na outra ponta ...

http://sub.domain.com/context/smith/staticePath/location/columbus/material/abc%2F123

O problema é que abc / 123 é um material único que precisa ser mais parecido com "abc% 2F123", onde a barra '/' está alterando o caminho real.

Eu estou tentando pegar isso no proxy, eu posso obter regex para capturar o que eu preciso, mas parece que sempre que eu tento ter uma "barra" '/' em um grupo de captura e / ou tentar colocar uma barra de volta para a seção de substituição, ele quebra a reescrita.

Aqui estão exemplos do que eu tentei, também tenha em mente que eu pretendo expandir a captura para pegar o URL inteiro, mas estava simplificando para tentar resolver isso, também estou tentando contar algumas das histórias de memória neste momento, então por favor, perdoe se o abaixo não está morto em .. Eu tentei muitas, muitas combinações tentando chegar a uma estratégia que funcionaria.

Desta forma ..

reqrep (\w+\s?)\/(material)\/(\w+\s?)\/(.*) %2f

Eu posso obter os grupos de captura para colocar a URL novamente, mas sem os delímetros de caminho ("/") entre os nós de caminho.

Assim, ele não substitui, apenas enviará o caminho original.

reqrep (\w+\s?)\/(material)\/(\w+\s?)\/(.*) \/\/%2f

Tomando uma estratégia como essa ...

reqrep (\w+\s?)(\/)(material)(\/)(\w+\s?)\/(.*) %2f

Uma outra estratégia que eu tentei é manter os "/" 's nos grupos de captura para que eles possam sair na substituição, deixando a "barra" não desejada em um grupo de captura, semelhante a abaixo. / p>

reqrep (\w+\s?)(\/material\/)(\w+\s?)\/(.*) %2f

Eu também li sobre, e vi exemplos onde alguns dos regex tem espaços e o replace tem algum espaçamento .. Eu posso chegar perto usando algum espaçamento na substituição, mas isso deixa espaços não desejados no resultado final. / p>

também ..

Se eu escapar de um espaço, adicione uma barra que parece funcionar mais perto. ex. \ / mas então eu obteria algo como (por exemplo) location /material.. adicionando o espaço como mencionado acima.

O padrão que eu estou percebendo é que quando eu tento adicionar as barras a um grupo de captura na regex ele estraga a substituição me fazendo adivinhar coisas como .. são as barras não sendo escapadas porque elas estão no grupo de captura? E por que não posso simplesmente colocá-los de volta na substituição como literais? Este é o ponto onde eu imagino que posso ter tropeçado em um bug .. mas também estou ciente de que eu posso estar estragando tudo. Uma solução foi desenvolvida usando o Nginx, mas uma instância disso na frente do que precisamos também não é a mais prática se eu puder fazer a Haproxy fazer isso, principalmente porque nós já estamos usando o Haproxy para fazer um monte de outras coisas. já.

Eu sinceramente prefiro abordar essa questão de outra maneira, mas por enquanto usar o proxy parece ser uma das minhas melhores escolhas. Eu também não tenho o luxo de forçar o originador a dar caminhos melhores.

    
por rhaag71 06.12.2016 / 05:39

1 resposta

2

Esta sugestão que fiz em comentários parece fazer quase a coisa certa:

reqrep ^([^\ :]+)(\ ?/.+/material/)(.+)/(.+)(\ .+)$ %2f

Na verdade, coloquei no lado errado de %2f . Eu também fiz incorretamente o espaço no início do segundo grupo de captura opcional, que não quebra o regex mas não é tecnicamente correto.

Esta é a forma correta:

reqrep ^([^\ :]+)(\ /.+/material/)(.+)/(.+)(\ .+)$ %2f

Esse é o problema com reqrep - você está ajustando a primeira linha da solicitação HTTP diretamente. Poderoso, mas tedioso.

Quebrando isso:

^ Sempre ancore seu padrão no início da linha.

([^\ :]+) Este é o verbo HTTP ( GET , POST , etc.). Não deve conter espaços nem cólon. Este é o grupo de captura 1.

(\ /.+/material/) O verbo deve ser seguido por um espaço, a barra inicial (barras não precisam de uma barra invertida em expressões regulares HAProxy), um ou mais caracteres, e / material / ... este é o grupo de captura 2.

(.+) A primeira parte do que queremos dividir em / é o grupo de captura 3 ... e, na verdade, seria mais corretamente escrito ([^/]+) , embora a maioria das incompatibilidades em potencial sejam evitadas pelo espaço que exigimos no grupo 5, abaixo.

/ da barra que queremos eliminar

(.+) A parte da URL após o / ser o grupo de captura 4

(\ .+) um espaço, seguido por 1 ou mais caracteres, que capturarão HTTP/1.x no final da linha de solicitação como grupo de captura 5.

$ ancorado ao final da linha.

Em seguida, junte-os novamente.

%2f

O HAProxy 1.6 lida com isso de maneira mais elegante com o interpretador Lua integrado, bem como com um conversor chamado regsub() (embora seja muito simples - apenas substituições, sem grupos de captura, mas é bom para dividir cadeias) e variáveis definidas onde você pode "esconder" pequenos nuggets de dados enquanto processa o pedido. Ele também permite que você use http-request set-path e tenha uma path para ler e gravar o caminho isoladamente do resto da URL e sem ajustar o buffer de solicitação HTTP diretamente com uma expressão regular. A maioria ou todas essas coisas não estão em 1.5.

    
por 07.12.2016 / 02:37