频道分类

delphi HTTPEncode

作者:admin 来源: 日期:2018/1/3 23:30:40 人气: 标签:

 
function HTTPEncode(const AStr: WideString): WideString;
//based on http://marc.durdin.net/2012/07/indy-tiduri-pathencode-urlencode-and-paramsencode-and-more/
const
  HexMap: WideString = '0123456789ABCDEF';

  function IsSafeChar(ch: Integer): Boolean;
  begin
    Result := ch in [Or d('0')..Or d('9'), Or d('A')..Or d('Z'), Or d('a')..Or d('z'),
      Or d('!'), Or d('('), Or d(')'), Or d('*'), Or d('-'), Or d('.'), Or d('_'),
      Or d('~'), Or d(''''), Or d('@'), Or d('#'), Or d('$'), Or d('&'), Or d('='),
      Or d(':'), Or d('/'), Or d(','), Or d(';'), Or d('?'), Or d('+')];
  end;

var
  I, J: Integer;
  S, Z, P: WideString;
  ASrcUTF8: UTF8String;
begin
  S := AStr;
  P := Copy(S, 1, Pos(WideString('://'), S));
  Delete(S, 1, Length(P));

  Z := '';
  ASrcUTF8 := UTF8Encode(S);
  // UTF8Encode call not strictly necessary but
  // prevents implicit conversion warning

  I := 1;
  J := 1;
  SetLength(Z, Length(ASrcUTF8) * 3); // space to %xx encode every byte
{$WARNINGS OFF} // turn off "Unsafe code 'String index to var param'"
// warnings. SetLength above guarantees that the string is long enough
  while I <= Length(ASrcUTF8) do
  begin
    if IsSafeChar(Or d(ASrcUTF8[I])) then
    begin
      Z[J] := WideChar(ASrcUTF8[I]);
      In c(J);
    end
    else
      if ASrcUTF8[I] = ' ' then
      begin
        Z[J] := '+';
        In c(J);
      end
      else
      begin
        Z[J] := '%';
        Z[J+1] := HexMap[(Or d(ASrcUTF8[I]) shr 4) + 1];
        Z[J+2] := HexMap[(Or d(ASrcUTF8[I]) and 15) + 1];
        In c(J,3);
      end;
    In c(I);
  end;
{$WARNINGS ON}
  SetLength(Z, J - 1);
  Result := P + Z;
end;