mirror of
https://github.com/bol-van/zapret2.git
synced 2026-03-14 06:13:09 +00:00
nfqws2, zapret-lib: gzip
This commit is contained in:
@@ -162,3 +162,7 @@ v0.8.1
|
||||
* init.d: 80-dns-intercept
|
||||
* winws2: --wf-filter-loopback
|
||||
* blockcheck2: NOTEST_MISC_HTTP[S], NOTEST_SYNDATA_HTTP[S]
|
||||
|
||||
0.8.3
|
||||
|
||||
* nfqws2, zapret-lib: gzip compression and decompression
|
||||
|
||||
@@ -1426,6 +1426,83 @@ function tls_client_hello_mod(tls, options)
|
||||
return tls
|
||||
end
|
||||
|
||||
-- checks if filename is gzip compressed
|
||||
function is_gzip_file(filename)
|
||||
local f, err = io.open(filename, "r")
|
||||
if not f then
|
||||
error("gunzip_file: "..err)
|
||||
end
|
||||
local hdr = f:read(2)
|
||||
f:close()
|
||||
return hdr and hdr=="\x1F\x8B"
|
||||
end
|
||||
-- ungzips file to raw string
|
||||
function gunzip_file(filename, read_block_size)
|
||||
local f, err = io.open(filename, "r")
|
||||
if not f then
|
||||
error("gunzip_file: "..err)
|
||||
end
|
||||
if not read_block_size then read_block_size=16384 end
|
||||
|
||||
local decompressed=""
|
||||
gz = gunzip_init()
|
||||
if not gz then
|
||||
error("gunzip_file: stream init error")
|
||||
end
|
||||
repeat
|
||||
local compressed, err = f:read(read_block_size)
|
||||
if not compressed then
|
||||
f:close()
|
||||
gunzip_end(gz)
|
||||
if err then
|
||||
error("gunzip_file: file read error : "..err)
|
||||
else
|
||||
error("gunzip_file: premature EOF")
|
||||
end
|
||||
end
|
||||
local decomp, eof = gunzip_inflate(gz, compressed)
|
||||
if not decomp then
|
||||
f:close()
|
||||
gunzip_end(gz)
|
||||
return nil
|
||||
end
|
||||
decompressed = decompressed .. decomp
|
||||
until eof
|
||||
f:close()
|
||||
gunzip_end(gz)
|
||||
return decompressed
|
||||
end
|
||||
-- zips file to raw string
|
||||
-- level : 1..9 (default 9)
|
||||
-- memlevel : 1..8 (default 8)
|
||||
function gzip_file(filename, data, level, memlevel, compress_block_size)
|
||||
local f, err = io.open(filename, "w")
|
||||
if not f then
|
||||
error("gzip_file: "..err)
|
||||
end
|
||||
if not write_block_size then compress_block_size=16384 end
|
||||
|
||||
gz = gzip_init(nil, level, memlevel)
|
||||
if not gz then
|
||||
error("gunzip_file: stream init error")
|
||||
end
|
||||
local off=1, block_size
|
||||
repeat
|
||||
block_size = #data-off+1
|
||||
if block_size>compress_block_size then block_size=compress_block_size end
|
||||
local comp, eof = gzip_deflate(gz, string.sub(data,off,off+block_size-1))
|
||||
if not comp then
|
||||
f:close()
|
||||
gzip_end(gz)
|
||||
return nil
|
||||
end
|
||||
f:write(comp)
|
||||
off = off + block_size
|
||||
until eof
|
||||
f:close()
|
||||
gzip_end(gz)
|
||||
end
|
||||
|
||||
-- DISSECTORS
|
||||
|
||||
function http_dissect_header(header)
|
||||
|
||||
214
nfq2/lua.c
214
nfq2/lua.c
@@ -2591,7 +2591,210 @@ static int luacall_tls_mod(lua_State *L)
|
||||
LUA_STACK_GUARD_RETURN(L,2)
|
||||
}
|
||||
|
||||
struct userdata_zs
|
||||
{
|
||||
bool valid, inflate;
|
||||
z_stream zs;
|
||||
};
|
||||
static struct userdata_zs *lua_uzs(int idx, bool bInflate)
|
||||
{
|
||||
struct userdata_zs *uzs = (struct userdata_zs *)luaL_checkudata(params.L, idx, "userdata_zstream");
|
||||
if (!uzs->valid) luaL_error(params.L, "gzip stream is not valid");
|
||||
if (bInflate!=uzs->inflate) luaL_error(params.L, "gzip stream role mismatch");
|
||||
return uzs;
|
||||
}
|
||||
static int luacall_gunzip_init(lua_State *L)
|
||||
{
|
||||
// gunzip_init(windowBits) return zstream
|
||||
lua_check_argc_range(L,"gunzip_init",0,1);
|
||||
|
||||
LUA_STACK_GUARD_ENTER(L)
|
||||
|
||||
int argc=lua_gettop(L);
|
||||
int windowBits = (argc>=1 && !lua_isnil(L,1)) ? luaL_checkinteger(L, 1) : 47;
|
||||
|
||||
struct userdata_zs *uzs = (struct userdata_zs *)lua_newuserdata(L, sizeof(struct userdata_zs));
|
||||
memset(&uzs->zs, 0, sizeof(uzs->zs));
|
||||
int r = inflateInit2(&uzs->zs, windowBits);
|
||||
if (r == Z_OK)
|
||||
{
|
||||
uzs->inflate = true;
|
||||
uzs->valid = true;
|
||||
luaL_newmetatable(L, "userdata_zstream");
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pop(L,1);
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
LUA_STACK_GUARD_RETURN(L,1)
|
||||
}
|
||||
static int luacall_gunzip_end(lua_State *L)
|
||||
{
|
||||
lua_check_argc(L,"gunzip_end",1);
|
||||
|
||||
LUA_STACK_GUARD_ENTER(L)
|
||||
|
||||
struct userdata_zs *uzs = lua_uzs(1, true);
|
||||
inflateEnd(&uzs->zs);
|
||||
uzs->valid = false;
|
||||
|
||||
LUA_STACK_GUARD_RETURN(L,0)
|
||||
}
|
||||
#define BUFMIN 128
|
||||
static int luacall_gunzip_inflate(lua_State *L)
|
||||
{
|
||||
// gunzip_inflate(zstream, compressed_data, expected_uncompressed_chunk_size) return decompressed_data
|
||||
lua_check_argc_range(L,"gunzip_inflate",2,3);
|
||||
|
||||
LUA_STACK_GUARD_ENTER(L)
|
||||
|
||||
int argc=lua_gettop(L);
|
||||
size_t l;
|
||||
int r;
|
||||
size_t bufsize=0, size=0;
|
||||
uint8_t *buf=NULL, *newbuf;
|
||||
struct userdata_zs *uzs = lua_uzs(1, true);
|
||||
uzs->zs.next_in = (z_const Bytef*)luaL_checklstring(L,2,&l);
|
||||
uzs->zs.avail_in = (uInt)l;
|
||||
size_t bufchunk = argc>=3 ? luaL_checkinteger(L,3) : l*4;
|
||||
|
||||
do
|
||||
{
|
||||
if ((bufsize - size) < BUFMIN)
|
||||
{
|
||||
bufsize += bufchunk;
|
||||
newbuf = buf ? realloc(buf, bufsize) : malloc(bufsize);
|
||||
if (!newbuf)
|
||||
{
|
||||
r = Z_MEM_ERROR;
|
||||
goto zerr;
|
||||
}
|
||||
buf = newbuf;
|
||||
}
|
||||
uzs->zs.avail_out = bufsize - size;
|
||||
uzs->zs.next_out = buf + size;
|
||||
r = inflate(&uzs->zs, Z_NO_FLUSH);
|
||||
if (r != Z_OK && r != Z_STREAM_END) goto zerr;
|
||||
size = bufsize - uzs->zs.avail_out;
|
||||
} while (r == Z_OK && uzs->zs.avail_in);
|
||||
|
||||
lua_pushlstring(L, buf, size);
|
||||
lua_pushboolean(L, r==Z_STREAM_END);
|
||||
end:
|
||||
free(buf);
|
||||
LUA_STACK_GUARD_RETURN(L,2)
|
||||
zerr:
|
||||
lua_pushnil(L);
|
||||
lua_pushnil(L);
|
||||
goto end;
|
||||
}
|
||||
|
||||
static void *z_alloc(voidpf opaque, uInt items, uInt size)
|
||||
{
|
||||
return malloc((size_t)items*size);
|
||||
}
|
||||
static void z_free(voidpf opaque, voidpf address)
|
||||
{
|
||||
return free(address);
|
||||
}
|
||||
static int luacall_gzip_init(lua_State *L)
|
||||
{
|
||||
// gzip_init(windowBits, level, memlevel) return zstream
|
||||
lua_check_argc_range(L,"gunzip_init",0,3);
|
||||
|
||||
LUA_STACK_GUARD_ENTER(L)
|
||||
|
||||
int argc=lua_gettop(L);
|
||||
int windowBits = (argc>=1 && !lua_isnil(L,1)) ? luaL_checkinteger(L, 1) : 31;
|
||||
int level = (argc>=2 && !lua_isnil(L,2)) ? luaL_checkinteger(L, 2) : 9;
|
||||
int memlevel = (argc>=3 && !lua_isnil(L,3)) ? luaL_checkinteger(L, 3) : 8;
|
||||
|
||||
struct userdata_zs *uzs = (struct userdata_zs *)lua_newuserdata(L, sizeof(struct userdata_zs));
|
||||
memset(&uzs->zs, 0, sizeof(uzs->zs));
|
||||
uzs->zs.zalloc = z_alloc;
|
||||
uzs->zs.zfree = z_free;
|
||||
int r = deflateInit2(&uzs->zs, level, Z_DEFLATED, windowBits, memlevel, Z_DEFAULT_STRATEGY);
|
||||
if (r == Z_OK)
|
||||
{
|
||||
uzs->inflate = false;
|
||||
uzs->valid = true;
|
||||
luaL_newmetatable(L, "userdata_zstream");
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pop(L,1);
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
LUA_STACK_GUARD_RETURN(L,1)
|
||||
}
|
||||
static int luacall_gzip_end(lua_State *L)
|
||||
{
|
||||
lua_check_argc(L,"gzip_end",1);
|
||||
|
||||
LUA_STACK_GUARD_ENTER(L)
|
||||
|
||||
struct userdata_zs *uzs = lua_uzs(1, false);
|
||||
deflateEnd(&uzs->zs);
|
||||
uzs->valid = false;
|
||||
|
||||
LUA_STACK_GUARD_RETURN(L,0)
|
||||
}
|
||||
|
||||
static int luacall_gzip_deflate(lua_State *L)
|
||||
{
|
||||
// gzip_deflate(zstream, decompressed_data, expected_compressed_chunk_size) return compressed_data
|
||||
lua_check_argc_range(L,"gzip_deflate",1,3);
|
||||
|
||||
LUA_STACK_GUARD_ENTER(L)
|
||||
|
||||
int argc=lua_gettop(L);
|
||||
size_t l=0;
|
||||
int r;
|
||||
size_t bufsize=0, size=0;
|
||||
uint8_t *buf=NULL, *newbuf;
|
||||
struct userdata_zs *uzs = lua_uzs(1, false);
|
||||
if (argc>=2 && !lua_isnil(L,2))
|
||||
{
|
||||
uzs->zs.next_in = (z_const Bytef*)luaL_checklstring(L,2,&l);
|
||||
uzs->zs.avail_in = (uInt)l;
|
||||
}
|
||||
size_t bufchunk = argc>=3 ? luaL_checkinteger(L,3) : 1+l/4;
|
||||
|
||||
do
|
||||
{
|
||||
if ((bufsize - size) < BUFMIN)
|
||||
{
|
||||
bufsize += bufchunk;
|
||||
newbuf = buf ? realloc(buf, bufsize) : malloc(bufsize);
|
||||
if (!newbuf)
|
||||
{
|
||||
r = Z_MEM_ERROR;
|
||||
goto zerr;
|
||||
}
|
||||
buf = newbuf;
|
||||
}
|
||||
uzs->zs.avail_out = bufsize - size;
|
||||
uzs->zs.next_out = buf + size;
|
||||
r = deflate(&uzs->zs, l ? Z_NO_FLUSH : Z_FINISH);
|
||||
if (r != Z_OK && r != Z_STREAM_END) goto zerr;
|
||||
size = bufsize - uzs->zs.avail_out;
|
||||
} while (r == Z_OK && (uzs->zs.avail_in || !uzs->zs.avail_out));
|
||||
|
||||
lua_pushlstring(L, buf, size);
|
||||
lua_pushboolean(L, r==Z_STREAM_END);
|
||||
end:
|
||||
free(buf);
|
||||
LUA_STACK_GUARD_RETURN(L,2)
|
||||
zerr:
|
||||
lua_pushnil(L);
|
||||
lua_pushnil(L);
|
||||
goto end;
|
||||
}
|
||||
|
||||
// ----------------------------------------
|
||||
|
||||
@@ -3125,7 +3328,16 @@ static void lua_init_functions(void)
|
||||
{"resolve_range",luacall_resolve_range},
|
||||
|
||||
// tls
|
||||
{"tls_mod",luacall_tls_mod}
|
||||
{"tls_mod",luacall_tls_mod},
|
||||
|
||||
// gzip decompress
|
||||
{"gunzip_init",luacall_gunzip_init},
|
||||
{"gunzip_end",luacall_gunzip_end},
|
||||
{"gunzip_inflate",luacall_gunzip_inflate},
|
||||
// gzip compress
|
||||
{"gzip_init",luacall_gzip_init},
|
||||
{"gzip_end",luacall_gzip_end},
|
||||
{"gzip_deflate",luacall_gzip_deflate}
|
||||
};
|
||||
for(int i=0;i<(sizeof(lfunc)/sizeof(*lfunc));i++)
|
||||
lua_register(params.L,lfunc[i].name,lfunc[i].f);
|
||||
|
||||
Reference in New Issue
Block a user