《深入理解Nginx:模块开发与架构解析》一3.9 用C++语言编写HTTP模块

简介: 本节书摘来自华章出版社《深入理解Nginx:模块开发与架构解析》一书中的第3章,第3.9节,作者 陶辉,更多章节内容可以访问云栖社区“华章计算机”公众号查看

3.9 用C++语言编写HTTP模块

Nginx及其官方模块都是由C语言开发的,那么能不能使用C++语言来开发Nginx模块呢?C语言是面向过程的编程语言,C++则是面向对象的编程语言,面向对象与面向过程的优劣这里暂且不论,存在即合理。当我们由于各种原因需要使用C++语言实现一个Nginx模块时(例如,某个子功能是用C++语言写成,或者开发团队对C++语言更熟练,又或者就是喜欢使用C++语言),尽管Nginx本身并没有提供相应的方法支持这样做,但由于C语言与C++语言的近亲特性,我们还是可以比较容易达成此目的的。
首先需要弄清楚相关解决方案的设计思路。
不要试图用C++编译器(如G++)来编译Nginx的官方代码,这会带来大量的不可控错误。正确的做法是仍然用C编译器来编译Nginx官方提供的各模块,而用C++编译器来编译用C++语言开发的模块,最后利用C++向前兼容C语言的特性,使用C++编译器把所有的目标文件链接起来(包括C编译器由Nginx官方模块生成的目标文件和C++编译器由第三方模块生成的目标文件),这样才可以正确地生成二进制文件Nginx。
保证C++编译的Nginx模块与C编译的Nginx模块互相适应。所谓互相适应就是C++模块要能够调用Nginx框架提供的C语言方法,而Nginx的HTTP框架也要能够正常地回调C++模块中的方法去处理请求。这一点用C++提供的extern “C”特性即可实现。
下面详述如何实现上述两点内容。

3.9.1 编译方式的修改

Nginx的configure脚本没有对C++语言编译模块提供支持,因此,修改编译方式就有以下两种思路:
1)修改configure相关的脚本。
2)修改configure执行完毕后生成的Makefile文件。
我们推荐使用第2种方法,因为Nginx的一个优点是具备大量的第三方模块,这些模块都是基于官方的configure脚本而写的,擅自修改configure脚本会导致我们的Nginx无法使用第三方模块。
修改Makefile其实是很简单的。首先我们根据3.3.2节介绍的方式来执行configure脚本,之后会生成objs/Makefile文件,此时只需要修改这个文件的3处即可实现C++模块。这里还是以mytest模块为例,代码如下。

CC =   gcc
CXX = g++
CFLAGS =  -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Wunused-function -Wunused-variable -Wunused-value -Werror -g
CPP =   gcc -E
LINK =  $(CXX)

…
objs/addon/httpmodule/ngx_http_mytest_module.o: $(ADDON_DEPS) \
        ../sample/httpmodule/ngx_http_mytest_module.c
        $(CXX) -c $(CFLAGS)  $(ALL_INCS) \
                -o objs/addon/httpmodule/ngx_http_mytest_module.o \
                ../sample/httpmodule/ngx_http_mytest_module.cpp
…

下面解释一下上述代码中修改的地方。
在Makefile文件首部新增了一行CXX = g++,即添加了C++编译器。
把链接方式LINK = $(CC)改为了LINK = $(CXX),表示用C++编译器做最后的链接。
把模块的编译方式修改为C++编译器。如果我们只有一个C++源文件,则只要修改一处,但如果有多个C++源文件,则每个地方都需要修改。修改方式是把$(CC)改为$(CXX)。
这样,编译方式即修改完毕。修改源文件后不要轻易执行configure脚本,否则会覆盖已经修改过的Makefile。建议将修改过的Makefile文件进行备份,避免每次执行configure后重新修改Makefile。
注意 确保在操作系统上已经安装了C++编译器。请参照1.3.2节中的方式安装gcc-c++编译器。

3.9.2 程序中的符号转换

C语言与C++语言最大的不同在于编译后的符号有差别(C++为了支持多种面向对象特性,如重载、类等,编译后的方法名与C语言完全不同),这可以通过C++语言提供的extern “C” {}来实现符号的互相识别。也就是说,在C++语言开发的模块中,include包含的Nginx官方头文件都需要使用extern “C”括起来。例如:

extern "C" {
    #include <ngx_config.h>
    #include <ngx_core.h>
    #include <ngx_http.h>
}

这样就可以正常地调用Nginx的各种方法了。
另外,对于希望Nginx框架回调的类似于ngx_http_mytest_handler这样的方法也需要放在extern “C”中。

相关文章
|
缓存 监控 搜索推荐
301重定向实现原理全面解析:从HTTP协议到SEO最佳实践
301重定向是HTTP协议中的永久重定向状态码,用于告知客户端请求的资源已永久移至新URL。它在SEO中具有重要作用,能传递页面权重、更新索引并提升用户体验。本文详解其工作原理、服务器配置方法(如Apache、Nginx)、对搜索引擎的影响及最佳实践,帮助实现网站平稳迁移与优化。
1352 68
|
11月前
|
缓存 网络协议 UED
深度解析HTTP协议从版本0.9至3.0的演进和特性。
总的来说,HTTP的演进是互联网技术不断发展和需求日益增长的结果。每一次重要更新都旨在优化性能,增进用户体验,适应新的应用场景,而且保证了向后兼容,让互联网的基础架构得以稳定发展。随着网络技术继续进步,我们可以预期HTTP协议在未来还会继续演化。
1108 0
|
11月前
|
数据采集 JSON Go
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
|
网络协议 API Python
解析http.client与requests在Python中的性能比较和改进策略。
最后,需要明确的是,这两种库各有其优点和适用场景。`http.client` 更适合于基础且并行的请求,`requests` 则因其易用且强大的功能,更适用于复杂的 HTTP 场景。对于哪种更适合你的应用,可能需要你自己进行实际的测试来确定。
303 10
|
域名解析 网络协议 网络安全
SSL证书验证全攻略:DNS/HTTP/手动解析怎么选?
SSL证书在网络安全中至关重要,1Panel提供三种验证方式:DNS验证、HTTP验证和手动解析。DNS验证便捷,适合CDN网站;HTTP验证快速,需服务器在线;手动解析灵活,但操作复杂。根据需求选择合适确认方式,定期检查证书状态。
1364 2
|
安全 网络协议 算法
HTTP/HTTPS与SOCKS5协议在隧道代理中的兼容性设计解析
本文系统探讨了构建企业级双协议隧道代理系统的挑战与实现。首先对比HTTP/HTTPS和SOCKS5协议特性,分析其在工作模型、连接管理和加密方式上的差异。接着提出兼容性架构设计,包括双协议接入层与统一隧道内核,通过协议识别模块和分层设计实现高效转换。关键技术部分深入解析协议转换引擎、连接管理策略及加密传输方案,并从性能优化、安全增强到典型应用场景全面展开。最后指出未来发展趋势将更高效、安全与智能。
671 1
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
1520 29
|
网络安全
网络问题解析:如何解决CondaHTTPError HTTP 000 CONNECTION FAILED错误。
以上就是斯诺普为你准备的解决Conda出现HTTP连接错误的手术室。希望这辆小车可以顺利驶出棘手的泥潭,再次在自由的大路上疾驰。一切的尝试和努力,只为更好的探索与开发。
548 17
|
安全 网络安全 数据安全/隐私保护
HTTP 与 HTTPS 协议及 SSL 证书解析-http和https到底有什么区别?-优雅草卓伊凡
HTTP 与 HTTPS 协议及 SSL 证书解析-http和https到底有什么区别?-优雅草卓伊凡
830 3
|
缓存 安全 Java
深入解析HTTP请求方法:Spring Boot实战与最佳实践
这篇博客结合了HTTP规范、Spring Boot实现和实际工程经验,通过代码示例、对比表格和架构图等方式,系统性地讲解了不同HTTP方法的应用场景和最佳实践。
1186 5

推荐镜像

更多
  • DNS