Domanda

Stiamo costruendo un framework di test di integrazione completa in C # per la nostra applicazione che esiste in cima HTTP utilizzando IIS7 per ospitare le nostre applicazioni.

Come parte dei nostri test di integrazione che vogliamo testare le richieste in arrivo che si tradurrà in EndOfStreamExceptions ( "Impossibile leggere oltre la fine del flusso"), che si verificano quando un client invia un'intestazione HTTP che indica una dimensione del corpo più grande di quanto trasmette in realtà come parte del corpo. Vogliamo testare il nostro codice di recupero degli errori di questa condizione così abbiamo bisogno di simulare questo tipo di richieste.

Sto cercando una libreria presa NET Fx-based o personalizzato HttpWebRequest sostitutiva che assicuri specificamente agli sviluppatori a simulare le condizioni da aggiungere alla nostra suite di test di integrazione. Qualcuno sa di tali librerie? Una soluzione script avrebbe funzionato pure.

È stato utile?

Soluzione

Impostare la proprietà ContentLength prima di chiamare GetRequestStream (o BeginGetRequestStream) e poi scrivere un minor numero di byte a tale flusso. ContentLength getterà se si tenta di impostare dopo aver ottenuto il flusso di richiesta. Se non si imposta ContentLength, HttpWebRequest sarà tamponare le intestazioni fino a quando il flusso è chiuso in modo che possa impostare in modo appropriato ContentLength (in alternativa, è possibile utilizzare SendChunked, ma che non funziona per voi qui). Se volete il massimo controllo su questo, creare una richiesta malormed o due a mano e poi aprire un socket alla porta 80 del server e scrivere la richiesta al flusso TCP e quindi leggere la risposta e controllare la connessione per vedere se è stato chiuso .

TUTTAVIA: non credo che questo test è una buona idea. Ecco il problema:

Il client invia una richiesta al server. Si ferma il contenuto sarà di 100 byte. Quindi invia 90 byte e poi appena smette di inviare, lasciando la connessione aperta. Il server legge 90 byte, quindi attende per il resto dal momento che il cliente ha detto che 100 byte sarebbero stati inviati. Ora, il client invia una seconda richiesta. Quale sarà il server che fare con i primi 10 byte della nuova richiesta?

La risposta è che il server per scontato che quei byte facevano parte della precedente richiesta e li trattano come tali, quindi iniziare la lettura dei "nuovi" richiesta 10 byte dopo il suo inizio, che sarà ovviamente tradurrà in intestazioni malformati. Il server non piace che, in modo che manderà un errore di 4xx e poi si chiuderà la connessione. La ragione di chiudere la connessione è perché ha ormai alcun modo di sapere quali sono i dati che vengono inviati al vuol dire e non c'è modo di recuperare. Inoltre, la chiusura della connessione non sarà aggraziata, sarà improvviso e il HttpWebRequest su l'altra estremità che inoltra una seconda richiesta (o un terzo o quarto se sono in coda) lancerà un WebException dicendo che la connessione sottostante è stata chiusa e si lascia indovinare perché.

Questo stesso comportamento è ciò che provoca la connessione da chiudere con la Expect 100-continue intestazione e il server restituisce un 100 continuano seguito da un 4xx come quando è richiesta autenticazione. Anche se è respinto la richiesta, ancora deve presumere che i prossimi byte fanno parte della stessa richiesta dal momento che si è impegnato a ricevere tali byte inviando il 100-continua. Se non servirà tale richiesta o se il cliente vuole annullare la richiesta e inviare una nuova (presumibilmente con le credenziali auth) allora deve chiudere la connessione e aprirne uno nuovo.

Infine, il test per un EndOfStreamException da un flusso di rete utilizzando il protocollo TCP non ha alcun senso per me a tutti. TCP non segna la "fine" di un flusso, mantiene solo l'invio di dati come è scritto alla presa. Non v'è alcun "EOF" per essa e non c'è modo di rilevare se i dati sono stati trasmessi tutti se non si sa quanti dati aspettarsi. TCP in realtà non hanno una "fine" al suo flusso a meno che la connessione è chiusa, nel qual caso si otterrà una WebException o un SocketException a seconda di dove nello stack si opera. Eventuali errori di trasmissione nel protocollo sono trattati in Winsock. Se vengono inviati più dati, una delle estremità del collegamento saranno eventualmente un keepalive all'altro per assicurarsi che la connessione è ancora effettivamente aperto e un host non si limitò a cadere. Se i tempi di keepalive out, il collegamento sarà chiuso e si può ottenere un WebException la prossima volta che si tenta di leggere da esso. Dato come tutto questo funziona, io non vedo come si sta andando per ottenere qualsiasi valore di questo test. Tu sei molto meglio solo l'invio di richieste malformate e garantire che gli errori sono trattati di conseguenza e il messaggio 4xx appropriata viene inviato al client e la connessione viene chiusa correttamente.

Altri suggerimenti

Non so di qualsiasi libreria, ma sembra a me sarebbe molto semplice sul ricevente lato, se è lì che si esegue la codifica.

È sufficiente recuperare l'intero WebRequest, troncare tanto o poco, come si desidera, e poi in avanti su. Potrebbe essere necessario fare una nuova copia del WebRequest nel processo, piuttosto che tronca sul posto, ma dovrebbe comunque essere straight-forward.

Non puoi solo impostare la proprietà HttpWebRequest.ContentLength sui client su un valore inferiore o superiore alla dimensione effettiva dei dati?

Se si vuole simulare eventuali cose come questa, dove si sta violando il protocollo HTTP, allora si dovrà scrivere il proprio codice per farlo. HttpWebRequest non ti permettono di fare cose come questa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top