OK, da das exefile()-Problem wohl erstmal nur umgangen werden kann, wenn subprocess genommen wird, hier eine neue Version:
Code:
#!/usr/bin/python
# -*- coding: ISO-8859-1 -*-
__version__ = "0.0.6"
__history__ = """
v0.0.6
- Überschreiben der CGIHTTPServer.execfile() damit Skripte nicht per
execfile() sondern per subprocess ausgeführt werden. Damit alle
"Sub"-Module immer neu geladen werden.
v0.0.5
- os.environ["QUERY_STRING"] wird richtig übergeben
"""
import CGIHTTPServer, SocketServer
import os, sys, socket, webbrowser, subprocess
class execscript:
def __call__( self, scriptfile, dummy ):
p = subprocess.Popen(
"%s %s" % ( sys.executable, scriptfile ),
cwd = ".",
shell = True,
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE
)
p.stdin = sys.stdin
sys.stdout.write( p.stdout.read() )
sys.stderr.write( p.stderr.read() )
# Überschreiben der execscript() Funktion, mit der subprocess-Variante ;)
CGIHTTPServer.execfile = execscript()
class MyRequestHandler( CGIHTTPServer.CGIHTTPRequestHandler ):
"Modifizieren des Standart RequestHandlers"
# Damit auch unter Linux, welches fork unterstützt, das Python-CGI-Skript
# unter dem User ausgeführt wird, mit dem der CGIHTTPServer gestartet wurde
# und nicht mit User nobody...
have_fork = False
have_popen2 = False
have_popen3 = False
def is_cgi(self):
"Modifikation, sodas man im CGI-Verzeichnis ein Dir-Listing bekommt"
if "?" in self.path:
script_file, query_string = self.path.split("?",1)
query_string = "?" + query_string
else:
query_string = ""
script_file = self.path
script_base, script_filename = os.path.split( script_file )
if script_filename=="":
return False
if os.path.splitext( script_filename )[1] != ".py":
return False
script_base = os.path.normpath( script_base )
# Wird für self.run_cgi() benötigt
self.cgi_info = script_base, script_filename + query_string
os.environ['DOCUMENT_ROOT'] = os.getcwd()
os.environ["SCRIPT_FILENAME"] = script_filename
return True # Ist ein "CGI"
class MyThreadingServer( SocketServer.ThreadingTCPServer ):
"""
Verbesserung des Standart Servers:
- ermöglicht das abarbeiten mehrere Anfragen parallel (z.B. Download mehrere Dateien gleichzeitig)
- Ermöglicht das einschränken des IP-Bereiches aus denen der Server Anfragen behandelt
"""
allow_reuse_address = 1 # Seems to make sense in testing environment
def __init__(self, server_address, request_handler, AllowIPs):
SocketServer.ThreadingTCPServer.__init__(self, server_address, request_handler)
self.AllowIPs = [mask.split('.') for mask in AllowIPs]
def server_bind(self):
"""Override server_bind to store the server name. (Parallele Anfragen)"""
SocketServer.ThreadingTCPServer.server_bind(self)
host, port = self.socket.getsockname()[:2]
self.server_name = socket.getfqdn(host)
self.server_port = port
def verify_request(self, dummy, client_address):
"""Checkt ob die IP-Adresse der Anfrage in 'AllowIPs' vorhanden ist"""
def check_ip(mask):
for mask_part, ip_part in zip(mask, ip):
if mask_part != ip_part and mask_part != '*':
return False
return True
ip = client_address[0].split('.')
for mask in self.AllowIPs:
if check_ip(mask):
return True
print "IP [%s] not allowed!" % client_address
return False
def ServerStart( cgiVerz, ListenPort, AllowIPs ):
print "="*80
print "ROOT-Pfad .......................:", os.getcwd()
print "Starte CGI-HTTP-Server auf Port .:", ListenPort
print "Zugelassener IP-Bereich .........:", AllowIPs
print
print "Seiten sind nun unter [http://localhost:%s] erreichbar!\n" % ListenPort
httpd = MyThreadingServer( ("", ListenPort), MyRequestHandler, AllowIPs )
# Öffne Browser
webbrowser.open_new("http://localhost/index.py")
httpd.serve_forever()
if __name__=="__main__":
cgiVerz = "." # CGI's in jedem Pfad erlauben
ListenPort = 80
AllowIPs = ('127.0.0.1', '192.168.*.*')
ServerStart( cgiVerz, ListenPort, AllowIPs )
Dabei gibt es allerdings wieder mal ein anderes Problem, wofür ich eure hilfe brauche!
Und zwar, werden anscheinend keine POST-Formulare korrekt an's CGI geschickt.
Genauer gesagt, liefert cgi.FieldStorage() keine Werte. Aus den cgi.py Sourcen kann man entnehmen, das cgi.FieldStorage() die Daten per stdin liest (Zeile 629). In CGIHTTPServer.py Zeile 294 wird anscheinen stdin irgendwie gefüttert.
Offensichtlich klappt die übertragung der Daten per subprocess nicht richtig...
Kann mir jemand helfen???