diff --git a/uppsrc/Core/Core.h b/uppsrc/Core/Core.h index 01e32c46e..6c7d514dc 100644 --- a/uppsrc/Core/Core.h +++ b/uppsrc/Core/Core.h @@ -196,6 +196,22 @@ enum typedef int SOCKET; #endif +#ifdef PLATFORM_WIN32 +#include +#include +#else +#include + +#ifndef DEF_MEM_LEVEL +#define DEF_MEM_LEVEL 8 +#endif + +#ifndef OS_CODE +#define OS_CODE 0x03 +#endif + +#endif + #include #include #include diff --git a/uppsrc/Core/Web.h b/uppsrc/Core/Web.h index 6f1adf057..b614a1859 100644 --- a/uppsrc/Core/Web.h +++ b/uppsrc/Core/Web.h @@ -54,16 +54,11 @@ class TcpSocket { public: Callback WhenWait; - - TcpSocket& Timeout(int ms) { timeout = ms; global = false; return *this; } - TcpSocket& GlobalTimeout(int ms); - TcpSocket& Blocking() { return Timeout(Null); } + + static String GetHostName(); int GetDone() const { return done; } - TcpSocket(); - ~TcpSocket() { Close(); } - static void Init(); bool IsOpen() const { return socket != INVALID_SOCKET; } @@ -114,7 +109,12 @@ public: bool PutAll(const char *s, int len) { return Put(s, len) == len; } bool PutAll(const String& s) { return Put(s) == s.GetCount(); } - static String GetHostName(); + TcpSocket& Timeout(int ms) { timeout = ms; global = false; return *this; } + TcpSocket& GlobalTimeout(int ms); + TcpSocket& Blocking() { return Timeout(Null); } + + TcpSocket(); + ~TcpSocket() { Close(); } }; struct HttpHeader { diff --git a/uppsrc/Core/z.cpp b/uppsrc/Core/z.cpp index ae4d42c98..309f576fe 100644 --- a/uppsrc/Core/z.cpp +++ b/uppsrc/Core/z.cpp @@ -1,20 +1,7 @@ #include "Core.h" -#ifdef PLATFORM_WIN32 -#include -#include -#else -#include - -#ifndef DEF_MEM_LEVEL -#define DEF_MEM_LEVEL 8 -#endif - -#ifndef OS_CODE -#define OS_CODE 0x03 -#endif - -#endif +#define LDUMP(x) // DDUMP(x) +#define LLOG(x) // DLOG(x) NAMESPACE_UPP @@ -43,6 +30,8 @@ enum RESERVED = 0xE0, /* bits 5..7: reserved */ }; +static byte sGZip_header[10] = { GZ_MAGIC1, GZ_MAGIC2, Z_DEFLATED, 0, 0, 0, 0, 0, 0, OS_CODE }; + void Crc32Stream::Out(const void *ptr, dword count) { crc = crc32(crc, (byte *)ptr, count); @@ -65,6 +54,227 @@ dword CRC32(const String& s) return CRC32(~s, s.GetLength()); } +void Zlib::Begin() +{ + Free(); + error = false; + if(docrc || gzip) + crc = crc32(0, NULL, 0); + out.Clear(); +} + +void Zlib::Compress() +{ + Begin(); + if(deflateInit2(&z, Z_DEFAULT_COMPRESSION, Z_DEFLATED, + hdr && !gzip ? MAX_WBITS : -MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY) != Z_OK) + Panic("deflateInit2 failed"); + mode = DEFLATE; + if(gzip) + WhenOut(sGZip_header, 10); +} + +void Zlib::Decompress() +{ + Begin(); + if(inflateInit2(&z, hdr && !gzip ? +MAX_WBITS : -MAX_WBITS) != Z_OK) + Panic("inflateInit2 failed"); + mode = INFLATE; +} + +void Zlib::Pump(bool finish) +{ + if(error) + return; + if(gzip_footer) + return; + ASSERT(mode); + LDUMP(mode); + if(!output) + output.Alloc(chunk); + for(;;) { + LLOG("---"); + LDUMP(z.avail_in); + int code; + z.avail_out = chunk; + z.next_out = output; + code = (mode == DEFLATE ? deflate : inflate)(&z, finish ? Z_FINISH : Z_NO_FLUSH); + LDUMP(code); + LDUMP(z.avail_in); + LDUMP(z.avail_out); + int count = chunk - z.avail_out; + LDUMP(count); + LDUMP(count); + if(count) { + if((docrc || gzip) && mode == INFLATE) + crc = crc32(crc, output, count); + WhenOut((const char *)~output, count); + if(mode == INFLATE) + total += count; + } + if(mode == INFLATE && code == Z_STREAM_END) { + gzip_footer = true; + break; + } + if(mode == INFLATE ? code == Z_BUF_ERROR : count == 0) + break; + if(code != Z_OK && code != Z_STREAM_END) { + LLOG("ERROR " << code); + Free(); + error = true; + break; + } + } +} + +int Zlib::GzipHeader(const char *ptr, int size) +{ + int pos = 10; + if(pos > size) + return 0; + int flags = ptr[3]; + if(ptr[2] != Z_DEFLATED || (flags & RESERVED) != 0) { + error = true; + return 0; + } + if(flags & EXTRA_FIELD) { + if(pos + 2 > size) + return 0; + int len = MAKEWORD(ptr[pos], ptr[pos + 1]); + if(len < 0) { + error = true; + return 0; + } + if((pos += len + 2) > size) + return 0; + } + for(int i = !!(flags & ORIG_NAME) + !!(flags & COMMENT); i > 0; i--) { + while(ptr[pos]) + if(++pos > size) + return 0; + if(++pos > size) + return 0; + } + if(flags & HEAD_CRC) + if((pos += 2) > size) + return 0; + return pos; +} + +void Zlib::Put0(const char *ptr, int size) +{ + if(error) + return; + ASSERT(mode); + if(size <= 0) + return; + if(gzip && !gzip_done && mode == INFLATE) { + if(gzip_hs.GetCount()) { + gzip_hs.Cat(ptr, size); + ptr = ~gzip_hs; + size = gzip_hs.GetCount(); + } + int pos = GzipHeader(ptr, size); + if(!pos) { + if(gzip_hs.GetCount() == 0) + gzip_hs.Cat(ptr, size); + return; + } + + gzip_done = true; + size -= pos; + ptr += pos; + } + + if(size <= 0) + return; + + if(mode == DEFLATE) { + total += size; + if(docrc || gzip) + crc = crc32(crc, (const Bytef *)ptr, size); + } + + z.next_in = (Bytef *)ptr; + z.avail_in = size; + Pump(Z_NO_FLUSH); +} + +void Zlib::Put(const void *ptr, dword size) +{ + if(error) + return; + const char *p = reinterpret_cast(ptr); + while(size) { + LLOG("Put " << size); + int psz = (int) min(size, dword(INT_MAX / 4)); + Put0(p, size); + size -= psz; + p += psz; + } +} + +void Zlib::PutOut(const void *ptr, dword size) +{ + out.Cat((const char *)ptr, (int)size); + LDUMP(out.GetCount()); +} + +void Zlib::End() +{ + LLOG("End"); + if(mode != INFLATE || !gzip || gzip_done) + Pump(Z_FINISH); + if(gzip && mode == DEFLATE) { + char h[8]; + Poke32le(h, crc); + Poke32le(h + 4, total); + WhenOut(h, 8); + } + Free(); +} + +void Zlib::Free() +{ + if(mode == INFLATE) + inflateEnd(&z); + if(mode == DEFLATE) + deflateEnd(&z); + mode = NONE; + gzip_hs.Clear(); + gzip_done = false; + gzip_footer = false; + total = 0; +} + +Zlib& Zlib::ChunkSize(int n) +{ + ASSERT(n < INT_MAX / 4); + output.Clear(); + chunk = n; + return *this; +} + +Zlib::Zlib() +{ + z.zalloc = zalloc_new; + z.zfree = zfree_new; + z.opaque = 0; + docrc = false; + crc = 0; + hdr = true; + WhenOut = callback(this, &Zlib::PutOut); + mode = NONE; + gzip = false; +} + +Zlib::~Zlib() +{ + if(mode) + End(); +} + static int sZpress(Stream& out, Stream& in, int size, Gate2 progress, bool nohdr, dword *crc, bool compress) { @@ -169,8 +379,7 @@ String ZDecompress(const String& s, Gate2 progress) int GZCompress(Stream& out, Stream& in, int size, Gate2 progress) { - static byte gzip_header[10] = { GZ_MAGIC1, GZ_MAGIC2, Z_DEFLATED, 0, 0, 0, 0, 0, 0, OS_CODE }; - out.Put(gzip_header, 10); + out.Put(sGZip_header, 10); dword crc; int sz = ZCompress(out, in, size, progress, true, &crc); out.Put32le(crc); diff --git a/uppsrc/Core/z.h b/uppsrc/Core/z.h index 9465f70a7..a4cf9d3f8 100644 --- a/uppsrc/Core/z.h +++ b/uppsrc/Core/z.h @@ -13,6 +13,55 @@ public: dword CRC32(const void *ptr, dword count); dword CRC32(const String& s); +class Zlib { + enum { NONE, DEFLATE, INFLATE }; + + z_stream z; + Buffer output; + int chunk; + int mode; + dword crc; + int total; + bool docrc; + bool hdr; + bool error; + bool gzip; + bool gzip_done; + bool gzip_footer; + String gzip_hs; + + void PutOut(const void *ptr, dword size); + void Pump(bool finish); + void Begin(); + void Free(); + void Put0(const char *ptr, int size); + int GzipHeader(const char *ptr, int size); + +public: + Callback2 WhenOut; + String out; + + dword GetCrc() const { return crc; } + + bool IsError() const { return error; } + + void Compress(); + void Decompress(); + void Put(const void *ptr, dword size); + void Put(const String& s) { Put(~s, s.GetCount()); } + void End(); + + Zlib& GZip(bool gzip_ = true) { gzip = gzip_; return *this; } + Zlib& Header(bool hdr_ = true) { hdr = hdr_; return *this; } + Zlib& NoHeader() { return Header(false); } + Zlib& Crc(bool b = true) { docrc = b; return *this; } + Zlib& NoCrc() { return Crc(false); } + Zlib& ChunkSize(int n); + + Zlib(); + ~Zlib(); +}; + int ZCompress(Stream& out, Stream& in, int size, Gate2 progress = false, bool nohdr = false, dword *crc = NULL); int ZDecompress(Stream& out, Stream& in, int size, Gate2 progress = false, bool nohdr = false, dword *crc = NULL); diff --git a/uppsrc/Web/init b/uppsrc/Web/init index c29a6149b..211ff68d2 100644 --- a/uppsrc/Web/init +++ b/uppsrc/Web/init @@ -1,7 +1,8 @@ #ifndef _Web_icpp_init_stub #define _Web_icpp_init_stub #include "Core/init" -#define BLITZ_INDEX__ F812213f29e8b190fead32d3e1aa22ad7 +#include "Web/SSL/init" +#define BLITZ_INDEX__ F173e4988d70c85ab4a78f4702f196919 #include "Web_init.icpp" #undef BLITZ_INDEX__ #endif diff --git a/uppsrc/ide/ide.upp b/uppsrc/ide/ide.upp index 37e198c6e..9965ca6e5 100644 --- a/uppsrc/ide/ide.upp +++ b/uppsrc/ide/ide.upp @@ -17,7 +17,8 @@ uses plugin/astyle, usvn, TextDiffCtrl, - TabBar; + TabBar, + Web/SSL; uses(POSIX) ide\SrcUpdater; diff --git a/uppsrc/ide/init b/uppsrc/ide/init index d807e9e3c..5266a0d26 100644 --- a/uppsrc/ide/init +++ b/uppsrc/ide/init @@ -17,5 +17,6 @@ #include "usvn/init" #include "TextDiffCtrl/init" #include "TabBar/init" +#include "Web/SSL/init" #include "ide\SrcUpdater/init" #endif