如何在mod_python中打开并传输文件?

1 投票
2 回答
867 浏览
提问于 2025-04-15 11:17

我刚接触mod_python和Apache,现在在处理GET请求后返回文件给用户时遇到了麻烦。我现在的设置非常简单,原本希望能直接打开文件并把它写入响应中:

from mod_python import apache

def handler(req):
    req.content_type = 'application/octet-stream'
    fIn = open('response.bin', 'rb')
    req.write(fIn.read())
    fIn.close()
    return apache.OK

但是,当我使用open()时却出现错误,提示文件不存在(尽管我检查了好几遍,确认文件是存在的)。无论是用相对路径还是绝对路径都会出现这个问题。

我有两个问题:

  • 为什么open()找不到正确的文件?
  • 从文件系统返回文件的最佳方法是什么?(我问这个是想确认我没有错过更好的方法来使用mod_python返回文件。)

谢谢

编辑:在找到这个讨论串后: http://www.programmingforums.org/thread12384.html,我发现如果我把文件移动到家目录以外的其他目录,open()就能正常工作(我之前是从/home/myname/httpdocs中别名,但如果使用/data就可以)。你知道为什么这样可以吗?

编辑2:这是我调试错误的一部分,按要求提供:

MOD_PYTHON ERROR

ProcessId:      13642
Interpreter:    '127.0.1.1'

ServerName:     '127.0.1.1'
DocumentRoot:   '/var/www'

URI:            '/test/mptest.py'
Location:       None
Directory:      '/home/myname/httpdocs/'
Filename:       '/home/myname/httpdocs/mptest.py'
PathInfo:       ''

Phase:          'PythonHandler'
Handler:        'mptest'

Traceback (most recent call last):

  File "/usr/lib/python2.5/site-packages/mod_python/importer.py", line 1537, in HandlerDispatch
    default=default_handler, arg=req, silent=hlist.silent)

  File "/usr/lib/python2.5/site-packages/mod_python/importer.py", line 1229, in _process_target
    result = _execute_target(config, req, object, arg)

  File "/usr/lib/python2.5/site-packages/mod_python/importer.py", line 1128, in _execute_target
    result = object(arg)

  File "/home/myname/httpdocs/mptest.py", line 13, in handler
    fIn = open('/home/myname/httpdocs/files/response.bin', 'rb')

IOError: [Errno 2] No such file or directory: '/home/myname/httpdocs/files/response.bin'

2 个回答

0

你能把你遇到的错误信息贴出来吗?

这很可能是权限错误(如果你尝试使用文件的完整路径)。记住,脚本是以运行网页服务器的用户身份来执行的——所以你访问文件时通常是以“www-data”或“nobody”的身份。

也检查一下文件夹 /home/myname/httpdocs/files/ 的权限。这个文件夹应该对 www-data 用户有 +x 权限:

$ mkdir blah
$ echo works > blah/response.bin
$ chmod 000 blah/
$ cat blah/response.bin
cat: blah/response.bin: Permission denied
$ chmod +x blah/
$ cat blah/response.bin
works

你可以通过以下方式排除 Apache 或你的脚本的问题:

you:~$ sudo su - www-data
www-data:~$ file /home/myname/httpdocs/files/response.bin

(su 命令可能不管用,这取决于你使用的操作系统或发行版,比如 OS X 不允许你以它的 www 用户身份登录)

除了文件权限,为什么脚本还依赖于你主文件夹里的一个文件呢?能不能把 response.bin 移到和你的 Python 脚本同一个文件夹里?或者干脆放到数据库里?(也许用 SQLite?这可能不必要或过于复杂,具体要看 response.bin 里的内容以及它变化的频率)

4

要调试这种问题,你需要从正在运行的mod_python实例中收集所有信息。

别再反复“检查它是否存在”了。有些假设是不正确的。

可以尝试这样做来获取一些调试信息。

def handler(req):
    req.content_type = 'text/plain'
    req.write(os.environ)
    req.write(os.getcwd())
    # etc.
    return apache.OK

补充说明

现在你对重要的内容有了一些了解。在这种情况下,可能是权限问题——你需要使用os.filestat来确认一下。Apache以几乎没有可用权限的用户身份运行mod_python。Apache也不喜欢链接,但这不应该影响mod_python。如果你的文件没有“所有人可读”权限,并且不在正确的目录下,你就会遇到问题。

你可能想考虑切换到mod_wsgi

撰写回答