Seite 1 von 1

inetd will nicht ;(

Verfasst: Donnerstag 24. März 2005, 13:46
von jens
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()

Verfasst: Donnerstag 24. März 2005, 13:53
von jens
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...

Verfasst: Donnerstag 24. März 2005, 14:14
von Leonidas
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).

Verfasst: Donnerstag 24. März 2005, 14:28
von jens
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() )

Verfasst: Donnerstag 24. März 2005, 14:32
von jens
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

Verfasst: Donnerstag 24. März 2005, 15:09
von Leonidas
Ich verweise immer noch auf mein inetd Script, es macht zwar kein HTTP, aber es lies doch von stdin ein.

Verfasst: Donnerstag 24. März 2005, 16:58
von jens
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...

Verfasst: Donnerstag 24. März 2005, 17:10
von jens
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