博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
tinyhttpd源码分析
阅读量:6819 次
发布时间:2019-06-26

本文共 1680 字,大约阅读时间需要 5 分钟。

  我们经常使用网页,作为开发人员我们也部署过httpd服务器,比如开源的apache,也开发过httpd后台服务,比如fastcgi程序,不过对于httpd服务器内部的运行机制,却不是非常了解,前几天看见tinyhttpd,只有短短500行左右的代码,就实现了一个简单的httpd服务器的基本功能,这种tiny程序,其实对于我们了解基本核心有一定的帮助,可以通过分析其代码,了解构建一个简单的httpd服务器需要的基本元素。

  (1) startup函数

  这个函数的代码非常简单,其实就是简单创建一个server端的socket,让它绑定指定的端口,然后开始listen

  (2) accept_request函数

  此函数中首先解析客户端的请求方式,是GET,还是POST,tinyhttpd只能处理这2种请求,如果都不是,就返回错误。然后解析请求的url,然后对应到服务器中tinyhttpd中htdocs目录下的文件,检查文件状态,如果文件不存在,那么返回错误。如果文件存在,是GET方法时,tinyhttpd直接返回此文件,通常是html。如果是POST,那么会执行对应的.cgi文件,tinyhttpd中的CGI文件,是用PERL脚本实现的。

  (3) execute_cgi函数

  此函数中就是如何执行CGI脚本的地方,首先还是将POST部分的数据解析出来,然后fork一个子进程去执行CGI脚本,这里有一个小的技巧,就是tinyhttpd使用了管道来让执行CGI脚本的子进程,通过标准输出写入和父进程的管道中,父进程在fork之后,读取此管道中的数据,然后返回给客户端。

  父进程中创建管道的代码:

if (pipe(cgi_output) < 0) {  cannot_execute(client);  return; } if (pipe(cgi_input) < 0) {  cannot_execute(client);  return; }

  这里创建了2个管道,每个管道都有一个写端,一个读端。

  子进程是通过下面代码执行的:

execl(path, path, NULL);

  父进程中,读取管道中的内容:

while (read(cgi_output[0], &c, 1) > 0)   send(client, &c, 1, 0);

  color.cgi代码:

#!/usr/bin/perl -Twuse strict;use CGI;my($cgi) = new CGI;print $cgi->header;my($color) = "blue";$color = $cgi->param('color') if defined $cgi->param('color');print $cgi->start_html(-title => uc($color),                       -BGCOLOR => $color);print $cgi->h1("This is $color");print $cgi->end_html;

  单独在控制台下运行的结果是:

BLUE

This is blue

  也就是说,tinyhttpd通过子进程运行PERL的CGI脚本,然后脚本输出了一个HTML,这个HTML内容通过父子进程之间的管道进程消息传递,父进程读取管道中的内容发送给浏览器。

  不过我们从代码中只看到了设置环境变量putenv的部分,如果是POST方法,并没有看见设置参数的部分,其实这部分代码,是在fork之后,parent中通过for循环,将content_length长的content通过管道write给了子进程的标准输入,这也就是为什么在fork子进程之前先创建了2个管道的原因。

  这样,整个tinyhttpd核心的内容就结束了。

转载于:https://www.cnblogs.com/chobits/p/5142207.html

你可能感兴趣的文章
【常规发布】开年大戏! 值得我们关注的 1k+ star 及码云 GVP 项目
查看>>
Mysql 5.6主从同步配置与解决方案
查看>>
超微服务器开机后没有反应解决方法
查看>>
WinAPI: SetWindowPos - 改变窗口的位置与状态
查看>>
Delphi 中的自动释放策略
查看>>
python3——字符串基础
查看>>
Java VisualVM 插件地址
查看>>
MacOS自带PHPGD库问题
查看>>
Setting up 11g Active Dataguard(ADG)
查看>>
五天学redhat系列之---系统基础管理
查看>>
土地划分
查看>>
IPv6静态路由配置
查看>>
初识Nginx——nginx的编译、安装及特点(一)
查看>>
通过redis扩展分布式存储fastdfs的数据对应及方案
查看>>
我的友情链接
查看>>
Linux学习记录--日志系统
查看>>
什么是OTT
查看>>
大型互联网站解决高并发的常见策略
查看>>
Apache Rewrite
查看>>
UML学习笔记(7)——时序图
查看>>