您的位置:

Civetweb:轻量级跨平台Web服务器的利器

一、简介

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还支持多个上下文和插件,可以实现更加复杂和灵活的应用场景。