免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: luren04
打印 上一主题 下一主题

Mod_python 3.2.8中文手册 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2008-04-18 23:19 |只看该作者
第六章标准处理器

6.1发布处理器

发布处理器是一种快速开发应用程序,避免(avoid)直接书写处理器的好方法。收到Zope中ZPublisher的启发。

6.1.1简介

使用处理器需要书写如下配置:

<Directory /some/path>

SetHandler mod_python

PythonHandler mod_python.publisher

</Directory>

这个处理器允许通过URL在模块中存储函数和变量。例如,如果有如下模块,叫做'hello.py':

""" Publisher example """

def say(req,what="NOTHING"):

return "I am saying %s" % what

则如下路径显示"I am saying NOTHING"

http://www.mysite.com/hello.py/say

如下路径显示"I am saying hello"

http://www.mysite.com/hello.py/say?what=hello

6.1.2发布处理器规则(algorithm)

发布处理器从URI映射到Python变量或可执行对象,返回调用的返回值。

Traversal(?)

发布处理器定位和导入URI指定的模块。模块的位置按照req.filename属性指定。在到如之前,如果有扩展名则丢弃。

如果req.filename为空,则模块名缺省为index。

一旦模块成功导入,则URI剩余的部分成为query字段的开始(a.k.a also known as也叫做PATH_INFO),来在模块里查找对象。发布处理器切断路径,从左到右,每个元素一次的映射到Python对象。

如果URL里未指定path_info,则发布处理器使用缺省的'index'。如果最后一个元素是模块里的一个对象,且它领先与一个目录(也就是没有给出模块名),模块名也会默认到'index'。

当如下情况发生时,转换结束,并返回HTTP_NOT_FOUND到客户端:

任何一个横断(traverse?)对象名以下划线开头。使用下划线保护对象不被web存取。

模块冲突(encounter),发布的对象因为安全原因不可以成为模块。

如果路径中找不到对象,则HTTP_NOT_FOUND也会发送到客户端。

例如,如下的配置:

DocumentRoot /some/dir

<Directory /some/dir>

SetHandler mod_python

PythonHandler mod_python.publisher

</Directory>

如下是脚本'/some/dir/index.py':

def index(req):

return "We are in index()"

def hello(req):

return "We are in hello()"

然后:

http://www.mysite.com/index/index 显示"We are in index()"

http://www.mysite.com/index/ 显示"We are in index()"

http://www.mysite.com/index/hello 显示"We are in hello()"

http://www.mysite.com/hello 显示"We are in hello()"

http://www.mysite.com/spam 显示'404 Not Found'

如果找到了目标对象,且它是可调用对象而不是一个类,则发布处理器会提取一个对象预期的列表。这个列表包含从HTML表单提交数据中的字段。字段值和字段名以字符串匹配并传入可调用对象的参数。任何没有匹配的名字都被默认丢弃,除非目标对象有一个**kwargs风格的参数。未匹配参数传入这个词典中。

如果目标对象不是可调用的或者是一个类,则会返回它创建的字符串到客户端。

发布处理器提供了对模块和函数简单的存取控制。

在每个处理阶段,发布处理器按顺序检查__auth__和__access__属性,还有__auth_realm__属性。

如果__auth__是可调用的,将会被传入三个参数:一个请求对象,字符串包含用户名和密码。如果返回值是False,则将发送HTTP_UNAUTHORIZED到客户端,一般来说还会弹出一个输入密码的对话框。

如果__auth__是一个词典,则用户名和密码按照键值对在词典中尝试匹配。如果不匹配则返回HTTP_UNAUTHORIZED。注意,如果明文将密码存入源代码中是不安全的。

__auth__也可以是常量。在这种情况下,如果为False(也同None、0、""、等等)则返回HTTP_UNAUTHORIZED。

如果存在__auth_realm__字符串,它将会被发送到客户端作为认证区域的提示,通常还显示在密码提示框中。

如果__access__存在并可调用,则传入两个参数:请求对象和用户名字符串。如果返回值为False则发送HTTP_FORBIDDEN到客户端。

如果__access__是一个列表,则用户名将会被尝试匹配。如果用户名不再列表中,则返回HTTP_FORBIDDEN。

类似的__auth__、__access__也可以是常量。

在下例中,仅用户'eggs'使用密码'spam'可以访问函数hello:

__auth_realm__="Members only"

def __auth__(req,user,passwd):

if user=="eggs" and passwd=="spam":

return 1

else:

return 0

def __access__(req,user):

if user=="eggs":

return 1

else:

return 0

def hello(req):

return "hello"

这里还有一个具有相同功能,但使用类似技术:

__auth__realm__="Members only"

__auth__={"eggs":"spam"}

__access__=["eggs"]

def hello(req):

return "hello"

如果函数无法被指定属性,为了保护函数,也可以将__auth__和__access__函数放入这个函数中定义,如:

def sensitive(req): #受保护函数

def __auth__(req,user,password):

if user=="spam" and password=="eggs":

return 1

else:

return 0

#受保护函数的函数体

return 'sensitive information'

注意,这种技术也可用于__auth__或__access__是常量的情况,但是不可以是词典或列表。

__auth__和__access__机制独立于PythonAuthenHandler而存在。它可能使用,例如认证处理器。然后__access__列表用于已经验证过的用户访问具体函数。

注意:为了让mod_python可以访问__auth__,包含它的模块必须首先导入。因此,任何模块级(module-level)的代码在导入__auth__之前,即时__auth__为False,也是可以执行的。为了真正的保护模块,使用另外一种认证技术,比如apache的mod_auth模块或者用mod_python的PythonAuthenHandler处理器。

6.1.3表单数据

在处理参数结束后,发布处理器将会创建一个FieldStorage类的实例。实例的引用存入请求对象的form属性中。

每次请求只能拥有一个FieldStorage类的实例,在使用发布处理器的时候不可以自己实例化FieldStorage,只能使用Request.form代替。




6.2PSP处理器

PSP处理器是处理含有mod_python.psp模块中psp类的。要使用它,只需简单的在httpd的配置中加入:

AddHandler mod_python .psp

PythonHandler mod_python.psp

更多的PSP语法参见4.9节。

如果打开了服务器选项PythonDebug为On,则在URL的末尾添加下划线"_"会显示响应的PSP源代码和对应的Python代码。这对调试是非常有用的。

注意:开启调试选项时,远程用户同样有权查看PSP源码。




6.3CGI处理器

CGI处理器用来在mod_python中模拟CGI环境。

但是注意,在Python级别并不能真正的模拟出一个完整的CGI环境。stdin和stdout是由sys.stdin和sys.stdout来替换(substitute)的。环境变量也被替换为词典。一点类似(implication)是外部程序通过环境变量os.system交互,等。不要指望外部可以看到Python的环境变量,也不要指望读写标准输入输出象真正的CGI环境那样。

这个处理器是为了逐步(step stone)移植(migration)CGI遗留(legacy)下来的代码。不建议大量使用这种方式。因为CGI程序没有打算(intend)过在线程环境中使用(比如请求更换当前目录,就不是线程安全的。这就需要在多线程服务器程序中使用线程锁)。他的实现方式也远不如mod_python中的其他方式。

需要使用它,只需在.htaccess文件中加入如下内容:

SetHandler mod_python

PythonHandler mod_python.cgihandler

在版本2.7中,cgihandler会完全的重新载入来间接(indirectly)的重新导入模块。这是为了保护装入模块列表(sys.modules)来优先(prior)执行CGI脚本,然后在脚本执行后对比导入模块。除了一些__file__属性指向标准Python库的模块外,将会被在sys.modules中删除来强制Python在下次CGI脚本导入时再次装入他们。

如果你不希望如上的行为,可以编辑'cgihandler.py'文件注释掉###代码。

测试表明,cgihandler在多次文件上传时会发生内存泄漏(leak)。而且至今还没有完全解决这个问题。暂时的解决办法是设置apache的MaxRequestsPerChild到一个非零的值。




完成...




注:本文由gashero翻译,欢迎转载,转载前情确保同意英文原版的版权声明。因本人英语水平有限,文中有错误之处欢迎指出,意见发送到harry.python@gmail.com。本文不定期更新,请关注"河边的小屋"(http://blog.csdn.net/gashero)来查看最新翻译版本。翻译全程特别感谢"画鬓如霜"的支持,没有你的爱我无法完成这一切。也感谢python-chinese邮件列表上朋友的支持。

论坛徽章:
0
12 [报告]
发表于 2008-04-19 13:55 |只看该作者

不错

不错不错不错不错不错不错不错不错
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP