一、简介
Civetweb是一个跨平台的、轻量级的Web服务器,它以MIT许可证开源,可以在商业和非商业环境中自由使用。Civetweb支持HTTP/1.1、HTTPS、WebSocket和CGI等多种协议,可以运行在Windows、Linux、macOS等各种操作系统上,因此Civetweb被广泛地应用于各种嵌入式设备和服务器端应用程序。
Civetweb的特点主要包括:
- 快速轻量:Civetweb采用高度优化的C代码编写,可以运行在低端嵌入式设备上。
- 易于集成:Civetweb可以非常容易地集成到其他项目中,支持动态链接和静态链接两种方式。
- 易于扩展:Civetweb支持插件和动态链接库,可以方便地扩展其功能。
- 安全可靠:Civetweb支持HTTPS和WebSocket协议,可以保证数据传输的安全性,而且Civetweb有非常完善的日志记录机制,可以追踪问题和安全漏洞。
二、使用方法
使用Civetweb非常简单,只需要下载源码编译即可。以下是一个示例的代码:
#include "civetweb.h" static int hello_handler(struct mg_connection* conn, void* cbdata) { mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n"); mg_printf(conn, "Hello from Civetweb!"); return 1; } int main(int argc, char* argv[]) { struct mg_mgr mgr; struct mg_connection* nc; mg_mgr_init(&mgr, NULL); nc = mg_bind(&mgr, "8080", NULL); mg_set_protocol_http_websocket(nc); mg_register_http_endpoint(nc, "/hello", hello_handler, NULL); printf("Starting Civetweb on port %s\n", mg_get_option(&mgr, "listening_ports")); for (;;) { mg_mgr_poll(&mgr, 1000); } mg_mgr_free(&mgr); return 0; }
上述代码中,我们定义了一个简单的HTTP请求处理函数hello_handler,只是简单地输出Hello from Civetweb!。然后,我们使用mg_bind函数创建了一个监听8080端口的连接,并使用mg_register_http_endpoint函数将hello_handler函数注册为/hello的处理函数。最后,我们使用mg_mgr_poll函数进入事件轮询循环,等待连接请求。
使用上述代码编译并运行,可以通过浏览器访问http://localhost:8080/hello,就可以看到浏览器输出Hello from Civetweb!。
三、配置选项
Civetweb可以通过命令行参数和配置文件进行配置。以下是一些常用的配置选项:
- listening_ports:监听端口,默认为80。
- ssl_certificate:SSL证书文件路径。
- ssl_certificate_chain:SSL证书链文件路径(可选)。
- ssl_protocols:SSL协议类型,可选值为TLSv1.1、TLSv1.2、TLSv1.3等。
- access_log_file:访问日志文件路径。
- error_log_file:错误日志文件路径。
- num_threads:工作线程数量,默认为50。
- document_root:文档根目录,默认为当前目录。
配置选项可以通过以下两种方式进行设置:
- 命令行参数:Civetweb支持类似于Apache的命令行参数设置方式,例如设置listening_ports选项可以使用-c选项,例如-c listening_ports=8080。
- 配置文件:配置文件可以使用JSON或INI格式,例如以下是一个JSON格式的配置文件示例:
{ "listening_ports": "8080", "ssl_certificate": "/path/to/ssl/certificate.pem", "ssl_certificate_chain": "/path/to/ssl/certificate_chain.pem", "ssl_protocols": "TLSv1.2", "access_log_file": "/path/to/access.log", "error_log_file": "/path/to/error.log", "num_threads": 10, "document_root": "/path/to/document_root" }
通过指定配置文件路径启动Civetweb:
./civetweb -c /path/to/config.json
四、上下文和插件
Civetweb支持多个上下文,一个上下文对应一个Web站点,可以使用不同的配置选项和处理程序。以下是一个使用多个上下文的示例:
#include "civetweb.h" static int hello_handler(struct mg_connection* conn, void* cbdata) { mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n"); mg_printf(conn, "Hello from Civetweb!"); return 1; } int main(int argc, char* argv[]) { struct mg_context* ctx1, * ctx2; /* 创建两个上下文 */ ctx1 = mg_start(NULL, NULL, NULL); ctx2 = mg_start(NULL, NULL, NULL); /* 在第一个上下文注册/hello处理程序 */ mg_register_http_endpoint(ctx1, "/hello", hello_handler, NULL); /* 在第二个上下文注册/hello/deep处理程序 */ mg_register_http_endpoint(ctx2, "/hello/deep", hello_handler, NULL); /* 等待事件 */ getchar(); /* 停止上下文 */ mg_stop(ctx1); mg_stop(ctx2); return 0; }
通过上述代码,我们创建了两个上下文,然后在每个上下文中分别注册了不同的处理程序。可以用两个浏览器分别访问http://localhost:8080/hello和http://localhost:8081/hello/deep来验证这个示例。
除了多个上下文,Civetweb还支持插件。插件可以是动态链接库,可以通过mg_load_plugin函数加载,并且可以在启动时自动加载。以下是一个使用插件的示例:
#include "civetweb.h" int main(int argc, char* argv[]) { struct mg_context* ctx; const char* plugin_names[] = { "mod_auth_digital_signature.dll", "mod_rewrite.dll", NULL }; /* 创建上下文 */ ctx = mg_start(NULL, NULL, plugin_names); /* 等待事件 */ getchar(); /* 停止上下文 */ mg_stop(ctx); return 0; }
上述代码会自动加载mod_auth_digital_signature.dll和mod_rewrite.dll这两个插件。
总结
Civetweb是一个跨平台的、轻量级的Web服务器,可以应用于各种嵌入式设备和服务器端应用程序。它支持HTTP/1.1、HTTPS、WebSocket和CGI等多种协议,支持插件和动态链接库,易于集成和扩展。通过命令行参数和配置文件,可以方便地进行配置。同时,Civetweb还支持多个上下文和插件,可以实现更加复杂和灵活的应用场景。