簡體   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