鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 编程语言开发 > erlang > >

Cowboy 源码分析(十五)

来源:互联网 作者:佚名 时间:2012-11-15 13:43
大家好,无意间发现 CodeMirror,挺不错的,在线代码编辑器,支持erlang,go等等语言,官方介绍如下: CodeMirror is a JavaScript component that provides a code editor in the browser. When a mode is available for the language you are coding in, i

  大家好,无意间发现 CodeMirror,挺不错的,在线代码编辑器,支持erlang,go等等语言,官方介绍如下:

  CodeMirror is a JavaScript component that provides a code editor in the browser. When a mode is available for the language you are coding in, it will color your code, and optionally help with indentation.

  A rich programming API and a CSS theming system are available for customizing CodeMirror to fit your application, and extending it with new functionality.

  地址:

  Erlang版本地址如下:

  看到这个不错的东西,我第一感觉是怎么加到博客上,因为我太喜欢这个样式了。

  好了,回到Cowboy,上一篇,我们提到了cowboy_http_req:parse_header/4这个函数,今天我们来详细看下:

%% @todo This doesn't look in the cache. parse_header(Name, Req=#http_req{p_headers=PHeaders}, Default, Fun) -> case header(Name, Req) of {undefined, Req2} -> {Default, Req2#http_req{p_headers=[{Name, Default}|PHeaders]}}; {Value, Req2} -> case Fun(Value) of {error, badarg} -> {error, badarg}; P -> {P, Req2#http_req{p_headers=[{Name, P}|PHeaders]}} end end.

  这边我们可以用debugger工具看下第一次调用这个函数接受到的参数的值:

  

  从上面,我们可以看到 p_headers=PHeaders =[],Default = [],Name = 'Connetion',弄清楚了这几个值,我们看下:

  case header(Name, Req) of

  我们看下这一行,调用了 cowboy_http_req:header/2,这个函数,代码如下:

%% @equiv header(Name, Req, undefined) -spec header(atom() | binary(), #http_req{}) -> {binary() | undefined, #http_req{}}. header(Name, Req) when is_atom(Name) orelse is_binary(Name) -> header(Name, Req, undefined). %% @doc Return the header value for the given key, or a default if missing. -spec header(atom() | binary(), #http_req{}, Default) -> {binary() | Default, #http_req{}} when Default::any(). header(Name, Req, Default) when is_atom(Name) orelse is_binary(Name) -> case lists:keyfind(Name, 1, Req#http_req.headers) of {Name, Value} -> {Value, Req}; false -> {Default, Req} end.

   cowboy_http_req:header/2 直接调用了cowboy_http_req:header/3 函数,传递第三个参数为 undefined。这个函数也很简单,如果 Req#http_req.headers列表中,存在Name,则返回 {Name, Value},然后函数返回 {Value, Req},否则,函数返回 {Default, Req} = {undefined, Req}。这里:

Req#http_req.headers = [{'Connection',<<"keep-alive">>},
           {'Accept-Encoding',<<"gzip, deflate">>},
           {'Accept-Language',<<"zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3">>},
           {'Accept',<<"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8">>},
           {'User-Agent',<<"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/12.0">>},
           {'Host',<<"localhost">>}]

是存在该key的,所以返回 {<<"keep-alive">>, Req}。

  接着我们回到 cowboy_http_req:parse_header/4函数:

{undefined, Req2} -> {Default, Req2#http_req{p_headers=[{Name, Default}|PHeaders]}};

  当返回 {undefined, Req2} 时,函数返回 {[], Req2#http_req{p_headers=[{'Connection',  [] } | [] ]}};

  当返回 {Value, Req2} = {<<"keep-alive">>, Req2} 时,执行以下代码:

case Fun(Value) of {error, badarg} -> {error, badarg}; P -> {P, Req2#http_req{p_headers=[{Name, P}|PHeaders]}} end

  这里调用传递进来的匿名函数,虚拟主机,我们回顾下这个匿名函数是如何定义的:

fun (Value) -> cowboy_http:nonempty_list(Value, fun cowboy_http:token_ci/2) end);

  如果大家忘了,这2个函数的实现,可以回到 Cowboy 源码分析(十三) Cowboy 源码分析(十四),回忆下,这里 Value = <<"keep-alive">>,那么如果正确,将会返回列表,

网友评论
<