在CGI脚本中调用urlopen时出现'连接被拒绝'错误

1 投票
1 回答
853 浏览
提问于 2025-04-16 07:33

我有一个用Python写的cgi脚本,它会检查一个进程是否在运行,如果没有找到这个进程,就会启动它。这个进程是一个基于web.py的网络服务器。在确认这个进程正在运行后,我会尝试向它发送一个网址请求。我的想法是把这个请求的结果返回给调用我cgi脚本的用户,简单来说,就是想把一个查询重定向到一个监听不同端口的本地网络服务器。

这段代码在我先手动启动服务器(findImgServerProcess返回True)并从命令行运行时效果很好,而不是通过cgi请求。但是如果我试图通过下面的cgi脚本来启动这个进程,我能走到urllib2.urlopen这个调用,但会抛出一个连接被拒绝的异常。我不明白为什么会这样?如果我打印出进程列表(rfindImgServerProcess()中),我可以看到这个进程确实存在,但为什么urllib2.urlopen会抛出异常呢?我已经把apache2网络服务器设置为使用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

一种可能性是,子进程在你尝试连接它之前还没有完全启动。你可以试着在调用urlopen之前加上一个time.sleep(5),这样可以等5秒再连接。

虽然这样做不是最好的办法,但至少可以帮助你判断这是不是问题所在。以后你可能会想要找一个更好的方法来检查HTTP服务是否在运行,并确保它一直在运行。

撰写回答