Frage

Wir bauen einen umfassenden Integration Test-Framework in C # für unsere Anwendung, die auf HTTP existiert IIS7 mit unseren Anwendungen hosten.

Im Rahmen unserer Integrationstests wir eingehende Anfragen testen möchten, die in EndOfStreamExceptions führen ( „Kann nicht über Ende des Stream lesen“), die auftreten, wenn ein Client oben sendet ein HTTP-Header angibt, eine größere Körpergröße, als es tatsächlich überträgt als Teil des Körpers. Wir wollen, dass unser Fehlerbehebungscode für diese Bedingung testen, damit wir diese Art von Anfragen simulieren müssen.

Ich bin für eine .NET-Fx-basierte Socket-Bibliothek oder benutzerdefinierten HttpWebRequest Ersatz, dass speziell Entwickler solcher Bedingungen zu simulieren, ermöglicht unsere Integrationstestsuite hinzuzufügen. Kennt jemand von solchen Bibliotheken? Eine skriptfähige Lösung würde auch funktionieren.

War es hilfreich?

Lösung

Stellen Sie die Eigenschaft ContentLength vor dem Aufruf GetRequestStream (oder BeginGetRequestStream) und dann Schreib weniger Bytes an diesem Strom. ContentLength wird ausgelöst, wenn Sie versuchen, es zu setzen, nachdem Sie die Anfrage Strom bekommen haben. Wenn Sie nicht gesetzt ContentLength tun, werden HttpWebRequest die Header-Puffer, bis der Strom geschlossen wird, so dass es ContentLength in geeigneter Weise eingestellt werden (alternativ können Sie SendChunked verwenden, aber das wird nicht funktionieren für Sie hier). Wenn Sie die maximale Kontrolle über diese möchten, erstellen Sie eine malormed Anfrage oder zwei mit der Hand und dann einen Socket auf Port 80 auf dem Server öffnen und die Anforderung an den TCP-Stream schreiben und dann die Antwort lesen und die Verbindung prüfen, ob es geschlossen wurde .

ABER: Ich glaube nicht, dass dieser Test eine gute Idee ist. Hier ist das Problem:

sendet Client eine Anfrage an den Server. Sie behauptet, der Inhalt 100 Byte sein. Er sendet dann 90 Bytes und dann einfach nicht mehr zu senden, so dass die Verbindung offen. Der Server liest 90 Bytes, wartet dann für den Rest da die Client gesagt, dass 100 Bytes gesendet werden würde. Nun sendet der Client eine zweite Anforderung. Was wird der Server tut mit dem ersten 10 Bytes der neuen Anforderung?

Die Antwort ist, dass der Server davon aus, dass diese Bytes Teil der vorherigen Anfrage war und behandelt sie als solche, dann starten Sie die „neue“ Anfrage 10 Bytes nach dem Start Lesen, die in fehlerhaften Header offensichtlich zur Folge haben werden. Der Server wird nicht so, so wird es einen Fehler 4xx senden und dann wird es die Verbindung schließen. Der Grund wird die Verbindung getrennt ist, weil es jetzt keine Möglichkeit hat, zu wissen, was die Daten gesendet werden, um es bedeutet, und keine Möglichkeit, sich zu erholen. Auch wird nicht das Schließen der Verbindung anmutig sein, wird es plötzlich und die HttpWebRequest am anderen Ende, die eine zweite Anforderung einreicht (oder ein dritten oder vierten, wenn sie eine Warteschlange eingereiht sind) wird ein WebException werfen sagen, dass die zugrunde liegende Verbindung wurde geschlossen und lassen Sie erraten, warum.

Das gleiche Verhalten ist das, was die Verbindung verursacht mit der Expect 100-Continue-Header und der Server gibt ein 100-fortgesetzt, gefolgt von einem 4xx wie geschlossen werden, wenn Auth erforderlich ist. Auch wenn er die Anfrage abgelehnt hat, davon ausgehen, noch muss es, dass das nächste Bytes Teil der gleichen Anforderung ist, da sie dieses Bytes zu empfangen durch das Senden der 100-weiter begangen hat. Wenn es wird nicht Dienst, den Wunsch oder wenn der Kunde will die Anforderung abzubrechen und einen neuen (vermutlich mit Auth-Anmeldeinformationen) einreicht dann hat es die Verbindung zu schließen und einen neuen zu öffnen.

Schließlich testet für eine EndOfStreamException von einem Netzwerk-Stream unter Verwendung von TCP macht keinen Sinn überhaupt zu mir. TCP markiert nicht das „Ende“ eines Stroms, es hält nur das Senden von Daten, wie sie an die Buchse geschrieben wird. Es gibt keinen „EOF“ für sie und keine Möglichkeit zu erkennen, ob die Daten alle übertragen wurden, es sei denn, Sie wissen, wie viele Daten zu erwarten. TCP ist nicht wirklich ein „Ende“ zu seinem Strom haben, wenn die Verbindung geschlossen wird, in dem Fall, dass Sie einen WebException oder eine Socket bekommen je nachdem, wo in dem Stapel Sie sind Betriebs. Übertragungsfehler in dem Protokoll mit in winsock behandelt. Wenn keine Daten mehr gesendet wird, wird ein Ende der Verbindung schließlich eine Keep-Alive zum anderen schicken, um sicherzustellen, dass die Verbindung immer noch ist tatsächlich offen und ein Host nicht nur fallen lassen. Wenn das Keep-Alive-Timeout, wird die Verbindung geschlossen werden und Sie können eine WebException das nächste Mal bekommen Sie versuchen, daraus zu lesen. Bedenkt man, wie all dies funktioniert, ich einfach nicht sehen, wie du gehst jeden Wert, um aus diesem Test. Sie sind viel besser dran ungültige Anforderungen nur das Senden und sichergestellt wird, dass die Fehler entsprechend verarbeitet werden, und die entsprechende 4xx Nachricht wird zurück an den Client und die Verbindung geschlossen wird richtig gesendet.

Andere Tipps

Ich weiß nicht, von einer solchen Bibliothek, aber es scheint mir, wäre es sehr einfach sein, auf der Empfangsseite, wenn es das ist, wo Sie codieren.

abrufen einfach das gesamte WebRequest, truncate so viel oder so wenig, wie Sie wollen, und dann weiterleiten. Sie können eine neue Kopie der WebRequest in dem Prozess machen müssen, anstatt truncate an Ort und Stelle, aber es sollte noch geradlinig sein.

Sie kann nicht festlegen nur die HttpWebRequest.ContentLength Eigenschaft auf dem Clients auf einen kleineren oder größeren Wert als die tatsächliche Größe der Daten?

Wenn Sie irgendwelche Dinge wie diese simulieren möchten, wo Sie das HTTP-Protokoll verstoßen, dann müssen Sie Ihren eigenen Code schreiben, es zu tun. HttpWebRequest erlaubt Ihnen nicht, solche Dinge zu tun.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top