28. Oktober 2005

Protokoll bluehands Seminar 28.10.2005

Thema: Firefox XMLDoc braucht Content-Length

Auch wir machen natütlich AJAX. Wir machen das schon seit 4 Jahren, also schon lang bevor es einen berühmten Namen hatte. Klar, die Leserin hat nichts anderes von bluehands erwartet. AJAX heisst im Browser mit einem HTTP-Request im Hintergrund Daten vom Server zu erfragen, die dann in Javascript ausgewertet werden. Dazu verwende an das in moderne Browswr eingebaute XMLDocument Objekt. Das heisst natürlich verschieden bei IE und FF, aber der Code fängt typisherweise so an:

var oXmlDoc = null;
if (document.implementation)
oXmlDoc = document.implementation.createDocument("", "", null);
else
oXmlDoc = new ActiveXObject("Microsoft.XMLDOM");


Dann setzt man einen Callback:

oXmlDoc.onload = OnLoaded;

und lädt eine Datai vom Server, die typischerweise dynamisch erzeugt wird:

oXmlDoc.load(sUri);

Soweit so gut, aber...

Manchmal geht es nicht bei FF. Das heisst er macht den Request, liesst die Daten, erkennt sogat das character encoding aus dem XML header, aber die Tags kommen nicht im DOM an. Bei manchen Anwendungen geht es.

Es stellt sich nach viel probieren heraus, dass es genau dann nicht geht, wenn der Server kein Content-Length HTTP-Headerfield schickt. Bei Servern, die Content-Length setzen, geht es. Das ist [seltsamwitziginteressant], weil es
1. dem IE nichts ausmacht
2. die HTTP-Spec sagt, dass Content-Length nicht notwendig ist, wenn die TCP Verbindung beednet. Dann ist die Content-Length nämlich genau die Daten, die bis zum Ender der verbindung kamen
3. Selbst wenn es dem FF unmöglich wäre die Content-Length herauszufinden,der XML Parser im FF aus dem Schliessen des auessersten XML-Tags erkennen könnte, dass das XML fertig ist. Danach darf sowieso nichts mehr kommen
4. PHP normalerweise keine Content-Length schickt, weil die noch nicht bekannt ist, wenn nach dem HTTP Header die ersten Daten geschickt werden und man.

Ergebnis: AJAX/PHP/Firefox geht nicht, denn das findet der normale PHP Programmierer nie heraus. Aber wenn er googelt und das hier findet sei ihm gesagt: Man muss alle Daten in einer Variable speichern und die Content-Length setzen mit:

header("Content-Length: " . strlen($data);

oder PHP output buffering einschalten, dann geht es möglicherweise auch (nicht getestet). Das hätte den Vorteil, dass der Code nicht umgeschrieben werden muss, um überall einzufügen:

$data .= DasWasVorherImEchoStand;

Das ganze hängt vermutlich nur an einem Detail. Ich nehme an, dass der TCPStream im FF beim XML Parser das "final" flag nicht setzt wenn die TCP Verbindung beendet und so dem Parser nicht signalisiert, dass die Daten fertig sind. Wahrscheinlich parst der Parser das XML korrekt (darauf deutet das character encoding hin), aber das DOM wird nicht fuer den externen Zugriff bereitgestellt, weil "final" fehlt.

Fazit: Noch ein Indiz, dass AJAX noch nicht erwachsen ist. Nicht das einzige. Aber dank des Überhypes darf man hoffen, dass sich Entwicklungsanstrengungen darauf konzentrieren und es das bald wird.

_happy_coding()

20. Oktober 2005

Mein erster eigener kleiner Firefox Security Bug

Javascript: Wenn eine Webseite auf Objekte oder Code in einer anderen Seite zugreift, dann heisst das Cross Site Scripting (XSS). Vor allem dann, wenn die Webseiten von verschiedenen Servern kommen. Dann ist das naemlich verboten. Was ein verschiedener Server ist ist Auslegungssache. IE meint, dass der Domainname gleich sein muss. Firefox zaehlt auch den Port dazu. Die Beschraenkung gilt auch fuer IFRAMEs. Aber es gibt einen Mechanismus, um die XSS Beschraenkung zu umgehen. Man darf die Security Domain des Dokuments aendern, aber nur verkuerzen. Wenn ein Dokument auf "spock.bluehands.de" liegt und ein anderes "kirk.bluehands.de", dann ...ist der Script-Zugriff verboten, aber man kann beiden Dokumenten sagen, dass sie auf "bluehands.de" liegen, also Domain Name verkuerzt.

OK, also die Browser haben einen Mechanismus, mit dem man Strings sinnvoll verkuerzen kann, bis nur noch ein Punkt drin ist. Damit kann Firma-A.de nicht auf Firma-B.de zugreifen, aber Host-1.Firma-A.de auf Host-2.Firma-A.de.

Und jetzt kommt der Witz: Das geht auch mit IP-Adressen. Man kann "212.86.216.75" verkuerzen auf "216.75" (1 Punkt muss bleiben). Nur: bei Domainnamen verkuerzt man dabei auf die Hauptdomain, aber IP-Adressen stehen andersherum. Da verkuerzt man auf die Spezialisierung. Und damit kann im Prinzip jeder in seinem eigenen Netz "102.168.216.75" verkuerzen auf "216.75" und die ganze XSS-Security-mit-Domain-Verkuerzung ad absurdum fuehren.

_happy_coding()

26. September 2005

Mein Content Management System

Es heisst jeder Kuenstler macht in seinem Leben mindestens eine Madonna, als Skulptur oder als Bild. Was dem Bildkuenstler die Madonna ist, ist dem Programmierer das Content Managmenent System. Jeder Programmierer schreibt mal eins. Deshalb gibt es Content Management Systeme, wie Sand am Meer. Weil ich nicht der erste sein will, der mit der Tradition bricht, habe auch ich in den letzten Tagen ein CMS geschrieben.

Name: SCMS (= Simple CMS)
Features: Templates, CSS/DOM Pagegenerator, News, RSS, Weblog, Extensions.
Besondere Kennzeichen: einfach, keine Datenbank.
Kommentar: alle Dateien im HTML Editor editierbar, auch die Content-Dateien. Pagegenerator verwendet Decorator-Pattern.

Wer es haben will, bitte melden bei wolf@bluehands.de. Es wird nicht veroeffentlicht, weil es damit sicher bleibt. Security by obscurity. Die letzte Rettung, wenn man bei "Standardsoftware" von Hackern geplagt wird. SCMS bleibt geheim und sicher.

_happy_coding()

20. September 2005

Protokoll bluehands Seminar 20.09.2005

Thema: Logging Strategie

Das Thema Loggin hat viele Dimensionen. Folgende Punkte wurden diskutiert:

  • Logging in Applikationen vs. Logging in Libraries: Libraries sollten nicht selbst bis zur Oberflaeche loggen, sondern ihr Logging an die Host-Applikation delegieren (callback, delegate).
  • Tracing: zusaetzlich zum Logging braucht man manchmal Tracing, d.h. jede Methode meldet Einsprung und Aussprung.
  • Multithread-save Logging
  • Loglevel: wir verwenden folgende Loglevel: Fatal, Error, Warning, Debug, Info, Verbose, Trace, VeryVerbose
  • Bedeutung der Loglevel sollte ueber eine gesamte Applikation hinweg aehnlich sein.
  • Channels; Logging braucht Channels damit Logging-Quellen getrennt (gefiltert) werden koennen. Man will zB nicht eine gesamte Applikation auf VeryVerbose schalten, sondern nur eine Klasse oder ein Modul. Der Klassen name als Channel ist ein guter Ansatz. Das muss dann manchmal verfeinert werden.
  • Syslog/EventLog: Logging auf einen Systemdienst.
  • TCP/MsgQ: Logging auf eine Netzwerkverbindung an einen Logserver.
    Logging sollte immer mitgefuehrt werden, nicht erst, wenn es Probleme gibt oder gar nach dem Deployment.
  • Problem und Loesung von Logging in Libraries ist verwandt mit Konfiguration in Libraries.
  • Daten fuer Verbose und VeryVerbose levels sollten nur dann erzeugt werden, wenn entsprechende Level aktiviert sind.

Loglevel-Bedeutungen bei bluehands:

  • Fatal: wenn die Applikation beenden muss
  • Error: Fehler, der zum Funktionsabbruch fuehrt
  • Warning: Fehler oder schlechte Datenlage, die behoben werden kann
  • Debug: temporaerer Level fuer printf-Debugging. (Auskommentieren, drin stehen lassen)
  • Info: regelmaessige (wichtige) Systemzustaende und Aenderungen
  • Verbose: Verarbeitungsverlauf, 10-100 Zeilen pro Sekunde
  • VeryVerbose: 1000 Zeilen pro Sekunde
Logging Klassen sind bei bluehands fuer C# und C++/C standardsisiert.

_happy_coding()

16. September 2005

Rechner gehackt

Vielleicht! Im Logfile stehen POST /xmlsrv/xmlrpc.php und einige "Maximum execution time of 30 seconds exceeded in /home/web/wwwroot/www.webmob.de/blogs/b2evocore/_functions_xmlrpc.php on line 402"

Es lebe die selbstgeschriebene Software.

Tja, plattmach.

8. September 2005

Protokoll bluehands Seminar 08.09.2005

Thema: Binary Encoding und String Encoding

base64: Encoding, um binaere Daten in ASCII zu codieren, sodass sie durch ASCII Protokolle uebertragen werden koennen, z.B. SMTP (Email) oder XML. Je 3 Byte Ausgangsdaten werden so auf 4 Byte verteilt, dass das hoechste Bit 0 bleibt und keine ASCII Steuerzeichen vorkommen.

Unicode: Unicode ist eine standardisierte Aufzaehlung von Zeichen aus allen moeglichen Zeichensaetzen dieser Erde. Alle Zeichen bekommen eine Nummer. Zufaellig absichtlich liegen die ASCII Zeichen in den niedrigen Nummern auf den gleichen Plaetzen, wie man es von ASCII gewohnt ist.

Microsoft Unicode Implementierung: MS hat beschlossen, dass Unicode Strings aus Zeichen zu je 2 Byte bestehen (Typ: short). Dabei vernachlaessigt MS bewusst Unicode Zeichen mit Nummer ueber 64k. Alle Strings im NT/XP/Vista Kernel sind in Unicode im Memory dargestellt.

UTF-8: Unicde Transfer Format, mindestens 8 Bit, manchmal mehr. ASCII Zeichen werden mit einem Byte dargestellt, alle anderen mit mehr als einem Byte, z.B. MS Unicode mit 2 Byte. So wird z.B. ö als ö dargestellt.

Weitere Themen: PPP, SLIP encoding, Modem, Escape Sequenzen, ISO/OSI Modell.

_happy_coding()

2. September 2005

Auto beleidigt

Mein Auto ist beleidigt, weil ich es verkaufen wollte. Es hat gemerkt, dass was in der Luft liegt. Ich hatte den Fahrzeugbrief herausgesucht und neuen TÜV gemacht, obwohl der erst in einem Jahr faellig gewesen waere. Und weil mein Auto sich in seinem Alter nicht mehr an jemand anders gewoehnen will, stellt es sich jetzt tot. Ploetzlich ist die Kupplung kaputt, verliert Wasser und Oel und die Bremsen sind hin. Jahrelang hatte es nichts. Ich habe es nicht verwoehnt, alle 30.000 km Oelwechsel musste reichen, aber ich habe es mit Achtung behandelt. Das hat es mir gedankt durch reparaturfreies Fahren bis 219.000 km. Aber anscheinend will es nicht verkauft werden. Dann kommt es jetzt zum Abdecker. Pech.

_happy_coding() trotzdem

Nachtrag: Das Abschiedsbild.