diff --git a/uppsrc/Core/Http.cpp b/uppsrc/Core/Http.cpp index 2839070d2..ce74c7914 100644 --- a/uppsrc/Core/Http.cpp +++ b/uppsrc/Core/Http.cpp @@ -286,7 +286,7 @@ bool HttpRequest::Do() case TRAILER: if(ReadingHeader()) break; - header.Parse(data); + header.ParseAdd(data); Finish(); break; case FINISHED: diff --git a/uppsrc/Core/Inet.h b/uppsrc/Core/Inet.h index b3cd977b3..9c249f979 100644 --- a/uppsrc/Core/Inet.h +++ b/uppsrc/Core/Inet.h @@ -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); } diff --git a/uppsrc/Core/InetUtil.cpp b/uppsrc/Core/InetUtil.cpp index 12673df6b..d6549438a 100644 --- a/uppsrc/Core/InetUtil.cpp +++ b/uppsrc/Core/InetUtil.cpp @@ -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 diff --git a/uppsrc/Core/String.h b/uppsrc/Core/String.h index e77fcdb1b..ccf9afbef 100644 --- a/uppsrc/Core/String.h +++ b/uppsrc/Core/String.h @@ -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); } diff --git a/uppsrc/Core/src.tpp/Inet$en-us.tpp b/uppsrc/Core/src.tpp/Inet$en-us.tpp index f825d5b4c..f11a16365 100644 --- a/uppsrc/Core/src.tpp/Inet$en-us.tpp +++ b/uppsrc/Core/src.tpp/Inet$en-us.tpp @@ -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.&] diff --git a/uppsrc/plugin/pcre/RegExp.cpp b/uppsrc/plugin/pcre/RegExp.cpp index 67e6a44b4..3a23d7503 100644 --- a/uppsrc/plugin/pcre/RegExp.cpp +++ b/uppsrc/plugin/pcre/RegExp.cpp @@ -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) diff --git a/uppsrc/plugin/pcre/RegExp.h b/uppsrc/plugin/pcre/RegExp.h index 7ba06812e..1ac894098 100644 --- a/uppsrc/plugin/pcre/RegExp.h +++ b/uppsrc/plugin/pcre/RegExp.h @@ -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: