Wieder mal ein internal server error

Django, Flask, Bottle, WSGI, CGI…
Antworten
Mister
User
Beiträge: 36
Registriert: Freitag 24. Januar 2020, 21:58

... Ja ich Weiss ich mache immer noch mit cgi rum...
Ich habe eine Datenbank erstellt in der musikdaten gespeichert sind (Name, Künstler,pfad(wos gespeichert ist)). Dann habe ich eine HTML Seite mit einer such Zeile mit der man dann die Musik bekommen soll auf eine r dynamischen HTML Seite. Das cgi skript macht mit dem sqlite3 Modul halt eine Abfrage und erstellt dann die html Seite auf der man sich die Musik anhören kann. Ich bekomme aber einen internal server error.
Im error log heisst es "end of script output before headers". Und das sagt mir nicht was das Problem ist? Hat jmd eine Idee (der cgi code wird gleich nachgereicht)
Grüße
Mister
Mister
User
Beiträge: 36
Registriert: Freitag 24. Januar 2020, 21:58

Der Code vom cgi skript:

Code: Alles auswählen

import sqlite3,cgitb,cgi
cgitb.enable()
form=cgi.FieldStorage()
suche=form.getvalue("search")
question="""select titel,pfad from musik where (titel={}) or (album={}) or (künstler={})"""
conn=sqlite3.connect("/var/www/html/datenbanken/mxstream_musik.db")
c=conn.cursor()
c.execute(question.format(suche,suche,suche))
answer=list(c)
x=0
html=""
while x!=len(answer):
    html=(html+((ergebnisse[x])[0])+'<audio controls><source src="'+((ergebnisse[x])[1])+'" type="audio/mpeg"></audio><br/>')
    x=x+1


answer="""Content-type: text/html; charset=utf-8

<html>
<head><title>Ergebnisse</title></head>
<body>
Suche nach {}
{}
</body>
</html>"""
print(answer.format(suche,html))
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Mister: Wo definierst Du denn `ergebnisse`? Und man formatiert niemals nicht Werte in Zeichenketten mit SQL. Das ist potentiell ineffizient und eine Sicherheitslücke weil die Daten hier auch noch von aussen kommen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
... Ja ich Weiss ich mache immer noch mit cgi rum...
Na ja, manche brauchen halt länger, um auf den Pfad des Lichts zu gelangen.

Ist das der einzige Fehler? Oder kommen davor noch andere Fehlermeldung im Error Log?

Gruß, noisefloor
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Es ist auch nicht so wirklich schlau den gleichen Namen im gleichen Namensraum für völlig unterschiedliche Dinge zu verwenden.

Auf Modulebene gehört nur Code der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

`cgitb` sollte als allererstes importiert werden und sofort danach die `enable()`-Funktion aufgerufen werden. Sonst bekommt man keinen Traceback für Code der davor steht im Browser zu sehen.

Namen sollte man nicht kryptisch abkürzen. Wenn man `connection` meint, sollte man nicht `conn` schreiben. Und einbuchtabige Namen wie `c` für `cursor` gehen gar nicht wenn der Gütigkeitsbereich sich über mehr als einen Ausdruck erstreckt. Das Ding heisst `cursor`.

Die Datenbankverbindung sollte man auch sauber wieder schliessen. Bei `sqlite3` ist die Verbindung netterweise ein Kontextmanager und kann deshalb mit ``with`` verwendet werden.

Den Datenbankdateinamen würde man als Konstante definieren, damit ihn einfacher am Anfang des Programms ändern kann. Die Vorlage für die Antwort auch.

Die Klammern im SQL sind überflüssig und ich würde keine Umlaute in Namen verwenden.

Die ``while``-Schleife ist so überhaupt kein idiomatisches Python. Umständlicher kann man das ja kaum ausdrücken. Man kann in Python mit einer ``for``-Schleife *direkt* über die Elemente von Sequenzwerten iterieren, ohne den Umweg über einen Index. Der dann auch noch manuell hochgezählt wird und das damit auch noch vor die Schleife und ans Schleifenende verteilt wird.

Selbst die Liste braucht man nicht, weil man über `sqlite3.Cursor`-Objekte nach dem Ausführen einer Anfrage direkt iterieren kann. Sonst würde das ``list(c)`` auch gar nicht funktionieren, das nutzt diesen Umstand ja auch.

Zeichenketten durch wiederholtes addieren von neuen Teilen aufzubauen ist ineffizient. Idiomatisches Python sammelt die Teile in einer Liste und fügt die hinterher mit der `join()`-Methode von Zeichenketten zusammen.

Dass es ``format()`` gibt weisst Du ja bereits, warum stückelst Du dann das HTML so unübersichtlich mit ``+`` zusammen?

Wenn man Werte in HTML einbaut, muss man darauf achten das die nichts enthalten was in HTML eine Bedeutung hat, sonst macht man sich im besten Fall einfach nur die Seite kaputt und hat im schlechtesten Fall wieder eine Sicherheitslücke.

Man kann das mit `html.escape()` absichern. Dann muss man immer aufpassen was man schon escaped hat, damit man a) nichts vergisst, aber b) auch nichts doppelt escaped. Da ist es besser wenn man so etwas wie das `markupsafe`-Modul verwendet oder gleich eine Template-Engine wie Jinja2.

Zwischenstand (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
import cgitb

cgitb.enable()

import cgi
import html
import sqlite3

DB_FILENAME = "/var/www/html/datenbanken/mxstream_musik.db"
SONG_LINE_TEMPLATE = (
    '{title}'
    ' <audio controls><source src="{path}" type="audio/mpeg"></audio><br/>'
)
TEMPLATE = """Content-type: text/html; charset=utf-8

<!DOCTYPE html>
<html>
<head><title>Ergebnisse</title></head>
<body>
    <p>Suche nach {}</p>
    <p>{}</p>
</body>
</html>"""


def main():
    search_term = cgi.FieldStorage().getvalue("search")
    with sqlite3.connect() as connection:
        cursor = connection.cursor()
        cursor.execute(
            "SELECT titel, pfad"
            " FROM musik"
            " WHERE titel=? OR album=? OR kuenstler=?",
            search_term,
            search_term,
            search_term,
        )
        song_lines = "".join(
            SONG_LINE_TEMPLATE.format(
                title=html.escape(title), path=html.escape(path)
            )
            for title, path in cursor
        )

    print(TEMPLATE.format(html.escape(search_term), song_lines))


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Mister
User
Beiträge: 36
Registriert: Freitag 24. Januar 2020, 21:58

__blackjack__ hat geschrieben: Freitag 3. April 2020, 18:15 @Mister: Wo definierst Du denn `ergebnisse`?
Vielen Dank das war der fehler
Ich hatte aus irgendeinem Grund die variable umbenannt...
Und den Lösungsvorschlag schaue ich mir auch mal an. Mit diesen for Anweisungen habe ich mich nich nicht wirklich auseinandergesetzt aber es scheint als würde sie viele meiner Probleme lösen können daher mach ich das auch mal
noisefloor hat geschrieben: Freitag 3. April 2020, 18:17 Na ja, manche brauchen halt länger, um auf den Pfad des Lichts zu gelangen.
:D ich mach ja schon
Danke für die Antworten
Mister
User
Beiträge: 36
Registriert: Freitag 24. Januar 2020, 21:58

Das hat jetzt garnicht mehr mit dem cgi skript zu tun: ich habe auf meinem rpi Musik und ich habe einige mp3dateien gelöscht da ich sie nicht mehr benötigt habe. Nur zeigt der dateimanager sie immer noch an, nur wenn man sie öffnen will gibt es eine Fehlermeldung dass die Datei nicht gefunden wurde
Was ist das?
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Mister: Ein kaputtes Dateisystem? Oder Du hast die ausserhalb des Dateimanagers gelöscht und musst dessen Sicht der Dinge mal aktualisieren‽
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Mister
User
Beiträge: 36
Registriert: Freitag 24. Januar 2020, 21:58

__blackjack__ hat geschrieben: Freitag 3. April 2020, 20:28 @Mister: Ein kaputtes Dateisystem? Oder Du hast die ausserhalb des Dateimanagers gelöscht und musst dessen Sicht der Dinge mal aktualisieren‽
OK wie repariere ich es/aktualisiere den manager?
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@Mister: warum entführst du denn deinen eigenen Thread mit einer 2., völlig anderen Frage? Das ist ja noch schlechterer Stil als in Python ein CGI Skript zu schreiben...

Der Fehler mit der Variablen sollte auch im Log auftauchen? Wenn du schon deinen CGI Masochismus betreibst, dann lohnt es sich immer mehr als nur die letzte Zeile im Log zu lesen.

Gruß, noisefloot
Mister
User
Beiträge: 36
Registriert: Freitag 24. Januar 2020, 21:58

__blackjack__ hat geschrieben: Freitag 3. April 2020, 18:15 @Mister: Wo definierst Du denn `ergebnisse`?
__blackjack__ hat den Fehler entdeckt also bin ich mit dem cgi Problem fertig nur bei dessen Anwendung brauche ich diese Dateien und es hat halt nicht funktioniert deswegen habe ich mich erdreistet hier noch eine Frage zu stellen
Sorryyy
Antworten