Windows 環境的 libcurl https 支援

cURL 是一個很知名的開源專案(官網),他主要的功能是用來存取包含 Http、FTP、SMTP 等在內通訊協定的命令提示字元工具,在 Linux 環境算是相當常用到的。

而同時,他也有 libcurl 這個 C 語言的函式庫(官網),讓開發者可以透過它還存取網路上的 資源。

而 Heresy 這次會要用他,主要是要去下載 https 的檔案,但是一開始用 CMake 來建置的時候,卻發現真的去開 https 的時候,卻出現了不支援的錯誤…

curl_easy_perform() failed: Unsupported protocol

後來研究了一下,才發現 libcurl 在自己建置的時候,還有很多參數可以可以/需要設定…如果要特定的功能,可能也還會需要額外的函式庫才行。而 Heresy 這邊就是因為沒有設定 SSL 相關功能要用什麼函式庫,所以建置出來的 libcurl 和 curl 就變得不支援 https 了。

另一方面,如果是像 Heresy 這樣要用 Visual C++ 來建置的話,其實 libcurl 也有在 winbuild 這個目錄下提供現成的 Makefile.vc 可以用、可以直接用 nmake 來建置、而不需要使用 CMake。這部分的說明可以參考《Building curl with Visual C++》。

他最簡單的指令就是(要用 Visual Studio 環境的命令提示字元):

nmake /f Makefile.vc mode=static

而如果想要編譯成 DLL、用動態連結的形式的話,則是:

nmake /f Makefile.vc mode=dll

如果有需要使用到其他函式庫的話,則是需要把需要的其他函式庫(例如 zlib、OpenSSL)按照他的規範,放到 ../deps 裡面,結構要如下:

somedirectory\
 |_curl-src
 | |_winbuild
 |
 |_deps
   |_ lib
   |_ include
   |_ bin

像是如果有要加上 zlib 的壓縮功能的話,就把 zlib 的 header 放到 deps/include、然後把 zlib.lib 放到 deps/lib,編譯的時候再加上「WITH_ZLIB=static」就好了~

而如果 zlib 是編譯成 DLL 的型式的話,則是改成「WITH_ZLIB=dll」就可以了。

雖然少了一些彈性,但是在使用上其實相當方便。


使用 OpenSSL

因為是需要 SSL 的功能才能開啟 https,所以 Heresy 第一個想到的就是 OpenSSL(官網)。

這邊是要把 OpenSSL 的 header 檔,放到 deps/include/openssl 這個資料夾中,然後再把對應的兩個 .lib 放到 deps/lib 裡,之後就可以用下面的命令來建置出使用 OpenSSL 的 libcurl 了。

nmake /f Makefile.vc mode=dll WITH_ZLIB=static WITH_SSL=dll

不過,這樣弄出來的 curl.exe 在開啟 https 的網站的時候,卻會出現下面的錯誤:

curl: (60) SSL certificate problem: unable to get local issuer 
certificate
More details here: https://curl.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could 
not establish a secure connection to it. To learn more about this situation 
and how to fix it, please visit the web page mentioned above.

查了一下,這才知道原來在使用 OpenSSL 的情況下,還要另外準備一個 curl-ca-bundle.crt 憑證檔,他在執行的時候可以讀到、作為 local 憑證使用。

而根據《CA certificates extracted from Mozilla》這邊的說法,是可以下載 Mozilla 核發的 cacert.pem 這個檔案,直接改名成 curl-ca-bundle.crt  來使用。


使用 Windows 內建的 SSL 功能

理論上,如果在使用 nmake 來建置 curl 的話,在沒有指定其他 SSL 函式庫的情況下,他會預設去使用 Windows 內建的 SSL 功能(Schannel);這個情況下,由於他會去使用 Windows 的 local 憑證,所以也不需要去準備那個 curl-ca-bundle.crt 檔案,算是比較方便?

但是要注意的是,如果使使用較早期、已經停止維護的作業系統(例如 Windows XP)的話,可能會因為對應的 SSL 版本太舊、而出現無法正常運作的狀況;這個時候就得使用像是 OpenSSL 等其他 SSL backend 了。

所以這邊是改用下面的參數來建置 libcurl:

nmake /f Makefile.vc mode=dll WITH_ZLIB=static ENABLE_SCHANNEL=yes

理論上這邊是可以不用加「ENABLE_SCHANNEL」也可以,這邊算是強制加上去、預防萬一了。

這樣編譯出來的 curl.exe 就可以直接開 https 網頁沒問題了~


其實可以用來開啟 https 的 C/C++ 函式庫還滿多的,libcurl 自己就有列了一份《available alternatives》,有需要的話可以參考。

而實際上,Heresy 之前也有用過 Boost Beast 寫過一個簡單哦 https client(更早是直接用 Boost ASIO 刻),後來也有用 Qt 玩過

不過以 Boost Beast 來說,雖然他算是已經把 Boost asio 包了一層了,但是實際上還是相當地低階,寫起來很麻煩…

相較於 Boost Beast,libcurl 的簡易模式在使用上就相當地簡單了。(官方範例

發佈留言

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