1、源码网整理:源码网整理:Mod_python 3.2.8中文手册From Download 第一章 简介1.1性能使用mod_python的主要优势在于比传统 CGI更高的性能。一个测试,使用在 Pentium 1.2GHz的机器上运行 Red Hat Linux 7.3。使用 4种类型的脚本,基于标准的CGI导入模块( 以典型的Python CGI脚本开始 ),然后输出Hello! ,测试 10000次请求作为基准。标准CGI : 23 次请求/秒mod_python CGI处理器: 385 次请求/秒mod_python 发布处理器: 476 次请求/ 秒mod_python 处理器: 1
2、203 次请求/ 秒1.2可移植性apache是按照阶段处理请求的(比如:读取请求、处理请求头、检查存取等)。这些阶段可以分别用处理器调用的函数来实现。传统上,使用C语言编写处理器模块。mod_python提供了使用Python 拜你些apache处理器扩展apache功能的方法。更多的apache请求处理过程,参考“Apache API Notes“,或者参考“Mod_python-Integrating Python with Apache“文件。为了方便的从CGI移植,标准的mod_python处理器提供了CGI模拟环境,允许用户不修改遗留下来的脚本,而在大多数时候无需进行任何修改。参考
3、:http:/dev.apache.orgapache开发者资源http:/www.modpython.org/python10/mod_python-整合Python和Apache ,出现在Python 10(?)1.3历史mod_python起源于Httpdapy 项目(1997)。很久以后Httpdapy才被叫做mod_python,因为Httpdapy并不是特定用于 apache服务器的。Httpdapy 设计成跨平台的,而实际上主要从 Netscape服务器开始( 追溯到1997年的Nsapy)。摘录自Httpdapy项目的README文件的描述将Python嵌入到apache服务器
4、的挑战与解决方法。“ #小字体源码网整理:源码网整理:在我多年前开发第一个WEB应用程序时就发现 CGI访问数据库非常慢,因为每次点击请求都会装入解释器并执行数MB 的数据。数据库往往都很大,并将大量时间浪费在数据库的连接/认证等“ 意义重大“的事情上,像DNS查询、编码与解码、内存分配等等。在应用提速的压力下,我尝试过使用Python 和多种工具的综合使用。我并不迷信微软的ASP ,又被Netscape的性能和满是臭虫而郁闷。“Cold Fusion“(冷聚变)看起来有希望,但我稍后学会了 HTML类标签的书写方式,可读性跟汇编有一拼。比如PHP。但是我真的很想用 Python来写东西。就在
5、同时有关Python互联网编程的书籍出版了,其中将Python嵌入到Netscape服务器的方式立即引起了我的注意。我在我的项目中使用了这个例子,并在稍后开发了我自己的改进版,叫做Nsapy,并在WindowsNT和 Solaris上编译。尽管Nsapy 仅能工作在 Netscape服务器上,但是出于灵活通用的面向对象设计,在 Python精灵中,很容易移植到其他的WEB服务器。后来,曾经流行的Netscape服务器挂了,我就将Nsapy移植到最流行的服务器 apache上。所以从Nsapy 衍生出了 Httpdapy。“继续这个传奇,你会想到将Httpdapy移植到其他服务器上,实际上他们比
6、预想要复杂而且枯燥。反之,提供一个类似于Perl语言的apache扩展mod_perl一样或更好性能的部件会更有意思。俱往矣,mod_python的第一个版本发布于 2000年5月。完成.第二章 安装注意:获得关于安装的帮助和其他问题的最好地方是mod_python的邮件列表。可以发送标题为“subscribe“的邮件到mod_python-requestmodpython.org 。2.1先决条件 Python 2.2.1或更新的版本,早起版本将无法使用。 apache 2.0.40或更新的版本,如果要使用apache 1.3.x,请使用mod_python的版本2.7.x 。编译mod_p
7、ython需要有apache 和Python的包含文件,并且确保安装了Python 标准库。如果你从源代码安装了Python和apache,那么你已经拥有了这些了。如果你使用了预打包软件,如 RPM或其他方式则只有二进制版本,而没有源码。通常apache和Python的包含文件和库文件在各自的“develop源码网整理:源码网整理:ment“包中。如果你不确定拥有这些重要文件,请从源码安装Python和apache,或者阅读你系统的文档以了解如何获得开发包。2.2编译有两种链接apache模块的方式:静态的和DSO方式。DSO方式现在非常流行,并推荐用于mod_python 的安装。模块被编译
8、成共享库,并在运行时动态装入。DSO方式的优势在于安装模块时无需重新编译apache。关于DSO机制的详细信息参见http:/httpd.apache.org/docs-2.0/dso.html。当前版本的mod_python仅支持 DSO方式。静态链接是一种较老的方式,比动态连接的方式支持更多的平台,但是较少使用。主要的缺陷是必须要重新编译apache,在很多情况下并不是一个好的选择。2.2.1运行 ./configure./configure脚本将会分析你的运行环境,并创建自定义的 Make文件用于你的系统。使用autoconf生成的 ./configure包含如下内容: 查看apxs程序
9、是否存在。这个程序作为apache标准发行版的一部分提供 DSO支持。如果找不到则无法实现DSO功能。使用 -with-apxs指定选项:$ ./configure -with-apxs=/usr/local/apache/bin/apxs强烈建议使用这个选项。 检查Python版本,并尝试找到libpython参数变量的二进制发行版。缺省时可以在 Path变量中找到python。如果找到的首个python二进制版本不适合mod_python ,则可以手动指定python的路径使用-with-python ,如:$ ./configure -with-python=/usr/local/bin
10、/python2.3 设置mod_python保留的互斥锁数量。在某些系统中,互斥锁是一种有限的资源。增加最大互斥锁数量将会增加使用session锁定的性能。缺省值是8,一个性能不错的数值是32。使用-with-max-locks选项:$ ./configure -with-max-locks=32这个选项是在3.2.0版本开始提供的。 尝试查找flex并确定版本。如果PATH 中找不到flex则configure会出错。如果版本不对则会给出警告。一般可以忽略这个警告,除非需要重新创建src/psp_parser.c。剖析器(parser)会被PSP 调用,使用flex的C 语言书写。要求的版
11、本是 2.5.31,在大多数平台上2.5.4 并不合适。所以已经源码里已经包含了一个psp_parser.c 的副本。如果需要编译src/psp_parser.c则需要获取正确版本的flex。如果PATH 中的flex版本有误,则可用-with-flex选项:$ ./configure -with-flex=/usr/local/bin/flex源码网整理:源码网整理:这是3.2.0 版本中的新特性 构建mod_python文档时需要用到 python的源代码。可以如果不需要文档,可以忽略这个选项。如果需要则用-with-python-src选项:$ ./configure -with-pyt
12、hon-src=/usr/src/python2.3这个是3.2.0 版本中的新特性2.2.2运行 make开始构建过程,简单的运行如下即可:$ make2.3安装2.3.1运行 make install这个安装过程必须在root用户下完成:$ su# make install这将会简单的将二进制版本复制到apache的libexec目录。并且会安装python-libraries到site-packages并编译他们。如果你想只安装python库或者只安装 DSO,可以用如下make目标:# make install_py_lib# make install_dso2.3.2配置 apach
13、e按照DSO 模式安装的 apache,需要在 httpd.conf中加入启动mod_python的句子:LoadModule python_module libexec/mod_python.so实际的mod_python.so路径可能有所变化,但是make install将会显示这个文件的确切路径。2.4测试注意次部分内容仅适用于3.x版本,如果使用 2.7.x版本,你需要找到更适合的文档。 创建一个在WEB站点可见的目录,如 htdocs/test。 在httpd.conf 或者.htaccess文件中添加如下内容。如果是在.htaccess 文件中,则无需 标签。并且确保httpd.c
14、onf 文件中的AllowOverride目标至少包含FileInfo,缺省是None,将会无法工作。AddHandler mod_python .py源码网整理:源码网整理:PythonHandler mptestPythonDebug On 重定向所有以.py结尾的URL到mod_python 处理器。mod_python收到请求之后查找合适的处理器来处理请求。这里有个简单的自定义处理器叫mptest。我们看看如何定义这个处理器。 此时如果修改了主配置文件httpd.conf则需要重启apache来使之生效。 编辑mptest.py 文件在htdocs/test目录。from mod_py
15、thon import apachedef handler(req):req.content_type=text/plainreq.write(“Hello, world!“)return apache.OK 指向URL 路径到mptest.py。将会看到“Hello, world!“。如果看不到则参考故障处理。 依照配置文件的规则,指定任何.py 文件都会最终指向mptest.py 做处理。因为已经明确的指定了mptest做处理器。如果需要用不同的处理器处理不同的文件则需要更高层的处理器,比如publisher 发布器、mpservlets或vampire。这些都是动态装入的处理器。 如果都
16、运行无误则转入第三章,入门。参考:http:/ 检查错误输出 检查服务器错误日志 单处理执行apache$ ./httpd -X这样将会显示更多有用信息 从mod_python3.2.0开始,可以使用mod_python.testhandler来诊断你的配置。添加到httpd.conf 文件:源码网整理:源码网整理:SetHandler mod_pythonPythonHandler mod_python.testhandler这时指向你的/mpinfo 的URL则会显示一些信息帮助处理mod_python的问题。 在mod_python邮件列表提问,并确保提供如下信息:mod_python版
17、本操作系统类型、名字、版本号Python版本、非常规的编辑选项apache服务器版本相关的apache配置,.htaccess相关的Python代码完成.第三章 指南3.1使用发布器(Publisher) 的快速例子这一节提供无需太多细节的发布器指南。更多如何使用mod_python处理器的细节将在以后解释。发布器(publisher)提供了发布mod_python标准模块的方式。需要在配置文件中加入如下配置:AddHandler mod_python .pyPythonHandler mod_python.publisherPythonDebug On下例会返回简单的表单数据。询问姓名、电子
18、邮件、注释之后将会给管理员发邮件。这个简单的应用程序由两个文件组成:form.html 用于提交数据, form.py用于处理表单动作。如下是表单:Please provide feedback below:Name: 源码网整理:源码网整理:Email: Comment: 注意表单的action属性指向form.py/email调用,如下创建form.py,如下:import smtplibWEBMASTER=“webmaster“ #管理员电邮SMTP_SERVER=“localhost“ #本机SMTP服务器def email(req,name,email,comment):#一定要确保
19、用户提供了所有的参数if not(name and email and comment):return “缺少必要的参数“#创建消息文本msg=“ “From: %sSubject: feedbackTo: %sI have the following comment:%sThank You,%s“ % (email,WEBMASTER,comment,name)#发送信息conn=smtplib.SMTP(SMTP_SERVER)conn.sendmail(email,WEBMASTER,msg)conn.quit()#提供返回页面s=“Dear %s,Thank you for your
20、kind comments, we源码网整理:源码网整理:will get back to you shortly.“ % namereturn name当用户点击提交按钮时,发布器将会装入email 函数到form模块,传递表单字段作为关键字参数。也会传递请求对象到req。注意逆必须要有req参数。发布器已经可以很聪明的传递必要的参数。函数的返回值将被发送到客户端浏览器。即使使用发布器可以非常简单的处理,但是程序仍然可以利用mod_python的强大功能,比如调用请求对象。当然也可以调用本地的mod_python处理器来完成大量的工作。比如设置 HTML头路由req.headers_out;
21、返回错误抛出apache.SERVER_ERROR 异常;从客户端的重定向读写文件req.write()和req.read(),等等。阅读6.1节了解更多关于发布器的详细信息。3.2apache处理器概览节标题翻译有误,应为“快速学习apache如何处理请求“。如果你想要深入钻研mod_python 的功能,需要理解什么是处理器。apache分阶段(phase)处理请求。比如第一个阶段是用户认证,之后是检验用户是否有权访问特定的文件,然后是读取文件并发送到客户端。一个典型的静态文件请求包含三个阶段:1.翻译URI到文件位置2.读取文件并发送到客户端 3.记录请求日志。更复杂的处理依赖于配置文件
22、。一个处理器就是初始处理某个阶段的函数。同一个阶段可以有多于一个处理器进行处理,被叫做apache序列。对应每个阶段有个缺省的apache处理器(大多数只做缺省动作或者什么都不作)。然后由其他的apache模块提供处理器,比如mod_python。mod_python提供了apache每一个重要的处理器。 mod_python处理器缺省时不会做任何事情,除非用特定的配置文件标志。这些标志以“Python“ 开始并以“Handler“ 结尾(如:PythonAuthenHandler),指定 Python函数来处理指定的阶段。所以 mod_python的主函数只是作为发报机的角色连接apache
23、处理器和 Python函数。最常用的处理器是PythonHandler 。它处理含有上下文的请求。因为它没有名字,所以有时也成为通用处理器。这个处理器的apache缺省行为是读取文件并发送到客户端。大多数应用应该重写这个处理器。3.3mod_python做了什么我们假设有如下配置:AddHandler mod_python .py源码网整理:源码网整理:PythonHandler myscriptPythonDebug On所以还需要一个如下文件,/mywebdir/myscript.py如下:from mod_python import apachedef handler(req):req.
24、content_type=“text/plain“req.write(“Hello World!“)return apache.OK如下的事情将会发生:AddHandler标志告诉apache所有的以.py结尾的/mywebdir 下或其子目录下的文件请求都由mod_python 负责处理。 PythonHandler myscript标志告诉mod_python通用处理器在 myscript脚本。PythonDebug On标志告诉 mod_python如果发生错误,则把错误信息输出到客户端,便于开发。当请求到来时,apache开始分步骤处理请求并讲请求发送到mod_python。mod_p
25、ython 处理器检查配置获取处理器。在本例,我们除了通用处理器之外没有调用其他东西。当读取配置到PythonHandler myscript时,会发生下面的事情:1.如果没有做过,假设预设目录已经存在于sys.path中。2.尝试按名字导入模块myscript。注意子目录是不在sys.path中的,如果需要只能按照包名的方式调用。3.在myscript中查找函数handler4.调用这个函数并传递请求对象( 关于请求对象的更多东西在后面)5.在这里我们细致研究一下脚本:from mod_python import apache导入apache模块来获取apache的接口。大多数mod_pyt
26、hon程序需要有这一行。def handler(req):这是处理器函数的声明。叫做handler是因为mod_python 按照配置标志寻找函数。将配置标志转换成小写,然后去掉python即可。这样PythonHandler就成了handler。当然也可以用其他的名字,但是需要用: 来分隔函数名,比如一个处理器函数叫 spam,那么配置标志就是PythonHandler myscript:spam注意,处理器必须包含一个请求对象参数。请求对象提供了关于请求的大量信息,比如客户端的IP,请求头, URL等。向客户端发送信息也需要用到请求对象,这里是没有response 对象的。req.cont
27、ent_type=“text/plain“源码网整理:源码网整理:设置文档MIME 类型为text/plain。缺省的是text/html ,但是如果处理器没有打算返回 html,那么text/plain更恰当(appropriate) 一些。特别注意:需要在req.write方法之前调用如上语句,因为一旦调用req.write,HTTP响应头就被发送出去了,其后的HTTP 响应头的改变都会忽略。req.write(“Hello World!“)将会把字符串写入到客户端。return apache.OK告知apache,请求处理完成并成功。如果没有返回OK ,则apache会自动返回为apac
28、he.HTTP_INTERNAL_SERVER_ERROR或 return apache.HTTP_FORBIDDEN。当处理失败时会在错误日志中记录,并告知客户端一点错误信息。小技巧:如果你注意到,会发现如果请求的URL不是指向myscript.py,而只是一个.py结尾的文件,哪怕是一个不存在的文件,也可以得到相同的结果。因为服务器只是将特定结尾的处理直接交给相关模块的,而并不要求那一定是一个存在的文件。3.4更复杂的例子- 认证现在,你知道写一个处理器多么的简单,下面我们来显示一个更复杂的例子。如果需要用密码来保护一个目录。比如登录名为spam ,密码为eggs。首先需要告诉apache
29、在需要认证时调用我们的认证处理器。加入PythonAuthenHandler 标志到配置文件:AddHandler mod_python .pyPythonHandler myscriptPythonAuthenHandler myscriptPythonDebug On因为一个模块可以包含多个函数,所以也可以在一个模块中使用多个处理器。然后是告知apache,使用Basic HTTP认证。仅限有效用户进入。配置如下:AddHandler mod_python .pyPythonHandler myscriptPythonAuthenHandler myscriptPythonDebug On
30、AuthType BasicAuthName “Restricted Area“源码网整理:源码网整理:require valid-user然后在myscript.py 中写认证函数,一个简单认证函数如下:from mod_python import apachedef authenhandler(req):pw=req.get_basic_auth_pw()user=req.userif user=“spam“ and pw=“eggs“:return apache.OKelse:return apache.HTTP_UNAUTHORIZED如下是逐行解释:def authenhandler
31、(req):认证函数的声明,至于为什么叫这个名字,自己可以参考命名规则。pw=req.get_basic_auth_pw()这里获取密码。basic HTTP认证采用 base64编码发送到服务器。这个函数返回的直接就是密码了。注意必须在获取用户名之前先获取密码。user=req.user获取用户名if user=“spam“ and pw=“eggs“:return apache.OK对比用户名和密码的值,如果正确返回告知验证成功,并进入下一个阶段的处理。在本例里下一个阶段是handler()。else:return apache.HTTP_UNAUTHORIZED告知apache验证失败。
32、这通常会导致客户端浏览器弹出对话框要求用户名和密码。实测:发现我使用的httpd-2.0.55提示验证类型无效,一共两种验证类型,一种是Basic一种是Digest,都是不允许的。就是按照如上例子。终于实验成功了,最上面的配置必须写在httpd.conf中才会有效,写在.htaccess中无效。无论是否指定了AllowOverride 源码网整理:源码网整理:FileInfo都是。这样进入一个目录之后会弹出系统的对话框提示输入用户名密码。验证成功后只要浏览器不关闭就可以继续进入这个目录,但是关闭后就需要再次验证。3.5你自己的404处理器在某些时候,如果希望返回404(HTTP_NOT_FOU
33、ND)或者其他非200的结果到客户端,这里有个窍门。如果从你的处理器返回HTTP_NOT_FOUND, apache将会生成错误页。但是却未必是你喜欢的错误页。这时,你只要设置req.status=apache.HTTP_NOT_FOUND,提交你的页面,然后返回apache.OK就可以了:from mod_python import apachedef handler(req):if req.filename-17:=apache-error.html:#放行apache的错误页if req.filename-18:=handler-error.html:#使用自己的错误页req.statu
34、s=apache.HTTP_NOT_FOUNDpagebuffer=页面不存在else:#使用文件内容pagebuffer=open(req.filename,r).read()#输出错误页req.write(pagebuffer)return(apache.OK)完成.第四章 Python API4.1多解释器使用mod_python工作的时候应该理解,并不是使用 Python在命令行下写脚本,而是用Python调用C 语言API。源码网整理:源码网整理:Python的C语言API 提供了创建子解释器的能力。关于子解释器的更多信息详见Py_NewInterpreter()函数。在这里,每个子
35、解释器拥有独立的命名空间,并与其他子解释器不可访问。子解释器非常适合于理解同一个服务器中处理各个请求的进程。服务器启动mod_python的时候会启动一个主解释器。主解释器包含子解释器词典。刚开始词典是空的。对应每一个请求就会创建一个子解释器,并将引用存储在词典里。这个词典用解释器名作为键名,主解释器叫做main_interpreter 。其他的解释器受到 PythonInterp*的控制。缺省的行为是使用apache虚拟服务器名来命名 (ServerName标志)。这意味着同一个虚拟服务器中的脚本在同一个子解释器中执行,但不再同一个虚拟服务器中的脚本因为不同的子解释器而无法互相访问。Pyth
36、onInterpPerDirectory和PythonInterpPerDirective标志改变(alter)命名惯例(convention)到要存取的绝对路径,或者在Python*Handler可以访问到的地方,分别的 (respectively)。PythonInterpreter能够强制使用解释器名重载所有的命名惯例。一旦创建,一个子解释器将会被接踵而来的请求重用,在apache停止之前不会被销毁。从调用req.interpreter可以获取当前的解释器名。参考Python的C语言API :http:/www.python.org/doc/current/api/api.html4.2
37、请求(request)处理器一个请求处理器是处理请求阶段细节的处理器。apache在处理请求的每一个阶段都对调用相应的处理器。对每一个阶段都会调用请求处理器,由apache的核心或者模块提供,比如mod_python由用户的Python函数提供。用Python书写的处理器只要遵守如下规则就与C写的没有区别:处理器函数总是会传递请求对象的引用,一般是req变量。每个处理器可以返回如下: apache.OK:这个阶段处理无误 apache.DECLINED:这个阶段处理过后还需要队列中的其他模块处理 apache.HTTP_ERROR:发生了HTTP错误,如下值:HTTP_CONTINUE 100
38、HTTP_SWITCHING_PROTOCOLS 101HTTP_PROCESSING 102HTTP_OK 200HTTP_CREATED 201HTTP_ACCEPTED 202HTTP_NON_AUTHORITATIVE 203HTTP_NO_CONTENT 205HTTP_PARTIAL_CONTENT 206源码网整理:源码网整理:HTTP_MULTI_STATUS 207HTTP_MULTIPLE_CHOICES 300HTTP_MOVED_PERMANENTLY 301HTTP_MOVEDTEMPORARILY 302HTTP_SEE_OTHER 303HTTP_NOT_MODI
39、FIED 304HTTP_USE_PROXY 305HTTP_TEMPORARY_REDIRECT 307HTTP_BAD_REQUEST 400HTTP_UNAUTHORIZED 401HTTP_PAYMENT_REQUIRED 402HTTP_FORBIDDEN 403HTTP_NOT_FOUND 404HTTP_METHOD_NOT_ALLOWED 405HTTP_NOT_ACCEPTABLE 406HTTP_PROXY_AUTHENTICATION_REQUIRED 407HTTP_REQUEST_TIME_OUT 408HTTP_CONFLICT 409HTTP_GONE 410HT
40、TP_LENGTH_REQUIRED 411HTTP_PRECONDITION_FAILED 412HTTP_REQUEST_ENTITY_TOO_LARGE 413HTTP_REQUEST_URI_TOO_LARGE 414HTTP_UNSUPPORTED_MEDIA_TYPE 415HTTP_RANGE_NOT_SATISFIABLE 416HTTP_EXPECTATION_FAILED 417HTTP_UNPROCESSABLE_ENTITY 422HTTP_LOCKED 423HTTP_FAILED_DEPENDENCY 424HTTP_INTERNAL_SERVER_ERROR 50
41、0HTTP_NOT_IMPLEMENTED 501HTTP_BAD_GATEWAY 502源码网整理:源码网整理:HTTP_SERVICE_UNAVAILABLE 503HTTP_GATEWAY_TIME_OUT 504HTTP_VERSION_NOT_SUPPORTED 505HTTP_VARIANT_ALSO_VARIES 506HTTP_INSUFFICIENT_STORAGE 507HTTP_NOT_EXTENDED 510可以通过抛出apache.SERVER_RETURN 异常来返回错误码,并将 HTTP错误码作为异常的参数。例如:raise apache.SERVER_RETUR
42、N, apache.HTTP_FORBIDDEN处理器可以通过req.write()方法将文档发送到客户端。客户端提交的数据可以通过req.read()读取。注意:Python*Handler所在的目录必须已经在sys.path中,如果没有在配置段指定则不会在。一个请求处理器的例子:from mod_python import apachedef requesthandler(req):req.content_type=text/plainreq.write(Hello World!)return apache.OK4.3过滤(filter)处理器过滤处理器可以改变服务器的输入和输出。分两种:
43、输入和输出的过滤。现在mod_python仅提供请求级别(request-level)的过滤器,就是HTTP 的请求和回应体可以被过滤。未来的 apache将会提供连接级别(connection-level)的过滤器。过滤处理器接收一个filter对象做参数,请求对象可经由此得出 filter.req,但是所有的读写动作必须经由filter 的方法。过滤器在读到None时需要被关闭,代表流的结束。过滤器的返回值将会被忽略,但可用filter.pass_on()方法达到同样的效果。过滤器必须一开始就注册为PythonInputFilter 或PythonOutputFilter,然后添加到apa
44、che的配置标志Add/SetInputFilter或Add/SetOutputFilter 。如下例子把所有.py结尾文件用CAPITALIZE过滤器处理,如下是配置:PythonOutputFilter capitalize CAPITALIZE源码网整理:源码网整理:AddOutputFilter CAPTITALIZE .py如下是文件capitalize.py的内容:from mod_python import apachedef outputfilter(filter):s=filter.read()while s:filter.write(s.upper()s=filter.re
45、ad()if s is None:filter.close()书写过滤器时应该注意到过滤器随时都会被调用。过滤器无法控制数据的总量,也无法确定请求何时调用。比如对于一个请求,过滤器可能会执行一次或五次,并无法知晓调用何时结束和先后顺序。从一个read操作返回的EOS代表请求的结束。过滤器也可能在子请求的递归调用中。为避免数据多次被改变,经常的确保并不在子请求中,依靠req.main变量值。4.4连接(connection)处理器连接处理器处理连接到服务器的TCP连接。不同于HTTP处理器,连接处理器接收connection对象做参数。连接处理器可以用于实现协议。如下例配置:PythonConn
46、ectionHandler echo实现文件echo.py:from mod_python import apachedef connectionhandler(conn):while 1:conn.write(conn.readline()return apache.OK4.5apache-访问Apache 内部apache内部对Python的接口也恰好叫做apache,在mod_python包。提供了连接apache内部的重要功能,比如有用的函数,文档等(request对象也提供访问Apache内部的接口,但不在本节)。apache模块仅可作为mod_python 下的一个脚本来导入,因为
47、它依赖于mod_python 内建的_apache模块。最好按照如下导入:from mod_python import apache源码网整理:源码网整理:mod_python.apache模块定义了如下函数和对象,更多深入的信息查看Apache 文档。4.5.1函数log_error(message,level,server)Apache函数ap_log_error()的接口,message是错误信息,level是如下值:APLOG_EMERGAPLOG_ALERTAPLOG_CRITAPLOG_ERRAPLOG_WARNINGAPLOG_NOTICEAPLOG_INFOAPLOG_DEBUGAPLOG_NOERRNOserver是req.server对象的引用。如果没有指定则写入到缺省的日志,否则写入到对应虚拟服务器的日志中。当server没有指定时,日志级别也无效,日志级别是httpd在编译时指定的,经常为warn。如果拥有请求对象的引用,最好用req.log_error ,这样将会