mochiweb 原始碼閱讀 十七

2021-09-06 05:40:51 字數 4434 閱讀 9970

headers/5函式

,當所有協議頭解析完畢後會有乙個空行,它標誌著報文頭部的結束,剩下的便是訊息正文。

**中第乙個分支就是當讀取到空行時,繼續處理訊息正文,第二個分支則是解析每乙個協議頭。

接下來我們首先看下:mochiweb_http:

new_request/3函式:

new_request(socket, request, revheaders) ->ok =mochiweb_socket:setopts(socket, ),

mochiweb:new_request().

這個函式首先修改socket選項,不設定訊息打包規則,如果,則表示每乙個包都會帶上乙個n(1,2或4)位元組長的長度計數。

該函式接著呼叫mochiweb:new_request/1函式:

%%

@spec new_request() -> mochiwebrequest

%%@doc return a mochiweb_request data structure.

new_request(, version}, headers}) ->mochiweb_request:new(socket,

method,

uri,

version,

mochiweb_headers:make(headers));

% this case probably doesn't "exist".

new_request(,

version}, headers}) ->mochiweb_request:new(socket,

method,

uri,

version,

mochiweb_headers:make(headers));

%%request-uri is "*"

%%from

#sec5.1.2

new_request(, headers}) ->mochiweb_request:new(socket,

method,

uri,

version,

mochiweb_headers:make(headers)).

這個函式一共有三個分支,但是每乙個都是匹配對應的引數,緊接著呼叫mochiweb_request:new/5函式,但是這裡注意,我在mochiweb_request模組匯出的函式列表中,並沒有發現對應的函式,那麼這究竟是怎麼回事呢?

這裡注意mochiweb_request模組定義:

-module(mochiweb_request, [socket, method, rawpath, version, headers]).

這裡我們還需要看下:mochiweb_headers:make/1函式:

%%

@spec make(headers() | ) -> headers()

%%@doc construct a headers() from the given list.

make(l) when is_list(l) ->from_list(l);

%%assume a non-list is already mochiweb_headers.

make(t) ->t.

如果l為列表,則呼叫函式mochiweb_headers:from_list/1函式:

%%

@spec from_list() -> headers()

%%@doc construct a headers() from the given list.

from_list(list) ->lists:foldl(

fun (, t) -> insert(k, v, t) end, empty(), list).

mochiweb_headers:empty/0函式

%%

@type headers().

%%@type key() = atom() | binary() | string().

%%@type value() = atom() | binary() | string() | integer().

%%@spec empty() -> headers()

%%@doc create an empty headers structure.

empty() ->gb_trees:empty().

mochiweb_headers:insert/3函式

%%

@spec insert(key(), value(), headers()) -> headers()

%%@doc insert the pair into the headers, merging with any pre-existing key.

%%a merge is done with value = v0 ++ ", " ++ v1.

insert(k, v, t) ->k1 =normalize(k),

v1 =any_to_list(v),

trygb_trees:insert(k1, , t)

catch

error: -> =gb_trees:get(k1, t),

v2 =merge(k1, v1, v0),

gb_trees:update(k1, , t)

end.

mochiweb_headers:normalize/1函式

normalize(k) when is_list(k) ->string:to_lower(k);

normalize(k)

when is_atom(k) ->normalize(atom_to_list(k));

normalize(k)

when is_binary(k) ->normalize(binary_to_list(k)).

mochiweb_headers:any_to_list/1函式

any_to_list(v) when is_list(v) ->v;

any_to_list(v)

when is_atom(v) ->atom_to_list(v);

any_to_list(v)

when is_binary(v) ->binary_to_list(v);

any_to_list(v)

when is_integer(v) ->integer_to_list(v).

這幾個函式都比較簡單,我們重點看下:gb_trees

這裡注意:

delete/2delete_any/2函式的區別是,如果key不在樹中,呼叫delete/2

會導致崩潰,而delete_any/2則什麼也不做,返回新樹;

enter/3insert/3函式的區別是,如果key在樹中存在,呼叫insert/3會導致崩潰,則enter/3則跟新樹中的值。

get/2

呼叫該函式根據key檢索樹中儲存的值。假設,關鍵是目前在樹中,否則崩潰。

最後得到的資料如下:

< headers = [,,,

,,,]

< h = ,

,,nil,nil},

,,nil,nil},

nil}}},,,

nil,nil},

nil}}}

好了,這一篇就到這裡,晚安。

《原始碼閱讀》原始碼閱讀技巧,原始碼閱讀工具

檢視某個類的完整繼承關係 選中類的名稱,然後按f4 quick type hierarchy quick type hierarchy可以顯示出類的繼承結構,包括它的父類和子類 supertype hierarchy supertype hierarchy可以顯示出類的繼承和實現結構,包括它的父類和...

原始碼閱讀 Glide原始碼閱讀之with方法(一)

前言 本篇基於4.8.0版本 原始碼閱讀 glide原始碼閱讀之with方法 一 原始碼閱讀 glide原始碼閱讀之load方法 二 原始碼閱讀 glide原始碼閱讀之into方法 三 大多數情況下,我們使用glide 就一句 但是這一句 裡面蘊含著成噸的 with方法有以下幾個過載方法 publi...

原始碼閱讀 Glide原始碼閱讀之load方法(二)

原始碼閱讀 glide原始碼閱讀之load方法 二 原始碼閱讀 glide原始碼閱讀之into方法 三 首先,load方法有以下幾個過載方法 public requestbuilder load nullable bitmap bitmap public requestbuilder load nu...