Aufgabe 5 - mother

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

Aufgabe 5 - mother
Hallo zusammen!

Hab ein kleines problem mit der mother:

Wenn ich ins Verzeichnis /wwwdir gehe, dann wird (wie verlangt) die dort liegende index.html-Datei angezeigt.
Dann klicke ich den Hyperlink “Verzeichnis mit Perl-Skripten” und kann dann z.B. “Aufgaben” auswählen.
Warum schreibt mir der Browser jetzt folgende HTML-Anfrage in den Socket:

buffer: GET /wwwdir/perl-test/wwwdir/perl-test/Aufgaben HTTP/1.1 (das steht in meinem Puffer)
wwwPath: ., requestPath: /wwwdir/perl-test/wwwdir/perl-test/Aufgaben, combinedPath: ./wwwdir/perl-test/wwwdir/perl-test/Aufgaben (so sehen die Bestandteile für den angefragten Pfad aus)

Ich hätte halt ein GET /wwwdir/perl-test/Aufgaben HTTP/1.1 erwartet. Wenn ich jetzt aber den Pfad einfach aus dem Socket lese, dann wird die Anfrage natürlich immer fehlschlagen, da der Pfad so ja falsch ist.
Liegt das an mir? Oder weiß jemand, was ich falsch mache? :slight_smile:

Vielen Dank!

Gruß


Relativer link in der index.html?


[quote=hjk]
Ich hätte halt ein GET /wwwdir/perl-test/Aufgaben HTTP/1.1 erwartet.[/quote]

Verzeichnisse sollten immer mit Slashes am Ende aufgerufen werden – sonst funktionieren relative Links nicht korrekt. Normalerweise leiten Webserver deswegen von [m]/wwwdir/perl-test/Aufgaben[/m] nach [m]/wwwdir/perl-test/Aufgaben/[/m] weiter. Eventuell ist das sogar der Grund für dein Problem?


Danke für eure Antworten! :slight_smile:

Aber das war nicht der Grund dafür. Sondern (anscheinend) etwas anderes:
Nämlich die Tatsache, dass ich die Aufgabenstellung, dass man bei fehlendem Slash am Ende der URL die Moved-Permanently-Antwort schicken soll.
Ich hab bei der void httpMovedPermanently (FILE* tx, const char newRelPath[]) -Methode als “newRelPath” meinen combinedPath statt des requestPaths angegeben. Das war wohl der Fehler.

Danke für die Hilfe!

Edit: Sollte man dann bei all den http-Methoden immer den “requestPath” angeben?

Edit2: Ich bekomme es jetzt hin, die Perl-Skripte auszuführen. Allerdings wird mir im Terminal dann “Can’t ignore signal CHLD, forcing to default.” ausgegeben. Ist es falsch, das Einsammeln der Zombies durch das Ignorieren von SIGCHLD umszusetzen?


Das ist eine Meldung von Perl, dass es die Signalbehandlung für SIGCHLD auf den Default zurücksetzt. Das ist kein Problem. (Du könntest aber vor dem exec selbst die Signalbehandlungen auf Default zurücksetzen, dann verschwindet die Meldung. SIGCHLD kann zu dem Zeitpunkt im Kind ja eh noch nicht auftreten, also ist das auch keine Race-Condition.)


Stimmt das denn, dass bei einem fehlenden [m]/[/m] einfach folgende Seite im Browser angezeigt werden soll?

HTTP/1.0 301 Moved permanently
Location: /perl-test/
Cache-Control: no-cache

Oder soll das mit der URL angegeben werden? Also:

HTTP/1.0 301 Moved permanently
Location: http://faui42a.cs.fau.de:2014/perl-test/
Cache-Control: no-cache

[line]
[s]edit
Was anders: Ich hab für die Perl-Skripte jeweils einen Kindprozess erstellt und den sighandler im Vaterprozess auf [m]SIG_IGN[/m] gesetzt. Jetzt sagt der Server ab und zu (wenn ich z.B. ein Skript schnell mehrmals hintereinander ausführen lasse):

Can't ignore signal CHLD, forcing to default.

Woher kommt das?[/s] - wer lesen kann ist klar im Vorteil.


Dazu möchte ich einmal Wikipedia zitieren:

Früher durfte also nur die erste Version verwendet werden, mittlerweile sind beide in Ordnung.

Für die andere Frage bediene ich mich mal an einer vorhergehenden Antwort:


:facepalm: das hab ich irgendwie übersehen.

edit: es ist übrigens nicht okay, wenn der obige Text einfach angezeigt wird. Ich hatte ein [m]200 OK[/m] zuviel verschickt. man sollte einfach zum Testen [m]netcat[/m] verwenden :wink:


Wie meinst Du das? :stuck_out_tongue:


Na wenn du im Browser z.B. http://fau42k.cs.fau.de/perltest eingibst, dann solltest du einfach an http://fau42k.cs.fau.de/perltest/ weitergeleitet werden. Das bekommt man nur mit, weil in der Adressleiste eben der Schägstrich erscheint.

Diese Ausgabe:

HTTP/1.0 301 Moved permanently
Location: /perl-test/
Cache-Control: no-cache

bekommt man nur mit Programmen wie [m]netcat[/m], oder wenn man die Weiterleitungen im Browser deaktiviert.


Achso, ja. Das stimmt - ist bei uns auch so. Der Browser leitet dann automatisch weiter.
Ich hab dann einfach noch ein printf() eingebaut, um zu testen, dass der richtige Pfad durchlaufen wird und die Moved-permanently-Meldung ausgegeben wird, weil ich an netcat nicht gedacht habe.


==21727== 84 bytes in 3 blocks are still reachable in loss record 3 of 6
==21727==    at 0x4C28BED: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21727==    by 0x7BF721D: ???
==21727==    by 0x7BF4AA4: ???
==21727==    by 0x79E93EB: ???
==21727==    by 0x79E9544: ???
==21727==    by 0x513DF37: gethostbyaddr_r@@GLIBC_2.2.5 (getXXbyYY_r.c:256)
==21727==    by 0x514392E: getnameinfo (getnameinfo.c:212)
==21727==    by 0x40388C: errorPage (in /proj/i4sp2/********/trunk/aufgabe5/mother)
==21727==    by 0x402DBB: handleRequest (request-httpx.c:299)
==21727==    by 0x401F43: thread_action (connection-mt.c:66)
==21727==    by 0x4E35B4F: start_thread (pthread_create.c:304)

In der Referenzimplementierung passiert das nicht, bei mir passiert das bei jeder der i4httools-Ausgabefunktionen (hier speziell notFound für favicon). Woran kann das liegen?


Beschreib doch mal, wann das genau passiert. Was machst du in [m]errorPage[/m]? [m]getnameinfo[/m] schlaegt fehl. Was macht du damit?


Ich mache damit gar nichts, ich rufe lediglich httpNotFound(path, tx) auf und returne, also gehe aus der Funktion raus. Das sieht für mich aus als ob die vorgegebenen Funktionen irgendwo Speicher allokieren aber nicht mehr freigeben, meine bis dahin allokierten Bereich sind bereits gefreet


Was übergibst du [m]httpNotFound()[/m]? Ist [m]tx [/m]noch offen? Stimmt der Pfad?

Vielleicht passiert das ja auch gar nicht dort, wo du es vermutest. Kompilier mal mit [m]-ggdb[/m] und setzt im GDB einen Breakpoint auf [m]httpNotFound()[/m]. Dann kannst du schrittweise durchgehen und dir die Variablen anschauen.

Ansonsten kann ich nur weiter raten. Wenn das nicht hilft musst du in die Rechnerübung gehen.


Das sieht mir nach einem bekannten Bug in der C-Bibliothek aus, nicht nach einem Fehler in deinem Programm. Mich wundert’s nur, warum die Musterlösung nicht dasselbe Verhalten aufweisen sollte.


@Airhardt
Jap, scheint wirklich so zu sein. Nach mehreren Tests kommt es manchmal, sowohl bei mir, als (inzwischen) auch bei der Referenzimplementierung. Danke :slight_smile:

Socket-Vererbung
Um sicherzustellen, dass die Sockets in Ringpuffer nicht vererbt werden setzte ich in der handleConnection() die close-on-exec-Flag. So bleiben aber zwischen accept und setzten der Flag einige Instruktionen dazwischen in der der Socket vererbet werden könnte. Ist mein Ansatz falsch oder nimmt man diese kleine Chance einfach hin?


Die nimmst du hin, besser wird es - mit standardkonformen Funktionen - leider nicht. Es ist aber immer noch sehr viel besser, als die Sockets einfach offen zu lassen. Besser ginge es mit accept4(), da könntest du das Close-on-Exec direkt beim accept4() mitgeben, das ist aber eine Linux-Erweiterung und steht nicht im Standard.

1 Like