Pergunta

Estamos construindo um quadro de teste de integração abrangente em C # para a nossa aplicação que existe em cima de HTTP usando IIS7 para hospedar nossas aplicações.

Como parte de nossa integração testa queremos testar as solicitações de entrada que irá resultar em EndOfStreamExceptions ( "Não é possível ler além final do stream") que ocorrem quando um cliente envia um cabeçalho HTTP que indica um tamanho maior do corpo do que realmente transmite como parte do corpo. Queremos testar o nosso código de recuperação de erro para esta condição por isso precisamos simular esses tipos de solicitações.

Eu estou procurando uma biblioteca de soquetes baseado no Fx .NET ou costume HttpWebRequest substituição que permite especificamente desenvolvedores a simular as condições a acrescentar ao nosso conjunto de testes de integração. Alguém sabe de quaisquer bibliotecas? Uma solução programável iria funcionar tão bem.

Foi útil?

Solução

Defina a propriedade ContentLength antes de chamar GetRequestStream (ou BeginGetRequestStream) e em seguida, escrever menos bytes para esse fluxo. ContentLength vai jogar se você tentar defini-lo depois que você começou o fluxo de solicitação. Se você não definir ContentLength, HttpWebRequest irá amortecer os cabeçalhos até que o fluxo está fechado para que ele possa definir ContentLength apropriadamente (alternadamente, você pode usar SendChunked mas isso não vai funcionar para você aqui). Se você quiser o máximo controle sobre isso, crie um pedido malormed ou dois à mão e, em seguida, abrir um soquete para a porta 80 no servidor e escrever o pedido para o fluxo TCP e, em seguida, ler a resposta e verifique a conexão para ver se ele foi fechada .

No entanto: Eu não acho que este teste é uma boa idéia. Aqui está o problema:

O cliente envia uma solicitação para o servidor. Ele afirma que o conteúdo será de 100 bytes. Em seguida, envia 90 bytes e depois é só pára de enviar, deixando a conexão aberta. O servidor lê 90 bytes, então espera para o resto já que o cliente disse que 100 bytes seriam enviados. Agora, o cliente envia uma segunda solicitação. Qual será o servidor ver com os primeiros 10 bytes do novo pedido?

A resposta é que o servidor irá assumir que esses bytes faziam parte do pedido anterior e tratá-los como tal, então começar a ler o "novo" pedido 10 bytes após o seu início, que obviamente vai resultar em cabeçalhos malformados. O servidor não é assim, então vai enviar um erro 4xx e, em seguida, ele vai fechar a conexão. A razão de fechar a conexão é porque ele agora não tem nenhuma maneira de saber o que os dados enviados a ele significa e não há maneira de recuperar. Além disso, o fechamento da conexão não será graciosa, vai ser súbita e na outra extremidade que é a apresentação de um segundo pedido HttpWebRequest (ou uma terceira ou quarta se eles estão na fila) irá lançar um WebException dizendo que o conexão subjacente foi fechada e deixar você adivinhar o porquê.

Este mesmo comportamento é o que faz com que a conexão seja fechada com os Expect 100-Continue retornos de cabeçalho e o servidor 100-continuar seguido por uma 4xx como quando Auth é necessária. Mesmo que seja rejeitado o pedido, ele ainda deve assumir que os próximos bytes são parte do mesmo pedido, uma vez que se comprometeu a receber os bytes enviando o 100-continuar. Se ele não vai serviço que solicitar ou se o cliente quiser cancelar o pedido e submeter um novo (presumivelmente com as credenciais de autenticação), então ele tem que fechar a ligação e abrir uma nova.

Finalmente, testando para uma EndOfStreamException a partir de um fluxo de rede usando TCP não faz qualquer sentido para mim em tudo. O TCP não marcar o "fim" de um fluxo, ele simplesmente continua a enviar dados, como está escrito na tomada. Não há "EOF" para ele e não há maneira de detectar se os dados foram todos transmitidos se você não sabe a quantidade de dados que esperar. TCP não tem realmente um "fim" para seu fluxo a menos que a conexão é fechada, caso em que você vai ter um WebException ou um SocketException dependendo de onde na pilha você está operando. Quaisquer erros de transmissão no protocolo são tratados em winsock. Se não houver mais dados são enviados, uma extremidade da conexão irá eventualmente enviar um keepalive para o outro para garantir que a conexão ainda é realmente aberto e um host não só soltá-lo. Se os tempos de manutenção de atividade fora, a conexão será fechada e você pode obter um WebException a próxima vez que você tenta ler a partir dele. Dada a forma como tudo isso funciona, eu simplesmente não consigo ver como você está indo para obter qualquer valor fora deste teste. Você é muito melhor fora apenas o envio de pedidos mal formados e garantir que os erros são processados ??em conformidade e a mensagem 4xx apropriado está sendo enviado de volta para o cliente e a conexão está sendo fechada.

Outras dicas

Eu não sei de qualquer biblioteca, mas parece-me que seria muito simples no lado do recebimento da, se é aí que você está codificando.

Simplesmente recuperar todo o WebRequest, truncar tanto ou tão pouco como você quer, e depois enviá-lo. Talvez seja necessário fazer uma nova cópia do WebRequest no processo, em vez de truncar no local, mas ainda deve ser claro e direto.

Você não pode apenas definir a propriedade HttpWebRequest.ContentLength nos clientes para um valor menor ou maior do que o tamanho real dos dados?

Se você quiser simular todas as coisas como esta, onde você está violando o protocolo HTTP, então você terá que escrever o seu próprio código para fazê-lo. não HttpWebRequest não permitem que você faça coisas como esta.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top