[Lua] 使用 lua-zlib 套件,解開 gzip 壓縮後的資料

[Lua] 使用 lua-zlib 套件,解開 gzip 壓縮後的資料

之前使用 lua-http 套件,連線 HTTPS 網站並取得回應內容

結果後來遇到一個網站,它回傳的 Content-Encoding 是 x-gzip,

因此收到的 body 部分事實上是 gzip 編碼的。

這要怎麼解開呢?

 

當然如果存成檔案,再用命令列  gunzip 指令是可以解開,

不過我想在 Lua 程式裡直接解開,再做後續的處理…

 

查了一下,有人說 gzip 的壓縮格式和 zlib 的很像。

因此,去找了 lua-zlib 這個套件來試試看~

 

1. 安裝 lua-zlib 套件

用 luarocks 安裝 lua-zlib 套件,結果出現找不到 zlib 標頭檔的訊息:

$ sudo luarocks install lua-zlib

Installing https://luarocks.org/lua-zlib-1.2-1.rockspec
Cloning into 'lua-zlib'...
remote: Enumerating objects: 17, done.
remote: Counting objects: 100% (17/17), done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 17 (delta 0), reused 10 (delta 0), pack-reused 0
Receiving objects: 100% (17/17), 17.51 KiB | 358.00 KiB/s, done.
Note: switching to 'a305d98f473d0a253b6fd740ce60d7d5a5f1cda0'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false


Error: Could not find header file for ZLIB
  No file zlib.h in /usr/local/include
  No file zlib.h in /usr/include
  No file zlib.h in /include
You may have to install ZLIB in your system and/or pass ZLIB_DIR or ZLIB_INCDIR to the luarocks command.
Example: luarocks install lua-zlib ZLIB_DIR=/usr/local

 

zlib 的標頭檔,哪邊找的到呢?

上網查了一下,說 Mac 上有裝 Xcode 的話就會有,

可以執行  xcrun --show-sdk-path 看 SDK 的路徑:

$ xcrun --show-sdk-path

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk

 

這個路徑下面,有個 usr 目錄,

它下面的結構就很像一般 Linux 的 /usr 目錄,

會有 bin, include, lib 這些目錄:

$ ll /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk

-rw-r--r--  1 root  wheel   127 Mar 16  2021 Entitlements.plist
-rw-r--r--  1 root  wheel  4512 Mar 16  2021 SDKSettings.json
-rw-r--r--  1 root  wheel  3691 Mar 16  2021 SDKSettings.plist
drwxr-xr-x  4 root  wheel   128 Mar 16  2021 System/
drwxr-xr-x  7 root  wheel   224 Mar 16  2021 usr/

 

在 usr/include 目錄下,就會看到 zlib.h 這個標頭檔。

因此我們可以將這個 usr 目錄,傳進 ZLIB_DIR 參數,

就可以成功用 luarocks 安裝 lua-zlib 套件了:

sudo luarocks install lua-zlib ZLIB_DIR=$(xcrun --show-sdk-path)/usr

 

2. 使用 lua-zlib 套件

先做個測試檔案,內容寫 abcdefg,再用 gzip 壓起來,

這會產生一個 aaa.gz 檔案:

echo abcdefg > aaa
gzip aaa

 

來看看怎麼用 lua-zlib 解開這個 aaa.gz 的內容吧~

讀檔之後,可以看到檔案的內容是一串奇怪的資料,

這是被 gzip 壓縮過後的資料:

> f = io.open("aaa.gz", "r")
> data = f:read()
> data
cAlaaaaKLJNIMK�$*S

 

接下來引用 zlib 模組,

接著用  zlib.inflate() 函式來解開資料。

這邊比較特別的是  zlib.inflate() 函式還可以傳參數進去 (也可以不傳),

這會傳回一個另一個函式,這個函式才是真正拿來解資料的。

解成功的話,第一個傳回值就是解完的資料,

可以看到它有成功解出原始值 abcdefg:

> zlib = require "zlib"
> zlib.inflate()(data)
abcdefg
    true	32	8

 

其他的用法就再請直接參考 lua-zlib 網站上面的說明囉~

 

參考資料:

Lua: How to gzip a string (gzip, not zlib) in memory? – Stack Overflow

Cannot find zlib headers on macOS 10.15 Catalina – Rob Allen’s DevNotes

homebrew – brew install zlib-devel on Mac OS X Mavericks – Stack Overflow

(本頁面已被瀏覽過 13 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料