inetd will nicht ;(

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Also ich bin irgendwie zu dumm... Hab schon einiges ausprobiert, aber dennoch bekomme ich nicht mal ein kleinen Test mit inetd hin ;(

Ich erhalte immer, den für mich nichts sagenden, Fehler "server failing (looping), service terminated" in /var/log/syslog oder /var/log/daemon.log

Meine Config:

/etc/services

Code: Alles auswählen

inetdtest	9001/tcp
/etc/inetd.conf

Code: Alles auswählen

inetdtest	stream	tcp	wait	root	/usr/bin/python	/daten/www/PyAdmin/inetd_test.py
inetd_test.py

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: ISO-8859-1 -*-

log = file('/daten/www/PyAdmin/inetd.log','a')
log.writeline("OK")
log.close()

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Aha, hab mal "wait" auf "nowait" geändert... Nun erhalte ich im Browser allerdings immer nur den folgenden Text:

Code: Alles auswählen

  File "<stdin>", line 2
    Host: 192.168.6.2:9002
        ^
SyntaxError: invalid syntax
Das wahrscheinlich aber nicht's mit meinem "inetd_test.py"-Skript zu tun, selbst wenn die Datei leer ist, kommt der Fehler...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Wieso bekommst du in Browser den Fehler? Auf das Script musst du mit netcat zugreifen, damit du sinnvolle Ergebnisse bekommst. Das gibt dir dann genau aus, was das Script beim Stdout heruasgelassen hat (in deinem Fall nichts, also macht es auch keinen sinn mit einem HTTP Client, in deinem Fall einen Browser da irgendetwas zu machen).
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Das war ja nur ein Test, um zu sehen, ob das Skript überhaupt ausgeführt wird ;)

Es geht jetzt... Nur nicht immer... d.h. wenn ich im Browser einen reload mache, kommt bei ca. jedem zweiten reload mal die Meldung "Das Dokument enthält keine Daten." :(

/etc/inetd.conf

Code: Alles auswählen

inetdtest	stream	tcp	nowait	root	/daten/www/PyAdmin/inetd_test.py inetd_test
inetd_test.py

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: ISO-8859-1 -*-

import sys, time


#~ while raw_input(): pass

sys.stdout.write("HTTP/1.1 200 OK")
sys.stdout.write("Content-Type: text/html\n\n")

sys.stdout.write("HELLO WORLD!\n")

sys.stdout.write( time.asctime() )

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

jens hat geschrieben:Es geht jetzt... Nur nicht immer...
Aha! Es muß ein raw_input() gemacht werden, damit wird der "Request-Text" eingelesen, ohne dem funktioniert es nicht immer... Ich denke, weil stdin nicht geleert wird?!?

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: ISO-8859-1 -*-

import os,sys, time

html_request = raw_input()

print "HTTP/1.1 200 OK"
print "Content-Type: text/html\n"

print "HELLO WORLD!"

print time.asctime()

print html_request

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ich verweise immer noch auf mein inetd Script, es macht zwar kein HTTP, aber es lies doch von stdin ein.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Jep, dafür hab ich nun auch was gebastelt:

Code: Alles auswählen

for i in xrange(20):
    line = sys.stdin.readline()
    if line == "\r\n": break
    print line,"<br>"
Dumm ist nur, wenn kein "\r\n", aber ich gehe mal von aus, das das dem Standard entspricht und somit immer bei einem richtigen HTTP-Header vorhanden ist...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

So, nun hab ich mal was gebastelt... Es erscheint eine Webseite mit einem Formular, um zu testen, ob die GET/POST daten richtig verarbeitet werden...

inetd_test.py

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: ISO-8859-1 -*-

import os,sys


class CGI_data_Parser:
    """
    parsen/speichern und abrufen der POST/GET Daten
    """
    def __init__( self ):
        self.data = {}
        self.content_length_bytes = 0

    def content_length( self, content_length_line ):
        "Holt sich die POST-Daten aus dem HTML-Header"
        self.content_length_bytes = int( content_length_line.split(":")[1] )

    def parse_POST_data( self ):
        "Eine POST-Zeile in self.data speichern"

        #~ sys.stdin.readline() # Leerzeile zwischen Header und POST-Daten überspringen
        POST_data = sys.stdin.read( self.content_length_bytes )

        for i in POST_data.split("&"):
            item = i.split("=")
            if len(item) == 2:
                self.data[ item[0] ] = item[1]
            else:
                print "Fehler:", item

    def parse_GET_data( self, GET_data_line ):
        "ermittelt die GET-Daten aus der Request-Zeile und speicher sie in self.data"

        # GET-Daten vorhanden ?
        if not "?" in GET_data_line: return

        GET_data = GET_data_line.split("?")[1]
        GET_data = GET_data.rsplit(" ",1)[0]

        for item in GET_data.split("&"):
            item = item.split("=")
            if len(item) == 2:
                self.data[ item[0] ] = item[1]
            else:
                self.data[ item[0] ] = ""

    def get_data( self ):
        return self.data


class environ_data_Parser:
    """
    Speichert die environ-Daten
    """
    def __init__( self ):
        self.data = {}

    def parse( self, line ):
        line = line.split(":")
        line = [i.strip() for i in line]
        if len(line) == 2:
            self.data[ line[0] ] = line[1]

    def get_data( self ):
        return self.data


if __name__ == "__main__":
    print "HTTP/1.1 200 OK"
    print "Content-Type: text/html\n"

    print "<hr><pre>"

    MyCGIdata       = CGI_data_Parser()
    MyEnvironData   = environ_data_Parser()


    for i in xrange(20):
        line = sys.stdin.readline()
        if line == "\r\n": break

        MyEnvironData.parse( line )

        if "POST" in line:
            MyCGIdata.parse_GET_data( line )
        elif "content-length" in line.lower():
            MyCGIdata.content_length( line )
        print line.replace("\n","")

    MyCGIdata.parse_POST_data()

    print "\n*** CGI-daten ***"
    for k,v in MyCGIdata.get_data().iteritems():
        print k,":",v

    print "\n*** Environ-Data ***"
    for k,v in MyEnvironData.get_data().iteritems():
        print k,":",v

    print "</pre><hr>"

    print """<form name="form" id="form" method="post" action="inetd_test.py?GET1=jo&GET2=buh&biii">
        <input name="feld1" type="text" size="20" />
        <input name="feld2" type="text" size="20" /></p>
        <input type="submit" name="Submit" value="Senden" />
    </form>"""
Dabei ist mir aufgefallen, das man besser mit if "content-length" in line.lower() abfragen sollte... Zwar spuckt Firefox und IE richtig "Content-Length" aus, aber wenn man mit Python's urllib2.urlopen() eine Anfrage stellt, wird "Content-length" geschrieben...

EDIT:
Das ganze funktioniert nun, s. http://python.sandtner.org/viewtopic.php?p=17056#17056

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten