欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Mochiweb的設計分析

系統(tǒng) 1905 0

?

Mochiweb的設計分析

March 15th, 2009 :: refactor

轉自: http://erlang-china.org/misc/mochiweb-inside.html

Web服務器 的基本工作大致分3步:?

  1. 接收HTTP請求;?
  2. 處理HTTP請求,生成響應內(nèi)容;
  3. 發(fā)送響應

一、處理請求和發(fā)送響應 ?

模塊mochiweb_request可說是Mochiweb處理HTTP請求的核心部分,它總共負責了第2步和第3步工作。因此參數(shù)化模塊mochiweb_request的實例不像它的模塊名那樣單純:它還負責將請求的響應(通過Socket連接,調(diào)用gen_tcp:send)發(fā)還(response)給瀏覽器。這個模塊是一個 參數(shù)化模塊 。這意味著它具有基于對象(Object-based)的特點,它的每個實例化對象代表一個用戶請求,用戶可以像OO那樣操作HTTP請求:獲取請求信息,生成響應內(nèi)容等。?

對靜態(tài)內(nèi)容(如html文件,靜態(tài)圖片)來說,無非是讀取文件系統(tǒng)中靜態(tài)文件的內(nèi)容作為響應消息體(Body)發(fā)送給客戶端瀏覽器。?

對動態(tài)內(nèi)容來說,生成響應內(nèi)容的業(yè)務邏輯是用戶通過編程實現(xiàn)的:解析請求(包括URL路徑和HTTP請求頭),然后生成相應的響應內(nèi)容。用戶編寫業(yè)務邏輯處理函數(shù),然后將函數(shù)插入到mochiweb中。此函數(shù)帶有一參數(shù),該參數(shù)是參數(shù)化模塊mochiweb_request的實例(假設為Req),在這個定制函數(shù)中可以通過這個Req實例對象獲取瀏覽器請求的所有信息(包括URL路徑和HTTP請求頭),處理后的響應數(shù)據(jù)也通過Req實例提供的函數(shù)發(fā)還給瀏覽器,有好幾種方式:?

  1. 通過Req實例對象直接發(fā)還給瀏覽器

    ?

      a)? 通過這個Req實例對象的response/1函數(shù)直接發(fā)還給瀏覽器:
      Req:response({Code, ResponseHeaders, Body})
      這個函數(shù)接收一個tuple參數(shù),參數(shù)的第一個元素是HTTP狀態(tài)碼(比如200),第二個元素是響應消息頭列表(一個二元tuple,key和value都是字符串,如{“Content-Type”, “image/jpeg”}),第三個元素即為HTTP響應內(nèi)容;如果是動態(tài)內(nèi)容,采用response函數(shù)直接發(fā)還響應數(shù)據(jù)還是比較方便的。

      b)? 如果是靜態(tài)文件,通過Req的serve_file(…)函數(shù)可以直接將文件發(fā)還給瀏覽器,告訴此函數(shù)文件的Web根目錄(doc_root)和相對路徑就可以將指定的靜態(tài)文件發(fā)給瀏覽器了。doc_root目錄一般在配置文件中設置,這個目錄下的所有文件都可以通過HTTP訪問。

      c)? 一些常見的例行響應:
      不存在的URL請求返回404錯誤,可以直接調(diào)用Req:not_found() 若一切正常,調(diào)用Req:ok({…, Body})直接返回狀態(tài)碼為200的HTTP響應
      b,c兩種情況的內(nèi)部其實還是調(diào)用的Req:response()

  2. 通過Response模塊對象將響應發(fā)還給瀏覽器

    ?

      Req:response函數(shù)會返回一個mochiweb_response參數(shù)化模塊實例對象(假設為Response),Response實例對象包含有對應的Req實例對象。通過Response對象可以得到響應的相關信息(如響應狀態(tài)碼,響應消息頭,對應的Req對象),它還有一個send函數(shù)可以將響應數(shù)據(jù)發(fā)還給瀏覽器(它的實現(xiàn)其實還是調(diào)用Req對象的send函數(shù)進行的)。Response之所以還要有send函數(shù)是為了發(fā)送chunked數(shù)據(jù)(HTTP 1.1)的方便,在第一次響應完成后,后繼的chunk數(shù)據(jù)就可以通過最初返回的Response對象繼續(xù)進行發(fā)送了,為此Response有個函數(shù)write_chunk()專門干這事,write_chunk檢查了請求消息頭中的HTTP 版本消息后就調(diào)用Response:send。

      因此,響應內(nèi)容最終都是由參數(shù)化模塊mochiweb_request的response/1函數(shù)發(fā)送的。而這個response(…)函數(shù)內(nèi)部最后調(diào)用了Req:send(Data)函數(shù)將響應通過socket連接(調(diào)用gen_tcp:send)返還給瀏覽器,這一發(fā)送過程又分成兩個階段:響應消息頭(Headers)的發(fā)送和消息體(Body)的發(fā)送,這兩步都是通過Req:send完成的。

小結:對于程序員來說,他編寫的服務器端處理HTTP請求的函數(shù)必須帶有一個參數(shù),這個參數(shù)代表了mochiweb_request參數(shù)化模塊的一個實例對象。通過這個實例程序員可以得到HTTP請求的所有信息(包括路徑、請求參數(shù)以及HTTP請求消息頭),然后生成響應,他還可以通過該mochiweb_request實例對象將響應數(shù)據(jù)發(fā)還給瀏覽器。?

  • 如果響應的是靜態(tài)文件,可以通過Request:server_file()函數(shù)發(fā)送響應;
  • 如果響應是動態(tài)生成的內(nèi)容,通過Request:response()函數(shù)發(fā)送響應數(shù)據(jù)(文本數(shù)據(jù)和二進制數(shù)據(jù)都可以);
  • 如果是chunk響應,第一次調(diào)用Request:response()函數(shù)發(fā)送數(shù)據(jù)后,該函數(shù)會返回一個Response實例對象(參數(shù)化模塊mochiweb_response的一個實例),以后的響應數(shù)據(jù)可以通過這個Response實例對象(調(diào)用Response:write_chunk(Data))發(fā)送后續(xù)的響應數(shù)據(jù)。

二、Web服務器的業(yè)務處理邏輯如何嵌入到Mochiweb ?

業(yè)務處理邏輯被程序員編寫成一個函數(shù)(函數(shù)式編程中函數(shù)也是一種數(shù)據(jù),以下稱為HttpLoop),處理函數(shù)HttpLoop是作為mochiweb啟動時的參數(shù)之一進入Mochiweb,Mochiweb是這樣啟動的:?

mochiweb_http : start ([ { loop ,? HttpLoop },... ]) ??

Request實例對象最終要調(diào)用gen_tcp:send(Socket,…)將響應數(shù)據(jù)由socket連接發(fā)給瀏覽器,因此,Request實例對象應該持有HTTP請求的socket連接。這個目標是這樣實現(xiàn)的:?
在啟動過程中,mochiweb_http又對用戶的HttpLoop函數(shù)進行了重新包裝?

Loop ?=? fun ? ( Socket ) ?->
?? ?
mochiweb_http : loop ( Socket ,? HttpLoop )
end ,

每個瀏覽器連接請求對應著一個Socket連接,新的Loop函數(shù)以此Socket作為參數(shù),然后通過mochiweb_http:loop函數(shù)對Socket連接和用戶自定義的HttpLoop函數(shù)進行了處理,簡單的說,這個函數(shù)做了如下工作:?

  1. 將Socket連接設置成能處理HTTP數(shù)據(jù)包 (inet:setopts(Socket, [{packet, http}]));
  2. 準備接收socket連接傳來的數(shù)據(jù)(gen_tcp:recv(Socket,…));

當收到數(shù)據(jù)時:

  1. 將HTTP消息頭數(shù)據(jù)提出(成為{HeaderName, HeaderValue}的tuple列表)
  2. 生成一個參數(shù)化模塊mochiweb_request的實例對象,并將Socket連接、HTTP請求信息(路徑、請求方法、HTTP版本)以及請求消息頭列表包裝到此實例對象中,
  3. 然后調(diào)用用戶的HttpLoop對請求進行處理和響應(如前所述,處理得到的響應數(shù)據(jù)也在用戶編寫的HttpLoop函數(shù)中被發(fā)送給瀏覽器)
  4. 最后根據(jù)HTTP請求信息決定是簡單的關閉Socket連接,還是清理一下Req對象并保持連接(例如對keep-alive,chunk等類型的HTTP請求,以及還沒完成數(shù)據(jù)傳送的HTTP請求),以便繼續(xù)讓HttpLoop函數(shù)進行處理,

這都是在headers函數(shù)中進行的,還是看mochiweb_http模塊的代碼:?

  1. headers ( Socket ,? Request ,? Headers ,? HttpLoop ,? HeaderCount ) ?->?
  2. ? ?? case ? gen_tcp : recv ( Socket ,? 0 , ? IDLE_TIMEOUT ) ? of ?
  3. ? ? ? ? { ok ,? http_eoh } ->?
  4. ? ? ? ? ? ?? inet : setopts ( Socket ,? [ { packet ,? raw } ]) ,?
  5. ? ? ? ? ? ?? % 將Socket連接、HTTP請求信息(路徑、請求方法、HTTP版本)以及請求消息頭列表打包成參數(shù)化模塊(mochiweb_request)的實例對象?
  6. ? ? ? ? ? ?? Req ?=? mochiweb : new_request ( { Socket ,? Request ,?
  7. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? lists : reverse ( Headers ) } ) ,? ?
  8. ? ? ? ? ? ?? HttpLoop ( Req ) ,? % 讓用戶編寫的函數(shù)處理HTTP請求?
  9. ? ? ? ? ??? case ? Req : should_close () ? of ?
  10. ? ? ? ? ? ? ? ?? true ?->??
  11. ? ? ? ? ? ? ? ? ? ?? gen_tcp : close ( Socket ) ,?
  12. ? ? ? ? ? ? ? ? ? ?? exit ( normal ) ;?
  13. ? ? ? ? ? ? ? ?? false ?->??
  14. ? ? ? ? ? ? ? ? ? ?? Req : cleanup () ,?
  15. ? ? ? ? ? ? ? ? ? ?? mochiweb_http : loop ( Socket ,? HttpLoop ) ?
  16. ? ? ? ? ? ?? end ;?
  17. ? ? ? ? { ok , { http_header ,? _ ,? Name ,? _ ,? Value }} ->?
  18. ? ? ? ? ? ?? headers ( Socket ,? Request ,? [ { margin-
分享到:
評論

Mochiweb的設計分析


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲电影免费 | 色综合欧美 | 国产精品区二区三区日本 | 日韩精品一区二区三区不卡 | 日韩色视频 | 波多野结衣hd在线播放 | 日本精品一二区 | 婷婷激情综合五月天 | 91免费影片 | 日本一级成人毛片免费观看 | 欧美成年 | 五月天色丁香 | 天天躁日日躁狠狠躁中文字幕 | 欧美三级午夜理伦三级小说 | 91精品观看91久久久久久国产 | a级片在线免费看 | 91精品久久一区二区三区 | 亚洲色图偷拍视频 | 亚洲一区二区在线视频 | 欧美成人精品一区二区三区 | 亚洲免费在线播放 | 久草精品视频在线观看 | 奇米狠狠色| 亚洲十欧美十日韩十国产 | av色站| 精品久久 | 亚洲一区二区在线视频 | 成人免费网址在线 | 国产乱码精品一区二区三上 | 特黄一区二区三区 | 欧美日韩在线电影 | 欧美日韩一区二区三区免费视频 | 嫩草嫩草嫩草 | 天天躁日日躁很很躁2022 | 精品亚洲欧美高清不卡高清 | 午夜在线亚洲男人午在线 | 日本一区中文字幕 | 亚洲涩涩 | 久久综合九九 | 奇米狠狠操 | 秋霞激情|