用C写Web:CGI、FastCGI与Nginx模块的实战笔记
为什么还要用C搞Web开发?
C语言在Web领域不算主流,但当你需要榨干服务器性能、写出极低延迟的服务时,它依然是个硬核选择。CGI、FastCGI和Nginx模块代表了从简单到极致的三个层次,理解它们不仅让你明白HTTP协议背后的机制,也能在特定场景下给出更靠谱的方案。
CGI:古老而直接的接口
CGI的工作模型很原始:每个请求到来,Web服务器拉起一个新进程执行你的CGI程序,程序跑完输出响应,进程就销毁了。这种隔离性天然防止了内存泄漏累积,但代价是每次请求都要走一遍进程创建与销毁,并发一上来系统负载就爆了。所以它只适合低频、隔离要求高的内部工具。
程序访问请求参数全靠环境变量。GET的参数在QUERY_STRING里,POST的数据从标准输入读取,长度由CONTENT_LENGTH指定。输出必须严格遵循HTTP格式:头部和主体之间用两个换行分隔。
一个最简的Hello World:
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Content-Type: text/plain\n\n");
printf("Hello from CGI!");
return 0;
}
处理URL解码和参数解析的完整例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void decode_url(char *src, char *dst) {
int i = 0, j = 0;
while (src[i]) {
if (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(, );
}
}
;
}


