YAWShh.docx
- 文档编号:7040421
- 上传时间:2023-01-16
- 格式:DOCX
- 页数:63
- 大小:136.47KB
YAWShh.docx
《YAWShh.docx》由会员分享,可在线阅读,更多相关《YAWShh.docx(63页珍藏版)》请在冰豆网上搜索。
YAWShh
Yaws–YetAnotherWebServer
ClaesWikstrom
klacke@hyber.org
2016-9-22(Yaws-2.0.4)
读我:
除了--id、--heart等不能用以外,Win32版本的Yaws使用与在UNIX中类似。
yaws--help可以查看可用选项。
>yaws–i,这将使用安装目录下的yaws.conf配置文件来启动一个基本的Yaws系统。
如果你安装了unxutils和perl工具,实际上是可以在windows中开发和编辑Yaws的。
享受Yaws吧。
PS:
个人学习,非官方翻译,仅供参考。
目录
1介绍
1.1前提
1.2示例
2编译、安装、配置及运行
2.0.1编译与安装
2.0.2配置
3静态内容
4动态内容
4.1介绍
4.2EHTML
4.3POSTs
4.3.1查询
4.3.2表单
4.4提交文件
5工作模式
5.1实际编译情况
5.2评估Yaws代码
6SSL
6.1服务器名指定
7应用
7.1登陆情景
7.1.1会话服务器
7.1.2改写参数
7.1.3认证
7.1.4数据库驱动应用
7.2Appmods
7.3Opaque数据
7.4用户定制
7.4.1404文件未找到
7.4.2崩溃信息
7.5内容流
7.6out/1函数返回值
8调试与开发
8.1日志记录
9基于CGI的外部脚本
10FastCGI
10.1FastCGI响应器角色
10.2FastCGI认证器角色
10.3FastCGI过滤器角色
10.4FastCGI配置
11安全
11.1网络认证
12嵌入式模式
12.1创建全局和服务器配置
12.2在嵌入式模式下启动Yaws
13配置文件——yaws.conf
13.1全局部分
13.2服务器部分
13.3.yaws_auth文件中包含的原语
13.4配置示例
14网络套接字协议支持
14.1建立一个网络套接字连接
14.1.1支持的选项
14.2网络套接字回调模块
14.2.1基础回调模块
14.2.2高级回调模块
14.3记录定义
第1章介绍
Yaws是用Erlang编程语言写的一个网络服务器。
它把Erlang作为作为嵌入式语言,就像Apache的PHP或者Tomcat的Java一样。
相对于Java或PHP来说,Erlang作为嵌入式网页语言的优点很多:
●速度——使用Erlang来实现网络服务器以及作为嵌入式脚本能得到很好的生成动态网页的性能
●优美——当然这是主观观点。
●可扩展性——Erlang的轻量级进程使得Yaws可以处理大量的并发连接。
Yaws支持:
●HTTP1.0与HTTP1.1
●输出静态网页
●在HTML页面中嵌入Erlang代码来生成动态内容
●NCSA/XLF/ELF日志格式的传输日志
●虚拟主机(同一IP地址上的多个服务器)
●多个IP地址上的多个服务器
●HTTP跟踪调试
●开发调试网站时可用的网络服务器交互式解释器环境
●RAM缓存经常访问的页面
●上传和下载动态生成页面的完整的流功能
●SSL
●支持网络认证页面
●提供API,支持基于cookie的会话
●建立虚拟目录层次的应用模块
●嵌入式模式
●网络套接字(RFC6455)
●长轮询(COMET)应用
●正、反向代理
1.1前提
此文档要求读者:
●熟悉Erlang编程语言
●理解基本的网络技术
1.2示例
我们通过一个小示例的帮助来介绍Yaws网络服务器。
Yaws传输静态网页与其它的老式网络服务器类似,只是它比大多数都快。
有趣的地方在于Yaws传输动态页面。
任意带有“.yaws”后缀的页面都被认为是Yaws动态页面。
Yaws页面能包含嵌入式Erlang代码片段,这些代码片段能在页面被传输到网络浏览器时执行。
示例1.1是一个小的Yaws页面的HTML代码。
Firstparagraph
Out(Arg)->
{html,“
ThisstringgetsinsertedintoHTMLdocumentdynamically”}.
AndhereissomemoreHTMLcode
它说明了Yaws的基本概念。
通常,存储在以“.yaws”为后缀的文件中的HTML代码能包含
同一Yaws页面中可以有多个HTML代码块及多个Erlang代码块。
out/1函数的Arg参数的数据类型是一个Erlang记录,其中包含不同的数据,这些数据在生成动态页面时很有趣。
例如网络用户发送的HTTP头,通向网络用户的实际TCP/IP套接字。
这些将在后继章节详述。
out/1函数返回元组{html,String},其中String被插入到HTML输出中。
out/1函数能返回不同的值,以控制Yaws网络服务器的行为和输出。
第2章编译、安装、配置及运行
这章更多的是Yaws配置的开始指南,而不是一个完整的描述。
Yaws的源代码保存在Github上,网址是
$gitclone
Yaws发行版本的网址是http:
//yaws.hyber.org/download。
2.0.1编译及安装
编译及安装Yaws的前提之一是正确安装Erlang系统。
Yaws运行于ErlangOTP发行版R16B01或更新版本,可从http:
//www.erlang.org/得到Erlang。
直接编译安装即可:
#cd/usr/local/src
#tarxfzyaws-X.XX.tar.gz
#cdyaws-X.XX
#./configure&&make
#makeinstall
这里make命令将使用配置脚本里找到的erlc编译器来编译Yaws网络服务器。
●makeinstall–将安装Yaws可执行文件于/usr/local/bin/,工作配置文件于/usr/local/etc/yaws.conf
另外你也可以通过rebar来编译Yaws如下:
#rebarget-depscompile
如果你想支持SOAP,运行下列命令:
#YAWS_SOAP=1rebarget-depscompile
使用reltool创建Yaws发行版,执行下列命令:
#rebargenerate
因为它捆绑了Erlang/OTP及所有相关应用,所以rel/里生成的发行版是独立的,没有其它要求。
Rebar的未来版本将允许你创建不捆绑Erlang/OTP的简化版,但是目前还未实现。
当开发Yaws站点时,使用配置脚本的--prefix选项来直接本地安装并以非优先级用户运行Yaws通常非常方便:
#./configure–prefix=/path/to/yaws&&makeinstall
#/path/to/yaws/bin/yaws-i
2.0.2配置
让我们看看本地安装后的配置文件/home/klacke/yaws/etc/yaws/yaws.config:
#firstwehaveasetofglobals
logdir=/home/klacke/yaws/var/log/yaws
ebin_dir=/home/klacke/yaws/lib/yaws/examples/ebin
include_dir=/home/klacke/yaws/lib/yaws/examples/include
……
#andthenasetofservers
Port=8000
Listen=127.0.0.1
Docroot=/home/klacke/yaws/var/yaws/www
配置文件由初始全局变量集合组成,它们对所有已定义的服务器都有效。
目前我们需要考虑的唯一一个全局原语是logdir。
Yaws会产生一些日志文件。
我们启动Yaws交互模式如下:
#~/bin/yaws–i
Erlang(BEAM)emulatorversion5.1.2.b2[source]
EshellV5.1.2.b2(abortwith^G)
1>
=INFOREPORT====30-Oct-2002:
:
01:
38:
22===
Usingconfigfile/home/klacke/yaws/etc/yaws/yaws.conf
INFOREPORT====30-Oct-2002:
:
01:
38:
22===
Listeningto127.0.0.1:
8000forservers[“localhost:
8000”]
1>
通过启动Yaws的交互模式(使用命令开关-i),我们得到常规的Erlang弹出框,这在开发Yaws页面时非常方便。
例如我们可以:
●动态编译及载入需要的帮助模块
●使得所有的崩溃及错误报告直接输出到终端
上述配置定义了一个地址为127.0.0.1:
8000,名称为“localhost”的HTTP服务器。
理解服务器名称与地址的区别很重要。
名称是用户HTTPHost:
头的期望值,它通常与服务器的DNS名称一致,而地址则是服务器的实际IP地址。
因为Yaws支持同一IP地址上的多个服务器的虚拟主机,所以这很重要。
虽然如此,我们的服务器监听127.0.0.1:
8000端口,其名称为“localhost”,因此正确的服务器URL为http:
//localhost:
8000。
服务器的文档根目录(docroot)为Yaws源代码发布版中www目录的拷贝。
此目录包含一些示例,而且我们能够在URLhttp:
//localhost:
8000运行所有的这些示例。
我们不是在Yawswww目录下编辑及添加文件,而是在同一IP地址的不同端口创建了另外一个服务器,尤其是不同的文档根目录以便于我们添加自己的文件。
#mkdir~/test
#mkdir~/test/logs
现在更改配置文件如下:
Logdir=/home/klacke/test/logs
Ebin_dir=/home/klacke/test
Include_dir=/home/klacke/test
……
port=8000
listen=127.0.0.1
docroot=/home/klacke/yaws/var/yaws/www
port=8001
listen=127.0.0.1
docroot=/home/klacke/test
我们定义了两个服务器,一个是初始默认,另一个指向自定义文档根目录。
现在我们可以开始添加HTML页面形式的静态内容、.yaws页面形式的动态内容或者能够产生动态内容的Erlang.beam代码了。
载入路径将被设定以便~/test目录里的beam代码在引用时自动加载。
在开发站点时运行Yaws于交互模式是很好的实践。
为了启动Yaws作为后台守护进程,我们给出标记:
#yaws-D--heart
-D或-daemon标记指示Yaws作为后台守护进程运行,--heart标记将启动一个心跳程序,这个程序将在后台守护进程崩溃或者停止响应正常心跳时重启Yaws。
默认情况下,心跳程序将重启后台守护进程,除非它已经在60秒或更少的时间内重启5次,此时它认为情况很严重并拒绝再次重启后台。
-heart-restart=C,t标记更改60秒内5次重启为T秒内C次重启。
对于无限次重启,设定C、T均为0。
这也使能--heart标记。
一旦启动为后台守护进程模式,我们就只有有限的方式与其交互了,可以查询如下:
#yaws–S
此命令产生简单的每个已配置服务器的运行时间及点击次数的打印输出。
如果我们更改配置,我们可以使用下面的命令来通知后台守护进程:
#yaws–h
这将强制后台守护进程重新读取配置文件。
第3章静态内容
Yaws在传输静态页面时与其它常规网络服务器没什么差别。
默认情况下Yaws将在RAM中缓存静态内容。
缓存行为由一些全局配置原语控制。
RAM缓存会占用内存,因此细微调节缓存原语的默认值或者甚至完全关闭将会很有趣。
下列配置原语控制缓存行为:
●max_num_cached_files=Integer,Yaws将在RAM中缓存小文件,例如经常访问的GIF图像。
这个原语设定缓存文件的最大数量,默认值为400个文件.
●max_num_cached_bytes=Integer,这个原语控制用于所有缓存RAM文件的最大字节数量,默认值为1000000,1M字节。
●max_size_cached_file=Integer,这个原语设定每个YawsRAM缓存文件的大小,默认值最大为8000字节,8batters。
这也许有点令人困惑,但是上述缓存原语是针对每个服务器的,因此如果我们指定max_num_cached_bytes=1000000,并且定义3个服务器,那么我们将实际上会使用3*1000000个字节。
第4章动态内容
动态内容才是Yaws所关注的。
大多数网络服务器设计时考虑的是HTTP和静态内容,而Yaws设计的初衷就是动态页面。
当前很多大型网站都大量使用动态页面。
4.1介绍
当用户请求一个“.yaws”后缀的页面时,Yaws服务器将从硬盘读取该页面,并把它分割为HTML代码块和Erlang代码块。
每个Erlang代码块分别编译为一个模块。
Erlang代码块必须包含out/1函数,否则Yaws服务器将在HTML输出中嵌入适当的错误信息。
当Yaws服务器传输.yaws页面时,它将一块一块的处理.yaws文件中的代码。
如果是HTML代码,则原样传输,然而如果是Erlang代码,Yaws服务器将调用其中的out/1函数,并将输出嵌入到HTML流,再传输给用户。
Yaws当然会缓存编译结果,这样当用户再次请求相同的.yaws页面时,它会直接调用已编译的模块。
4.2EHTML
使用out/1函数来生成HTML输出有两种方法。
第一种也是最容易理解的方法是返回元组{html,String},其中String是常规的HTML数据(字符串和/或二进制的深度列表),然后它被嵌入到输出流中。
例如:
Example1
out(A)->
Headers=A#arg.headers,
{html,io_lib:
format(“Yousaythatyou’rerunning~p”,[Headers#headers.user_agent])}.
第二种方法是返回元组{ehtml,EHTML}或者{exhtml,EHTML},其中exhtml生成严格的XHTML代码。
EHTML必须符合下列结构:
EHTML=[EHTML]|{TAG,Attrs,Body}|{TAG,Attrs}|{TAG}|
{Module,Fun,[Args]}|fun/0|
binary()|character()
TAG=atom()
Attrs=[{HtmlAttribute,Value}]
HtmlAttribute=atom()
Value=string()|binary()|atom()|integer()|float()|
{Module,Fun,[Args]}|fun/0
Body=EHTML
我们给出一个示例来说明,例如元组
{ehtml,{table,[{bgcolor,grey}],[
{tr,[],[
{td,[],“1”},
{td,[],“2”},
{td,[],“3”}
]
},
{tr,[],[
{td,[{colspan,“3”}],“444”}
]
}
]
}
}
可扩展为下列HTML代码
第一眼看上去HTML代码比Erlang元组更清晰优美,从纯美学角度来说是这样的,但是Erlang代码的优势在于支持Erlang语法的编辑器的完美缩进(Emacs),而且更容易由Erlang程序来控制处理。
注意ehtml支持函数调用,函数能够返回任意合法的ehtml值,包括其它函数值。
Yaws支持{M,F,[Args]}和fun/0函数值形式。
作为一些更有意思的ehtml示例,例如我们可以让out/1函数打印HTTP头。
Yaws源代码发布版的www目录下有一个arg.yaws文件,它展示了传递给out/1函数的Arg#arg记录参数。
在讨论那段代码前,我们先详细描述一下Arg记录。
默认情况下所有的Yaws文件都会包含yaws_api.hrl文件。
#arg{}记录中包含很多在动态处理HTTP请求时的有用字段。
我们基本上可以访问所有的与用户请求相关的信息,例如:
●通向HTTP用户的实际套接字
●所有的HTTP头——解析到#headers记录中
●HTTP请求——解析到#http_request记录中
●clidata——用户提交的数据
●querydata——URL中第一个“?
”字符后面的数据
●docroot——处理请求的虚拟服务器文档根目录的绝对路径
-record(arg,{clisock,%通向用户端的套接字
client_ip_port,%元组{ClientIp,ClientPort}
headers,%头
req,%请求
orig_req,%原始请求
clidata,%用户数据(POST请求中的二进制数据)
server_path,%规范化的服务器路径(URI的预查询字符串部分)
querydata,%...?
querydata形式的URI,与cgiQUERY_STRING等效
appmoddata,%通向查询路径的剩余部分(已弃用,建议使用pathinfo)
docroot,%当前请求的数据的物理起始位置
docroot_mount,%参考docroot的虚拟路径,例如/myapp/
fullpath,%到yaws文件的完整深度路径
cont,%分块多部分上传的后续部分
state,%out/1回调使用者用到的状态信息
pid,%yaws工作进程的ID
opaque,%对传输静态数据有用
appmod_prepath,%在
prepath,%URI‘动态’部分之前的路径,即http:
//some.host/
pathinfo,%当为请求调用c.yaws时设定’/d/e’,http:
//some.host/a/b/c.yaws/d/e,等效于cgiPATH_INFO
}
)
-record(http_request,{method,path,version}).
-record(headers,{connection,accept,host,if_modified_since,if_match,if_none_match,
If_range,if_unmodified_since,range,referrer,user_agent,accept_ranges,
cookie=[],keep_alive,location,content_lenth,content_type,
content_endoding,authorization,transfer_encoding,x_forwarded_for,
other=[]
}
)
#arg记录中有一些高级字段,例如appmod和opaque,这将在后面章节讨论。
现在我们展示一些代码来显示Arg#arg记录的内容。
这些代码在yaws/www/arg.yaws中,在本地安装后对http:
//localhost:
8000/arg.yaws的请求会导致运行该代码。
TheArg
ThispagedisplaystheArg#argumentstructuresuppliedtotheout/1function.
out(A)->
Req=A#arg.req,
H=yaws_api:
reformat_header(A#arg.headers),
{ehtml,[{h4,[],"Theheaderspassedtouswere:
"},
{hr},
{ol,[],lists:
map(fun(S)->{li,[],{p,[],S}}end,H)},
{h4,[],"Therequest"},
{ul,[],[{li,[],f("method:
~s",[Req#http_request.method])},
{li,[],f("path:
~p",[Req#http_request.path])},
{li,[],f("version:
~p",[Req#http_request.version])}
]
},
{hr},
{h4,[],"Other
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- YAWShh