由于之前没认真学习过http协议及服务端的相关实现,近日有空看到同事有本《Linux网络编程(第2版)》,
遂拾来翻阅,见其中包含一个web服务器的综合案例,于是想认真对照着学习下http的相关开发实现。
孰不知,一涉足才发现这是个坑。
首先,书本代码不完整,提供的源码链接也并没有该案例源码;
最终从这里http://blog.csdn.net/l979951191/article/details/47443089找到比较全的代码,感谢之;
其次,代码存在着一些bugs;上述博文链接的作者虽然代码比较全,
最后却没有实现功能,原因就是没有修改其中的bugs;
再者,提供的代码功能不完整,并没有实现cgi等一些功能。写这篇文章只是不想让自己几天的学习没有结果,虽然这本书是个坑,但如果哪位读者不小心也中踩进来了,
可以从这里获得些提醒,然后相互交流一下心得。不知是否该抨击下作者呢,误人子弟?
不过现在的技术书籍繁多,良莠不齐,还真是要看大神们的推荐比较好。
刚入门其实最好还是可以先看看轻量级tinyhttpd,网上很多解析,github上随便都能找到源码,
https://github.com/search?utf8=%E2%9C%93&q=tinyhttpd&type=Repositories
鄙人认为实现web服务器的难点,在于如何处理并发和实现cgi。
并发的实现,可以通过维护线程池或者IO多路复用,epoll模型在linux下是比较好的选择。
cgi的实现则涉及到管道通信, 当然cgi已经不常用了,但理解下原理还是有益的。
下面主要是贴出我发现《linux网络编程》shttpd案例代码有问题的地方,
由于我也是才学习实现http服务器,源码中未实现的功能如post、put、cgi等方法,我也还未想好如何较好的实现。
b. 根据关键字判断取值时 strncmp()没有取反。 正确应该如下:
void Para_FileParse(char* file)
{
......
......
name = pos;
while (!isspace(*pos) && *pos != '=') {
++pos;
}
*pos++ = '\0';
while (isspace(*pos) || *pos == '=') {
++pos;
}
value = pos;
while (!isspace(*pos) && *pos != '\0' && *pos != '\r' && *pos != '\n') {
++pos;
}
*pos = '\0';
int ivalue;
if (!strncmp("CGIRoot", name, 7)) {
memcpy(conf_para.CGIRoot, value, strlen(value) + 1);
} else if (!strncmp("DefaultFile", name, 11)) {
memcpy(conf_para.DefaultFile, value, strlen(value) + 1);
} else if (!strncmp("DocumentRoot", name, 12)) {
memcpy(conf_para.DefaultFile, value, strlen(value) + 1);
} else if (!strncmp("ListenPort", name, 10)) {
ivalue = strtol(value, NULL, 10);
conf_para.ListenPort = ivalue;
} else if (!strncmp("MaxClient", name, 9)) {
ivalue = strtol(value, NULL, 10);
conf_para.MaxClient = ivalue;
} else if (!strncmp("TimeOut", name, 7)) {
ivalue = strtol(value, NULL, 10);
conf_para.TimeOut = ivalue;
}
......
......
}
snprintf(req->rpath, URI_MAX, "%s%s",conf_para.DocumentRoot, req->uri);
if (req->uri[strlen(req->uri) - 1] == '/') {
strcat(req->rpath, conf_para.DefaultFile);
}
1. 源码中uri解析、cgi实现的代码并未用到;uri解析应该是给cgi程序传参时用到的。
其实鄙人认为源码中的cgi实现也是有问题的,执行cgi程序需要用到环境变量或通过管道传参,
但代码中却丝毫没有;
2. post/put等其他方法需要进一步学习http协议去实现。鄙人浅薄之见,欢迎交流讨论。