Probleme mit SocketServer.ThreadingTCPServer

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:

Ich habe einige CGIs programmiert, diese spucken HTML-Seiten aus, in den z.B. CSS-Dateien nur verlinkt sind. Diese zieht sich der Browser ja automatisch vom Server.

Ich denke dabei kann man ganz gut sehen, das es da mit dem ThreadingTCPServer ärger gibt. Denn manchmal kommen die angeforderten CSS-Dateien anscheinen nicht vom Server zum Browser. Beim nächsten Reload aber schon, dann wieder nicht...

Bei den Server Ausgaben kann man auch sehen, beim http GET Befehl wird mit Status 404 geantwortet und wenn die CSS-Datei beim Browser angekommen ist, mit Status 200. Dabei ist der Pfad der CSS-Datei immer der selbe...

Kann das einer bestätigen, oder liegt es vielleicht an etwas anderes?
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Hi ein wenig Code und ein Beispiel der Pfadangabe im HTML samt Abfrageurl im Browser wäre nicht schlecht. Nur so zu urteilen ist net möglich :wink: ...
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich weiß nicht recht, ob es was mit meinen Sourcen zu tun hat...

Im Prinzip nutze ich diesen Server: http://python.sandtner.org/viewtopic.php?p=16132#16132

Zum testen hab ich MyThreadingServer() von ThreadingTCPServer auf HTTPServer umgestellt und die Funktion server_bind() rausgenommen... Hier die modifizierten Teile:

Code: Alles auswählen

class MyThreadingServer( BaseHTTPServer.HTTPServer ):
#~ class MyThreadingServer( SocketServer.ThreadingTCPServer ):
    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)
        BaseHTTPServer.HTTPServer.__init__(self, server_address, request_handler)
Und damit geht es dann, CSS-Dateien sind immer da... Stelle ich wieder um auf ThreadingTCPServer und nehme die Funktion server_bind() wieder rein, werden nur hin und wieder alle CSS-Daten vom Server gefunden...
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Nun hab ich festgestellt, das ein Threading-Server doch einen wesendlichen Vorteil gegenüber der normalen Variante hat...
Wenn ein CGI relativ lange braucht um eine Tabelle aufzubauen (jede Zeile bracht halt in dem Fall seine Zeit) dann sieht man bei dem normalen Server solange nix, bis das laufende CGI komplett fertig ist... Bei dem Threading-Server sieht man aber wie sich nach und nach die Seite aufbaut... Was mir viel besser gefällt ;)

Nun ist aber immernoch das Problem mit den CSS-Dateien da... Ist das nur bei mir so?


Ich hab es jetzt nochmal mit einer Minimal-Version des Servers probiert:

Code: Alles auswählen

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


import sys, os
import CGIHTTPServer
import SocketServer, socket
#~ import BaseHTTPServer


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

    cgi_directories = ["/modules", "/routines"]



#~ class MyThreadingServer( BaseHTTPServer.HTTPServer ):
class MyThreadingServer( SocketServer.ThreadingTCPServer ):

    allow_reuse_address = 1    # Seems to make sense in testing environment

    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


if __name__=="__main__":
    sys.path.append( os.path.join( os.getcwd(), "routines" ) ) # Wird von meinen Modulen verwendet

    ListenPort = 9000
    print "Starte CGI-HTTP-Server auf Port .:", ListenPort
    httpd = MyThreadingServer( ("", ListenPort), MyRequestHandler )
    httpd.serve_forever()
EDIT:
So, jetzt hab ich mal ein Test-Script geschrieben:

Code: Alles auswählen

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

import os,sys

print "Content-Type: text/html\n\n"


qs = os.environ['QUERY_STRING']
if "nr=" in qs:
    print '<link rel="stylesheet" href="/css/test.css" type="text/css">'
    print "%03i" % int( qs.split("=")[1] )
    sys.exit()


br_nr = 0
for i in xrange(150):
    print "%03i" % i
    print '<iframe src="ServerTest.py?nr=%s" width="50px" height="30px" scrolling="no" marginheight="4"></iframe>' % i
    br_nr += 1
    if br_nr == 10:
        br_nr = 0
        print "<br>"
Die Funktionsweise dürfte klar sein, oder?

Es läuft auch fast immer richtig ab... Nur hin und wieder (vielleicht einmal bei zehn durchläufen) scheint sich der Server zu verschlucken. Plötzlich geraten die Zahlen durcheinander...

Ganz lustig wird es, wenn man von mehreren Rechnern gleichzeitig den Test startet... Dann kommt ziemlich oft falsche Werte...

Aber ich weiß nicht, ob das verhalten überhaupt was mit meinen CSS-Problem zu tun hat, denn die iframes werden immer geladen, es kommt nie vor, das die URL nicht gefunden wird (Fehler 400)...

EDIT2:
So jetzt hab ich auch noch eine CSS-Datei die beim iframe immer geladen werden soll:
/css/test.css

Code: Alles auswählen

body { background-color: #CCCCCC; }
Diese wird auch fast immer geladen, aber nur fast...

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:

Ich hab's!!!

Code: Alles auswählen

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

import os, sys, time

print "Content-Type: text/html\n\n"

print '<link rel="stylesheet" href="/css/test1.css" type="text/css">'

# Ohne die Pause geht's nicht!
time.sleep(1)

os.chdir("/etc")
for file in os.listdir( "." ):
    if os.path.isfile( file ):
        print file, os.popen( "file '%s'" % file ).read()
        print "<br>"
Wenn kein time.sleep(1) gemacht wird, liefert der Server die CSS-Datei nicht aus! Auf der Console sehe ich "GET /css/test1.css HTTP/1.1" 404

Und warum ist es so? Hat der Server durch dir Abarbeitung der for-Schleife keine Zeit die CSS-Datei auszuliefern???

EDIT: Für den Aufruf von file könnte ich wohl besser das Modul "magic" nehmen, s. http://python.sandtner.org/viewtopic.php?p=16904#16904

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:

Hab ich nur das Problem? Kann es mal jemand testen, ob es nicht evtl. bei mir liegt und nicht an Python...

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