我们经常使用网页,作为开发人员我们也部署过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) < ) {
cannot_execute(client);
return;
}
if (pipe(cgi_input) < ) {
cannot_execute(client);
return;
}

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

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

execl(path, path, NULL);

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

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

  color.cgi代码:

#!/usr/bin/perl -Tw

use 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;

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

<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head>
<title>BLUE</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body bgcolor="blue">
<h1>This is blue</h1>
</body>
</html>

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

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

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

tinyhttpd源码分析的更多相关文章

  1. HTTP服务器的本质:tinyhttpd源码分析及拓展

    已经有一个月没有更新博客了,一方面是因为平时太忙了,另一方面是想积攒一些干货进行分享.最近主要是做了一些开源项目的源码分析工作,有c项目也有python项目,想提升一下内功,今天分享一下tinyhtt ...

  2. ABP源码分析一:整体项目结构及目录

    ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...

  3. HashMap与TreeMap源码分析

    1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...

  4. nginx源码分析之网络初始化

    nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...

  5. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  6. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

  7. zookeeper源码分析之三客户端发送请求流程

    znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...

  8. java使用websocket,并且获取HttpSession,源码分析

    转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...

  9. ABP源码分析二:ABP中配置的注册和初始化

    一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...

随机推荐

  1. WCF初探文章列表

    WCF初探-1:认识WCF WCF初探-6:WCF服务配置 WCF初探-2:手动实现WCF程序 WCF初探-7:WCF服务配置工具使用 WCF初探-3:WCF消息交换模式之单向模式 WCF初探-8:W ...

  2. Linq to xml 小例

    static void Main(string[] args)        {            string strXml = @"<?xml version='1.0' en ...

  3. 简单研究Loader笔记

    2015-11-11 18:25:34 1. Loader是什么? /** * Static library support version of the framework's {@link and ...

  4. iOS权限问题

    判断相机权限: NSString *mediaType = AVMediaTypeVideo; AVAuthorizationStatus authStatus = [AVCaptureDevice ...

  5. linux内核学习之七 可执行程序的装载和运行

    一 程序的装载和运行的基本知识补充    1 当进程开始执行一个新的程序时,从父进程继承的所有页被释放,以便在新的用户地址空间开始执行新的计算,甚至进程的特权都可能发生改变,但是,进程的PID不会改变 ...

  6. 思维导图MindManager的文件格式与例图

    思维导图软件很多,能够画出思维导图的软件更多.作为流传较广而又比较成熟的思维导图软件,MindManager有专门的文件格式.如果读者想多借鉴导图,就应该了解MindManager的文件格式. Min ...

  7. 执行时关闭标识位 FD_CLOEXEC 的作用

    首先先回顾 apue 中对它的描述: ① 表示描述符在通过一个 exec 时仍保持有效(书P63,3.14节 fcntl 函数,在讲 F_DUPFD 时顺便提到) ② 对打开文件的处理与每个描述符的执 ...

  8. [转]as3 算法实例【输出1 到最大的N 位数 题目:输入数字n,按顺序输出从1 最大的n 位10 进制数。比如输入3,则输出1、2、3 一直到最大的3 位数即999。】

    思路:如果我们在数字前面补0的话,就会发现n位所有10进制数其实就是n个从0到9的全排列.也就是说,我们把数字的每一位都从0到9排列一遍,就得到了所有的10进制数. /** *ch 存放数字 *n n ...

  9. 如何在网页中调用百度地图api

    我想在木有提供地图接口的年代,前端工程师门要么只写上企业的具体地址,要么就是用一张标有自己位置的地图图片.但是现在不一样啦!为了增强用户体验,谷歌,甚至百度都很开放了,你可以在他们的网站上找到地图接口 ...

  10. 基于WWF搭建的通用审批流程

    月明星稀,却不见明月:蛾儿雪柳暗香飘过,纵使回首千百回,却不知,心已灭:壮志未酬,却落得个多情应该笑我:扬帆起航,却不知,帆已破.这是我刚离职时的心情,曾几何时,真的想呆在一家公司,做一名优秀的技术管 ...