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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章