├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── lib └── resty │ └── zip.lua └── t └── sanity.t /.gitignore: -------------------------------------------------------------------------------- 1 | t/servroot 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 doujiang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | OPENRESTY_PREFIX=/usr/local/openresty-debug 2 | 3 | PREFIX ?= /usr/local 4 | LUA_INCLUDE_DIR ?= $(PREFIX)/include 5 | LUA_LIB_DIR ?= $(PREFIX)/lib/lua/$(LUA_VERSION) 6 | INSTALL ?= install 7 | 8 | .PHONY: all test install 9 | 10 | all: ; 11 | 12 | install: all 13 | $(INSTALL) -d $(DESTDIR)/$(LUA_LIB_DIR)/resty 14 | $(INSTALL) lib/resty/*.lua $(DESTDIR)/$(LUA_LIB_DIR)/resty 15 | 16 | test: all 17 | PATH=$(OPENRESTY_PREFIX)/nginx/sbin:$$PATH prove -I../test-nginx/lib -r t 18 | 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Name 2 | ============= 3 | 4 | lua-resty-zip - zip functions(compress/uncompress) for LuaJIT 5 | 6 | Status 7 | ====== 8 | 9 | This library is considered experimental. 10 | 11 | 12 | Description 13 | =========== 14 | 15 | The code mainly from http://luajit.org/ext_ffi_tutorial.html. 16 | 17 | 18 | Synopsis 19 | ======== 20 | 21 | ```lua 22 | # nginx.conf: 23 | 24 | lua_package_path "/path/to/lua-resty-zip/lib/?.lua;;"; 25 | 26 | server { 27 | location = /test { 28 | content_by_lua_block { 29 | local zip = require "resty.zip" 30 | 31 | local txt = string.rep("abcd", 1000) 32 | ngx.say("Uncompressed size: ", #txt) 33 | 34 | local c = zip.compress(txt, 1) 35 | ngx.say("Compressed size on level 1: ", #c) 36 | 37 | local c = zip.compress(txt, 9) 38 | ngx.say("Compressed size on level 9: ", #c) 39 | 40 | local txt2 = zip.uncompress(c, #txt) 41 | assert(txt2 == txt) 42 | } 43 | } 44 | } 45 | ``` 46 | 47 | 48 | Methods 49 | ======= 50 | 51 | compress 52 | ---- 53 | `syntax: c = resty.compress(txt, level?)` 54 | 55 | 56 | uncompress 57 | ---- 58 | `syntax: txt = resty.uncompress(c)` 59 | 60 | 61 | Author 62 | ====== 63 | 64 | Dejiang Zhu (doujiang24) 65 | -------------------------------------------------------------------------------- /lib/resty/zip.lua: -------------------------------------------------------------------------------- 1 | -- mainly from http://luajit.org/ext_ffi_tutorial.html 2 | 3 | 4 | local ffi = require "ffi" 5 | local ffi_new = ffi.new 6 | local ffi_str = ffi.string 7 | 8 | 9 | local _M = { _VERSION = '0.01' } 10 | 11 | local mt = { __index = _M } 12 | 13 | 14 | ffi.cdef[[ 15 | unsigned long compressBound(unsigned long sourceLen); 16 | int compress2(uint8_t *dest, unsigned long *destLen, 17 | const uint8_t *source, unsigned long sourceLen, int level); 18 | int uncompress(uint8_t *dest, unsigned long *destLen, 19 | const uint8_t *source, unsigned long sourceLen); 20 | ]] 21 | 22 | local zlib = ffi.load(ffi.os == "Windows" and "zlib1" or "z") 23 | 24 | local buflen = ffi_new("unsigned long[1]", 0) 25 | 26 | 27 | -- level: 0 - 9 28 | function _M.compress(txt, level) 29 | local n = zlib.compressBound(#txt) 30 | local buf = ffi.new("uint8_t[?]", n) 31 | 32 | buflen[0] = n 33 | local res = zlib.compress2(buf, buflen, txt, #txt, level or 1) 34 | 35 | if res == 0 then 36 | return ffi_str(buf, buflen[0]) 37 | end 38 | end 39 | 40 | 41 | function _M.uncompress(comp, n) 42 | local buf = ffi_new("uint8_t[?]", n) 43 | 44 | buflen[0] = n 45 | local res = zlib.uncompress(buf, buflen, comp, #comp) 46 | 47 | if res == 0 then 48 | return ffi_str(buf, buflen[0]) 49 | end 50 | end 51 | 52 | 53 | return _M 54 | -------------------------------------------------------------------------------- /t/sanity.t: -------------------------------------------------------------------------------- 1 | # vi:ft= 2 | 3 | use Test::Nginx::Socket::Lua; 4 | 5 | repeat_each(2); 6 | no_long_string(); 7 | 8 | plan tests => repeat_each() * (3 * blocks()); 9 | 10 | our $HttpConfig = <<'_EOC_'; 11 | lua_package_path 'lib/?.lua;;'; 12 | _EOC_ 13 | 14 | #log_level 'warn'; 15 | 16 | run_tests(); 17 | 18 | __DATA__ 19 | 20 | === TEST 1: sanity 21 | --- http_config eval: $::HttpConfig 22 | --- config 23 | location /t { 24 | content_by_lua ' 25 | local zip = require "resty.zip" 26 | 27 | local txt = string.rep("abcd", 1000) 28 | ngx.say("Uncompressed size: ", #txt) 29 | 30 | local c = zip.compress(txt, 1) 31 | ngx.say("Compressed size on level 1: ", #c) 32 | 33 | local c = zip.compress(txt, 9) 34 | ngx.say("Compressed size on level 9: ", #c) 35 | 36 | local txt2 = zip.uncompress(c, #txt) 37 | assert(txt2 == txt) 38 | 39 | collectgarbage() 40 | '; 41 | } 42 | --- request 43 | GET /t 44 | --- response_body 45 | Uncompressed size: 4000 46 | Compressed size on level 1: 49 47 | Compressed size on level 9: 32 48 | --- no_error_log 49 | [error] 50 | --------------------------------------------------------------------------------