2011-02-08 2 views
1

Nous avons une application utilisant HttpWebRequest pour publier des données sur un serveur distant, via HTTPS (géré par une interface apache).problème aléatoire avec HttpWebRequest sur HTTPS

La plupart du temps, tout fonctionne bien.

De temps en temps, nous avons l'exception suivante:

WebException occured SecureChannelFailure ---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel. 
    at System.Net.HttpWebRequest.GetRequestStream() 

Mais cette exception est pris, l'application retente un peu plus tard, et tout va à nouveau bien (quelque chose doit échouer dans la poignée de main HTTPS, je je ne sais pas quoi).

Récemment, nous avons eu un nouveau problème, nous ne pouvons pas reproduire:

Sur le côté site web (apache), nous avons un HTTP 403, avec le message "poignée de main Re-négociation a échoué: Non accepté par le client !? ". Sur le côté client .NET, nous avons un crash silencieux (ou l'application est bloquée sans timeout, je ne peux pas le dire). La seule chose que nous savons: ce n'est pas une exception WebException qui est correctement gérée par l'application. Malheureusement, il n'y a pas assez de journalisation des exceptions autour de cette partie du code, et nous ne pouvons pas facilement déployer une nouvelle version de l'application avec des traces System.Net pour une enquête autour de la prise de contact.

Est-ce que quelqu'un a une idée de ce qui pourrait être le problème?

Voici le code:

 HttpWebRequest req = WebRequest.Create(new Uri(url)) as HttpWebRequest; 

     // set client certificate and server certificate validation callback 
     ConfigureWebRequestSecurity(req); 

     req.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip"); 
     req.AutomaticDecompression = DecompressionMethods.GZip; 
     req.Method = "POST"; 
     req.ContentType = "text/xml"; 
     req.ContentLength = data.Length; 

     HttpWebResponse resp = null; 
     try 
     { 
      using (Stream post = req.GetRequestStream()) 
      { 
       post.Write(data, 0, data.Length); 
      } 

      resp = req.GetResponse() as HttpWebResponse; 

      Log.Logger.DebugFormat("REST : HTTP Response={0}({1})", (int)resp.StatusCode, resp.StatusCode.ToString()); 

      if (!resp.StatusCode.Equals(HttpStatusCode.OK)) 
      { 
       throw new MOServerErrorException("The server did not respond with status 200 (OK), but with " + resp.StatusCode); 
      } 
     } 
     catch (WebException e) 
     { 
      string m = string.Format("REST : WebException occured {0}", e.Status.ToString()); 
      throw new MOServerErrorException(m, e); 
     } 
     finally 
     { 
      if (resp != null) 
       resp.Close(); 
     } 

EDIT: Ok, je suis parvenu à reproduire le problème. Le thread se bloque dans GetRequestStream(). Voici la pile:

mscorlib.dll!System.Threading.WaitHandle.WaitOne(long timeout, bool exitContext) + 0x2f bytes 
    mscorlib.dll!System.Threading.WaitHandle.WaitOne(int millisecondsTimeout, bool exitContext) + 0x25 bytes  
> System.dll!System.Net.LazyAsyncResult.WaitForCompletion(bool snap) + 0xd3 bytes 
    System.dll!System.Net.Security.SslState.CheckEnqueueRead(byte[] buffer = {byte[4096]}, int offset = 0, int count = 4096, System.Net.AsyncProtocolRequest request) + 0x194 bytes 
    System.dll!System.Net.Security._SslStream.StartReading(byte[] buffer = {byte[4096]}, int offset = 0, int count = 4096, System.Net.AsyncProtocolRequest asyncRequest = null) + 0x6d bytes  
    System.dll!System.Net.Security._SslStream.ProcessRead(byte[] buffer, int offset, int count, System.Net.AsyncProtocolRequest asyncRequest = null) + 0x6b bytes 
    System.dll!System.Net.TlsStream.Read(byte[] buffer, int offset, int size) + 0x58 bytes 
    System.dll!System.Net.PooledStream.Read(byte[] buffer, int offset, int size) + 0x1b bytes 
    System.dll!System.Net.Connection.SyncRead(System.Net.HttpWebRequest request = {System.Net.HttpWebRequest}, bool userRetrievedStream = false, bool probeRead = true) + 0x12a bytes 
    System.dll!System.Net.Connection.PollAndRead(System.Net.HttpWebRequest request, bool userRetrievedStream) + 0x5a bytes 
    System.dll!System.Net.ConnectStream.PollAndRead(bool userRetrievedStream) + 0x1b bytes 
    System.dll!System.Net.HttpWebRequest.EndWriteHeaders(bool async) + 0xa2 bytes 
    System.dll!System.Net.HttpWebRequest.WriteHeadersCallback(System.Net.WebExceptionStatus errorStatus, System.Net.ConnectStream stream = {System.Net.ConnectStream}, bool async) + 0x16 bytes 
    System.dll!System.Net.ConnectStream.WriteHeaders(bool async) + 0x2d1 bytes 
    System.dll!System.Net.HttpWebRequest.EndSubmitRequest() + 0x82 bytes  
    System.dll!System.Net.HttpWebRequest.SetRequestSubmitDone(System.Net.ConnectStream submitStream) + 0xf7 bytes 
    System.dll!System.Net.Connection.CompleteConnection(bool async, System.Net.HttpWebRequest request = {System.Net.HttpWebRequest}) + 0x158 bytes 
    System.dll!System.Net.Connection.CompleteStartConnection(bool async, System.Net.HttpWebRequest httpWebRequest) + 0x177 bytes  
    System.dll!System.Net.Connection.CompleteStartRequest(bool onSubmitThread, System.Net.HttpWebRequest request = {System.Net.HttpWebRequest}, System.Net.TriState needReConnect = True) + 0x9a bytes 
    System.dll!System.Net.Connection.SubmitRequest(System.Net.HttpWebRequest request = {System.Net.HttpWebRequest}) + 0x293 bytes 
    System.dll!System.Net.ServicePoint.SubmitRequest(System.Net.HttpWebRequest request = {System.Net.HttpWebRequest}, string connName = "S>1054081937") + 0x7c bytes  
    System.dll!System.Net.HttpWebRequest.SubmitRequest(System.Net.ServicePoint servicePoint) + 0xf9 bytes 
    System.dll!System.Net.HttpWebRequest.GetRequestStream(out System.Net.TransportContext context = null) + 0x1d3 bytes 
    System.dll!System.Net.HttpWebRequest.GetRequestStream() + 0xe bytes 

Il se bloque ici, aucun délai ne. Cela ressemble à un bug dans la pile réseau !!

+0

Informations complémentaires: il existe un cas particulier dans l'application où ce code est exécuté par un thread d'arrière-plan qui possède * un gestionnaire d'exception "dernière chance" avec journalisation ... et aucune exception n'a été enregistrée! Notre meilleur pari est que la demande est bloquée, sans timeout, mais je ne sais pas comment cela pourrait être possible. Peut-être quelque chose dans la pile réseau? – mathieu

+1

J'ai vu des réponses se bloquer lorsque j'appelle 'Close()'. Je ne sais pas pourquoi cela arrive, et cela n'arrive pas très souvent. J'ai trouvé que si je fais 'request.Abort()' suivi de 'response.Close()', alors cela ne se produit jamais. Cela peut être lié à une utilisation élevée de la mémoire par l'instance réseau de svchost.exe, un problème qui me tourmente depuis un certain temps et que j'ai été incapable de trouver des informations sur. –

+0

Pourquoi ne pouvez-vous pas activer le suivi System.net? Vous venez d'ajouter un fichier de configuration d'application qui a le paramètre activé. Sans cela, il sera difficile de déboguer. Ou, vous pouvez y attacher windbg.exe, et il s'arrêtera lorsque l'application se bloque. Vous pouvez ensuite le déboguer en tant qu'application gérée. – feroze

Répondre

0

Semble être KB980817

Je n'ai pas réussi à installer le correctif proposé (configuration va bien ... mais System.dll reste inchangé). Pour contourner ce problème, j'utilise la version asynchrone de l'API (Begin ... End) et gère un délai d'expiration par moi-même.