Thrift&SSL编程#03#zlib编译篇

关于Thrift和OpenSSL的安全通信,上篇我们描述了Boost的编译方法,本文编译zlib库。

  • 01#编译OpenSSL库;
  • 02#编译Boost库;
  • 03#编译zlib库
  • 04#编译Libevent库;
  • 05#编译Thrift库;
  • 06#生成客户端和服务端通信所用的数字证书;
  • 07#编写基于Linux系统的测试代码(单向验证:客户端验证服务端);
  • 08#编写基于Windows系统的测试代码(单向验证:客户端验证服务端);
  • 09#编写基于Linux系统的测试代码(双向验证:客户端验证服务端+服务端验证客户端);
  • 10#编写基于Windows系统的测试代码(双向验证:客户端验证服务端+服务端验证客户端);
  • 11#自定义数字证书的验证策略;

下载zlib

OpenSSL的官方网站列表:
官网网站:https://www.zlib.net
历史版本:https://github.com/madler/zlib/releases

本系列演示用的版本V1.3.1的下载地址如下:
https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz

Windows版本编译方法

1/4) 下载zlib代码并解压

zlib下载完毕并解压后,如下图所示:

2/4) 编译zlib代码安装
在Windows上我们使用cmake+visual studio 2017编译zlib库,如下命令(本文我们以编译shared+static+release库举例):

1
2
3
4
5
6
7
8
9
# 编译shared+static+release库,使用如下命令:
cmake -S . -B build -A x64 -DCMAKE_INSTALL_PREFIX=../build/zlib-1.3.1
cmake --build build --config Release
cmake --install build --config Release

# 编译shared+static+debug库,使用如下命令:
cmake -S . -B build -A x64 -DCMAKE_INSTALL_PREFIX=../build/zlib-1.3.1
cmake --build build --config Debug
cmake --install build --config Debug

使用cmake配置,如下图所示:

使用cmake编译,如下图所示:

使用cmake安装,如下图所示:

至此,zlib的shared+static+release版本库已编译完成。我们看下安装后的文件:

其中:

  • bin/zlib.dll是release版本的动态库,lib/zlib.lib是zlib.dll的导出库;
  • lib/zlibstatic.lib是release版本的静态库

zlib库测试

我们写个测试代码,测试下我们刚生成的库。该测试代码在不解压*.tar、*.tar.gz、或者*.tgz等压缩文件的情况下,从中读取指定文件的内容。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <string>
#include <iostream>
#include <algorithm>
#include <zlib.h>

int ReadFileFromTar(const std::string& sTarFilePath, const std::string& sTargetFilePath, std::string& sFileContent)
{
gzFile gz = gzopen(sTarFilePath.c_str(), "rb");
if (!gz)
{
return -1;
}

char zHeader[512];
while (gzread(gz, zHeader, 512) > 0)
{
if (zHeader[0] == '\0')
{
break;
}

std::string sFileName(zHeader);
size_t pos = sFileName.find('\0');
if (pos != std::string::npos)
{
sFileName.resize(pos);
}

// 解析文件大小
size_t iFileSize = std::stoi(zHeader + 124, nullptr, 8);

if (sFileName == sTargetFilePath)
{
char zBuffer[4096];
for (size_t remaining = iFileSize, read_size = 0; remaining > 0; remaining -= read_size)
{
read_size = std::min(remaining, sizeof(zBuffer));

gzread(gz, zBuffer, read_size);

sFileContent.append(zBuffer, read_size);
}

gzclose(gz);

return 0;
}

// 跳过文件内容
gzseek(gz, (iFileSize + 511) & ~511, SEEK_CUR); // 512字节对齐
}

gzclose(gz);

return -2;
}

int main()
{
std::string sFileContent;
ReadFileFromTar("zlib-1.3.1.tar.gz", "zlib-1.3.1/contrib/blast/README", sFileContent);

std::cout << "==============================" << std::endl;
std::cout << sFileContent << std::endl;
std::cout << "------------------------------" << std::endl;

return 0;
}