Descrição
Valores de query string enviados com + no lugar de espaço não são decodificados.
Clientes como o axios serializam params: { name: 'João da Silva' } como
?name=Jo%C3%A3o+da+Silva, mas Req.Query['name'] retorna João+da+Silva
em vez de João da Silva.
Em application/x-www-form-urlencoded (formato usado pela query string), +
significa espaço, e um + literal é enviado como %2B.
Passos para reproduzir
THorse.Get('/hello',
procedure(Req: THorseRequest; Res: THorseResponse)
begin
Res.Send(Req.Query['name']);
end);
await axios.get('http://localhost:9000/hello', { params: { name: 'João da Silva' } });
// requisição: GET /hello?name=Jo%C3%A3o+da+Silva
Comportamento esperado
Req.Query['name'] retorna João da Silva.
?q=a%2Bb retorna a+b.
Comportamento atual
Req.Query['name'] retorna João+da+Silva.
Causa
THorseRequest.InitializeQuery decodifica com DecodeParam (src/Horse.Utils.pas),
que devolve o valor sem alteração quando não há % nele. Mesmo quando há %,
o TNetEncoding.URL.Decode não trata + como espaço por padrão.
Não dá para alterar o DecodeParam para converter +, porque ele também é usado
nos parâmetros de rota, onde + é um caractere literal (e o Tests.Horse.Utils
garante esse comportamento).
Proposta de correção
Adicionar DecodeQueryParam ao Horse.Utils, usando
TNetEncoding.URL.Decode(AValue, [TURLEncoding.TDecodeOption.PlusAsSpaces])
no Delphi e HTTPDecode no FPC, e usá-lo apenas na decodificação da query
dentro do InitializeQuery.
Descrição
Valores de query string enviados com
+no lugar de espaço não são decodificados.Clientes como o axios serializam
params: { name: 'João da Silva' }como?name=Jo%C3%A3o+da+Silva, masReq.Query['name']retornaJoão+da+Silvaem vez de
João da Silva.Em
application/x-www-form-urlencoded(formato usado pela query string),+significa espaço, e um
+literal é enviado como%2B.Passos para reproduzir
Comportamento esperado
Req.Query['name']retornaJoão da Silva.?q=a%2Bbretornaa+b.Comportamento atual
Req.Query['name']retornaJoão+da+Silva.Causa
THorseRequest.InitializeQuerydecodifica comDecodeParam(src/Horse.Utils.pas),que devolve o valor sem alteração quando não há
%nele. Mesmo quando há%,o
TNetEncoding.URL.Decodenão trata+como espaço por padrão.Não dá para alterar o
DecodeParampara converter+, porque ele também é usadonos parâmetros de rota, onde
+é um caractere literal (e oTests.Horse.Utilsgarante esse comportamento).
Proposta de correção
Adicionar
DecodeQueryParamaoHorse.Utils, usandoTNetEncoding.URL.Decode(AValue, [TURLEncoding.TDecodeOption.PlusAsSpaces])no Delphi e
HTTPDecodeno FPC, e usá-lo apenas na decodificação da querydentro do
InitializeQuery.