mochiweb源码分析(六)
1.说下call_body这函数
这里的Body就是之前说的处理http请求的方法,如下图
容易看出调用的是call_body/2的第三个分支,然后再看看我们写的简单的helloweb模块的开启服务器部分
这实际上是一个闭包的用法,即调用的是helloweb:loop(Req, DocRoot),DocRoot我自己写的是存放html文件的路径,方便下面处理http请求时用到,?MODULE是指当前的模块名
2.下面说一下helloweb:loop(Req, DocRoot)
这个方法一般是用户自己写的,实际上是将mochiweb各模块提供的API进行组装,得到想要的处理http请求的逻辑。
说一个特殊的地方,比如
Req:get(method)
一般我们用指定的模块名和函数名确定调用哪个API,但这里Req是一个元祖,可参考erlang程序设计第二版的第二十四章的有状态的模块,这里我截图了书上的解释
比如说,
{?MODULE, [Socket, Opts, Method, RawPath, Version, Headers]}:get(method)相当于 ?MODULE:get(method, [Socket, Opts, Method, RawPath, Version, Headers]).
3.
说一下怎样将消息体发送给浏览器,我自己写的一个逻辑是找到路径下的html文件,将写好的html文件发送给浏览器,浏览器会根据html文件的内容呈现静态页面。
这里是调用Req:serve_file/2这个函数,这个Req对象在mochiweb_request:new/6这个函数生成的
第一个元素就是模块名,即mochiweb_request,所以Req:serve_file/2就是mochiweb_request:serve_file/3,serve_file/3函数如下所示:
第一行代码会调用mochiweb_util:safe_relative_path/2,看这个函数的解释如下:
即检测相对路径是否是安全或未定义的,不安全和未定义的都会返回undefined。
如果是正确的相对路径,则会调用第二个分支,filename:join/2是路径名的拼接,然后用filelib:is_dir检查路径是否是一个目录,
如果是目录,则执行true流程,如果不是目录,则执行false流程