繁体   English   中英

Python CGI 访问 mySQL:脚本结束 output 在标题之前

[英]Python CGI accessing mySQL: end of script output before headers

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

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

拼写生成器脚本在 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 代码。 我删除了一些文档注释,但它应该非常简单:

#!/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 服务器上的用户帐户,“外部”(非 root)程序使用它来访问数据库。 实际部署脚本中的password是加密安全密码。

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

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

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

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

经过一番搜索,我发现通过 MySQL 连接器 Python 与 CGI 的数据库连接不起作用,这让我找到了真正的罪魁祸首:我以错误的顺序导入模块。 我更改了导入语句,因此import mysql.connector现在是第一个,并且脚本运行完美。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM