Webserver Redirect
-
tntnet schrieb:
Hallo,
ich kann das Problem hier nicht nachvollziehen. Ich habe tntnet verwendet, um genau so einen Request zu erzeugen. Der Request sieht bei mir so aus:
http://localhost:8000/redirect
und die Antwort:
HTTP/1.1 301 Moved Permanently Date: Sun, 02 Feb 2014 13:51:23 GMT Server: Tntnet/2.3 Content-Length: 26 Content-Type: text/html; charset=UTF-8 Connection: close Location: http://localhost:8000/foo http://localhost:8000/foo
Sowohl Firefox als auch Seamonkey und auch der Konquerer reagieren darauf wie erwartet. Sie führen den Redirect durch.
Hallo,
Danke für Deine Mühe. Das ist sehr komisch. Außer daß Dein Server beim Content-Type lügt, sehe ich keinen wirklichen Unterschied in der Antwort unserer Server. Vieleicht sollte ich mal ausprobieren, ob die Browser tatsächlich belogen werden wollen.
mfg Martin
-
mgaeckler schrieb:
Hallo,
Danke für Deine Mühe. Das ist sehr komisch. Außer daß Dein Server beim Content-Type lügt, sehe ich keinen wirklichen Unterschied in der Antwort unserer Server. Vieleicht sollte ich mal ausprobieren, ob die Browser tatsächlich belogen werden wollen.
mfg Martin
Hi,
auch mit "Content-Type: text/plain" funktioniert das bei mir. Das "text/html; charset=UTF-8" ist halt der default.
Das macht auch kaum Mühe. Mit tntnet ist das schnell gemacht. Hier ist die Seite, mit der ich teste:
<%cpp> const char* location = "http://localhost:8000/foo"; reply.setHeader(tnt::httpheader::location, location); reply.setContentType("text/plain"); reply.out() << location << '\n'; return HTTP_MOVED_PERMANENTLY; </%cpp>
-
tntnet schrieb:
mgaeckler schrieb:
Hallo,
Danke für Deine Mühe. Das ist sehr komisch. Außer daß Dein Server beim Content-Type lügt, sehe ich keinen wirklichen Unterschied in der Antwort unserer Server. Vieleicht sollte ich mal ausprobieren, ob die Browser tatsächlich belogen werden wollen.
mfg Martin
Hi,
auch mit "Content-Type: text/plain" funktioniert das bei mir. Das "text/html; charset=UTF-8" ist halt der default.
Das macht auch kaum Mühe. Mit tntnet ist das schnell gemacht. Hier ist die Seite, mit der ich teste:
<%cpp> const char* location = "http://localhost:8000/foo"; reply.setHeader(tnt::httpheader::location, location); reply.setContentType("text/plain"); reply.out() << location << '\n'; return HTTP_MOVED_PERMANENTLY; </%cpp>
Dann werd ich wohl mal schaun müssen, was Dein Server anders macht wie meiner.
mfg Martin
-
mgaeckler schrieb:
Dann werd ich wohl mal schaun müssen, was Dein Server anders macht wie meiner.
mfg MartinDas muß leider ausfallen.
make[1]: Entering directory
/root/tntnet/tntnet-2.2.1/sdk/demos' ../../sdk/tools/ecppc/ecppc -o alldemos.cpp alldemos.ecpp /root/tntnet/tntnet-2.2.1/sdk/tools/ecppc/.libs/ecppc: error while loading shared libraries: libcxxtools.so.9: cannot open shared object file: No such file or directory make[1]: *** [alldemos.cpp] Error 127 make[1]: Leaving directory
/root/tntnet/tntnet-2.2.1/sdk/demos'
make: *** [all-recursive] Error 1
linux-n8or:~/tntnet/tntnet-2.2.1 #mfg Martin
-
mgaeckler schrieb:
mgaeckler schrieb:
Dann werd ich wohl mal schaun müssen, was Dein Server anders macht wie meiner.
mfg MartinDas muß leider ausfallen.
make[1]: Entering directory
/root/tntnet/tntnet-2.2.1/sdk/demos' ../../sdk/tools/ecppc/ecppc -o alldemos.cpp alldemos.ecpp /root/tntnet/tntnet-2.2.1/sdk/tools/ecppc/.libs/ecppc: error while loading shared libraries: libcxxtools.so.9: cannot open shared object file: No such file or directory make[1]: *** [alldemos.cpp] Error 127 make[1]: Leaving directory
/root/tntnet/tntnet-2.2.1/sdk/demos'
make: *** [all-recursive] Error 1
linux-n8or:~/tntnet/tntnet-2.2.1 #mfg Martin
Mach mal ein
ldconfig
als root. Das hilft. Steht auch in den FAQs. Wenn man Libraries installiert, muss man immer ldconfig aufrufen, um den dynamic loader cache neu zu initialisieren.
-
tntnet schrieb:
Mach mal ein
ldconfig
als root. Das hilft. Steht auch in den FAQs. Wenn man Libraries installiert, muss man immer ldconfig aufrufen, um den dynamic loader cache neu zu initialisieren.Ich gestehe, habe nur den "quick start guide" gelesen. Danke es funktioniert jetzt. Ich werde den Fall jetzt untersuchen.
BTW: Spricht etwas dagegen, ldconfig ins makefile aufzunehmen?
mfg Martin
-
mgaeckler schrieb:
Danke es funktioniert jetzt. Ich werde den Fall jetzt untersuchen.
Bingo, ich habe meinen Fehler gefunden.
Da ärgere ich mich über mich selbst, weil 1. hab ich den RFC nicht richtig gelesen und 2. hätte ich es mir auch denken können.
Der Browser muß im HOST-Feld natürlich den Port, auf dem er schreibt, mitschicken. Das ist sinnvoll, weil der muß nicht identisch sein, mit dem Port, auf dem der Server lauscht.
Seamonkey und der IE haben daher im hostfeld localhost:12345 geschrieben. Das host-feld habe ich so wie ich's bekommen habe in den redirect eingefügt plus dem Port, auf dem mein Server lauscht. Dadurch war meine Antwort nicht wie behauptet
Location: http://localhost:12345/...
sondern
Location: http://localhost:12345:12345/...Das wurde natürlich zurecht von beiden Browsern angemossert.
Gemerkt habe ich das deshalb nicht, weil meine Prüfsoftware, mit der ich die Antwort überprüft habe, im hostfeld fälschlicherweise den Port weggelassen hat.
Jetzt habe ich sowohl den Server als auch den Client behoben und alles funkt so wie's soll.
mfg Martin
P.S.: Damit hat sich natürlich meine ursprüngliche Frage erledigt.
-
Da hätte ich für die Zukunft einen Tipp für Dich. Ich habe das so getestet:
echo -ne 'GET /redirect HTTP/1.1\r\nConnection:close\r\n\r\n'|nc localhost 8000
Damit kann ich meine Requests zusammenbauen wie ich will und sehe dann auch die komplette Antwort völlig unzensiert. Damit hattest Du es auch gleich gesehen.
Das ldconfig ist immer wieder ärgerlich. Das ist aber im Prinzip kein Problem von cxxtools/tntnet sondern ein Grundlegendes Problem des GNU Loaders. Im Build-System versuche ich mich soweit es geht an die Standards zu halten. Daher verwende ich autotools und ich verlasse mich darauf, dass die das richtig machen. Da es ein GNU Problem ist, sollte das nicht in der Library gefixt werden. Auch fürchte ich, dass Packager eher ein Problem damit haben, wenn ldconfig aufgerufen würde, da das nicht üblich ist. Tntnet läuft auch nicht nur auf GNU Systemen. Ich selbst verwende es auf der Arbeit unter AIX und dort tritt das Problem nicht auf.
-
tntnet schrieb:
Da hätte ich für die Zukunft einen Tipp für Dich. Ich habe das so getestet:
echo -ne 'GET /redirect HTTP/1.1\r\nConnection:close\r\n\r\n'|nc localhost 8000
Damit kann ich meine Requests zusammenbauen wie ich will und sehe dann auch die komplette Antwort völlig unzensiert. Damit hattest Du es auch gleich gesehen.
Guter Gedanke, hätte mir aber wahrscheinlich nix genützt, denn da mein Prüfprogramm den Port nicht angehängt hat, hätte ich das mit diesem Kommando auch nicht gemacht. Gefunden habe ich das Problem, weil ich 1. Dank Deiner Hilfe wußte, daß es hätte funktionieren müssen und 2. ich mit Wireshark den Mist gesehen habe.
tntnet schrieb:
Das ldconfig ist immer wieder ärgerlich. Das ist aber im Prinzip kein Problem von cxxtools/tntnet sondern ein Grundlegendes Problem des GNU Loaders. Im Build-System versuche ich mich soweit es geht an die Standards zu halten. Daher verwende ich autotools und ich verlasse mich darauf, dass die das richtig machen. Da es ein GNU Problem ist, sollte das nicht in der Library gefixt werden. Auch fürchte ich, dass Packager eher ein Problem damit haben, wenn ldconfig aufgerufen würde, da das nicht üblich ist. Tntnet läuft auch nicht nur auf GNU Systemen. Ich selbst verwende es auf der Arbeit unter AIX und dort tritt das Problem nicht auf.
OK sehe ich ein. Hab ich halt wohl Pech gehabt.
Übrigens, Dein Quick Start Guide enthält eine kleine Ungenauigkeit. Zumindest hat es bei mir so nicht gefunkt. Du schreibst:
To build and execute your first enter the following commands:
cd myfirstproject
make
tntnetDanach lief zwar der tntnet server, hat aber die Anwendung nicht gestartet. Ich konnte keine Verbindung herstellen. So hat's aber geklappt:
cd myfirstproject
make testZusätzlich hat der tntserver sich im Sekundentakt beschwert, weil eine Gruppe und ein User fehlte (hab jetzt vergessen wie die hiessen). Ich wundere mich, wozu er die braucht.
Ich habe mir auch erlaubt, einen Blick in Deine Quellen zu werfen. Sehr schön zu lesen, ich bin gleich zurecht gekommen. Dabei ist mir aufgefallen, daß Du eine Exception HttpReturn wirfst, wenn jemand HttpReply::redirect aufruft. Die wird zwar von Deinem Server abgefangen und dann eine entsprechende Antwort an den Client geschickt aber besteht da nicht die Gefahr, daß irgendwelche Ressourcen evtl. nicht freigegeben werden oder kann diese Funktiopn von einer Webanwendung gar nicht aufgerufen werden und Deine Objekt sind in der Lage, ihre Ressourcen in deren Destruktoren aufzuräumen?
mfg Martin
-
mgaeckler schrieb:
Ich habe mir auch erlaubt, einen Blick in Deine Quellen zu werfen. Sehr schön zu lesen, ich bin gleich zurecht gekommen. Dabei ist mir aufgefallen, daß Du eine Exception HttpReturn wirfst, wenn jemand HttpReply::redirect aufruft. Die wird zwar von Deinem Server abgefangen und dann eine entsprechende Antwort an den Client geschickt aber besteht da nicht die Gefahr, daß irgendwelche Ressourcen evtl. nicht freigegeben werden oder kann diese Funktiopn von einer Webanwendung gar nicht aufgerufen werden und Deine Objekt sind in der Lage, ihre Ressourcen in deren Destruktoren aufzuräumen?
mfg Martin
Freut mich, dass Du mit dem Code gut zurecht kommst. Die Probleme mit dem User und auch das "make test" verstehe ich nicht. Eigentlich sollte das out-of-the-box funktionieren. Und das tut es normalerweise auch.
In C++ muss man eigentlich immer exception-safe programmieren. Und tntnet ist exception-safe. Das bedeutet, dass alle Resourcen auch bei einer exception frei gegeben werden. Eine Webapplikation darf jederzeit eine Exception werfen. Tntnet kümmert sich darum, dass diese abgefangen wird und eine korrekte Antwort zum Client gesendet wird.
Genau das ist einer der größten Vorteile von C++. Nämlich dass Resourcen automatisch aufgeräumt werden können, obwohl von C++-Kritikern das Gegenteil behauptet wird. C++ braucht eben keine Garbage collection. Allerdings - und das wäre dann eher eine berechtigte Kritik - liegt das in der Verantwortung des Entwicklers. Aber wenn man sich einen gewissen Stil erlernt hat (Stichwort RAII), dann ist das gar kein Problem mehr.
-
tntnet schrieb:
Freut mich, dass Du mit dem Code gut zurecht kommst. Die Probleme mit dem User und auch das "make test" verstehe ich nicht. Eigentlich sollte das out-of-the-box funktionieren. Und das tut es normalerweise auch.
Das dachte ich mir schon. Du machst mir auch nicht den Eindruck, irgendwas hinzurotzen so nach dem Motto passt scho. Ich habe das Problem auch nicht näher untersucht, da mit dem Aufruf aus dem Makefile es ja gepasst hat.
tntnet schrieb:
In C++ muss man eigentlich immer exception-safe programmieren. Und tntnet ist exception-safe. Das bedeutet, dass alle Resourcen auch bei einer exception frei gegeben werden. Eine Webapplikation darf jederzeit eine Exception werfen. Tntnet kümmert sich darum, dass diese abgefangen wird und eine korrekte Antwort zum Client gesendet wird.
Genau das ist einer der größten Vorteile von C++. Nämlich dass Resourcen automatisch aufgeräumt werden können, obwohl von C++-Kritikern das Gegenteil behauptet wird. C++ braucht eben keine Garbage collection. Allerdings - und das wäre dann eher eine berechtigte Kritik - liegt das in der Verantwortung des Entwicklers. Aber wenn man sich einen gewissen Stil erlernt hat (Stichwort RAII), dann ist das gar kein Problem mehr.
Du hast vollkommen recht. Im übrigen muß man ja die Funktion nicht aufrufen, um einen Redirect zu senden, und es ist zumindest im Header auch dokumentiert, daß sie eine Exception wirft. So kann sich halt jeder Anwender Deines Frameworks selbst entscheiden, ob er Exceptions werfen will oder nicht.
Die C++-Kritiker haben die Philosophie von C++ nicht verstanden. Sie denken wohl, weil man nicht sicher programmieren muß, macht es auch niemand.
mfg Martin