【问题标题】:SOLVED - Python CGI accessing mySQL: end of script output before headers已解决 - Python CGI 访问 mySQL:头文件前的脚本输出结束
【发布时间】:2021-07-14 04:31:04
【问题描述】:

我无法让 Python CGI 脚本在虚拟 Ubuntu 18 服务器上运行的 apache2 网络服务器上正确执行。托管服务提供商是 DreamCompute,如果这很重要的话。我得到了在var/www/html/apps/cgi-bin/ 下工作的 CGI 脚本。 helloworld.py 和 helloworld.pl 在 SSH 终端和浏览器 (Microsoft Edge) 中都能正常执行。

给我带来麻烦的脚本是一个 Python 脚本,它访问 MySQL 数据库,从中读取数据,然后使用该数据填充一些列表并随机生成一些简单的输出(桌面 RPG 具有随机效果的魔法咒语) .

拼写生成器脚本在 SSH 中也可以正常执行,但是当我尝试在浏览器中查看它时会引发 500 内部服务器错误。 apache 错误日志告诉我问题是end of script output before headers。我环顾四周,但找不到任何有类似问题和配置的人。

编辑:错误日志中的完整条目是: [Tue Apr 20 00:20:25.324101 2021] [cgid:error] [pid 17275:tid 140105176721152] [client 2607:fea8:1d41:b800:7dca:305:b11a:447f:62505] End of script output before headers: spell_generator.py, referer: http://my.website/apps/cgi-bin/

在添加和删除部分 Python 脚本以查看它在浏览器中的行为之后,我相信我已经隔离了问题:连接到 MySQL 数据库的脚本部分。该数据库也托管在同一个 Ubuntu 虚拟机上,其中肯定包含正确类型的数据(只是字符串和 ID;没什么特别的)。

这是 Python 代码。我已经删除了一些文档 cmets,但它应该非常简单:

#!/usr/bin/python3
print("Content-type: text/html\n\n");
# The above two lines are boilerplate to ensure no print statements cause 
# problems later in the program.

# Import statements
import cgi
import cgitb
cgitb.enable();
from random import choice
import mysql.connector
import sys
from enum import Enum


# Initialize enums for system comparison
class Ruleset(Enum):
    GENERIC = "GENERIC"
    GENERIC_DB = "generic_attributes"
    DND_5 = "DND5e"
    DND_5_DB = "dnd5e_attributes"
    PATHFINDER_1 = "PF1e"
    PATHFINDER_1_DB = "pathfinder1e_attributes"


# Determine what system to use, generic by default
spellSystem = Ruleset.GENERIC.value;

if (len(sys.argv)) > 1:
    if (sys.argv[1] == Ruleset.DND_5.value):
        spellSystem = Ruleset.DND_5.value;
        
    if (sys.argv[1] == Ruleset.PATHFINDER_1.value):
        spellSystem = Ruleset.PATHFINDER_1.value;
        

# === PROBLEM HERE ===

# Initialize SQL cursor, defaulting to generic
if spellSystem == Ruleset.DND_5.value:
    spellDB = mysql.connector.connect(
        host = "localhost",
        user = "RemoteUser",
        password = "password",
        database = Ruleset.DND_5_DB.value
    )
elif spellSystem == Ruleset.PATHFINDER_1.value:
    spellDB = mysql.connector.connect(
        host = "localhost",
        user = "RemoteUser",
        password = "password",
        database = Ruleset.PATHFINDER_1_DB.value
    )
else:
    spellDB = mysql.connector.connect(
        host = "localhost",
        user = "RemoteUser",
        password = "password",
        database = Ruleset.GENERIC_DB.value
    )
spellCursor = spellDB.cursor();
spellCursor.execute("SELECT ElementName FROM Element");
listHolder = spellCursor.fetchall();

# === CODE BELOW DOES NOT CAUSE PROBLEMS ===

#
# [logic that uses the SQL data]
#

# Output HTML page
print("<html> <head> <title>TEST - Magic Spell Generator</title> <link rel='stylesheet' href='../../css/style.css'> </head>");
print("<body> body contents");
print("</body>");
print("</html>");

RemoteUser 是 SQL 服务器上的用户帐户,“外部”(非根)程序使用它来访问数据库。实际部署的脚本中的password 是加密安全密码。

我不是 Python 专家,但是当我从 SSH 终端执行代码时,代码运行没有问题,所以我不认为糟糕的代码是罪魁祸首(尽管我肯定是错的)。这是我已经尝试过的事情的列表:

  • 检查是否有太多活动 SQL 连接(似乎只有一个,即 root 用户)。
  • 确保脚本文件具有正确的权限(chmod 755,与其他文件相同)。
  • 确保已安装必要的 Python 模块(它们已安装,并且 Python-MySQL 连接器是与我正在使用的 Python 版本配合使用的最新版本)。
  • 正在重新启动 apache2。

我今天大部分时间都在寻找答案。欢迎任何帮助或潜在线索。

【问题讨论】:

  • apache 错误日志应该说明的不仅仅是您在问题中引用的内容,还应该指出潜在的错误。没有它,我们只能猜测。
  • @Shadow 我编辑了帖子以显示完整的错误日志条目。可以的话就看看吧。

标签: python mysql apache cgi


【解决方案1】:

原来问题实际上并不是试图访问 SQL 数据库的脚本,这是我在 SSH 终端中正确运行它时发现的(./spell_generator.py 而不是python3 spell_generator.py)。由于segmentation fault (core dumped)而崩溃,这暗示这是一个代码问题而不是配置问题。

经过一番搜索,我找到了Database connectivity through MySQL connector Python with CGI is not working,这让我找到了真正的罪魁祸首:我以错误的顺序导入模块。我更改了导入语句,现在import mysql.connector 是第一个,并且脚本运行完美。

它不应该有所作为,但确实如此。我很高兴。

【讨论】:

    猜你喜欢
    • 2015-04-04
    • 2018-05-30
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多