C 语言 Web 开发:CGI、FastCGI 与 Nginx 实战解析

前言:为什么 Web 开发离不开 C 语言?
虽然现代 Web 开发中 Python、Go 等语言很流行,但 C 语言的高性能和可移植性使其在底层网络服务领域依然占据重要地位。无论是嵌入式网关还是高性能反向代理,理解 C 语言如何与 Web 服务器交互都是后端工程师的必修课。
本章我们将深入探讨 CGI、FastCGI 以及 Nginx 模块开发的原理与实现,重点在于掌握核心架构、编写代码时的注意事项,以及实际案例中的避坑指南。
CGI(通用网关接口)基础
核心架构
CGI 是最早的 Web 服务器扩展标准之一。其工作流程相对简单:Web 服务器接收到客户端请求后,会启动一个新的进程来运行 CGI 程序,处理完请求后将结果返回给服务器,最后销毁该进程。
- Web 服务器:负责接收请求并转发给 CGI 程序。
- CGI 程序:独立进程,处理逻辑并生成响应。
- 客户端:发起请求并接收最终响应。
开发要点
使用 C 语言编写 CGI 程序时,主要通过环境变量获取请求信息。这里有一个简单的 Hello World 示例,展示了如何设置 HTTP 响应头。
#include <stdio.h>
#include <stdlib.h>
int main() {
// 设置 HTTP 响应头,注意两个换行符
printf("Content-Type: text/plain\n\n");
// 输出响应内容
printf("Hello from CGI!");
return 0;
}
在实际开发中,我们需要处理 GET 和 POST 参数。GET 参数通常通过 QUERY_STRING 环境变量传递,而 POST 数据则从标准输入读取。下面是一个获取并解码 URL 参数的示例。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
{
i = , j = ;
(src[i]) {
(src[i] == ) {
value;
(src + i + , , &value);
dst[j++] = ()value;
i += ;
} (src[i] == ) {
dst[j++] = ;
i++;
} {
dst[j++] = src[i++];
}
}
dst[j] = ;
}
{
*query_string = getenv();
*content_type = getenv();
*request_method = getenv();
();
(, query_string ? query_string : );
(, content_type ? content_type : );
(, request_method ? request_method : );
((request_method, ) == && query_string) {
*token = strtok(query_string, );
(token) {
*equals = (token, );
(equals) {
*equals = ;
*key = token;
*value = equals + ;
decoded_key[], decoded_value[];
decode_url(key, decoded_key);
decode_url(value, decoded_value);
(, decoded_key, decoded_value);
}
token = strtok(, );
}
}
;
}


