CookieContainer Umgang mit Pfaden (Wer hat meinen Keks gegessen?)

9

Ich arbeite an einem Projekt, das einige grundlegende Web-Crawling beinhaltet. Ich habe HttpWebRequest und HttpWebResponse ziemlich erfolgreich verwendet. Für die Cookie-Behandlung habe ich nur einen CookieContainer, den ich HttpWebRequest.CookieContainer jedes Mal zuweisen. Ich werde jedes Mal automatisch mit den neuen Cookies versorgt und benötige keine zusätzliche Bearbeitung von mir. Dies alles funktioniert bis vor einiger Zeit, als eine der Websites, die früher einmal gearbeitet haben, plötzlich nicht mehr funktioniert. Ich bin mir ziemlich sicher, dass es ein Problem mit den Cookies ist, aber ich habe keine Aufzeichnungen über die Cookies von früher gemacht, so dass ich nicht 100% sicher bin.

Ich habe es geschafft, das Problem mit dem folgenden Code zu simulieren:

%Vor%

Dies simuliert den Besuch von zwei Seiten, die beide zwei Cookies setzen. Es prüft dann, welche dieser Cookies für jede der drei Seiten eingestellt werden.

Von den beiden Cookies wird einer ohne Angabe eines Pfades und der andere mit einem Pfad angegeben. Wenn ein Pfad nicht angegeben ist, hatte ich angenommen, dass der Cookie an jede Seite in dieser Domäne zurückgesendet wird, aber er scheint nur an diese bestimmte Seite zurückgesendet zu werden. Ich gehe jetzt davon aus, dass das korrekt ist, da es konsistent ist.

Das Hauptproblem für mich ist die Behandlung von Cookies mit einem angegebenen Pfad. Wenn ein Pfad angegeben wird, sollte der Cookie sicher an jede Seite gesendet werden, die in diesem Pfad enthalten ist. Daher sollte "CookieWithPath" im obigen Code für jede Seite innerhalb von / some / path / gültig sein, die page1.html, page2.html und page3.html enthält. Wenn Sie die beiden "NoPathCookie" -Instanzen auskommentieren, wird der "CookieWithPath" sicher an alle drei Seiten gesendet, wie ich es erwarten würde. Mit "NoPathCookie" wie oben beschrieben, wird "CookieWithPath" jedoch nur an page2.html und page3.html gesendet, nicht jedoch an page1.html.

Warum ist das, und ist es richtig?

Nach diesem Problem suchen Ich bin auf eine Diskussion über ein Problem mit der Domänenbehandlung in CookieContainer gestoßen, konnte aber keine Diskussion über die Pfadbehandlung finden.

Ich verwende Visual Studio 2005 / .NET 2.0

    
Andy 15.09.2010, 09:02
quelle

1 Antwort

2
  

Wenn ein Pfad nicht angegeben wurde, hatte ich angenommen, dass der Cookie an jede Seite in dieser Domäne zurückgesendet würde, aber er scheint nur an diese bestimmte Seite zurückgesendet zu werden. Ich gehe jetzt davon aus, dass das korrekt ist, da es konsistent ist.

Ja, das stimmt. Wenn Domäne oder Pfad nicht angegeben ist, wird sie vom aktuellen URI übernommen.

OK, schauen wir uns CookieContainer an. Die fragliche Methode ist InternalGetCookies (Uri) . Hier ist der interessante Teil:

%Vor%

enumerator2 Hier ist eine (sortierte) Liste der Pfade von Cookies. Es ist so sortiert, dass spezifischere Pfade (wie /directory/subdirectory/ ) vor weniger spezifische (wie /directory/ ) gehen und ansonsten - in lexikographischer Reihenfolge ( /directory/page1 geht vor /directory/page2 ).

Der Code macht tatsächlich folgendes: Er iteriert über diese Liste von Cookies-Pfaden, bis er einen ersten Pfad findet, der ein Präfix für den angeforderten URI-Pfad ist. Dann fügt es einen Cookie unter diesem Pfad zur Ausgabe hinzu und setzt flag2 auf true , was bedeutet "OK, ich habe endlich die Stelle in der Liste gefunden, die sich tatsächlich auf den angeforderten URI bezieht". Danach wird der erste gefundene Pfad, der NICHT ein Präfix für den Pfad der angefragten URI ist, als das Ende der zugehörigen Pfade betrachtet, sodass der Code die Suche nach Cookies stoppt, indem er break ausführt.

Offensichtlich ist dies eine Art Optimierung, um zu verhindern, dass die gesamte Liste gescannt wird, und es funktioniert anscheinend, wenn keiner der Pfade zu einer konkreten Seite führt. Für Ihren Fall sieht die Pfadliste folgendermaßen aus:

%Vor%

Sie können das mit einem Debugger prüfen, indem Sie ((System.Net.PathList)(cookieJar.m_domainTable["www.somedomain.com"])).m_list im Überwachungsfenster nachschlagen

Also, für den 'page1.html' URI bricht der Code bei page2.html item ab und hat keine Chance, auch /some/path/ item zu verarbeiten.

Fazit: Dies ist offensichtlich ein weiterer Fehler in CookieContainer. Ich glaube, es sollte über connect berichtet werden.

PS: Das sind zu viele Bugs pro Klasse. Ich hoffe nur, dass der Typ bei MS, der Tests für diese Klasse geschrieben hat, bereits gefeuert wurde.

    
torvin 20.02.2013 12:24
quelle