-1

I was trying out this function to perform a GET request using Delphi and the WinIApi. The request itself works, but unforunately the response is encoded wrong. I haven't fully worked out how it is encoded, but when it returns

≻牯杩湩㨢㤢⸳㤱⸸ㄲ⸹㤵索

and I throw it into an online encoder it returns the following using utf-16 and utf-32 encoding:

"{rogini:"9".391.812.995}"

So it's almost what it's supposed to be, but it flips two chars around everywhere:

{"origin":"93.198.219.59"}

So the question is how to correctly encode this without using Indy components.

EDIT: I used the function from here:

uses WinInet;    

function GetUrlContent(const Url: string): string;
var
  NetHandle: HINTERNET;
  UrlHandle: HINTERNET;
  Buffer: array[0..1024] of Char;
  BytesRead: dWord;
begin
  Result := '';
  NetHandle := InternetOpen('Delphi 5.x', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);

  if Assigned(NetHandle) then 
  begin
    UrlHandle := InternetOpenUrl(NetHandle, PChar(Url), nil, 0, INTERNET_FLAG_RELOAD, 0);

    if Assigned(UrlHandle) then
      { UrlHandle valid? Proceed with download }
    begin
      FillChar(Buffer, SizeOf(Buffer), 0);
      repeat
        Result := Result + Buffer;
        FillChar(Buffer, SizeOf(Buffer), 0);
        InternetReadFile(UrlHandle, @Buffer, SizeOf(Buffer), BytesRead);
      until BytesRead = 0;
      InternetCloseHandle(UrlHandle);
    end
    else
      { UrlHandle is not valid. Raise an exception. }
      raise Exception.CreateFmt('Cannot open URL %s', [Url]);

    InternetCloseHandle(NetHandle);
  end
  else
    { NetHandle is not valid. Raise an exception }
    raise Exception.Create('Unable to initialize Wininet');
end;
moronator
  • 304
  • 4
  • 11
  • That `GetUrlContent()` function is not taking character encodings into account at all. It assumes `string` is 8bit and stores the raw response body bytes *as-is* into it. The response body has an encoding, which is specified/inferred from the HTTP response headers. And `string` has an encoding too, whether that be ANSI in D2007 and earlier, or UTF-16 in D2009 and later. The code needs to convert the response body data from the response's encoding to Unicode, and then from Unicode to `string`'s native encoding. – Remy Lebeau Jun 22 '18 at 19:24
  • I would suggest switching from WinInet to Indy's `TIdHTTP` component instead, which does those conversions for you when returning a response body as a `string`. – Remy Lebeau Jun 22 '18 at 19:25

1 Answers1

-1

I solved it by using the following function from Andreas Rejbrand. With this function the encoding gets right.

function WebGetData(const UserAgent: string; const Server: string; const Resource: string): string;
var
  hInet: HINTERNET;
  hURL: HINTERNET;
  Buffer: array[0..1023] of AnsiChar;
  i, BufferLen: cardinal;
begin
  result := '';
  hInet := InternetOpen(PChar(UserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  try
    hURL := InternetOpenUrl(hInet, PChar('http://' + Server + Resource), nil, 0, 0, 0);
    try
      repeat
        InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen);
        if BufferLen = SizeOf(Buffer) then
          result := result + AnsiString(Buffer)
        else if BufferLen > 0 then
          for i := 0 to BufferLen - 1 do
            result := result + Buffer[i];
      until BufferLen = 0;
    finally
      InternetCloseHandle(hURL);
    end;
  finally
    InternetCloseHandle(hInet);
  end;
end;
moronator
  • 304
  • 4
  • 11