Python 2.6: BaseHTTPServer Problem mit Firefox?

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
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

Hallo alle Interessierten,

ich habe seit kürzerem ein Problem mit dem BaseHTTPServer und Firefox.
Der Server läuft bei mir meistens auf port 8080.

Wenn ich mich mit Chrome oder Safari verbinde, dann wird meine Seite super angezeigt, wenn ich mich mit Firefox verbinde dann seh ich den Sourcecode,
gewrappt in <html><body><pre>CODE</pre> ...

Warum?
Verbinde ich mich mit Telnet auf den Port und versuche ein GET, bekomme ich den originalen Code zurück so wie es sein soll, ohne dem gewrappe.

Es ist ja hier keine reine Python frage, aber vielleicht weiss ja jemand bescheid...

Unten seht ihr das Telnet Protokoll

Danke vorab für Ideen,
T


telnet localhost 8080
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET index.html

Code: Alles auswählen

<html>
<head>
<title>PyTom: Python and Tomography</title>

<link rel="icon" href="/images/pytom_logo.png" type="image/png" />
</head>
<body>

<script type="text/javascript" src="/javascript/functions.js"></script>
<script type="text/javascript" src="/javascript/cookies.js"></script>
<script type="text/javascript" src="/javascript/alignmentFunctions.js"></script>
<script type="text/javascript" src="/javascript/localizationFunctions.js"></script>
<script type="text/javascript" src="/javascript/mcoEXMXFunctions.js"></script>
<script type="text/javascript" src="/javascript/mcoACFunctions.js"></script>

<style type="text/css">
	@import "/css/pytomMainCSS.css";
	@import "/css/cssMainMenu.css";
</style>



<div id="Main" class="main">
	<div class="menu">
		<ul>
          	<li>
          		<a title="Reconstruct data" onMouseOver="document.getElementById('Help').innerHTML='<b>Reconstruction</b> Reconstruct complete tomograms or single subcubes.';" onMouseOut="document.getElementById('Help').innerHTML='';">Reconstruction</a>
          				<ul>
          					<li> <a title="Complete tomogram" onMouseOver="document.getElementById('Help').innerHTML='<b>Reconstruct</b> a complete tomogram.';" onMouseOut="document.getElementById('Help').innerHTML='';" onclick="setHTMLFromPage('pages/tomogramReconstruction.html',document.getElementById('MainDisplay'));">Tomogram</a></li>
          					<li> <a title="Load localization job" onMouseOver="document.getElementById('Help').innerHTML='<b>Reconstruct</b> subtomograms from a particle list.';" onMouseOut="document.getElementById('Help').innerHTML='';" onclick="">Subtomograms</a></li>
          				</ul>
			</li>
			<li>
				<a title="Setup localization job" onMouseOver="document.getElementById('Help').innerHTML='<b>Localization</b> allows you to find macromollecules in tomograms.';" onMouseOut="document.getElementById('Help').innerHTML='';" >Localization</a>
          				<ul>
          					<li> <a title="New localization job" onMouseOver="document.getElementById('Help').innerHTML='<b>New Job</b>: create a new localization job.';" onMouseOut="document.getElementById('Help').innerHTML='';" onclick="setHTMLFromPage('pages/newLocalizationJob.html',document.getElementById('MainDisplay'));">New Job</a></li>
          					<li> <a title="Load localization job" onMouseOver="document.getElementById('Help').innerHTML='<b>Load Job</b>: load an existing job and modify it.';" onMouseOut="document.getElementById('Help').innerHTML='';" onclick="">Load Job </a></li>
          					<li> <a title="Clear job settings" onMouseOver="document.getElementById('Help').innerHTML='<b>Clear Job</b>:clear all settings made.';" onMouseOut="document.getElementById('Help').innerHTML='';" onclick="eraseLocalizationCookies();resetLocalizationValues();">Clear Job Settings</a></li>
          				</ul>
			</li>
          	<li>
          		<a title="Align subtomograms" onMouseOver="document.getElementById('Help').innerHTML='<b>Alignment</b> register all subtomograms to one rotation and one position.';" onMouseOut="document.getElementById('Help').innerHTML='';">Alignment</a>
          			<ul>
          					<li><a title="New alignment job" onMouseOver="document.getElementById('Help').innerHTML='<b>New Job</b>: create a new alignment job.';" onMouseOut="document.getElementById('Help').innerHTML='';"  onclick="setHTMLFromPage('pages/newAlignmentJob.html',document.getElementById('MainDisplay'));">New Job</a></li>
          					<li><a title="Load alignment job" onMouseOver="document.getElementById('Help').innerHTML='<b>Load Job</b>: load an existing alignment job.';" onMouseOut="document.getElementById('Help').innerHTML='';" onclick="loadAlignmentJob()" >Load Job</a></li>
          					<li><a title="Clear job settings" onMouseOver="document.getElementById('Help').innerHTML='<b>Clear Job</b>:clear all settings made.';" onMouseOut="document.getElementById('Help').innerHTML='';" onclick="eraseAlignmentCookies();resetAlignmentValues();">Clear Job Settings</a></li>
          			</ul>
          	</li>
          	<li>
          		<a title="Classify aligned subtomograms">Classification</a>
          			<ul>
          					<li><a title="New MCO-EXMX job" onMouseOver="document.getElementById('Help').innerHTML='<b>New Job</b>: create a new MCO-EXMX job.';" onMouseOut="document.getElementById('Help').innerHTML='';"  onclick="setHTMLFromPage('pages/newMCOEXMXJob.html',document.getElementById('MainDisplay'));">New MCO-EXMX Job</a></li>
          					<li><a title="Load MCO-EMX job">Load Job</a></li>
          					<li><a title="New MCO-AC job" onMouseOver="document.getElementById('Help').innerHTML='<b>New Job</b>: create a new MCO-AC job.';" onMouseOut="document.getElementById('Help').innerHTML='';"  onclick="setHTMLFromPage('pages/newMCOACJob.html',document.getElementById('MainDisplay'));">New MCO-AC Job</a></li>
          					<li><a title="Load MCO-AC job">Load Job</a></li>
          			</ul>
          	</li>
          	<li>
          		<a title="Some quick processing tools">Tools</a>
          			<ul>
          					<li><a title="Quick average" onMouseOver="document.getElementById('Help').innerHTML='Generate average from particle list.';" onMouseOut="document.getElementById('Help').innerHTML='';">Average</a></li>
          					<li><a title="Split particle list" onMouseOver="document.getElementById('Help').innerHTML='Split a particle list by class.';" onMouseOut="document.getElementById('Help').innerHTML='';">Split</a></li>
          					<li><a title="" >---------------</a></li>
          					<li><a title="Run Unit Tests" onMouseOver="document.getElementById('Help').innerHTML='Run unit test on PyTom to see whether installation is correct.';" onMouseOut="document.getElementById('Help').innerHTML='';">Unit Test</a></li>
          			</ul>
          	</li>
          	<li>
          		<a title="Documentation">Documentation</a>
          				<ul>
          					<li><a title="" href="http://sourceforge.net/projects/pytom/" target="_blank">How To</a></li>
          					<li><a title="" href="http://sourceforge.net/p/pytom/wiki/Home/" target="_blank">FAQ</a></li>
          					<li><a id="documentationMenuLink" target="_blank" title="API Documentation HTML" onMouseOver="document.getElementById('Help').innerHTML='<b>API Documentation HTML</b>. Make sure they are the most recent!';" onMouseOut="document.getElementById('Help').innerHTML='';">API Documentation</a></li>
          				</ul>
			</li>
			<li>
          		<a title="Update">Updates</a>
          				<ul>
          					<li><a href="https://sourceforge.net/p/pytom/code/" title="Open pytom update site" target="_blank">Update site</a></li>
          				</ul>
			</li>
		</ul>
	</div>
	<div id="MainDisplay">
	<br/><br/><br/>
	<center>
		<img src="images/pytom_logo.png"/>
	</center>
	</div>
</div>

<div id="overlayBox" class="overlayBox" style="display: none;"></div>

<div id="Help" class="help" style="left:30px;top:650px;">

</div>


<script type="text/javascript">

	var documentationLink = document.getElementById('documentationMenuLink');
	
	var apiLink = getAPIDocumentationURL();
	
	documentationLink.href= 'file://' + apiLink;

</script>

</body>
</html>
Connection closed by foreign host.
BlackJack

@thomas15: Da fehlt ganz offensichtlich der HTTP-Header.
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

BlackJack hat geschrieben:@thomas15: Da fehlt ganz offensichtlich der HTTP-Header.
Stimmt, ich hab mit der plazierung von der do_HEAD methode rumgespielt, aber irgendwie werde ich nicht ganz schlau daraus wann der BaseHTTPServer
die headers haben will.

Natuerlich sollten diese vor jedem einzelnen Request kommen und mit

Code: Alles auswählen

server.end_headers()
beendet werden.

wie hier halt

Code: Alles auswählen

if self.path.find('.htm') !=-1:
            self.send_response(200)
            self.send_header('Host','PyTom Frontend Server')
            self.send_header("Content-type","text/htm")
        elif self.path.find('.html') !=-1:
            self.send_response(200)
            self.send_header('Host','PyTom Frontend Server')
            self.send_header("Content-type","text/html")
        elif self.path.find('.py') !=-1:
            self.send_response(200)
            self.send_header('Host','PyTom Frontend Server')
            self.send_header("Content-type","text/html")
        elif self.path.find('.css') !=-1:
            self.send_response(200)
            self.send_header('Host','PyTom Frontend Server')
            self.send_header("Content-type","text/css")
        elif self.path.find('.js') !=-1:    
            self.send_response(200)
            self.send_header('Host','PyTom Frontend Server')
            self.send_header("Content-type","text/javascript")
        elif self.path.find('.png') !=-1:
            self.send_response(200)
            self.send_header('Host','PyTom Frontend Server')
            self.send_header("Content-type","image/png")
        elif self.path.find('.jpg') !=-1:    
            self.send_response(200)
            self.send_header('Host','PyTom Frontend Server')
            self.send_header("Content-type","image/jpg")
        elif self.path.find('.gif') !=-1:    
            self.send_response(200)
            self.send_header('Host','PyTom Frontend Server')
            self.send_header("Content-type","image/gif")
        elif self.path.find('.tiff') !=-1:    
            self.send_response(200)
            self.send_header('Host','PyTom Frontend Server')
            self.send_header("Content-type","image/tiff")
        elif self.path.find('.ico') !=-1:    
            self.send_response(200)
            self.send_header('Host','PyTom Frontend Server')
            self.send_header("Content-type","image/x-icon")
                      
        self.end_headers()
Aber im Telnet tut sich da nix...
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Diese `if...elif`-Kaskaden sind so was von umständlich...

... packe die *Daten* in eine passende Struktur und wende dann eine Logik darauf an:

Code: Alles auswählen

suffix_mapper = (
    (".htm", "text/htm"),
    (".html", "text/htm"),
    (".py", "text/htm"),
    # ... usw.
)

for suffix, mimetype in suffix_mapper:
    if self.path.find(suffix) != -1:
        self.send_response(200)
        self.send_header('Host','PyTom Frontend Server')
        self.send_header("Content-type", mimetype)
        break
Das hat zwar nichts direkt mit Deiner Frage zu tun, aber das konnte ich nicht so stehen lassen :-D
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@thomas15: Hast Du überprüft ob die Methode überhaupt ausgeführt wird? Und ist Dir klar was die macht wenn keine der vielen Bedingungen zutrifft?

Zu den Bedingungen: Statt `find()` und Vergleich mit -1 sollte man für so etwas den ``in``-Operator verwenden. Wobei das der falsche Test ist, denn Du willst ja sicher nicht, dass bei einem Pfad in dem *irgendwo* eine Teilzeichenkette vorkommt, die auch eine Namensendung sein könnte, der Typ-Header gesendet wird, sondern nur wenn es tatsächlich die Endung ist.

Dann sind all die Zweige fast identisch. Code der sich 1:1 in jedem Zweig wiederholt gehört da nicht rein, das bläht das ganze doch nur unnötig auf.

Letztendlich ist das einzige was sich ändert der Wert von der 'Content-type'-Kopfzeile. Das kann man viel kompakter über ein Wörterbuch lösen, das Dateiendungen auf MIME-Typen abbildet. Oder man verwendet gleich das `mimetypes`-Modul aus der Standardbibliothek.
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

UI,

viele Verbesserungen, danke schonmal. Werde es einbinden wenns nicht anders geht!

Der Server ist einfach ein Frontend das etwas Stiefmütterlich behandelt wird.

Was super mit dem BaseHTTPServer ist dass man den direkt, ohne externe Abhängigkeiten, in das eigene Projekt integrieren kann, so dass die eigenen Module gleich in den Webservice integriert werden können.

Ich denke dass unser Design wahrscheinlich verbessert werden müsste, denn im Endeffekt wollen wir uns mit dem HTTP Protoll nicht auseinandersetzen müssen und darauf Rücksicht nehmen.
Ziel ist im Endeffekt ein möglichst unabhängiges Release mit der Möglichkeit von Python als Serverpages.

Hat jemand ne Idee für ein besseres Design?

Cheers,
T
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

Hallo,

ich hab euere Verbesserungen eingebaut, das mimetype modul integriert und mit urlparse den request besser bedient.
Trotzdem komme ich mit dem header nicht ganz klar.

Ich habe do_Head, das bei jedem Request ausgefuehrt wird.
Wenn ich allerdings index.html bekommen will, dann zeigt der Browser den header string + html source code an

Code: Alles auswählen

Host: PyTom Frontend Server
HTTP/1.0 200 OK
Server: BaseHTTP/0.3 Python/2.6.7
Date: Thu, 19 Apr 2012 14:30:46 GMT
Content-type: text/html

<html>
...
Eigentlich sollte der header doch als header erkannt werden und vollständig nicht angezeigt werden.
Warum sehe ich den? Ich glaub da fehlt sowas wie start_header / der header ist nicht vollstaendig / ich mach es an der falschen stelle.

Aber in Beispielen wie hier ists im Prinzip auch nicht anders
http://wiki.python.org/moin/BaseHttpServer

Jemand ne Idee?

Wenn ich do_Head vollständig deaktiviere zeigt Safari die Seite super an, mit aktiven Headers kommt der sourcecode... ???

Code: Alles auswählen

    def do_HEAD(self,path,extension):
        """
        do_HEAD
        @param realPath: URL between / and ? - like index.html or doSomething.py
        @param extension: File extension
        """
        import mimetypes
        from pytom.tools.files import getPytomPath, checkFileExists
  
        self.send_header('Host','PyTom Frontend Server')
        
        if path == '/index.html':
            self.send_response(200)
            self.send_header("Content-type","text/html")
            self.end_headers()
            return
    
        if not extension in fileTypePaths:
            #requested filetype not supported. abort!
            self.send_response(406)
            self.end_headers()
            return
        
        try:
            self._returnFilePath(path, extension)
        except IOError:
            #file not found! abort!
            self.send_response(404)
            self.end_headers()
            return
        
        #respond all is well!
        self.send_response(200)
        self.send_header("Content-type",mimetypes.guess_type(path)[0])
        self.end_headers()
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ich würde ja vermuten, dass die "HTTP..."-Zeile ganz am Anfang stehen muss. Und gibt es als Antwort vom Server tatsächlich einen Host-Eintrag? Das sollte doch eigentlich schon durch "Server" abgedeckt sein.
Das Leben ist wie ein Tennisball.
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

geloest,

lag daran dass ich den host vor der response geschickt habe und deshalb nicht mehr im header war sondern bereits im body...
Antworten