142 lines
3.7 KiB
C#
142 lines
3.7 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
namespace VAR.HttpServer
|
|
{
|
|
public static class HttpUtility
|
|
{
|
|
public static string UrlDecode(string str, Encoding e = null)
|
|
{
|
|
if (null == str) { return null; }
|
|
|
|
if (str.IndexOf('%') == -1 && str.IndexOf('+') == -1)
|
|
{
|
|
return str;
|
|
}
|
|
|
|
if (e == null) { e = Encoding.UTF8; }
|
|
|
|
long len = str.Length;
|
|
var bytes = new List<byte>();
|
|
|
|
for (int i = 0; i < len; i++)
|
|
{
|
|
char ch = str[i];
|
|
if (ch == '%' && i + 2 < len && str[i + 1] != '%')
|
|
{
|
|
int xChar;
|
|
if (str[i + 1] == 'u' && i + 5 < len)
|
|
{
|
|
xChar = HexToInt(str, i + 2, 4);
|
|
if (xChar != -1)
|
|
{
|
|
WriteCharBytes(bytes, (char)xChar, e);
|
|
i += 5;
|
|
}
|
|
else
|
|
{
|
|
WriteCharBytes(bytes, '%', e);
|
|
}
|
|
}
|
|
else if ((xChar = HexToInt(str, i + 1, 2)) != -1)
|
|
{
|
|
WriteCharBytes(bytes, (char)xChar, e);
|
|
i += 2;
|
|
}
|
|
else
|
|
{
|
|
WriteCharBytes(bytes, '%', e);
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
WriteCharBytes(bytes, ch == '+' ? ' ' : ch, e);
|
|
}
|
|
|
|
byte[] buf = bytes.ToArray();
|
|
return e.GetString(buf);
|
|
}
|
|
|
|
private static void WriteCharBytes(IList buf, char ch, Encoding e)
|
|
{
|
|
if (ch > 255)
|
|
{
|
|
foreach (byte b in e.GetBytes(char.ToString(ch)))
|
|
{
|
|
buf.Add(b);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
buf.Add((byte)ch);
|
|
}
|
|
}
|
|
|
|
private static int HexDigitToInt(byte b)
|
|
{
|
|
char c = (char)b;
|
|
if (c >= '0' && c <= '9')
|
|
{
|
|
return c - '0';
|
|
}
|
|
|
|
if (c >= 'a' && c <= 'f')
|
|
{
|
|
return c - 'a' + 10;
|
|
}
|
|
|
|
if (c >= 'A' && c <= 'F')
|
|
{
|
|
return c - 'A' + 10;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
private static int HexToInt(string str, int offset, int length)
|
|
{
|
|
int val = 0;
|
|
int end = length + offset;
|
|
for (int i = offset; i < end; i++)
|
|
{
|
|
char c = str[i];
|
|
if (c > 127) { return -1; }
|
|
|
|
int current = HexDigitToInt((byte)c);
|
|
if (current == -1) { return -1; }
|
|
|
|
val = (val << 4) + current;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
public static string UrlEncode(string str, Encoding e = null)
|
|
{
|
|
StringBuilder sbOutput = new StringBuilder();
|
|
if (e == null) { e = Encoding.UTF8; }
|
|
|
|
byte[] bytes = e.GetBytes(str);
|
|
foreach (byte c in bytes)
|
|
{
|
|
if (c == ' ')
|
|
{
|
|
sbOutput.Append('+');
|
|
continue;
|
|
}
|
|
|
|
if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
|
|
{
|
|
sbOutput.Append((char)c);
|
|
continue;
|
|
}
|
|
|
|
sbOutput.AppendFormat("%{0:X2}", (int)c);
|
|
}
|
|
|
|
return sbOutput.ToString();
|
|
}
|
|
}
|
|
} |