【问题标题】:Premature end of script headers for unknown reason脚本头因未知原因提前结束
【发布时间】:2015-09-17 11:13:39
【问题描述】:

每当我通过提交表单来调用下面的 cgi 脚本时,我都会收到内部服务器错误,并且服务器日志显示以下行: 脚本头过早结束:LoopF​​inderRetrieval.cgi,referer:http://loopfinder-prod-01.uit.tufts.edu/LoopFinderRetrieval.html

简而言之,cgi 文件的目的是转到提交时给出的运行 ID 指示的文件夹,打开并读取名为 JobStatus.txt 的文件,然后根据结果执行操作。这可以是向用户返回一个特定的错误,或者给他们他们的结果。据我了解,如果我是这样的话,我看到的错误将是由以下原因引起的,例如省略该行:

"Content-type:text/html\r\n\r\n"

但是该行存在,并且在同一服务器上使用完全相同的 PrintHeader() 和 PrintFooter() 函数的另一个 CGI 脚本正在运行而没有错误。任何人都可以看到任何可能导致这种情况的明显错误吗?如果不是,我读到的内容表明这可能是权限问题。在这种情况下,我将不得不联系管理员并修复它,但我不想这样做,除非我知道这是问题所在。谢谢。

#!/usr/bin/python2.6

# Import modules for CGI handling 
import cgi, cgitb
import os 
cgitb.enable()

#Functions to automatically print HTML headers and footers.
def PrintHeader():
    print "Content-type:text/html\r\n\r\n"
    print "<html>"
    print "<head>"
    print "<title>LoopFinder Running</title>"
    print "</head>"
    print "<body>"
def PrintFooter():
    print "</body>"
    print "</html>"

# Create instance of FieldStorage 
form = cgi.FieldStorage() 
ID_Number = form.getvalue('IDNum')

with open('/loopfinder_data/RunData/%s/JobStatus.txt' % ID_Number, 'r') as pre_textfile:
    textfile = pre_textfile.read()
    if textfile[0] == 'Running':
        PrintHeader()
        print '<h2>Your run is not complete. Please check back later.</h2>'
        PrintFooter()
    if textfile[0] == 'Stopped':
        PDBID = textfile[3]
        if textfile[1] == 'PDBError':
            PrintHeader()
            print '<h2>We were unable to download the PBDID you entered, which was %s</h2>' % PDBID
            print '<h2>Please check that this PDBID exists before trying again.</h2>'
            PrintFooter()
        elif textfile[1] == 'ChainCountError':
            PrintHeader()
            print '<h2>We were unable to either download or open the PBDID you entered, which was %s</h2>' % PDBID
            print '<h2>Please check that this PDBID exists before trying again.</h2>'
            PrintFooter()       
        elif textfile[1] == 'SingleChainError':
            PrintHeader()
            print '<h2>It appears that your PDB structure of interest contains only one chain.</h2>'
            print '<h2>LoopFinder requires a multi-chain interface from which to calculate energy values.</h2>'
            PrintFooter()
        elif textfile[1] == 'LoopFinderError':
            PrintHeader()
            print '<h2>LoopFinder experienced an unknown error while analyzing your PDB file.</h2>'
            print '<h2>Leave a comment including your run ID and we will try to solve this issue.</h2>'
            PrintFooter()   
        elif textfile[1] == 'PyRosettaError':
            PrintHeader()
            print '<h2>PyRosetta experienced an unknown error while analyzing your PDB file.</h2>'
            print '<h2>Leave a comment including your run ID and we will try to solve this issue.</h2>'
            PrintFooter()                   
    if textfile[0] == 'Completed':
        PrintHeader()
        print '<a href="http://<url_redacted>/loopfinder_data/RunData/%s/results/%s_Results.zip">\
Click here to download your results.</a>' % (ID_Number,ID_Number)
        PrintFooter()

【问题讨论】:

  • 你最终弄明白了吗? :)
  • 不怕。我已经向服务器的根级管理员提交了支持票(它由我的大学托管,我只是一个 httpd 管理员)。当/如果我知道原因是什么,我打算回来说出来,以帮助未来的谷歌人,但现在我仍然在徘徊。

标签: python web cgi python-2.6


【解决方案1】:

好的,事实证明我们这里有代码错误,而不是权限错误。 其实挺尴尬的。更正后的代码如下。第一个问题是我使用file.read() 尝试逐行读取文件。我应该一直使用file.readlines(),并另外将行更改为[line.rstrip('\n') for line in pre_textfile] 以删除换行符。第 33 行还有一个索引错误,我已更正。尚不清楚的是为什么我无法让任何类型的日志记录为我工作,这可以为几个人节省相当多的时间。

!/usr/bin/python2.6

# Import modules for CGI handling 
import cgi, cgitb
import os 
cgitb.enable()

#Functions to automatically print HTML headers and footers.
def PrintHeader():
    print "Content-type:text/html\r\n\r\n"
    print "<html>"
    print "<head>"
    print "<title>LoopFinder Running</title>"
    print "</head>"
    print "<body>"
def PrintFooter():
    print "</body>"
    print "</html>"

# Create instance of FieldStorage 
form = cgi.FieldStorage() 
ID_Number = form.getvalue('IDNum')

with open('/loopfinder_data/RunData/%s/JobStatus.txt' % ID_Number, 'r') as pre_textfile:
    textfile = [line.rstrip('\n') for line in pre_textfile]
    if textfile[0] == 'Running':
        PrintHeader()
        print '<h2>Your run is not complete. Please check back later.</h2>'
        PrintFooter()
    if textfile[0] == 'Stopped':
        PDBID = textfile[2]
        if textfile[1] == 'PDBError':
            PrintHeader()
            print '<h2>We were unable to download the PBDID you entered, which was %s</h2>' % PDBID
            print '<h2>Please check that this PDBID exists before trying again.</h2>'
            PrintFooter()
        elif textfile[1] == 'ChainCountError':
            PrintHeader()
            print '<h2>We were unable to either download or open the PBDID you entered, which was %s</h2>' % PDBID
            print '<h2>Please check that this PDBID exists before trying again.</h2>'
            PrintFooter()       
        elif textfile[1] == 'SingleChainError':
            PrintHeader()
            print '<h2>It appears that your PDB structure of interest contains only one chain.</h2>'
            print '<h2>LoopFinder requires a multi-chain interface from which to calculate energy values.</h2>'
            PrintFooter()
        elif textfile[1] == 'LoopFinderError':
            PrintHeader()
            print '<h2>LoopFinder experienced an unknown error while analyzing your PDB file.</h2>'
            print '<h2>Leave a comment including your run ID and we will try to solve this issue.</h2>'
            PrintFooter()   
        elif textfile[1] == 'PyRosettaError':
            PrintHeader()
            print '<h2>PyRosetta experienced an unknown error while analyzing your PDB file.</h2>'
            print '<h2>Leave a comment including your run ID and we will try to solve this issue.</h2>'
            PrintFooter()                   
    if textfile[0] == 'Completed':
        PrintHeader()
        print '<a href="http://<url_redacted>/loopfinder_data/RunData/%s/results/%s_Results.zip">\
Click here to download your results.</a>' % (ID_Number,ID_Number)
        PrintFooter()

【讨论】:

  • 哦!错过了read 而不是readlines :) 至少我找到了错误的位置! :P 很高兴你找到它。日志记录非常宝贵。
【解决方案2】:

错误信息很模糊,但基本上意味着输出在标头结束之前就结束了。就像你说的那样。

如果您的脚本崩溃了怎么办。然后不会打印任何标题,我猜可能会发生此错误。

在您的脚本中添加一些logging 以更好地了解实际发生的情况。例如,您可以将整个脚本包装在 try 块中并记录任何异常。

你有很多重复的代码,也许你稍微重构一下你的脚本,错误会更容易找到。在我看来,页眉和页脚总是被打印出来,例如,也许只能打印一次。

我的猜测是当您的文件太短时脚本会崩溃。当您点击一行带有textfile[1] == something 并且该文件只有一行时,您将收到以下异常:

IndexError: list index out of range

但这只是一个猜测,正确的日志会让你知道。

编辑:

我看到您正在使用cgitb。也许使用此模块的日志记录。尝试禁用浏览器输出并将任何异常发送到日志文件。将cgitb.enable() 更改为:

cgitb.enable(display=0, logdir='/tmp/')

如果您使用cgitb,则无需将程序包装在try 块中,实际上这两种方法可能会相互干扰。

【讨论】:

  • 感谢您的建议。我很确定您的猜测不正确,因为创建 JobStatus.txt 的程序不会将其状态从“正在运行”更改为“已停止”而不在其下方添加两行。我尝试按照this answer by nosklo 中的描述实现一些基本日志记录,但没有看到任何回溯打印到日志中,只有第一个 Debug:root: 行。我越来越开始认为这是服务器配置而不是脚本问题。谢谢。
  • 如果您在日志中看到 any 输出,这意味着您的脚本至少正在运行。您之前提到的权限问题可能在脚本开始之前就结束了 cgi 执行。
猜你喜欢
  • 1970-01-01
  • 2012-08-30
  • 2019-05-27
  • 1970-01-01
  • 2014-04-07
  • 2016-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多