2010-02-11 15 views
10

Je me demandais si vous pouviez m'aider avec un bug que j'ai. J'ai un gestionnaire HTTP que j'ai créé qui m'aide à gérer POSTing/GETing des données de sites Web. Cela a fonctionné très bien jusqu'à récemment lorsque j'essaie d'utiliser un mélange des deux. Première boucle tout fonctionne, sur la deuxième boucle, il se bloque sur HttpWebRequest.GetRequestStream(). J'ai lu partout sur le net et n'ai trouvé aucune vraie solution. Voici les codeblocks pour l'extraction/réception:Est-ce que quelqu'un sait pourquoi je reçois un Timeout HttpWebRequest?

ASCIIEncoding encoding = new ASCIIEncoding(); 
byte[] buffer = encoding.GetBytes(_PostData); 

_HttpWebRequest = (HttpWebRequest)WebRequest.Create(_FetchUrl); 
_HttpWebRequest.Credentials = _Credentials; 
_HttpWebRequest.Method = _RequestType.ToString(); 
_HttpWebRequest.ContentType = "application/x-www-form-urlencoded"; 
_HttpWebRequest.ContentLength = buffer.Length; 
_HttpWebRequest.UserAgent = userAgent; 
_HttpWebRequest.CookieContainer = _CookieContainer; 
_HttpWebRequest.KeepAlive = false; 
_HttpWebRequest.AllowAutoRedirect = _AllowAutoRedirect; 
_HttpWebRequest.AutomaticDecompression = DecompressionMethods.GZip; 
_HttpWebRequest.ServicePoint.Expect100Continue = false; 

if (_RequestType.Equals(RequestTypes.POST)) 
{ 
    // Write POST 
Stream reqStream = _HttpWebRequest.GetRequestStream(); 
{ 
    reqStream.Write(buffer, 0, buffer.Length); 
    reqStream.Flush(); 
    reqStream.Close(); 
    } 
} 

Et le Reponse:

HttpWebResponse httpWebResponse = (HttpWebResponse)_HttpWebRequest.GetResponse(); 
{ 
    Stream responseStream = httpWebResponse.GetResponseStream(); 
    { 
    if (_UseGzip) 
    { 
     if (httpWebResponse.ContentEncoding.ToLower().Contains("gzip")) 
     { 
     responseStream = new GZipStream(responseStream, CompressionMode.Decompress); 
     } 
     else 
     { 
     responseStream = new DeflateStream(responseStream, CompressionMode.Decompress); 
     } 
    } 

    if (responseStream != null) 
    { 
     StreamReader streamReader = new StreamReader(responseStream); 
     { 
     try 
     { 
      _PageContent = streamReader.ReadToEnd(); 
     } 
     finally 
     { 
      streamReader.Close(); 
      responseStream.Close(); 
      httpWebResponse.Close(); 
     } 
     } 
    } 
    else 
    { 
     _PageContent = string.Empty; 
    } 
    } 
} 
_HttpWebRequest.Abort(); 

Quelqu'un peut-il voir des défauts à la raison pour laquelle mon code est suspendu? Tous les flux sont fermés, j'ai mis les connexions autorisées à plus de 100, je ne comprends pas pourquoi cela se casse.

+0

Avez-vous essayé d'utiliser quelque chose comme Wireshark pour voir ce que les données sont effectivement envoyées? – Foole

+0

Quand vous dites que le code fonctionne la première fois mais s'arrête sur la seconde, quelles méthodes http utilisez-vous lors des requêtes respectives? –

+0

Le code se bloque sur un poste, GET semblent fonctionner correctement. Lorsque je cours le code via un proxy burp cela fonctionne bien pour une raison quelconque? Peut-être que le proxy répare certains de mes en-têtes parce que je ne comprends pas comment cela devrait faire la différence. –

Répondre

11

Cela peut être dû au fait que vous n'êtes pas vous débarrasser de votre WebResponse ou cours d'eau ou StreamReaders:

var request = WebRequest.Create(...); 
using (var response = request.GetResponse()) 
{ 
    using (var responseStream = response.GetResponseStream()) 
    { 
     using (var reader = new StreamReader(responseStream)) 
     { 
      // use the reader 
     } 
    } 
} 
+0

J'abandonne la requête (aucune méthode disponible) et ferme tous les flux disponibles. J'ai également essayé de mettre tous les objets à zéro, puis d'appeler le GC à la fin de chaque requête pour les éliminer et cela n'a eu aucun effet. –

+2

@Paul: vous devez également disposer 'StreamReader', car il implémente' IDisposable'. Même chose avec 'Stream', que vous ne fermez pas si une exception est levée. C'est ce que le bloc 'using' fait pour vous. Il s'assure que son paramètre est Disposé, quoi qu'il arrive. Dès que j'entends que votre code échoue lors de tentatives ultérieures, je me demande, "que n'a-t-il pas fait lors de la tentative précédente?". Très souvent, la réponse est "quelque chose n'a pas été détruit". –

2

J'ai eu le même problème. J'ai fermé (disposé) tous les flux et le HttpWebResponse correctement avec ces blocs utilisant. Le problème persistait quand j'ai spammé des requêtes qui ont été annulées par ThreadAbortExceptions. Enfin, il a aidé à appeler myWebRequest.Abort() lorsque l'exception ThreadAbortException s'est produite! J'espère que cela t'aides.

0

Je vois que vous utilisez:

HttpWebRequest.AutomaticDecompression = DecompressionMethods.GZip; 

Avec l'approche de décompression manuelle:

 if (httpWebResponse.ContentEncoding.ToLower().Contains("gzip")) 
     { 
     responseStream = new GZipStream(responseStream, CompressionMode.Decompress); 
     } 
     else 
     { 
     responseStream = new DeflateStream(responseStream, CompressionMode.Decompress); 
     } 

n'a pas essayé si cela est vraiment important, mais je l'utilise uniquement approche manuelle et un code similaire, et ça marche bien. En fait, j'ai un problème d'accrochage, mais seulement avec un domaine, l'expérimentation avec les propriétés a montré une différence.

Oh, et je soupçonne que si vous n'utilisez pas la compression de données de poste, vous devez supprimer le contenu en-tête de codage