开源代码学习之Tinyhttpd美学原理

   
想伊始陆续钻探一些感兴趣的开源代码于是先挑二个代码量短的来连接一下,写那篇博客的指标是记录下本身读书的历程。Tinyhttpd算是3个袖珍的web服务器,浏览器与Web服务器之间的通讯选择的是Http,所以一开端的切入点是HTTP协议,这里说一些比方有做HTTP通讯的费用照旧看一下奥迪Q5FC中对两样版本HTTP的定义,以下原理部分都以从《后台开发:大旨技术与行使实践》中HTTP协议章节中裁剪出来的,对后台感兴趣的同室能够看一下,讲述后台开发所必要持有的技巧点一本很不利的书。

一、HTTP协议

HTTP工作流程:

  在OSI七层模型中,HTTP是依照TCP上的应用层协议而作者辈所说的HTTPS基于同处于应用层的TLS、SSL协议层之上。HTTP暗中认可的端口号为80,HTTPS暗中认可的端口号为443。在HTTP1.第11中学(通过Connection头设置)默许在HTTP传输实现后连连开TCP连接,从前的HTTP版本则默许是断开连接的,也正是说此次请求与上次请求是分化的七个TCP连接。一遍HTTP操作称为一个政工,其行事进度能够分成以下四步。

  (1)首先客户机与服务器需求建立连接 。 只要单击有些超级链接, HTTP
的做事即起来 。
  (2)建立连接后,客户机发送二个请求给服务器,请求情势的格式为:统一财富标识符(UWranglerL
)、协议版本号,前面是 MIME
音信(包含请求修饰符、客户机消息和可能的内容) 。

  (3)服务器收到请求后,给予对应的响应音讯,其格式为1个气象行,包蕴音讯的商业事务版本号、三个打响或不当的代码,前边是
MTh伍音讯(包罗服务器音信、实体音讯和恐怕的剧情) 。

  (4)客户端接收服务器所再次来到的音讯通过浏览器显示在用户的显示器上,然后客户机与劳务器断开连接

HTTP协议结构:

  HTTP 协议无论是请求报文照旧答应报文,都分为以下 4 个部分 。

  (1)报文头( initial line ),上边的例证中的“ GET
http://www.baidu.com/favicon.icoHTTP/1.1 ”表示用 GET 方法请求
http://www.baidu.com/favicon. ic。那么些文件,用的是HTTP/1.1 协议。

  (2) 0 个或多少个请求头( header line ),例如 Accept-Language: en

  (3)空行(作为 header lines 的结束) 。

  (4)可选的音信体 。

  HTTP 协议是依据行的商谈,每一行 以 \r\n 作为分隔符 。
报文头平常注解报文的档次(例如请求类型),且报文头只占一行
;请求头附带一些与众差别音讯,每一种请求头占一行,其格式为 name:value
,即以分行作为分隔; 空行也就以叁个 \r\n 分隔;可选 body
经常包蕴数据,例如服务器再次回到的某些静态 HTML 文件的始末 。

  HTTP请求方法:

  HTTP/ 1.1 协议中国共产党定义了 9 种方法(有时也叫“动作”)来表 明
Request-UHighlanderI 钦赐的财富的不比操作方法,如下所述。

  ( 1 ) OPTIONS :再次来到服务器针对特定财富所支撑的 HTTP
请求方法;也能够采用向 Web服务器发送“*”的伸手来测试服务器的作用性。

  ( 2) HEAD :向服务器须求与 GET
请求相平等的响应,只可是响应体将不会被重回 。
这一方法能够在不必传输整个响应内容的图景下,就足以获得蕴涵在响应音信头中的元音信。该方法常用于测试超链接的管事,是不是足以访问,以及新近是否更新等音信。

  ( 3) GET :向特定的财富发出请求 。 注意 : GET
方法不应有被用来发生“副功效”的操作中,例如在 web app .
中的应用,当中三个缘故是 GET 大概会被互连网蜘蛛等任意访问 。

  ( 4 ) POST
:向钦定财富提交数据举办拍卖请求(例如提交表单或许上传文件) 。
数据被含有在请求体中 。 POST
请求只怕会促成新的财富的确立或对已有财富的修改 。

  ( 5 ) PUT :向钦命能源职分上传其最新内容 。

  ( 6) DELETE : 请求服务器删除 Request-U路虎极光I 所标识的能源 。

  ( 7 ) TRACE :回显服务器收到的央浼,首要用以测试或确诊。

  ( 8) CONNECT: HTTP/ 1.1
协议中留给给能够将接连改为管道情势的代理服务器 。

  ( 9) PATCH :用来将一些修改应用于某一能源,该操作添加于规范盯C5789
中 。

  HTTP 服务器至少应该完成 GET 和 HEAD 方法,别的办法都是可选的 。
别的,除了上述措施,特定的 HTTP 服务器还是能够够壮大自定义的主意 。

  HTTP 常见的伏乞头:

  在 HTTP/ l.l 协议中,全体的请求头(除 Host
外)都以可选的,因为Host首要用于请求的服务器的IP地址和端口号,请求头有Host、Connection、Accept、Accept-Encoding、User-Agent、库克ie等,请求头太多那里就不列出来了。

  HTTP回应报文:

  再次回到码由 3 位数字组成,第3个数字定义了响应的连串,且有 5
种也许的取值。

  ( 1 ) lxx :提示新闻,表示请求已接受,继续处理。

  ( 2) 2xx :成功,表示请求已被成功接到、驾驭 、 接受 。

  ( 3) 3xx :重定向,要到位请求必须开始展览更进一步的操作 。

  ( 4 ) 4xx :客户端错误,请求有语法错误或请求不能兑现。

  ( 5) 5xx :服务器端错误,服务器未能兑现合法的央浼 。

  Date :表示音信发送的时刻,时间的叙述格式由 rfc822 定义 。

  Server : 指明 Web 服务器用来处理请求的软件新闻 。

  Accept-Ranges : Web
服务器申明本人是或不是收取获取其有个别实体的一有的(比如文件的一局部)的呼吁
。 bytes 代表接受, none 表示不吸收。

  Vary: Web 服务器用该尾部的剧情告诉 Cache
服务器,在如何条件下才能用本响应所再次来到的对象响应后续的请求 。

  Content-Encoding : Web 服务器注脚本人使用了哪些压缩方法( gzip,
deflate)压缩响应中的对象。

  Content-Length: Web 服务器告诉浏览器本身响应的对象的长度 。

  Content-Type: Web 服务器告诉浏览器本身响应的对象的类型 。

二、CGI

  CGI ( Common Gateway Interface ,通用网关接口)是 HTTP
协议中最注重的技艺之一,有着不可取代的主要地位 。 CGI 是三个 Web
服务器提供音信服务的标准接口 。 通过 CGI 接口, Web
服务器就能够获得客户端提交的消息,转交给劳务器端的 CGI
程序举行拍卖,最终回来结果给客户端 。 组成 CGI 通讯系统的是两部分:
一部分是 HTML
页面,正是在用户端浏览器上出示的页面;另一有的则是运转在服务器上的 CG I
程序 。

  浏览器只要求钦点执行服务器上的哪位CGI程序就行,一般景观下,服务器和
CGI
程序之间是由此专业输入输出来拓展数量传递的(就如tinyhttpd中调用CGI程序),而这一个历程供给环境变茸的合作方可实现。环境变量在
CGI 中有所重庆大学的身价,每种 CGI
程序只好处理3个用户请求,所以在激活二个CGI程序进度时也开创了属于该进程的环境变量,CGI程序可以用Python、PE宝马7系L、Shell、C或C++等语言来兑现。

  CGI 环境变量在 CGI 程序运行时初步化,在截止时销毁。当一个 CGI
程序不是被 HTTP 服务器调用时,它的环境变盘差不离是系统环境变量的复制
。当以此 CGI 程序被 HTTP 服务器调用时,它的环境变量就会多了以下关于HTTP
服务器、客户端、 CGI 传输进程等体系。CGI 相关的环境变量有 3
种:与请求相关的环境变量、与服务器相关的环境变量和与客户端相关的环境变量,,详细见表
12-1 。

  美学原理 1

  CGI 工作原理:每当客户请求 CGI 的时候 Web
服务器就呼吁操作系统生成一个新的CGI
进度,该进度处理完请求后退出,下1个请求来时再次创下设新进度 。
当然,那样在访问量很少没有现身的气象使得,然则当访问量增大且并发存在时,那种方法就不切合了,于是就有了法斯特CGI。

  一般情况下, 法斯特CGI 的全体育工作作流程如下所述。

  ( 1 ) Web Server 运行时载入 FastCGI 进度管理器( IIS ISAPI 或 Apache
Module ) 。

  ( 2 )法斯特CGI 进程管理器自个儿开始化,运行多个 CGI 进程并伺机来自 Web
服务器的连接 。

  ( 3 )当客户端请求到达 Web Server 时, 法斯特CGI
进度管理器选取并接连到三个 法斯特CGI进度 。 Web 服务器将 CGI
环境变量和专业输入发送到 法斯特CGI 进度 。

  ( 4) 法斯特CGI 子进程实现处理后将正式输出和错误新闻从同接二连三接重回 Web
Server。当FastCGI 子进度关闭连接时,请求便被告知处理完毕 。 法斯特CGI
进程接着等待并处理来自法斯特CGI 进度管理器(运营在 Web
服务器中)的下3个连接 。

三、tinyhttpd解析

  关于tinyhttpd的代码解析的博客太多了,流程跟注释都讲述的很详细,随便搜个tinyhttpd解析就有诸多博客出现,那里照旧写一下和幸亏看那份源码时贫乏的知识点,因为本人大致向来不linux下编制程序的经验,所以对linux下用的Glib库调用不太熟习,TCP协议栈也是自家只看过过轻量级Lwip的源码。

  1.bind函数当传入的port为0时是会随随便便分配三个端口号,所以tinyhttpd中才会有显示随机的端口号,getsockname函数获取套接字的地址把动态分配的端口号值取出。

  美学原理 2美学原理 3

  2.int stat(const char *file_name, struct stat
*buf);通过文件名filename获取文件信息,并保留在buf所指的协会体stat中,S_IXUS昂Cora:文件全数者具可进行权限,S_IXG汉兰达P:用户组具可实施权限,S_IXOTH:别的用户具可读取权限。

美学原理 4

  3.int pipe(int filedes[2]);

  再次来到值:成功,重回0,否则再次回到-1。参数数组包蕴pipe使用的多个文件的叙说符。fd[0]:读管道,fd[1]:写管道。

  必须在fork()中调用pipe(),不然子进度不会一而再文件讲述符。八个经过不共享祖先进度,就不可能应用pipe。不过可以使用命名管道。

  pipe(cgi_output)执行成功后,cgi_output[0]:读通道
cgi_output[1]:写通道

  美学原理 5

   int dup2(int oldfd,int newfd);函数的法力是复制文件讲述符。

  4.fork函数,创设二个子历程,fork函数之后的局地由在fork函数执行完结后,假诺创立新进度成功,则产出八个经过,叁个是子进度,三个是父进程。在子进度中,fork函数再次来到0,在父进度中,fork重返新创设子进度的历程ID,有时间再看fork源码是什么促成的。

  5.execl函数履行,第1参数path字符指针所指向要履行的公文路径,后面随着可变参数,那里说一些出于GCC使用AAPCS规范,可变参数的兑现小于八个的话是从r0-r3获得,大于七个的话就要从栈中获取参数。 

  6.pid_t waitpid(pid_t pid, int * status, int
options);会临时告一段落近年来历程的实施, 直到有信号来到或子进度结束. 

  在编排博客边看tinyhttpd,近期温馨的不够掌握的函数就地方多少个,有空再看看它们的源码完成。