/ (JAVASCRIPT): Caching-Probleme (bei auto-refresh, server-push simulieren)
Andreas Korthaus
- https
Hallo!
Ich bin heute auf folgenden Artikel gestoßen: http://codewalkers.com/tutorials/87/1.html
Der Artikel beschreibt, wie man mit Hilfe von etwas PHP und Javascript eine HTML-Seite neu laden kann, und zwar direkt sobald sich was an irgendwelchen Daten ändert. Hierbei wird in einer JS-Schleife alle paar Sekunden ein Request an ein PHP-Script durchgeführt (und zwar so wie ein Bild per JS [vor-]geladen wird). Ein PHP-Script nimmt den Request entgegen, prüft die Daten und wenn sich was an den Daten geändert hat, verändert es einen Cookie und belegt diesen mit dem Timestamp der Änderung.
Die Idee finde ich ganz interessant, weil ich auch sowas in der Art benötige. Ich weiß dass dies nicht überall sinnvoll ist, wenn man aber einen "geschlossenen Anwenderkreis" hat kann man IMO solche Sachen mal machen, wenn es denn einen Zusatznutzen bringt.
Ich habe das Beispiel noch etwas vereinfacht um mal ein bisschen zu Testen wie das am besten mit verschiedenen Browsern funktioniert, und auch wie es möglichst wenig Resourcen verbraucht. Prinzipiell würde ich gerne vermeiden dass der Prüf-Request von einem PHP-Script bearbeitet werden muss, da dies extrem viele Resourcen verbraucht. Aber dieses Problem zu lösen hebe ich mir für später auf, da ich hierbei drauf achten muss dass die User authentifiziert sind (ohne HTTP-Auth), entsprechende Rechte haben ...
Zum Testen:
Man öffnet zunächst die HTML-Seite, von mir aus in mehreren Browsern / Browserfenstern gleichzeitig, und irgendwann öffnet man (am besten in noch einem anderen Fenster) das PHP-Script um Daten zu verändern, und wenige Sekunden später sollten sich alle zuvor geöffneten Browserfenster aktualisieren.
HTML-Seite (die im Hintergrund prüft ob sich was an den Daten geändert hat)
PHP-Script um Daten zu verändern (das Script ändert eine Datei, die von dem anderen Script überwacht wird)
PHP-Script um Daten auf Veränderungen zu prüfen (das Script prüft ob die entsprechende Datei geändert wurde und vergleicht den timestamp mit dem empfangenen Cookie (aus dem JS Bild-Request). Wenn sich nichts geändert hat sendet es einen 204-Header, sonst einen 200-Header mit neuem Cookie und ohne Content. Das Script wird "als Bild" aus dem Javascript in der
HTML-Seite aufgerufen)
Den PHP-Quelltext kann man über "?source=1" einzusehen.
Ich habe jetzt verschiedene Probleme. Das größte davon ist, dass ich nicht mit IE 5 und IE 4 testen kann, da ich diese bei mir nicht mit Cookie-Unterstützung neben meinen IE6 installieren kann. Wenn also jemand einen der beiden Browser hat, wäre ich dankbar für eine kurze Rückmeldung ob es geklappt hat ;-)
(Oder wenn jemand weiß wie ich einen IE4/5 mit Cookie-Unterstützung neben IE6 installieren kann wäre das natürlich noch besser!)
Für Netscape4 musste ich bereits eine Sonderbehandlung einbauen. Entweder ich sende diesem tatsächlich bei _jedem_ Request eine Grafik inkl. aggressiver Anti-Caching Header als Antwort, oder ich muss den Request jedesmal etwas ändern. Das habe ich jetzt gemacht, indem ich noch einen Parameter anhänge, das heißt Netscape4 macht immer:
GET /detector.php?i=1
GET /detector.php?i=2
...
img = new Image;
// NN4 Probleme
if(document.ids) {
img.src = 'detector.php?i='+ i++;
}
else {
img.src = 'detector.php';
}
Allerdings habe ich hierbei auch nicht das beste Gefühl, nicht dass mir hier irgendein Cache oder sowas volläuft?
Wie ist das denn mit Javascript, wenn ich einem Image-Objekt("img = new Image;") eine Resource zuweise ("img.src = 'detector.php';"), die entweder Statuscode 200 und "content-type: text/html", oder Statuscode 204 zurückgibt? Es funktioniert in IE6, FF und NN4, also keine Sorgen drum machen? Lieber wäre mir gewesen ich könnte im ersten Request ein Bild schicken (1 pixel gif), und danach einen 304-Header, aber das habe ich bisher nicht hinbekommen. Irgendwie hören alle getesteten Browser nach einer 304-Antwort einfach auf mit den Requests. Das hat mit Sicherheit was mit dem lokalen Cache zu tun, aber trotz aggressivster Anti-Caching Header hat es nicht funktionieren wollen. Außerdem handele ich mit hierbei Probleme mit den Unterschieden im Caching-Verhalten ein. Ich bin mir auch nicht 100%ig Sicher ob es hier nicht noch Unterschied zw. JS und HTML gibt.
(Meine verzweifelten Versuche gehen aus den Kommentaren im Prüfscript hervor - wobei, wo ich da gerade drübergucke, habe ich doch wohl keine HTTP 1.1 Header mit HTTP/1.0 verwendet, oder? och nö...)
Oder hat vielleicht jemand von Euch ein gutes Rezept wie die entsprechenden Header aussehen müssen, so dass es in IE4+, NN4+, FF und neueren Operas funktioniert?
Was haltet Ihr prinzipiell davon?
Viele Grüße
Andreas
Halihallo Andreas
Was haltet Ihr prinzipiell davon?
Nun, ich schätze, es ist einfach das kleinste Übel. HTTP kommt uns
bekanntermassen und generischerweise wenig entgegen, was Client-
Server-Kommunikation innerhalb eines einzigen Request betrifft.
Das kleinste Übel deswegen, da es noch halbwegs serverschonend ist.
Wie ist das denn mit Javascript, wenn ich einem Image-Objekt("img = new Image;") eine Resource zuweise ("img.src = 'detector.php';"), die entweder Statuscode 200 und "content-type: text/html", oder Statuscode 204 zurückgibt? Es funktioniert in IE6, FF und NN4, also keine Sorgen drum machen? Lieber wäre mir gewesen ich könnte im ersten Request ein Bild schicken (1 pixel gif), und danach einen 304-Header, aber das habe ich bisher nicht hinbekommen.
Hm. Die Grösse eines Gif's von 1x1 Pixel ist so etwa
50 Bytes. Die einer Header ca. 15 Bytes. Der Unterschied halte ich
doch für verschwindend klein, warum also nicht einfach ein 200 OK
mit 1x1 Bild (und ggf. Cookie) senden? - Das Bild gehört
natürlich Hart-Codiert in einen String der ausgegeben wird (sonst
müsste das OS noch eine weitere Datei öffnen).
Allerdings habe ich hierbei auch nicht das beste Gefühl, nicht dass mir hier irgendein Cache oder sowas volläuft?
Nun, das tut er. Aber ich halte es für einen Vorteil, denn dann haben
alle Besucher beim nächsten Visit bei cnn.com wieder die neusten News
und nicht mehr die von letzter Woche... OK, OK, und die Festplatte
voller 1x1 Gif's, was auch wenig Sinn macht.
Nun ja, du kannst ja einen Expires-Header senden, der in 1 Minute
abläuft. Wenn NS dann seinen Cache nicht richtig organisiert, trifft
dich wenigstens nicht die Schuld.
Am Schluss noch eine kleine Idee:
http://httpd.apache.org/docs/mod/mod_asis.html
Für jeden Benutzer legst du eine Datei an, welche das 1x1-Gif und
die vorbereiteten Header (und jetzt kommts: inklusive Cookie!)
bereits enthält (und z.B. durch das Eintrag-Geschrieben-Script neu
geschrieben wird) und sendest diese nicht per detector.php, sondern
über Apache direkt zum Client. Dies wäre z.B. bei einem öffentlichen
Chatroom auf HTTP-Basis wohl eine der performanteren Lösungsansätzen.
Vielleicht liesse sich dies für dich Nutzen? - Es kommt eben etwas
auf die Anwendung an und da du von Benutzerauthentifizierung
sprichst, räume ich ein, dass es unwahrscheinlich ist... Aber den
Gedanken wollte ich dennoch kurz loswerden (für die Script-Kiddies,
die mal einen so geilen HTTP-Chatroom haben möchten :-)).
Viele Grüsse und schönen Abend wünscht dir
Philipp
Hi Philipp!
Nun, ich schätze, es ist einfach das kleinste Übel. HTTP kommt uns
bekanntermassen und generischerweise wenig entgegen, was Client-
Server-Kommunikation innerhalb eines einzigen Request betrifft.Das kleinste Übel deswegen, da es noch halbwegs serverschonend ist.
Ich überlege ja schon nebenbei, wie sowas deutlich schonender funktioniert. Den Traffic lasse ich mal außer acht, es ist erheblich "schlimmer" wenn alle User alle 2 Sekunden den Server dazu veranlassen ein komplettes PHP-Framework zu laden, 20 DB-Abfragen abzufeuern... nur weil man wissen will ob der User das überhaupt darf! So ist es halt der einfachste Weg - fürs erste.
Es funktioniert in IE6, FF und NN4, also keine Sorgen drum machen? Lieber wäre mir gewesen ich könnte im ersten Request ein Bild schicken (1 pixel gif), und danach einen 304-Header, aber das habe ich bisher nicht hinbekommen.
Hm. Die Grösse eines Gif's von 1x1 Pixel ist so etwa
50 Bytes. Die einer Header ca. 15 Bytes. Der Unterschied halte ich
doch für verschwindend klein, warum also nicht einfach ein 200 OK
mit 1x1 Bild (und ggf. Cookie) senden? - Das Bild gehört
natürlich Hart-Codiert in einen String der ausgegeben wird (sonst
müsste das OS noch eine weitere Datei öffnen).
Naja, es funktiniert halt nur im IE, frag mich nicht warum ;-)
Ich hab wirklich _alles_ probiert (zumindest das was mit eingefallen ist), aber Firefox und Netscape gehen mit Resourcen (in diesewm Fall Bildern) die per JS geladen werden anders um, als mit HTML. Ich weiß gar nicht ob ich das alles noch zusammenbekomme, jedenfalls hat es im Firefox nur funktioniert, wenn ich _kein_ Bild sende. Sobald ich ein Bild sende - egal mit welchen Headern, auch wenn er es in HTML eingebunden sofort neu laden würde, bzw. "revalidieren", macht er das bei JS nur das erste mal. Der einzige Ausweg ist einen Zähler mitzuführen, und als Parameter an die URL anzuhängen. Da habe ich aber die Befürchtung, dass es da client-seitig irgendwann Probleme mit dem Cache/RAM gibt. Auf alle Fälle kann man den Prozessen zusehen wie sie sich nur dadurch langsam aber sicher ca. 8KB-weise aufblähen. Keine Ahnung unter welchen Bedingingen hier was "gesäubert" wird (wie gesagt, die JS-Implementierungen scheinen nicht dasselbe HTTP zu sprechen ;-)).
Wenn NS dann seinen Cache nicht richtig organisiert, trifft
dich wenigstens nicht die Schuld.
Wenn das so einfach wäre, erzähl das mal nem Kunden ;-)
Naja, die erste Variante funktioniert ja wenigstens, was mit Opera ist muss ich mal testen...
Am Schluss noch eine kleine Idee:
http://httpd.apache.org/docs/mod/mod_asis.html
Für jeden Benutzer legst du eine Datei an, welche das 1x1-Gif und
die vorbereiteten Header (und jetzt kommts: inklusive Cookie!)
bereits enthält (und z.B. durch das Eintrag-Geschrieben-Script neu
geschrieben wird) und sendest diese nicht per detector.php, sondern
über Apache direkt zum Client. Dies wäre z.B. bei einem öffentlichen
Chatroom auf HTTP-Basis wohl eine der performanteren Lösungsansätzen.
Eine sehr interessante Idee! Mein Problem mit diesen Dingen ist das folgende: Ich muss eine ganze Menge prüfen und initiieren, bevor ich weiß dass der Anwender ein entsprechendes Recht hat diese Information überhaupt zu bekommen. Es wäre recht angenehm wenn ich immer noch HTTP-Auth verwenden würde, aber leider konnte HTTP-Auth meinen Anforderungen nicht genügen, daher habe ich ein Session-basiertes Login. Der zweite Punkt ist, dass nicht jeder Anwender der eingeloggt ist, auch darauf Zugriff hat. Das Problem solcher performanten Lösunge ist jetzt, dass sie diese Prüfungen umgehen. Also müsste man diese Prüfungen auf anderer Weise vornehmen. Optimal wäre vermutlich LDAP oder ein eigenes Apache-Modul (oder lighttpd, damit soll das nach Möglichkeit auch funktionieren, aber das ist im Moment nicht wichtig), aber das ist natürlich auch nicht mal eben geschrieben - zumindest wenn man es noch nie gemacht hat.
Ich hatte (mal wieder) an mod_rewrite gedacht, welches den Request entsprechend dem Session-Cookie und der "Verzeichnis-ID" im Query-String in das Dateisystem abbildet. Das hatte ich mir schonmal als "performanten Cache" für PHP überlegt. Man könnte aus der Applikation heraus ein Verzeichnis mit einer ID für den Vorgang als Name ablegen, wo eben nur gewisse User Zugriff haben. In das Verzeichnis dann die aktuellen Session-IDs schreiben. Müsste man dann zur Not bei jedem "normalen" Request prüfen/aktualisieren. Mal etwas vereinfacht sowas:
RewriteCond %{QUERY_STRING} ID=([0-9]+)
RewriteCond %{HTTP_COOKIE} SID=([0-9a-z]{32})
RewriteCond %{DOCUMENT_ROOT}/ckeck/%0/%1 -f
ich bin noch nicht ganz sicher wie die RewriteRule aussehen sollte, aber die könnte ja z.B. wie Du es beschreibst auf eine fertige Datei inkl. Headern gelenkt werden, die bei jeder Änderung der Daten geändert wird. Aber selbst wenn ich hier auf ein PHP-Script leite, hätte ich immer noch den Vorteil, dass bei allen Requests wo sich nichts geändert hat, die Entscheidung und die Antwort selbst direkt vom Apache kommt.
Aber den
Gedanken wollte ich dennoch kurz loswerden (für die Script-Kiddies,
die mal einen so geilen HTTP-Chatroom haben möchten :-)).
Woher weißt Du... ;-)
Viele Grüsse und schönen Abend wünscht dir
Das wünsch ich Dir auch und vielen Dank für die Anregungen (mal wieder ;-))!
Viele Grüße
Andreas
Halihallo Andreas
Die Zeit... Die Zeit ist wie ein Raubtier. Du kannst ihm vielleicht
einige male entrinnen, aber am Ende holt es dich immer ein.
In diesem Sinne erst jetzt meine Antwort.
Ich überlege ja schon nebenbei, wie sowas deutlich schonender funktioniert. Den Traffic lasse ich mal außer acht, es ist erheblich "schlimmer" wenn alle User alle 2 Sekunden den Server dazu veranlassen ein komplettes PHP-Framework zu laden, 20 DB-Abfragen abzufeuern... nur weil man wissen will ob der User das überhaupt darf! So ist es halt der einfachste Weg - fürs erste.
Ich halte den Traffic ebenfalls nicht für so problematisch, wie der
erhebliche Aufwand der Scripte. Aber liesse sich diese
Authentifizierung und Überprüfung nicht irgendwie in eine Session
abbilden? - Also: Session einmal eröffnet, ist alles überprüft und es
muss nur noch die Session-Authentizität sichergestellt werden?
Hm. Die Grösse eines Gif's von 1x1 Pixel ist so etwa
50 Bytes. Die einer Header ca. 15 Bytes. Der Unterschied halte ich
doch für verschwindend klein, warum also nicht einfach ein 200 OK
mit 1x1 Bild (und ggf. Cookie) senden? - Das Bild gehört
natürlich Hart-Codiert in einen String der ausgegeben wird (sonst
müsste das OS noch eine weitere Datei öffnen).Naja, es funktiniert halt nur im IE, frag mich nicht warum ;-)
Oh, jeh. OK, das ist natürlich übel...
Ich hab wirklich _alles_ probiert (zumindest das was mit eingefallen ist), aber Firefox und Netscape gehen mit Resourcen (in diesewm Fall Bildern) die per JS geladen werden anders um, als mit HTML. Ich weiß gar nicht ob ich das alles noch zusammenbekomme, jedenfalls hat es im Firefox nur funktioniert, wenn ich _kein_ Bild sende. Sobald ich ein Bild sende - egal mit welchen Headern, auch wenn er es in HTML eingebunden sofort neu laden würde, bzw. "revalidieren", macht er das bei JS nur das erste mal. Der einzige Ausweg ist einen Zähler mitzuführen, und als Parameter an die URL anzuhängen. Da habe ich aber die Befürchtung, dass es da client-seitig irgendwann Probleme mit dem Cache/RAM gibt. Auf alle Fälle kann man den Prozessen zusehen wie sie sich nur dadurch langsam aber sicher ca. 8KB-weise aufblähen. Keine Ahnung unter welchen Bedingingen hier was "gesäubert" wird (wie gesagt, die JS-Implementierungen scheinen nicht dasselbe HTTP zu sprechen ;-)).
Ja, Firefox scheint in der Tat nur Bilder zu cachen... Andere
Ressourcen werden stets neu geladen; habe ich gerade auch bei mir
reproduziert. Nun, wenn es bei allen anderen ähnlich läuft, warum
nicht einfach kein Bild senden (ich z.B. habe es mit einem Flash-Film
versucht, der wurde immer neu geladen).
Wenn NS dann seinen Cache nicht richtig organisiert, trifft
dich wenigstens nicht die Schuld.Wenn das so einfach wäre, erzähl das mal nem Kunden ;-)
Hach ja, richtig...
Eine sehr interessante Idee! Mein Problem mit diesen Dingen ist das folgende: Ich muss eine ganze Menge prüfen und initiieren, bevor ich weiß dass der Anwender ein entsprechendes Recht hat diese Information überhaupt zu bekommen. Es wäre recht angenehm wenn ich immer noch HTTP-Auth verwenden würde, aber leider konnte HTTP-Auth meinen Anforderungen nicht genügen, daher habe ich ein Session-basiertes Login. Der zweite Punkt ist, dass nicht jeder Anwender der eingeloggt ist, auch darauf Zugriff hat. Das Problem solcher performanten Lösunge ist jetzt, dass sie diese Prüfungen umgehen.
Ich sehe das Problem...:
Damn if I do, damn if I don't...
Ich hatte (mal wieder) an mod_rewrite gedacht, welches den Request entsprechend dem Session-Cookie und der "Verzeichnis-ID" im Query-String in das Dateisystem abbildet. Das hatte ich mir schonmal als "performanten Cache" für PHP überlegt. Man könnte aus der Applikation heraus ein Verzeichnis mit einer ID für den Vorgang als Name ablegen, wo eben nur gewisse User Zugriff haben. In das Verzeichnis dann die aktuellen Session-IDs schreiben. Müsste man dann zur Not bei jedem "normalen" Request prüfen/aktualisieren. Mal etwas vereinfacht sowas:
RewriteCond %{QUERY_STRING} ID=([0-9]+)
RewriteCond %{HTTP_COOKIE} SID=([0-9a-z]{32})
RewriteCond %{DOCUMENT_ROOT}/ckeck/%0/%1 -f
Ein sehr interessanter Ansatz, wirklich!
ich bin noch nicht ganz sicher wie die RewriteRule aussehen sollte, aber die könnte ja z.B. wie Du es beschreibst auf eine fertige Datei inkl. Headern gelenkt werden, die bei jeder Änderung der Daten geändert wird. Aber selbst wenn ich hier auf ein PHP-Script leite, hätte ich immer noch den Vorteil, dass bei allen Requests wo sich nichts geändert hat, die Entscheidung und die Antwort selbst direkt vom Apache kommt.
Nun, falls es denn für deine Aufgabe überhaupt möglich ist eine
staatische Datei als Ausgabe zu definieren, so würde immer noch
einiges an Script-Traffic entstehen. Nur: wesentlich weniger als
vorher, im Normalfall. Denn: Das Script müsste nur noch im Falle
einer Datenänderung ausgeführt werden (Trigger) und nicht mehr im
Falle jedes (Lese-)Zugriffs auf "detector.php" (was jetzt eben die
as-is Datei wäre). Da Änderungen im genannten Normalfall wesentlich
weniger Häufig sind, als Anfragen auf das Set-Cookie-File
(detector.php), sinkt der Traffic auf das Script stark und wird durch
die schnellere "as-is-Architektur" (nur noch Apache, kein PHP!)
ersetzt.
Aber den
Gedanken wollte ich dennoch kurz loswerden (für die Script-Kiddies,
die mal einen so geilen HTTP-Chatroom haben möchten :-)).
Woher weißt Du... ;-)
... na, ich will natürlich auch so'n Ding! :-)
Viele Grüsse und schönen Abend wünscht dir
Das wünsch ich Dir auch und vielen Dank für die Anregungen (mal wieder ;-))!
HTH, natürlich :-)
Ach, die Servergeschichte von mir ist auch in Arbeit, aber du weisst
ja, wie es in der Wirtschaft läuft... laaaangsaaaam.
----
Aus dem anderen Posting:
Vielen Dank für den Test! (wenn Du den nicht gemacht hättest hätte ich Deine andere Antwort wohl nicht mehr gelesen ;-))
Warum hättest du meine erste Antwort nicht mehr gelesen? *lange-
leitung-hab-heute*
Viele Grüsse
Philipp
Hallo Philipp!
Die Zeit... Die Zeit ist wie ein Raubtier. Du kannst ihm vielleicht
einige male entrinnen, aber am Ende holt es dich immer ein.In diesem Sinne erst jetzt meine Antwort.
wir verstehen uns... ;-)
Ich halte den Traffic ebenfalls nicht für so problematisch, wie der
erhebliche Aufwand der Scripte. Aber liesse sich diese
Authentifizierung und Überprüfung nicht irgendwie in eine Session
abbilden? - Also: Session einmal eröffnet, ist alles überprüft und es
muss nur noch die Session-Authentizität sichergestellt werden?
Es gibt 2 Probleme:
1. wie stelle ich die Session-Authentizität denn sicher?
Durch Prüfung ob eine Session-ID übergeben wurde wäre wohl etwas - na sagen wir mutig ;-) Prüfung ob es im TMP-Verzeichnis eine Datei mit der Session-ID als Namen gibt (bzw. so wie PHP das eben speichert, ich glaub das war sess_[SID]), wobei ich mich hier auf den GC verlassen müsste, das heißt ich habe mit Sicherheit auch ungültige/abgelaufene Sessions da liegen. In jedem Fall muss man sicherstellen dass die Session-Daten in einem eigenen Verzeichnis / DB liegen, und nicht mit den Daten anderer vhosts kollidieren, wie es out-of-the-box der Normalfall ist.
2. In der Software gibt es eben Bereiche, auf die nicht jeder User zugreifen darf.
Vergleichbar mit einem Forum, wo nur bestimmte User Admin-Rechte haben. Wie willst Du jetzt diese Admin-User erkennen? Die Information steht in der Session, aber die ist ja eigentlich ein serialisierter PHP-Array. Daher könnte der User die Information im Query-String mitsenden (da habe ich ja direkt Zugriff drauf), ich muss nur gegenprüfen ob das was er da sendet auch korrekt ist. Dies sollte dann mit einer mod_rewrite-Geschichte wie unten erwähnt möglich sein.
Ja, Firefox scheint in der Tat nur Bilder zu cachen... Andere
Ressourcen werden stets neu geladen; habe ich gerade auch bei mir
reproduziert. Nun, wenn es bei allen anderen ähnlich läuft, warum
nicht einfach kein Bild senden (ich z.B. habe es mit einem Flash-Film
versucht, der wurde immer neu geladen).
Hm, irgendwie habe ich kein gutes Gefühl dabei mich auf sowas zu verlassen.
RewriteCond %{QUERY_STRING} ID=([0-9]+)
RewriteCond %{HTTP_COOKIE} SID=([0-9a-z]{32})
RewriteCond %{DOCUMENT_ROOT}/ckeck/%0/%1 -fEin sehr interessanter Ansatz, wirklich!
Diese Seite ist einigermaßen elegant, aber die andere Seite (Erzeugung der Dateien bei Änderung) ist nicht wirklich schön ;-)
Nun, falls es denn für deine Aufgabe überhaupt möglich ist eine
staatische Datei als Ausgabe zu definieren, so würde immer noch
einiges an Script-Traffic entstehen. Nur: wesentlich weniger als
vorher, im Normalfall. Denn: Das Script müsste nur noch im Falle
einer Datenänderung ausgeführt werden (Trigger) und nicht mehr im
Falle jedes (Lese-)Zugriffs auf "detector.php" (was jetzt eben die
as-is Datei wäre). Da Änderungen im genannten Normalfall wesentlich
weniger Häufig sind, als Anfragen auf das Set-Cookie-File
(detector.php), sinkt der Traffic auf das Script stark und wird durch
die schnellere "as-is-Architektur" (nur noch Apache, kein PHP!)
ersetzt.
ja, das ist in meinen Augen der wichtigste Effekt. Was mir allerdings nicht wirklich gefällt ist, dass ich bei meiner mod_rewrite Geschichte be jeder Änderung der Daten viele Dateien (eine je User) erstellen oder löschen muss. Gut, die Anzahl der User ist überschaubar, trotzdem nicht wirklich elegant.
(btw.: mod_rewrite kann auch Cookies setzen, aber ich glaube das bringt in diesem Zusammenhang nicht viel, da man den "Dateisystem-Cache" ja verändern muss, und das geht mit mod_rwrite AFAIK nicht)
Aber den
Gedanken wollte ich dennoch kurz loswerden (für die Script-Kiddies,
die mal einen so geilen HTTP-Chatroom haben möchten :-)).
Woher weißt Du... ;-)... na, ich will natürlich auch so'n Ding! :-)
Dacht ichs mir doch ;-)
Viele Grüsse und schönen Abend wünscht dir
Das wünsch ich Dir auch und vielen Dank für die Anregungen (mal wieder ;-))!HTH, natürlich :-)
immer...
Ach, die Servergeschichte von mir ist auch in Arbeit,
Das mit dem verteilten System?
aber du weisst
ja, wie es in der Wirtschaft läuft... laaaangsaaaam.
Hach ja...
Aus dem anderen Posting:
Vielen Dank für den Test! (wenn Du den nicht gemacht hättest hätte ich Deine andere Antwort wohl nicht mehr gelesen ;-))
Warum hättest du meine erste Antwort nicht mehr gelesen? *lange-
leitung-hab-heute*
"Die Zeit... Die Zeit ist wie ein Raubtier" ;-)
Ich hatte wenig Zeit und vermute dass der Thread im Archiv verschwunden wäre, hättest Du nicht noch den Test nachgeschoben...
Viele Grüße
Andreas
Halihallo Andreas
Ich halte den Traffic ebenfalls nicht für so problematisch, wie der
erhebliche Aufwand der Scripte. Aber liesse sich diese
Authentifizierung und Überprüfung nicht irgendwie in eine Session
abbilden? - Also: Session einmal eröffnet, ist alles überprüft und es
muss nur noch die Session-Authentizität sichergestellt werden?Es gibt 2 Probleme:
- wie stelle ich die Session-Authentizität denn sicher?
Durch Prüfung ob eine Session-ID übergeben wurde wäre wohl etwas - na sagen wir mutig ;-) Prüfung ob es im TMP-Verzeichnis eine Datei mit der Session-ID als Namen gibt (bzw. so wie PHP das eben speichert, ich glaub das war sess_[SID]), wobei ich mich hier auf den GC verlassen müsste, das heißt ich habe mit Sicherheit auch ungültige/abgelaufene Sessions da liegen. In jedem Fall muss man sicherstellen dass die Session-Daten in einem eigenen Verzeichnis / DB liegen, und nicht mit den Daten anderer vhosts kollidieren, wie es out-of-the-box der Normalfall ist.
Dieses Problem liesse sich im Normalfall einfach beheben:
Es wird eine Datei sess_<Session-Id>_<Session-Key> angelegt. Über
mod_rewrite z.B. wird dann die Session-Id, Session-Key aus dem
Request ausgelesen und auf die Datei mit -f getestet.
Wichtig ist einfach, dass die Session nur erstellt wird, wenn die
Authentifizierung sichergestellt ist. Das wegen dem abgelaufen, nun
ja, hier müsste man bei jedem Session-Ende die Datei wieder
löschen...
Mir ist schon klar, dass das Aufwand gäbe.
- In der Software gibt es eben Bereiche, auf die nicht jeder User zugreifen darf.
Vergleichbar mit einem Forum, wo nur bestimmte User Admin-Rechte haben. Wie willst Du jetzt diese Admin-User erkennen? Die Information steht in der Session, aber die ist ja eigentlich ein serialisierter PHP-Array. Daher könnte der User die Information im Query-String mitsenden (da habe ich ja direkt Zugriff drauf), ich muss nur gegenprüfen ob das was er da sendet auch korrekt ist. Dies sollte dann mit einer mod_rewrite-Geschichte wie unten erwähnt möglich sein.
Nun, hier fällt mir für die As-Is Lösung nur etwas ein:
An die Datei müssten alle Flags (z.B. ist-Administrator o.ä.) mit
angehängt werden. Beim Request auf den "detector.asis" müssten alle
Flags bekannt sein und auch genau denen der asis-Datei entsprechen,
so dass -f wahl liefert und die Datei ausliefert (Cookie setzt).
Oder anders formuliert: Versucht jemand ohne Admin-Rechte diese zu
erhalten und gibt beim Request admin=1 an, wird -f die Datei nicht
finden und folglich heisst dies, dass er eben keine admin-Rechte hat.
Nun ja, diese Lösung ist natürlich genauso starr wie komplizierend.
Ist also wohl auch kaum das Wahre für dich.
Hm, irgendwie habe ich kein gutes Gefühl dabei mich auf sowas zu verlassen.
Wie gefällt dir dies:
Man sendet stehts ein "404 Not found" zurück. Die Cookies werden
dennoch gespeichert, da diese völlig getrennt vom Content sind
(stehen ja auch im Header).
Funktioniert wunderbar, bis auf den Opera 7, NS4. Dort müsste man
halt wieder eine Zufallszahl anhängen (oder gleich bei allen, hat
keine Auswirkung bzw. nur auf den Traffic).
Vorteil: Der Cache sollte hier eigentlich nicht mehr vollgemüllt
werden, da ja gar keine Ressource gefunden wurde.
Und? Sprachlos? :-)
Diese Seite ist einigermaßen elegant, aber die andere Seite (Erzeugung der Dateien bei Änderung) ist nicht wirklich schön ;-)
Klar.
Ach, die Servergeschichte von mir ist auch in Arbeit,
Das mit dem verteilten System?
Jep.
Aus dem anderen Posting:
Vielen Dank für den Test! (wenn Du den nicht gemacht hättest hätte ich Deine andere Antwort wohl nicht mehr gelesen ;-))
Warum hättest du meine erste Antwort nicht mehr gelesen? *lange-
leitung-hab-heute*"Die Zeit... Die Zeit ist wie ein Raubtier" ;-)
Ich hatte wenig Zeit und vermute dass der Thread im Archiv verschwunden wäre, hättest Du nicht noch den Test nachgeschoben...
Ach so; kämpfen wir also wiedermal an der selben Front :-)
Viele Grüsse
Philipp
Hi Philipp!
- In der Software gibt es eben Bereiche, auf die nicht jeder User zugreifen darf.
[...]
Nun, hier fällt mir für die As-Is Lösung nur etwas ein:
An die Datei müssten alle Flags (z.B. ist-Administrator o.ä.) mit
angehängt werden. Beim Request auf den "detector.asis" müssten alle
Flags bekannt sein und auch genau denen der asis-Datei entsprechen,
so dass -f wahl liefert und die Datei ausliefert (Cookie setzt).
Ja, so ähnlich hatte ich das ja mit den Verzeichnissen überlegt, dürfte so funktionieren.
Nun ja, diese Lösung ist natürlich genauso starr wie komplizierend.
Ist also wohl auch kaum das Wahre für dich.
Vermutlich leider ja. Das wäre alles nicht so schlimm wenn ich mich wirklich auf einen Opcode-Cache für PHP5 verlassen könnte, aber da sieht es zur Zeit leider noch sehr Mau aus, die haben alle noch diverse Bugs, und leider verstehe ich da im C-Quellcode nur Bahnhof ;-)
Hm, irgendwie habe ich kein gutes Gefühl dabei mich auf sowas zu verlassen.
Wie gefällt dir dies:
Man sendet stehts ein "404 Not found" zurück. Die Cookies werden
dennoch gespeichert, da diese völlig getrennt vom Content sind
(stehen ja auch im Header).
Funktioniert wunderbar, bis auf den Opera 7, NS4. Dort müsste man
halt wieder eine Zufallszahl anhängen (oder gleich bei allen, hat
keine Auswirkung bzw. nur auf den Traffic).
Danke fürs probieren! Guter Tipp! Sollte auf jeden Fall günstiger für den Speicherverbrauch sein!
Vorteil: Der Cache sollte hier eigentlich nicht mehr vollgemüllt
werden, da ja gar keine Ressource gefunden wurde.Und? Sprachlos? :-)
Mal wieder ein sehr interessanter Gedanke, aber um mich sprachlos zu machen braucht es schon noch etwas ;-)
Ach so; kämpfen wir also wiedermal an der selben Front :-)
;-)
Viele Grüße
Andreas
Halihallo Andreas
Ich habe jetzt verschiedene Probleme. Das größte davon ist, dass ich nicht mit IE 5 und IE 4 testen kann, da ich diese bei mir nicht mit Cookie-Unterstützung neben meinen IE6 installieren kann. Wenn also jemand einen der beiden Browser hat, wäre ich dankbar für eine kurze Rückmeldung ob es geklappt hat ;-)
IE 5.00.2614.3500, Win OK
Opera 7.54 , Win NOK
Beim IE 5 funktioniert's. IE 4 habe ich leider nirgens mehr
installiert. Bei Opera7 hat es bei mir gar nicht funktioniert. Ich
weiss im Moment nicht, woran das liegt (Cookies habe ich aktiviert,
dieser wird auch gespeichert, aber ein Dialog-Fenster mit "Daten
haben geändert" erscheint nicht).
Viele Grüsse
Philipp
Hi Philipp!
IE 5.00.2614.3500, Win OK
Opera 7.54 , Win NOK
Vielen Dank für den Test! (wenn Du den nicht gemacht hättest hätte ich Deine andere Antwort wohl nicht mehr gelesen ;-))
Grüße
Andreas