C语言开源项目-tinyhttpd

tinyhttpd 是一个不到 500 行的超轻量型 Http Server,用来学习非常不错,可以帮助我们真正理解服务器程序的本质。

main

                           |<--------------------^
                           V                     |
start ----> start_up_port ---> accept ---> create_thread ---> accept_request ---> end

start_up_port:开启指定(或随机)的端口,并将端口与httpd服务绑定。指定端口开始监听http请求。
accept:指定端口监听到http请求
create_thread:创建一个线程执行accept_request来处理请求

start_up_port —>accept

一套标准的socket->bind->listen->connect->accept流程

socket:生成一个socket文件描符
bind:绑定了服务器要监听的ip/port
listen:对这对ip/port进行监听
connect:客户端请求连接
accept:服务器调用accept()接受客户端连接请求,并分配新的ip/port与客户端通信,之前的ip/port继续监听

accept_request

          start
            |
        get_line:读取请求的字符串
            |
        获取method:字符串中的第一个参数
       /    |     \
POST方法  GET方法  其它方法
   |        |          |
cgi = 1     |         end
    \       /
     获取url:字符串第二个参数
          |
method==GET && url中包含'?'
   /           \
  否           是
  |             |
  |          url从?截断
  |          query_string指令url?以后的部分
  |          cgi = 1
  \         /
格式化 url 到 path:path表示浏览器请求的服务文件路径,若path为文件夹,默认在path后加上index.html
       |
       判断cgi的值
      /          \
为0(无参的GET)  为1(POST或有参的GET)
      |                         |
serve_file:                 execute_cgi
输出服务器文件到浏览器       执行 cgi 脚本
      |                         |
     end                       end

serve_file

用于处理无参的GET方法的请求。
处理方法是把文件的内容输出到浏览器。
文件的地址就是解析出来的url

  start
    |
把剩下的数据扔掉
    |
headers:构造消息头,并send
    |
cat:读取文件内容,并send
    |
   end

execute_cgi

用于处理POST方法或带参数的GET方法。
由于需要执行CGI脚本,因此会新建一个进程。

            start
           /     \
    GET方法       POST方法
       |             |
把剩下的数据扔掉  剩下的数据, 提取Content-Length,其余扔掉
        \            /
      建立管道cgi_output
            |
      建立管道cgi_input
            |
      新建一个进程
            |
      把 HTTP 200  状态码写到套接字
        /          \
    父进程       子进程
      |             |
    配置管理     配置管理
      |             |
      |          配置cgi运行环境
      |                |
把数据写到input--->从STDIN读数据
      |                   |
      |            执行CGI文件(文件路径为path)
      |                   |
从cgi_output读取<---执行结果输出到STDOUT
      |                   |
    send                 end
      |
     end
发布了379 篇原创文章 · 获赞 324 · 访问量 110万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章