开源代码学习的Tinyhttpd

   
想起来陆续研究一些谢谢兴趣的开源代码于是先挑一个代码量短的来接一下,写就首博客的目的是记录下好学的过程。Tinyhttpd算是一个袖珍的web服务器,浏览器和Web服务器之间的通信采用的是Http,所以一律开始之切入点是HTTP协议,这里说一些设发召开HTTP通信的支付还是看一下RFC中对两样版本HTTP的概念,以下原理部分还是于《后台开发:核心技术与祭实践》中HTTP协议章节中推出来的,对后令感兴趣的同班可以关押一下,讲述后台开发所急需具有的艺点同样按照很正确的写。

团结从未有过使用任何表格插件,参考网上例子,自己编辑出来的django网页实例,请各位参考!

一、HTTP协议

第一看图工作,表格布局采用bootstrap,俗话说bootstrap橹多了即会css了,呵呵,下面看图:

HTTP工作流程:

图片 1

  在OSI七层模型中,HTTP是根据TCP上的应用层协议要我们所说之HTTPS基于同处应用层的TLS、SSL协议层之上。HTTP默认的端口号也80,HTTPS默认的捧口号为443。在HTTP1.1受(通过Connection头设置)默认在HTTP传输就后不停开TCP连接,在此之前的HTTP版本则默认是断开连接的,也就是说这次要和上次请求是不同之片只TCP连接。一不好HTTP操作称为一个业务,其工作历程可以分为以下四步。

面来点儿只按钮,是动态增长进去的,可以用jquery语言,$(“#xx”).append新补一个按钮,

  (1)首先客户机与服务器需要树立连接 。 只要单击某个超级链接, HTTP
的工作就是开始 。
  (2)建立连接后,客户机发送一个请求让服务器,请求方式的格式为:统一资源标识符(URL
)、协议版本号,后边是 MIME
信息(包括要修饰符、客户机信息和可能的情节) 。

最好中心的表单代码:

  (3)服务器收到请求后,给予相应的响应信息,其格式为一个态行,包括信息的合计版本号、一个中标还是不当的代码,后边是
MTh伍信息(包括服务器信息、实体信息以及可能的内容) 。

<button class="btn btn-small btn-primary" type="button" id="blank">添加空白表单</button>
<form class="form-inline">
       {% csrf_token %}
        <table class="table table-conde" id="t2">
            <caption class="text-left"></caption>
            <thead></thead>
            <tbody></tbody>
            <tfoot></tfoot>
        </table>
        <table class="table table-conde" id="t3">
            <caption class="text-left"></caption>
            <thead></thead>
            <tbody></tbody>
            <tfoot></tfoot>
        </table>
        <div class="text-center" id="form_add"></div>
 </form>

  (4)客户端接收服务器所返的音透过浏览器显示在用户的显示屏上,然后客户机与服务器断开连接

接下去使用js动态加载表格:

HTTP协议结构:

$('#blank').click(function(){//空白表单
            $("#t1 caption").append("<i class='icon-forward'></i> 合同基础清单");
            $("#t1 tbody").append(formbill());
            $("#t2 caption").append("<i class='icon-forward'></i> 附件1 合同手机清单 &nbsp;&nbsp;&nbsp;&nbsp;<a class='btn btn-small' id='t2row'><i class='icon-plus'></i> 添加一行</a>");
            $("#t2 thead").append("<th>客户姓名</th><th>合同号</th><th>业务号码</th><th>套餐类型</th><th>经办人</th><th>备注</th><th>操作</th>");
            $("#t3 caption").append("<i class='icon-forward'></i> 附件2 合同座机清单 &nbsp;&nbsp;&nbsp;&nbsp;<a class='btn btn-small' id='t3row'><i class='icon-plus'></i> 添加一行</a>");
            $("#t3 thead").append("<th>客户姓名</th><th>合同号</th><th>业务号码</th><th>套餐类型</th><th>经办人</th><th>备注</th><th>操作</th>");
            $("#form_add").append("<input type='button' id='btn_add' value='提交数据' class='btn btn-primary btn-sm'/>");
      });    

  HTTP 协议无论是请求报文还是对报文,都分为以下 4 独片 。

接下来实现行添加和行删除的功用:

  (1)报文头( initial line ),上面的例子中的“ GET
http://www.baidu.com/favicon.icoHTTP/1.1 ”表示为此 GET 方法要
http://www.baidu.com/favicon. ic。这个文件,用底凡HTTP/1.1 协议。

//行添加
$('#t2 caption').on("click","#t2row",function(){
               var len = $("#t2 tr").length+1; 
              $("#t2 tbody").append("<tr id="+len+">"
                                   +"<td><input type='text' class='input-medium acct_code' placeholder='.input-medium'></td>"
                                   +"<td><input type='text' class='input-medium acc_nbr' placeholder='.input-medium'></td>"
                                   +"<td><input type='text' class='input-medium tc_type' placeholder='.input-medium'></td>"
                                   +"<td><input type='text' class='input-medium con_agent' placeholder='.input-medium'></td>"
                                   +"<td><input type='text' class='input-medium remark' placeholder='.input-medium'></td>"
                                   +"<td><input type='text' class='input-medium remark' placeholder='.input-medium'></td>"
                                   +"<td><a class='btn btn-small' onclick='deltr("+len+")'>删除</a></td>"
                                   +"</tr>"
                                   );
      });
      $('#t3 caption').on("click","#t3row",function(){
            var len = $("#t3 tr").length+1; 
              $("#t3 tbody").append("<tr id="+len+">"
                                  +"<td><input type='text' class='input-medium acct_name' placeholder='.input-medium'></td>"
                                  +"<td><input type='text' class='input-medium acct_code' placeholder='.input-medium'></td>"
                                  +"<td><input type='text' class='input-medium acc_nbr' placeholder='.input-medium'></td>"
                                  +"<td><input type='text' class='input-medium tc_type' placeholder='.input-medium'></td>"
                                  +"<td><input type='text' class='input-medium con_agent' placeholder='.input-medium'></td>"
                                  +"<td><input type='text' class='input-medium remark' placeholder='.input-medium'></td>"
                                  +"<td><a class='btn btn-small' onclick='deltr("+len+")'>删除</a></td>"
                                  +"</tr>"
                                  );
      });
//行删除
   function deltr(index) {
     $("tr[id='"+index+"']").remove();//删除当前行
    }

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

 

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

 这里要小心少单问题:

  (4)可选取的音体 。

首先,像id=t2row/t3rowde
按钮是动态添加上的,如果利用普通的$(‘#xxx’).click是无因此底,必须用$(‘#t2
caption’).on(“click”,”#t2row”,function(){})这种格式

  HTTP 协议是基于行之说道,每一样尽 以 \r\n 作为分隔符 。
报文头通常表明报文的门类(例如请求类型),且报文头只占一行
;请求头附带一些独特信息,每一个央求头占一实践,其格式为 name:value
,即以分行作为分隔; 空行也尽管为一个 \r\n 分隔;可选 body
通常含数据,例如服务器返回的某部静态 HTML 文件之始末 。

第二,删除按钮的id必须同tr中之id相对应

  HTTP请求方法:

 

  HTTP/ 1.1 协议中共定义了 9 种办法(有时也让“动作”)来表 明
Request-URI 指定的资源的不同操作办法,如下所陈述。

兑现行添加和行删除的机能后,该考虑什么拿多字段的表单传递及django的后端中错过,代码如下:

  ( 1 ) OPTIONS :返回服务器对特定资源所支撑之 HTTP
请求方法;也堪运用为 Web服务器发送“*”的伸手来测试服务器的功能性。

          var str_tailsj = "[";
          $("#t2 tbody").find("tr").each(function(){
                var tdArr1 = $(this).children();
                str_tailsj = str_tailsj+"{'product_name':'手机',";
                str_tailsj = str_tailsj+"'acct_name':'"+ tdArr1.eq(0).find("input").val()+"',";
                str_tailsj = str_tailsj+"'acct_code':'"+ tdArr1.eq(1).find("input").val()+"',";
                str_tailsj = str_tailsj+"'acc_nbr':'"+ tdArr1.eq(2).find("input").val()+"',";
                str_tailsj = str_tailsj+"'tc_type':'"+ tdArr1.eq(3).find("input").val()+"',";
                str_tailsj = str_tailsj+"'con_agent':'"+ tdArr1.eq(4).find("input").val()+"',";
                str_tailsj = str_tailsj+"'remark':'"+ tdArr1.eq(5).find("input").val()+"'},";
          });
          str_tailsj = str_tailsj + "]";

  ( 2) HEAD :向服务器需要和 GET
请求相平等的响应,只不过响应体将未会见为归 。
这同方法可以在不必传输整个响应内容之景象下,就好落包含在应消息头着之正信息
。该方法常用于测试超过链接的有用,是否足以看,以及新近是否更新等消息

以多配段表单,用json字符串的样式传递到后端,然后于后端利用python中的eval转换成为对应的花样展开处理,具体代码参照下:

  ( 3) GET :向特定的资源发出请求 。 注意 : GET
方法不该于用来产生“副作用”的操作着,例如在 web app .
中的使用,其中一个原因是 GET 可能会见被网蜘蛛等任意访问 。

参考网址:http://www.cnblogs.com/CQ-LQJ/p/5442785.html

  ( 4 ) POST
:向指定资源提交数据进行处理要(例如提交表单或者上传文书) 。
数据为含有在求求体中 。 POST
请求或会见造成新的资源的成立或者对都产生资源的修改 。

a="[{'bill1':'1','bill41':'2'},{'bill1':'1','bill41':'2'},]"
print eval(a)[0]['bill1']
输出为1

  ( 5 ) PUT :向指定资源职务上传其最新内容 。

 

  ( 6) DELETE : 请求服务器删除 Request-URI 所标识的资源 。

  ( 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、Cookie等,请求头太多这里虽未列下了。

  HTTP回应报文:

  返回码由 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
程序只能处理一个用户要,所以于激活一个CGI程序进程时也创了属该过程的环境变量,CGI程序能够用Python、PERL、Shell、C或C++等语言来兑现。

  CGI 环境变量在 CGI 程序启动时初始化,在终结时销毁。当一个 CGI
程序不是于 HTTP 服务器调用时,它的条件变盘几乎是系环境变量的复制
。当以此 CGI 程序于 HTTP 服务器调用时,它的环境变量就见面多了以下关于HTTP
服务器、客户端、 CGI 传输过程相当类别。CGI 相关的环境变量有 3
种:与请求相关的环境变量、与服务器相关的环境变量和和客户端相关的环境变量,,详细呈现表
12-1 。

  图片 2

  CGI 工作原理:每当客户要 CGI 的上 Web
服务器即告操作系统生成一个新的CGI
进程,该过程处理了要后退出,下一个请求来常又创新过程 。
当然,这样于访问量很少没有出现的情景中,可是当访问量增大且并发存在时时,这种方法尽管非吻合了,于是就发出了FastCGI。

  一般情况下, FastCGI 的全套工作流程如下所陈述。

  ( 1 ) Web Server 启动时载入 FastCGI 进程管理器( IIS ISAPI 或 Apache
Module ) 。

  ( 2 )FastCGI 进程管理器自身初始化,启动多只 CGI 进程并伺机来自 Web
服务器的连接 。

  ( 3 )当客户端请求到达 Web Server 时, FastCGI
进程管理器选择并连接到一个 FastCGI进程 。 Web 服务器将 CGI
环境变量和标准输入发送至 FastCGI 进程 。

  ( 4) FastCGI 子进程就处理后将业内输出及错误信息从平连接返回 Web
Server。当FastCGI 子进程关闭连接时,请求虽为告知处理好 。 FastCGI
进程就等待并拍卖来自FastCGI 进程管理器(运行于 Web
服务器中)的下一个连接 。

三、tinyhttpd解析

  关于tinyhttpd的代码解析的博客太多矣,流程与注释都讲述的很详细,随便搜个tinyhttpd解析就有为数不少博客出现,这里要写一下和谐在扣押这卖源码时少的知识点,因为自身几乎从未linux下编程的更,所以本着linux下用的Glib库调用不极端熟悉,TCP协议栈也是自己仅看罢了轻量级Lwip的源码。

  1.bind函数当传入的port为0时凡会自由分配一个端口号,所以tinyhttpd中才见面生显示随机的捧口号,getsockname函数获取套接字之地方将动态分配的端口号值取出。

  图片 3图片 4

  2.int stat(const char *file_name, struct stat
*buf);通过文件名filename获取文件信息,并保留于buf所因的结构体stat中,S_IXUSR:文件所有者拥有可实施权,S_IXGRP:用户组具可实行权,S_IXOTH:其他用户具可读博权限。

图片 5

  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]:写通道

  图片 6

   int dup2(int oldfd,int newfd);函数的打算是复制文件讲述称。

  4.fork函数,创建一个子经过,fork函数之后的部分是因为以fork函数执行完毕后,如果创建新过程成功,则产出零星只经过,一个是子进程,一个是爸爸进程。在分进程遭到,fork函数返回0,在父亲进程被,fork返回新创建子进程的进程ID,有工夫还拘留fork源码是什么贯彻的。

  5.execl函数实践,第一参数path字符指针所据为设履的公文路径,后面随着可转移参数,这里说一些由于GCC使用AAPCS规范,可变换参数的兑现小于四独底言辞是于r0-r3到手,大于四个的讲话就假设起栈中获取参数。 

  6.pid_t waitpid(pid_t pid, int * status, int
options);会少已目前历程的实施, 直到闹信号到或子进程结束. 

  在编制博客边看tinyhttpd,目前祥和之不够懂的函数就端几乎单,有空再看它的源码实现。

 

  

  

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图