Преждевременное завершение заголовков скрипта по неизвестной причине

Всякий раз, когда я вызываю приведенный ниже сценарий cgi, отправляя ему форму, я получаю внутреннюю ошибку сервера, а в журнале сервера отображается строка: Преждевременное завершение заголовков сценария: LoopFinderRetrieval.cgi, referer: http://loopfinder-prod-01.uit.tufts.edu/LoopFinderRetrieval.html

Короче говоря, файл cgi предназначен для перехода в папку, обозначенную идентификатором запуска, указанным во время отправки, открытия и чтения файла с именем JobStatus.txt, а затем выполнения действия на основе результата. Это может либо возвращать пользователю конкретную ошибку, либо давать им результаты. Насколько я понимаю, ошибка, которую я вижу, была бы вызвана, если бы я, например, пропустил строку:

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

но строка присутствует, и другой сценарий CGI, использующий те же самые функции PrintHeader () и PrintFooter () на том же сервере, выполняется без ошибок. Кто-нибудь может увидеть какие-либо явные ошибки, которые могут быть причиной этого? Если нет, то то, что я прочитал, указывает на то, что это может быть проблема с разрешениями. В этом случае мне придется связаться с администраторами и исправить это, но я не хочу этого делать, если я не знаю, в чем проблема. Спасибо.

#!/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()

person Michael Bird    schedule 30.06.2015    source источник
comment
Вы в конце концов поняли это? :)   -  person André Laszlo    schedule 02.07.2015
comment
Не боюсь. Я отправил билеты в службу поддержки администраторам корневого уровня сервера (он находится в моем университете, а я всего лишь администратор httpd). Когда / если я узнаю, в чем была причина, я планирую вернуться, чтобы сказать это, чтобы помочь будущим гуглерам, но сейчас я все еще плаваю в подвешенном состоянии.   -  person Michael Bird    schedule 03.07.2015


Ответы (2)


Сообщение об ошибке достаточно расплывчатое, но в основном это означает, что вывод закончился до того, как закончились заголовки. Как ты и сказал.

Что делать, если ваш скрипт выйдет из строя. Тогда никакие заголовки не будут напечатаны и, я думаю, может возникнуть эта ошибка.

Добавьте в свой сценарий ведение журнала, чтобы лучше понять, что на самом деле происходит. Вы можете, например, заключить весь сценарий в блок try и зарегистрировать любое исключение.

У вас много повторяющегося кода, может быть, если вы немного реорганизуете свой скрипт, ошибку будет легче найти. Мне кажется, что верхние и нижние колонтитулы печатаются всегда, например, может быть, это можно сделать только один раз.

Я предполагаю, что скрипт вылетает, когда ваш файл слишком короткий. Когда вы нажимаете строку, на которой есть textfile[1] == something, а в файле только одна строка, вы получаете следующее исключение:

IndexError: list index out of range

Но это всего лишь предположение, правильное ведение журнала даст вам знать.

Изменить:

Я вижу, что вы используете cgitb. Может быть, использовать логирование из этого модуля. Попробуйте отключить вывод браузера и вместо этого отправить любое исключение в файл журнала. Измените cgitb.enable() на:

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

Вам не нужно заключать вашу программу в try блок, если вы используете cgitb, на самом деле оба метода, вероятно, будут мешать.

person André Laszlo    schedule 30.06.2015
comment
Спасибо за предложения. Я почти уверен, что ваше предположение здесь неверно, потому что программа, которая создает JobStatus.txt, не изменит свой статус с «Выполняется» на «Остановлен» без добавления двух строк под ним. Я попытался реализовать базовое ведение журнала, как описано в этом ответе от nosklo, но Я не вижу никакой трассировки, напечатанной в журнале, только первую строку Debug: root:. Я все больше начинаю думать, что это скорее конфигурация сервера, чем проблема скрипта. Спасибо. - person Michael Bird; 30.06.2015
comment
Если вы видите любой вывод в журнале, это означает, что ваш скрипт по крайней мере запущен. Проблема с разрешениями, о которой вы упоминали ранее, вероятно, завершает выполнение cgi еще до запуска скрипта. - person André Laszlo; 01.07.2015

Хорошо, получается, что здесь есть ошибки кода, а не ошибка разрешений. На самом деле довольно неприятные. Исправленный код ниже. Первая проблема заключается в том, что я использовал 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()
person Michael Bird    schedule 08.07.2015
comment
Ой! Пропустил read вместо readlines :) По крайней мере, я правильно указал местоположение ошибки! : P Рада, что вы его нашли. Ведение журнала неоценимо. - person André Laszlo; 08.07.2015