HashLoad / horse

Fast, opinionated, minimalist web framework for Delphi
MIT License
1.17k stars 217 forks source link

Na versão Seattle o Body do Request não esta reconhecendo caracteres especiais #364

Closed ds-sampaio closed 3 months ago

ds-sampaio commented 11 months ago

Utilizando o windows, postman e Delphi Seattle. Conteúdo do Body: { "nome": "TIPOSEPARACAO", "descricao": "Tipo de separação" }

Na api, na chegada do Request.Body: { "nome": "TIPOSEPARACAO",'#$D#$A' "descricao": "Tipo de separação"'}

Sugestão de correção no metodo Body do Horse.Request function THorseRequest.Body: string; begin {$IF CompilerVersion <= 31.0} Result := TEncoding.UTF8.GetString(BytesOf(FWebRequest.RawContent)); {$ELSE} Result := FWebRequest.Content; {$ENDIF} end;

viniciussanchez commented 10 months ago

@ds-sampaio chegou a testar esse código no Lazarus?

ds-sampaio commented 10 months ago

@viniciussanchez No lazarus não cheguei a testar

antoniojmsjr commented 10 months ago

Eu acho que essa alteração não é tão simples assim, desta forma está limitando a codificação em UTF-8, e por algum motivo pode estar sendo enviado no body um text com encoding ASCII que pode gera erro de codificação.

O problema não está no Horse, é sim na unit Web.HTTPApp.pas que faz o parse do body, verifica como está na tua versão do Delphi, estou usando o Delphi RIO 10.3.3.

image

viniciussanchez commented 10 months ago

Sim... eu vejo alguns reclamando de problemas de encode mas realmente usamos aqui e até hoje sem problemas com acentuação. Pode realmente ser algum problema na versão do Delphi mesmo.

antoniojmsjr commented 10 months ago

Sim... eu vejo alguns reclamando de problemas de encode mas realmente usamos aqui e até hoje sem problemas com acentuação. Pode realmente ser algum problema na versão do Delphi mesmo.

Uma alternativa é criar um overload da função Body passando um TEncoding, assim não fica engessado a codificação, por exemplo:

function Body(const Encoding: TEncoding): string; overload; virtual;

function THorseRequest.Body(const Encoding: TEncoding): string;
begin
  {$IF DEFINED(FPC)}
  Result := Body; // Tem que ver no Lazarus qual a classe de Encoding disponível, como default está retornando o Body
  {$ELSE}
  {$IF CompilerVersion <= 31.0}
  Result := Encoding.GetString(BytesOf(FWebRequest.RawContent));
  {$ELSE}
  Result := Encoding.GetString(FWebRequest.RawContent);
  {$ENDIF}
  {$ENDIF}
end;
ds-sampaio commented 9 months ago

Então na minha versão do delphi que é o Seatlle ta diferente do teu Delphi Rio. Veja:

image
ds-sampaio commented 9 months ago

antoniojmsjr Essa solução de criar um overload function Body(const Encoding: TEncoding): string; overload; virtual; atende ao que preciso, posso realizar a alteração e enviar o PR?

antoniojmsjr commented 9 months ago

antoniojmsjr Essa solução de criar um overload function Body(const Encoding: TEncoding): string; overload; virtual; atende ao que preciso, posso realizar a alteração e enviar o PR?

O bom seria a gente identificar a classe de Encoding que tem disponível no Lazarus para implementar essa alteração também, no momento estou de férias e não vou consegui te ajudar agora, só na volta.

antoniojmsjr commented 9 months ago

antoniojmsjr Essa solução de criar um overload function Body(const Encoding: TEncoding): string; overload; virtual; atende ao que preciso, posso realizar a alteração e enviar o PR?

Fiz um teste aqui no Lazarus e achei uma maneira de fazer o enconding:

function THorseRequest.Body(const Encoding: TEncoding): string;
{$IF DEFINED(FPC)}
var
  lContent: TStringStream;
{$ENDIF}
begin
  {$IF DEFINED(FPC)}
  try
    lContent := TStringStream.Create(FWebRequest.Content, Encoding);
    Result := lContent.DataString;
  finally
    lContent.Free;
  end;
  {$ELSE}
  {$IF CompilerVersion <= 31.0}
  Result := Encoding.GetString(BytesOf(FWebRequest.RawContent));
  {$ELSE}
  Result := Encoding.GetString(FWebRequest.RawContent);
  {$ENDIF}
  {$ENDIF}
end;

Compilado com sucesso Lazarus: :white_check_mark: Compilado com sucesso Delphi Rio: :white_check_mark: Compilado com sucesso Delphi Seatlle: :interrobang: - Consegue testar @ds-sampaio?

ds-sampaio commented 9 months ago

@antoniojmsjr Realizei o teste e funcionou perfeitamente no Delphi Seatlle

antoniojmsjr commented 9 months ago

@antoniojmsjr Realizei o teste e funcionou perfeitamente no Delphi Seatlle

Blz, altera os fontes e faz o commit.

ds-sampaio commented 9 months ago

@antoniojmsjr Acabei de realizar o commit @viniciussanchez