XML RPC Server (mit Passwort)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
q-rios
User
Beiträge: 8
Registriert: Freitag 16. Mai 2008, 13:39

Also habs mal hinbekommen, dass der Server läuft.

Code: Alles auswählen

#!/usr/bin/env python

import SimpleXMLRPCServer
import base64, socket, string

class new_post_handler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
        def do_POST(self):
                try:
                        header = self.headers['Authorization']
                        type, user_passwd = header.split()
                        username, password = string.split(base64.decodestring(user_passwd), ':')
                        if(username == 'ein_benutzer' and password == 'das_password'):
                                self.send_response(200)
                                print "authed successful"
                except:
                        print "no auth credentials"
                        self.send_response(401)

if __name__ == '__main__':
        server = SimpleXMLRPCServer.SimpleXMLRPCServer(('localhost', 8000), new_post_handler)
        server.register_introspection_functions()
        server.serve_forever()
Ich kann mit einem Client auch connecten und auf dem Server bekomme ich auch "authed successful", leider aber auch eine Fehlermeldung wenn ich mir eine Liste aller Methoden ausgeben lassen will.

Code: Alles auswählen

#!/usr/bin/env python

import xmlrpclib, os

if __name__ == '__main__':
        s = xmlrpclib.Server('http://ein_benutzer:das_passwort@127.0.0.1:8000')
        print s.system.listMethods()
Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "./client.py", line 7, in <module>
    print s.system.listMethods()
  File "/usr/lib/python2.5/xmlrpclib.py", line 1147, in __call__
    return self.__send(self.__name, args)
  File "/usr/lib/python2.5/xmlrpclib.py", line 1437, in __request
    verbose=self.__verbose
  File "/usr/lib/python2.5/xmlrpclib.py", line 1201, in request
    return self._parse_response(h.getfile(), sock)
  File "/usr/lib/python2.5/xmlrpclib.py", line 1338, in _parse_response
    p.close()
  File "/usr/lib/python2.5/xmlrpclib.py", line 550, in close
    self._parser.Parse("", 1) # end of data
xml.parsers.expat.ExpatError: no element found: line 1, column 0
Ich kann aus der Fehlermeldung leider nicht allzu viel herauslesen
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Ich vermute anhand der Fehlermeldung, dass da kein gültiges XML ankommt. Finde mal heraus, was da wirklich übertragen wird.
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Mach doch mal das reine `except` da weg. Das verbirgt sicher den Fehler..
q-rios
User
Beiträge: 8
Registriert: Freitag 16. Mai 2008, 13:39

audax hat geschrieben:Mach doch mal das reine `except` da weg. Das verbirgt sicher den Fehler..
Ich hab mal try: und except: auskommentiert (auch die nachfolgenden Zeilen von except)

Beim Server kommt kein Fehler, nur:

Code: Alles auswählen

localhost - - [16/May/2008 23:26:23] "POST /RPC2 HTTP/1.0" 200 -
authed successful
Und am Client:

Code: Alles auswählen

Traceback (most recent call last):
  File "./client.py", line 7, in <module>
    print s.system.listMethods()
  File "/usr/lib/python2.5/xmlrpclib.py", line 1147, in __call__
    return self.__send(self.__name, args)
  File "/usr/lib/python2.5/xmlrpclib.py", line 1437, in __request
    verbose=self.__verbose
  File "/usr/lib/python2.5/xmlrpclib.py", line 1201, in request
    return self._parse_response(h.getfile(), sock)
  File "/usr/lib/python2.5/xmlrpclib.py", line 1338, in _parse_response
    p.close()
  File "/usr/lib/python2.5/xmlrpclib.py", line 550, in close
    self._parser.Parse("", 1) # end of data
xml.parsers.expat.ExpatError: no element found: line 1, column 0
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Du gibst auch keinen Return-Wert.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
q-rios
User
Beiträge: 8
Registriert: Freitag 16. Mai 2008, 13:39

Code: Alles auswählen

#!/usr/bin/env python

import SimpleXMLRPCServer
import base64, socket, string

class new_post_handler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
	def do_POST(self):
		header = self.headers['Authorization']
		type, user_passwd = header.split()
		username, password = string.split(base64.decodestring(user_passwd), ':')
		if(username == 'sysadmin' and password == 'adm!n'):
			self.send_response(200)
			self.send_header("Content-type", "text/xml")
			self.send_header("Content-length", 0)
			self.end_headers()
			print "authed successful"
		else:
			self.send_response(401)
			self.end_headers()

if __name__ == '__main__':
	server = SimpleXMLRPCServer.SimpleXMLRPCServer(('localhost', 8000), new_post_handler)
	server.register_introspection_functions()
	server.serve_forever()
Leider kann ich Python nicht gut genug, als das mir der Link hilft.
Ich seh das Problem leider nicht :(
OldBoy
User
Beiträge: 41
Registriert: Samstag 12. Januar 2008, 20:39

Im XMLRPC-Server muss definiert sein, welche Funktionen/Methoden er überhaupt zur Verfügung stellen soll. Ein einfaches Beispiel findest du unter http://aspn.activestate.com/ASPN/Cookbo ... cipe/81549.

Gruss

OldBoy
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Du musst einfach einen 403-Statuscode senden, wenn Benutzername oder Passwort nicht stimmt und ansonsten einfach ``do_POST`` der Basisklasse aufrufen.

Also irgendwie so:

Code: Alles auswählen

class new_post_handler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
    def do_POST(self):
        if 'Authorization' in self.headers:
            header = self.headers['Authorization']
            type, user_passwd = header.split()
            username, password = base64.decodestring(user_passwd).split(':')
            if username == 'sysadmin' and password == 'adm!n':
                SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.do_POST(self)
            else:
                self.send_error(403)
        else:
            self.send_error(401)
Allerdings wirft das eine Ausnahme, falls jemand mutwillig "falsche" Header sendet.
q-rios
User
Beiträge: 8
Registriert: Freitag 16. Mai 2008, 13:39

Jetzt funtktioniert alles einwandfrei.
Das Problem lag einfach nur an dem do_POST.

Habt ihr irgendwie noch Verbesserungsvorschläge?
Antworten