mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
Core: Inet fixes, PCRE: more options support (thanks dolik)
git-svn-id: svn://ultimatepp.org/upp/trunk@4970 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
49a2d7d0e0
commit
af247bce1c
7 changed files with 367 additions and 320 deletions
|
|
@ -286,7 +286,7 @@ bool HttpRequest::Do()
|
|||
case TRAILER:
|
||||
if(ReadingHeader())
|
||||
break;
|
||||
header.Parse(data);
|
||||
header.ParseAdd(data);
|
||||
Finish();
|
||||
break;
|
||||
case FINISHED:
|
||||
|
|
|
|||
|
|
@ -251,6 +251,7 @@ struct HttpHeader {
|
|||
String GetVersion() const { return f3; }
|
||||
|
||||
void Clear();
|
||||
bool ParseAdd(const String& hdrs);
|
||||
bool Parse(const String& hdrs);
|
||||
|
||||
bool Read(TcpSocket& socket);
|
||||
|
|
@ -310,7 +311,7 @@ class HttpRequest : public TcpSocket {
|
|||
String digest;
|
||||
String request_headers;
|
||||
String postdata;
|
||||
bool cookies;
|
||||
String cookies;
|
||||
|
||||
String protocol;
|
||||
int status_code;
|
||||
|
|
@ -383,6 +384,7 @@ public:
|
|||
HttpRequest& PostUData(const String& pd) { return PostData(UrlEncode(pd)); }
|
||||
HttpRequest& Post(const String& data) { POST(); return PostData(data); }
|
||||
HttpRequest& Post(const char *id, const String& data);
|
||||
HttpRequest& ClearPost() { PostData(Null); GET(); return *this; }
|
||||
|
||||
HttpRequest& Headers(const String& h) { request_headers = h; return *this; }
|
||||
HttpRequest& ClearHeaders() { return Headers(Null); }
|
||||
|
|
|
|||
|
|
@ -1,305 +1,310 @@
|
|||
#include "Core.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
String WwwFormat(Time tm)
|
||||
{
|
||||
static const char *dayofweek[] =
|
||||
{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||
static const char *month[] =
|
||||
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
return String().Cat()
|
||||
<< dayofweek[DayOfWeek(tm)] << ", "
|
||||
<< (int)tm.day << ' ' << month[tm.month - 1]
|
||||
<< ' ' << (int)tm.year
|
||||
<< ' ' << Sprintf("%2d:%02d:%02d +0100", tm.hour, tm.minute, tm.second);
|
||||
}
|
||||
|
||||
String MIMECharsetName(byte charset)
|
||||
{
|
||||
if(charset == CHARSET_DEFAULT)
|
||||
charset = GetDefaultCharset();
|
||||
switch(charset) {
|
||||
case CHARSET_ISO8859_1: return "ISO-8859-1";
|
||||
case CHARSET_ISO8859_2: return "ISO-8859-2";
|
||||
case CHARSET_ISO8859_3: return "ISO-8859-3";
|
||||
case CHARSET_ISO8859_4: return "ISO-8859-4";
|
||||
case CHARSET_ISO8859_5: return "ISO-8859-5";
|
||||
case CHARSET_ISO8859_6: return "ISO-8859-6";
|
||||
case CHARSET_ISO8859_7: return "ISO-8859-7";
|
||||
case CHARSET_ISO8859_8: return "ISO-8859-8";
|
||||
case CHARSET_ISO8859_9: return "ISO-8859-9";
|
||||
case CHARSET_ISO8859_10: return "ISO-8859-10";
|
||||
case CHARSET_ISO8859_13: return "ISO-8859-13";
|
||||
case CHARSET_ISO8859_14: return "ISO-8859-14";
|
||||
case CHARSET_ISO8859_15: return "ISO-8859-15";
|
||||
case CHARSET_ISO8859_16: return "ISO-8859-16";
|
||||
case CHARSET_WIN1250: return "windows-1250";
|
||||
case CHARSET_WIN1251: return "windows-1251";
|
||||
case CHARSET_WIN1252: return "windows-1252";
|
||||
case CHARSET_WIN1253: return "windows-1253";
|
||||
case CHARSET_WIN1254: return "windows-1254";
|
||||
case CHARSET_WIN1255: return "windows-1255";
|
||||
case CHARSET_WIN1256: return "windows-1256";
|
||||
case CHARSET_WIN1257: return "windows-1257";
|
||||
case CHARSET_WIN1258: return "windows-1258";
|
||||
// case CHARSET_KOI8_R:
|
||||
// case CHARSET_CP852:
|
||||
// case CHARSET_MJK:
|
||||
case CHARSET_TOASCII: return "us-ascii";
|
||||
case CHARSET_UTF8: return "UTF-8";
|
||||
// case CHARSET_UNICODE:
|
||||
default: return Null;
|
||||
}
|
||||
}
|
||||
|
||||
static const char hex_digits[] = "0123456789ABCDEF";
|
||||
|
||||
String UrlEncode(const char *p, const char *e)
|
||||
{
|
||||
StringBuffer out;
|
||||
out.Reserve(e - p);
|
||||
for(; p < e; p++)
|
||||
{
|
||||
const char *b = p;
|
||||
while(p < e && (byte)*p > ' ' && (byte)*p < 127
|
||||
&& (IsAlNum(*p) || *p == '.' || *p == '-' || *p == '_'))
|
||||
p++;
|
||||
if(p > b)
|
||||
out.Cat(b, int(p - b));
|
||||
if(p >= e)
|
||||
break;
|
||||
if(*p == ' ')
|
||||
out << '+';
|
||||
else
|
||||
out << '%' << hex_digits[(*p >> 4) & 15] << hex_digits[*p & 15];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
String UrlEncode(const char *s, int len)
|
||||
{
|
||||
return UrlEncode(s, s + len);
|
||||
}
|
||||
|
||||
String UrlEncode(const String& s)
|
||||
{
|
||||
return UrlEncode(~s, s.GetLength());
|
||||
}
|
||||
|
||||
String UrlDecode(const char *b, const char *e)
|
||||
{
|
||||
StringBuffer out;
|
||||
byte d1, d2, d3, d4;
|
||||
for(const char *p = b; p < e; p++)
|
||||
if(*p == '+')
|
||||
out.Cat(' ');
|
||||
else if(*p == '%' && (d1 = ctoi(p[1])) < 16 && (d2 = ctoi(p[2])) < 16) {
|
||||
out.Cat(d1 * 16 + d2);
|
||||
p += 2;
|
||||
}
|
||||
else if(*p == '%' && (p[1] == 'u' || p[1] == 'U')
|
||||
&& (d1 = ctoi(p[2])) < 16 && (d2 = ctoi(p[3])) < 16
|
||||
&& (d3 = ctoi(p[4])) < 16 && (d4 = ctoi(p[5])) < 16) {
|
||||
out.Cat(WString((d1 << 12) | (d2 << 8) | (d3 << 4) | d4, 1).ToString());
|
||||
p += 5;
|
||||
}
|
||||
else
|
||||
out.Cat(*p);
|
||||
return out;
|
||||
}
|
||||
|
||||
String UrlDecode(const char *s, int len)
|
||||
{
|
||||
return UrlDecode(s, s + len);
|
||||
}
|
||||
|
||||
String UrlDecode(const String& s)
|
||||
{
|
||||
return UrlDecode(~s, s.GetLength());
|
||||
}
|
||||
|
||||
String Base64Encode(const char *b, const char *e)
|
||||
{
|
||||
static const char encoder[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
if(b == e)
|
||||
return Null;
|
||||
int out = (int(e - b) + 2) / 3 * 4;
|
||||
int rem = int(e - b) % 3;
|
||||
e -= rem;
|
||||
StringBuffer s(out);
|
||||
char *p = s;
|
||||
while(b < e)
|
||||
{
|
||||
p[0] = encoder[(b[0] >> 2) & 0x3F];
|
||||
p[1] = encoder[((b[0] << 4) & 0x30) | ((b[1] >> 4) & 0x0F)];
|
||||
p[2] = encoder[((b[1] << 2) & 0x3C) | ((b[2] >> 6) & 0x03)];
|
||||
p[3] = encoder[b[2] & 0x3F];
|
||||
b += 3;
|
||||
p += 4;
|
||||
}
|
||||
if(rem == 1)
|
||||
{
|
||||
p[0] = encoder[(b[0] >> 2) & 0x3F];
|
||||
p[1] = encoder[(b[0] << 4) & 0x30];
|
||||
p[2] = p[3] = '=';
|
||||
}
|
||||
else if(rem == 2)
|
||||
{
|
||||
p[0] = encoder[(b[0] >> 2) & 0x3F];
|
||||
p[1] = encoder[((b[0] << 4) & 0x30) | ((b[1] >> 4) & 0x0F)];
|
||||
p[2] = encoder[(b[1] << 2) & 0x3C];
|
||||
p[3] = '=';
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
String Base64Encode(const char *b, int len)
|
||||
{
|
||||
return Base64Encode(b, b + len);
|
||||
}
|
||||
|
||||
String Base64Encode(const String& data)
|
||||
{
|
||||
return Base64Encode(~data, data.GetCount());
|
||||
}
|
||||
|
||||
String Base64Decode(const char *b, const char *e)
|
||||
{
|
||||
static byte dec64[] =
|
||||
{
|
||||
/* 0x */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* 1x */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* 2x */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F,
|
||||
/* 3x */0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* 4x */0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
|
||||
/* 5x */0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* 6x */0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||
/* 7x */0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* 8x */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* 9x */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* Ax */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* Bx */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* Cx */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* Dx */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* Ex */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* Fx */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
StringBuffer out;
|
||||
byte c[4];
|
||||
int pos = 0;
|
||||
for(; b < e; b++)
|
||||
if((byte)*b > ' ') {
|
||||
byte ch = dec64[(byte)*b];
|
||||
if(ch & 0xC0)
|
||||
break;
|
||||
c[pos++] = ch;
|
||||
if(pos == 4) {
|
||||
out.Cat((c[0] << 2) | (c[1] >> 4));
|
||||
out.Cat((c[1] << 4) | (c[2] >> 2));
|
||||
out.Cat((c[2] << 6) | (c[3] >> 0));
|
||||
pos = 0;
|
||||
}
|
||||
}
|
||||
if(pos >= 2) {
|
||||
out.Cat((c[0] << 2) | (c[1] >> 4));
|
||||
if(pos >= 3) {
|
||||
out.Cat((c[1] << 4) | (c[2] >> 2));
|
||||
if(pos >= 4)
|
||||
out.Cat((c[2] << 6) | (c[3] >> 0));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
String Base64Decode(const char *s, int len)
|
||||
{
|
||||
return Base64Decode(s, s + len);
|
||||
}
|
||||
|
||||
String Base64Decode(const String& data)
|
||||
{
|
||||
return Base64Decode(~data, data.GetLength());
|
||||
}
|
||||
|
||||
void HttpHeader::Clear()
|
||||
{
|
||||
first_line.Clear();
|
||||
fields.Clear();
|
||||
f1 = f2 = f3 = Null;
|
||||
}
|
||||
|
||||
bool HttpHeader::Parse(const String& hdrs)
|
||||
{
|
||||
Clear();
|
||||
StringStream ss(hdrs);
|
||||
first_line = ss.GetLine();
|
||||
|
||||
while(!ss.IsEof()) {
|
||||
String s = ss.GetLine();
|
||||
if(s.IsEmpty()) break;
|
||||
int q = s.Find(':');
|
||||
if(q >= 0)
|
||||
fields.Add(ToLower(s.Mid(0, q))) = TrimLeft(s.Mid(q + 1));
|
||||
}
|
||||
|
||||
const char *s = first_line;
|
||||
if((byte)*s <= ' ')
|
||||
return false;
|
||||
while(*s != ' ' && *s)
|
||||
f1.Cat(*s++);
|
||||
while(*s == ' ')
|
||||
s++;
|
||||
if(!*s)
|
||||
return false;
|
||||
while(*s != ' ' && *s)
|
||||
f2.Cat(*s++);
|
||||
while(*s == ' ')
|
||||
s++;
|
||||
f3 = s;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HttpHeader::Read(TcpSocket& socket)
|
||||
{
|
||||
Clear();
|
||||
String h = socket.GetLine();
|
||||
if(h.IsVoid())
|
||||
return false;
|
||||
h << "\r\n";
|
||||
for(;;) {
|
||||
String s = socket.GetLine();
|
||||
if(s.IsVoid())
|
||||
return false;
|
||||
if(s.IsEmpty()) break;
|
||||
h << s << "\r\n";
|
||||
}
|
||||
return Parse(h);
|
||||
}
|
||||
|
||||
int HttpHeader::GetCode() const
|
||||
{
|
||||
return ScanInt(f2);
|
||||
}
|
||||
|
||||
bool HttpHeader::Request(String& method, String& uri, String& version)
|
||||
{
|
||||
method = GetMethod();
|
||||
uri = GetURI();
|
||||
version = GetVersion();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HttpHeader::Response(String& protocol, int& code, String& reason)
|
||||
{
|
||||
protocol = GetProtocol();
|
||||
code = GetCode();
|
||||
reason = GetReason();
|
||||
return !IsNull(code);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
#include "Core.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
String WwwFormat(Time tm)
|
||||
{
|
||||
static const char *dayofweek[] =
|
||||
{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||
static const char *month[] =
|
||||
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
return String().Cat()
|
||||
<< dayofweek[DayOfWeek(tm)] << ", "
|
||||
<< (int)tm.day << ' ' << month[tm.month - 1]
|
||||
<< ' ' << (int)tm.year
|
||||
<< ' ' << Sprintf("%2d:%02d:%02d +0100", tm.hour, tm.minute, tm.second);
|
||||
}
|
||||
|
||||
String MIMECharsetName(byte charset)
|
||||
{
|
||||
if(charset == CHARSET_DEFAULT)
|
||||
charset = GetDefaultCharset();
|
||||
switch(charset) {
|
||||
case CHARSET_ISO8859_1: return "ISO-8859-1";
|
||||
case CHARSET_ISO8859_2: return "ISO-8859-2";
|
||||
case CHARSET_ISO8859_3: return "ISO-8859-3";
|
||||
case CHARSET_ISO8859_4: return "ISO-8859-4";
|
||||
case CHARSET_ISO8859_5: return "ISO-8859-5";
|
||||
case CHARSET_ISO8859_6: return "ISO-8859-6";
|
||||
case CHARSET_ISO8859_7: return "ISO-8859-7";
|
||||
case CHARSET_ISO8859_8: return "ISO-8859-8";
|
||||
case CHARSET_ISO8859_9: return "ISO-8859-9";
|
||||
case CHARSET_ISO8859_10: return "ISO-8859-10";
|
||||
case CHARSET_ISO8859_13: return "ISO-8859-13";
|
||||
case CHARSET_ISO8859_14: return "ISO-8859-14";
|
||||
case CHARSET_ISO8859_15: return "ISO-8859-15";
|
||||
case CHARSET_ISO8859_16: return "ISO-8859-16";
|
||||
case CHARSET_WIN1250: return "windows-1250";
|
||||
case CHARSET_WIN1251: return "windows-1251";
|
||||
case CHARSET_WIN1252: return "windows-1252";
|
||||
case CHARSET_WIN1253: return "windows-1253";
|
||||
case CHARSET_WIN1254: return "windows-1254";
|
||||
case CHARSET_WIN1255: return "windows-1255";
|
||||
case CHARSET_WIN1256: return "windows-1256";
|
||||
case CHARSET_WIN1257: return "windows-1257";
|
||||
case CHARSET_WIN1258: return "windows-1258";
|
||||
// case CHARSET_KOI8_R:
|
||||
// case CHARSET_CP852:
|
||||
// case CHARSET_MJK:
|
||||
case CHARSET_TOASCII: return "us-ascii";
|
||||
case CHARSET_UTF8: return "UTF-8";
|
||||
// case CHARSET_UNICODE:
|
||||
default: return Null;
|
||||
}
|
||||
}
|
||||
|
||||
static const char hex_digits[] = "0123456789ABCDEF";
|
||||
|
||||
String UrlEncode(const char *p, const char *e)
|
||||
{
|
||||
StringBuffer out;
|
||||
out.Reserve(e - p);
|
||||
for(; p < e; p++)
|
||||
{
|
||||
const char *b = p;
|
||||
while(p < e && (byte)*p > ' ' && (byte)*p < 127
|
||||
&& (IsAlNum(*p) || *p == '.' || *p == '-' || *p == '_'))
|
||||
p++;
|
||||
if(p > b)
|
||||
out.Cat(b, int(p - b));
|
||||
if(p >= e)
|
||||
break;
|
||||
if(*p == ' ')
|
||||
out << '+';
|
||||
else
|
||||
out << '%' << hex_digits[(*p >> 4) & 15] << hex_digits[*p & 15];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
String UrlEncode(const char *s, int len)
|
||||
{
|
||||
return UrlEncode(s, s + len);
|
||||
}
|
||||
|
||||
String UrlEncode(const String& s)
|
||||
{
|
||||
return UrlEncode(~s, s.GetLength());
|
||||
}
|
||||
|
||||
String UrlDecode(const char *b, const char *e)
|
||||
{
|
||||
StringBuffer out;
|
||||
byte d1, d2, d3, d4;
|
||||
for(const char *p = b; p < e; p++)
|
||||
if(*p == '+')
|
||||
out.Cat(' ');
|
||||
else if(*p == '%' && (d1 = ctoi(p[1])) < 16 && (d2 = ctoi(p[2])) < 16) {
|
||||
out.Cat(d1 * 16 + d2);
|
||||
p += 2;
|
||||
}
|
||||
else if(*p == '%' && (p[1] == 'u' || p[1] == 'U')
|
||||
&& (d1 = ctoi(p[2])) < 16 && (d2 = ctoi(p[3])) < 16
|
||||
&& (d3 = ctoi(p[4])) < 16 && (d4 = ctoi(p[5])) < 16) {
|
||||
out.Cat(WString((d1 << 12) | (d2 << 8) | (d3 << 4) | d4, 1).ToString());
|
||||
p += 5;
|
||||
}
|
||||
else
|
||||
out.Cat(*p);
|
||||
return out;
|
||||
}
|
||||
|
||||
String UrlDecode(const char *s, int len)
|
||||
{
|
||||
return UrlDecode(s, s + len);
|
||||
}
|
||||
|
||||
String UrlDecode(const String& s)
|
||||
{
|
||||
return UrlDecode(~s, s.GetLength());
|
||||
}
|
||||
|
||||
String Base64Encode(const char *b, const char *e)
|
||||
{
|
||||
static const char encoder[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
if(b == e)
|
||||
return Null;
|
||||
int out = (int(e - b) + 2) / 3 * 4;
|
||||
int rem = int(e - b) % 3;
|
||||
e -= rem;
|
||||
StringBuffer s(out);
|
||||
char *p = s;
|
||||
while(b < e)
|
||||
{
|
||||
p[0] = encoder[(b[0] >> 2) & 0x3F];
|
||||
p[1] = encoder[((b[0] << 4) & 0x30) | ((b[1] >> 4) & 0x0F)];
|
||||
p[2] = encoder[((b[1] << 2) & 0x3C) | ((b[2] >> 6) & 0x03)];
|
||||
p[3] = encoder[b[2] & 0x3F];
|
||||
b += 3;
|
||||
p += 4;
|
||||
}
|
||||
if(rem == 1)
|
||||
{
|
||||
p[0] = encoder[(b[0] >> 2) & 0x3F];
|
||||
p[1] = encoder[(b[0] << 4) & 0x30];
|
||||
p[2] = p[3] = '=';
|
||||
}
|
||||
else if(rem == 2)
|
||||
{
|
||||
p[0] = encoder[(b[0] >> 2) & 0x3F];
|
||||
p[1] = encoder[((b[0] << 4) & 0x30) | ((b[1] >> 4) & 0x0F)];
|
||||
p[2] = encoder[(b[1] << 2) & 0x3C];
|
||||
p[3] = '=';
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
String Base64Encode(const char *b, int len)
|
||||
{
|
||||
return Base64Encode(b, b + len);
|
||||
}
|
||||
|
||||
String Base64Encode(const String& data)
|
||||
{
|
||||
return Base64Encode(~data, data.GetCount());
|
||||
}
|
||||
|
||||
String Base64Decode(const char *b, const char *e)
|
||||
{
|
||||
static byte dec64[] =
|
||||
{
|
||||
/* 0x */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* 1x */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* 2x */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F,
|
||||
/* 3x */0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* 4x */0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
|
||||
/* 5x */0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* 6x */0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||
/* 7x */0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* 8x */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* 9x */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* Ax */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* Bx */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* Cx */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* Dx */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* Ex */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* Fx */0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
StringBuffer out;
|
||||
byte c[4];
|
||||
int pos = 0;
|
||||
for(; b < e; b++)
|
||||
if((byte)*b > ' ') {
|
||||
byte ch = dec64[(byte)*b];
|
||||
if(ch & 0xC0)
|
||||
break;
|
||||
c[pos++] = ch;
|
||||
if(pos == 4) {
|
||||
out.Cat((c[0] << 2) | (c[1] >> 4));
|
||||
out.Cat((c[1] << 4) | (c[2] >> 2));
|
||||
out.Cat((c[2] << 6) | (c[3] >> 0));
|
||||
pos = 0;
|
||||
}
|
||||
}
|
||||
if(pos >= 2) {
|
||||
out.Cat((c[0] << 2) | (c[1] >> 4));
|
||||
if(pos >= 3) {
|
||||
out.Cat((c[1] << 4) | (c[2] >> 2));
|
||||
if(pos >= 4)
|
||||
out.Cat((c[2] << 6) | (c[3] >> 0));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
String Base64Decode(const char *s, int len)
|
||||
{
|
||||
return Base64Decode(s, s + len);
|
||||
}
|
||||
|
||||
String Base64Decode(const String& data)
|
||||
{
|
||||
return Base64Decode(~data, data.GetLength());
|
||||
}
|
||||
|
||||
void HttpHeader::Clear()
|
||||
{
|
||||
first_line.Clear();
|
||||
fields.Clear();
|
||||
f1 = f2 = f3 = Null;
|
||||
}
|
||||
|
||||
bool HttpHeader::ParseAdd(const String& hdrs)
|
||||
{
|
||||
StringStream ss(hdrs);
|
||||
first_line = ss.GetLine();
|
||||
|
||||
while(!ss.IsEof()) {
|
||||
String s = ss.GetLine();
|
||||
if(s.IsEmpty()) break;
|
||||
int q = s.Find(':');
|
||||
if(q >= 0)
|
||||
fields.Add(ToLower(s.Mid(0, q))) = TrimLeft(s.Mid(q + 1));
|
||||
}
|
||||
|
||||
const char *s = first_line;
|
||||
if((byte)*s <= ' ')
|
||||
return false;
|
||||
while(*s != ' ' && *s)
|
||||
f1.Cat(*s++);
|
||||
while(*s == ' ')
|
||||
s++;
|
||||
if(!*s)
|
||||
return false;
|
||||
while(*s != ' ' && *s)
|
||||
f2.Cat(*s++);
|
||||
while(*s == ' ')
|
||||
s++;
|
||||
f3 = s;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HttpHeader::Parse(const String& hdrs)
|
||||
{
|
||||
Clear();
|
||||
return ParseAdd(hdrs);
|
||||
}
|
||||
|
||||
bool HttpHeader::Read(TcpSocket& socket)
|
||||
{
|
||||
Clear();
|
||||
String h = socket.GetLine();
|
||||
if(h.IsVoid())
|
||||
return false;
|
||||
h << "\r\n";
|
||||
for(;;) {
|
||||
String s = socket.GetLine();
|
||||
if(s.IsVoid())
|
||||
return false;
|
||||
if(s.IsEmpty()) break;
|
||||
h << s << "\r\n";
|
||||
}
|
||||
return Parse(h);
|
||||
}
|
||||
|
||||
int HttpHeader::GetCode() const
|
||||
{
|
||||
return ScanInt(f2);
|
||||
}
|
||||
|
||||
bool HttpHeader::Request(String& method, String& uri, String& version)
|
||||
{
|
||||
method = GetMethod();
|
||||
uri = GetURI();
|
||||
version = GetVersion();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HttpHeader::Response(String& protocol, int& code, String& reason)
|
||||
{
|
||||
protocol = GetProtocol();
|
||||
code = GetCode();
|
||||
reason = GetReason();
|
||||
return !IsNull(code);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -792,6 +792,8 @@ int CompareNoCase(const wchar *a, const WString& b) {
|
|||
|
||||
template<> inline String AsString(const char * const &s) { return s; }
|
||||
template<> inline String AsString(char * const &s) { return s; }
|
||||
template<> inline String AsString(const char *s) { return s; }
|
||||
template<> inline String AsString(char *s) { return s; }
|
||||
template<> inline String AsString(const char& a) { return String(a, 1); }
|
||||
template<> inline String AsString(const signed char& a) { return String(a, 1); }
|
||||
template<> inline String AsString(const unsigned char& a) { return String(a, 1); }
|
||||
|
|
|
|||
|
|
@ -138,12 +138,18 @@ st]&]
|
|||
[s2;%% Clears data.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:HttpHeader`:`:Parse`(const String`&`): [@(0.0.255) bool]_[* Parse]([@(0.0.255) const]_
|
||||
[_^String^ String][@(0.0.255) `&]_[*@3 hdrs])&]
|
||||
[s5;:HttpHeader`:`:ParseAdd`(const String`&`): [@(0.0.255) bool]_[* ParseAdd]([@(0.0.255) c
|
||||
onst]_[_^String^ String][@(0.0.255) `&]_[*@3 hdrs])&]
|
||||
[s2;%% Parses the header (all lines of header) into [* first`_line
|
||||
]and [* fields].&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:HttpHeader`:`:Parse`(const String`&`): [@(0.0.255) bool]_[* Parse]([@(0.0.255) const]_
|
||||
[_^String^ String][@(0.0.255) `&]_[*@3 hdrs])&]
|
||||
[s2;%% Calls Clear and parses the header (all lines of header) into
|
||||
[* first`_line ]and [* fields].&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:HttpHeader`:`:Read`(TcpSocket`&`): [@(0.0.255) bool]_[* Read]([_^TcpSocket^ TcpSocket][@(0.0.255) `&
|
||||
]_[*@3 socket])&]
|
||||
[s2;%% Reads the header from [%-*@3 socket] and parses it.&]
|
||||
|
|
|
|||
|
|
@ -43,16 +43,8 @@ void RegExp::Clear(bool freemem)
|
|||
|
||||
void RegExp::SetOptions(int options)
|
||||
{
|
||||
if(options & UNICODE)
|
||||
compile_options |= UNICODE;
|
||||
if(options & CASELESS)
|
||||
compile_options |= CASELESS;
|
||||
if(options & UNGREEDY)
|
||||
compile_options |= UNGREEDY;
|
||||
if(options & MULTILINE)
|
||||
compile_options |= MULTILINE;
|
||||
if(options & PARTIAL)
|
||||
execute_options = PARTIAL;
|
||||
compile_options = options & COMPILE_OPTIONS;
|
||||
execute_options = options & EXECUTE_OPTIONS;
|
||||
}
|
||||
|
||||
void RegExp::SetPattern(const char * p)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,47 @@ public:
|
|||
UTF8 = PCRE_UTF8,
|
||||
CASELESS = PCRE_CASELESS,
|
||||
MULTILINE = PCRE_MULTILINE,
|
||||
UNGREEDY = PCRE_UNGREEDY
|
||||
UNGREEDY = PCRE_UNGREEDY,
|
||||
DOTALL = PCRE_DOTALL,
|
||||
|
||||
EXECUTE_OPTIONS = PCRE_ANCHORED
|
||||
| PCRE_NEWLINE_CR
|
||||
| PCRE_NEWLINE_LF
|
||||
| PCRE_NEWLINE_CRLF
|
||||
| PCRE_NEWLINE_ANYCRLF
|
||||
| PCRE_NEWLINE_ANY
|
||||
| PCRE_NOTBOL
|
||||
| PCRE_NOTEOL
|
||||
| PCRE_NOTEMPTY
|
||||
| PCRE_NOTEMPTY_ATSTART
|
||||
| PCRE_NO_START_OPTIMIZE
|
||||
| PCRE_NO_UTF8_CHECK
|
||||
| PCRE_PARTIAL_SOFT
|
||||
| PCRE_PARTIAL_HARD,
|
||||
COMPILE_OPTIONS = PCRE_ANCHORED
|
||||
| PCRE_AUTO_CALLOUT
|
||||
| PCRE_BSR_ANYCRLF
|
||||
| PCRE_BSR_UNICODE
|
||||
| PCRE_CASELESS
|
||||
| PCRE_DOLLAR_ENDONLY
|
||||
| PCRE_DOTALL
|
||||
| PCRE_DUPNAMES
|
||||
| PCRE_EXTENDED
|
||||
| PCRE_EXTRA
|
||||
| PCRE_FIRSTLINE
|
||||
| PCRE_JAVASCRIPT_COMPAT
|
||||
| PCRE_MULTILINE
|
||||
| PCRE_NEWLINE_CR
|
||||
| PCRE_NEWLINE_LF
|
||||
| PCRE_NEWLINE_CRLF
|
||||
| PCRE_NEWLINE_ANYCRLF
|
||||
| PCRE_NEWLINE_ANY
|
||||
| PCRE_NO_AUTO_CAPTURE
|
||||
| PCRE_NO_START_OPTIMIZE
|
||||
| PCRE_UCP
|
||||
| PCRE_UNGREEDY
|
||||
| PCRE_UTF8
|
||||
| PCRE_NO_UTF8_CHECK
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue