从cgi脚本中调用urlopen,“连接被拒绝”错误

时间:2010-11-24 14:24:26

标签: python cgi urllib2

我有一个python cgi脚本,用于检查进程是否处于活动状态,如果找不到此进程,则启动它。该过程本身是一个Web服务器(基于web.py)。确保进程正在运行后,我尝试向其发出url请求。我的想法是将此请求的结果重定向到我的cgi脚本的请求者,基本上我想将查询重定向到侦听不同端口的本地Web服务器。

如果我从shell启动服务器(findImgServerProcess返回True),而不是使用cgi请求,则此代码可以正常工作。但是,如果我尝试通过下面的cgi脚本启动该过程,我确实会得到urllib2.urlopen调用,这会引发拒绝连接的异常。 我不明白为什么? 如果我打印进程列表(r中的findImgServerProcess()),我可以看到进程在那里,但为什么urllib2.urlopen会抛出异常?我将apache2 webserver设置为使用suexec。

以下是代码:

#!/usr/bin/python
import cgi, cgitb
cgitb.enable()
import os, re
import sys
import subprocess

import urllib2
urlbase = "http://localhost:8080/getimage"
imgserver = "/home/martin/public_html/cgi-bin/stlimgservermirror.py" # this is based on web.py

def findImgServerProcess():
    r = subprocess.Popen(["ps", "aux"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0]
    return re.match(".*%s" % os.path.split(imgserver)[-1], r, re.DOTALL)

def ensureImgServerProcess():
    if findImgServerProcess():
        return True

    os.environ['LD_LIBRARY_PATH'] = '/home/martin/lib'
    fout = open("/dev/null", "w")
    ferr = fout
    subprocess.Popen([sys.executable, imgserver], stdout=fout, stderr=subprocess.STDOUT)
    # now try and find the process
    return findImgServerProcess() != None

def main():
    if not ensureImgServerProcess():
        print "Content-type: text/plain\n"
        print "image server down!"
        return

    form = cgi.FieldStorage()
    if form.has_key("debug"):
        print "Content-type: text/plain\n"
        print os.environ['QUERY_STRING']
    else:
        try:
            img = urllib2.urlopen("%s?%s" % (urlbase, os.environ['QUERY_STRING'])).read()
        except Exception, e:
            print "Content-type: text/plain\n"
            print e
            sys.exit()
        print "Content-type: image/png\n"
        print img

if __name__ == "__main__":
    main()

1 个答案:

答案 0 :(得分:0)

可能的情况是,在尝试连接子进程之前,子进程没有机会完全启动。要测试这一点,请在调用urlopen之前尝试添加time.sleep(5)。

这不太理想,但至少会帮助你弄清楚这是不是问题。在未来,您可能希望设置一种更好的方法来检查HTTP守护程序是否正在运行并保持运行。