[System.ServiceModel] Prevent server crash when client disconnect
authorMiguel de Icaza <miguel@gnome.org>
Mon, 16 Feb 2015 15:01:17 +0000 (10:01 -0500)
committerMiguel de Icaza <miguel@gnome.org>
Mon, 16 Feb 2015 15:01:22 +0000 (10:01 -0500)
This patch is an updated version of a pull request (377) from Rob
Wilkens to fix #5926

mcs/class/System.ServiceModel/System.ServiceModel.Channels/ReplyChannelBase.cs
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/BaseRequestProcessor.cs
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChannelDispatcher.cs

index 01d85a20b5d9f26215fd814c0dcde9f1bd8e9143..d73b0866495cf0a32fe3ef8b2796ea619e8a36f2 100644 (file)
@@ -29,11 +29,13 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Net;
+using System.Net.Sockets;
 using System.Net.Security;
 using System.ServiceModel;
 using System.ServiceModel.Description;
 using System.ServiceModel.Security;
 using System.Threading;
+using System.Xml;
 
 namespace System.ServiceModel.Channels
 {
@@ -124,12 +126,29 @@ namespace System.ServiceModel.Channels
                                        }
                                        try {
                                                return TryReceiveRequest (tout, out ctx);
+                                       } catch (XmlException ex) {
+                                               Console.WriteLine ("Xml Exception (Dropped Connection?):" + ex.Message);
+                                               //on dropped connection, 
+                                               //whatever you do don't crash
+                                               //the whole app.  Ignore for now
+                                       } catch (SocketException ex) {
+                                               Console.WriteLine ("Socket Exception (Dropped Connection?):" + ex.Message);
+                                               //on dropped connection, 
+                                               //whatever you do don't crash
+                                               //the whole app.  Ignore for now
+                                       } catch (IOException ex) {
+                                               Console.WriteLine ("I/O Exception (Dropped Connection?):" + ex.Message);
+                                               //on dropped connection, 
+                                               //whatever you do don't crash
+                                               //the whole app.  Ignore for now
                                        } finally {
                                                lock (async_result_lock) {
                                                        CurrentAsyncResult = null;
                                                        CurrentAsyncThread = null;
                                                }
                                        }
+                                       ctx = null;
+                                       return false;
                                        });
                        RequestContext dummy;
                        IAsyncResult result;
index fe05194d15b9e2054b90e581a3e7bdb55ea01ab3..1fcb4e2c413219142c6373d833efc88a60b68263 100644 (file)
@@ -5,6 +5,9 @@ using System.ServiceModel.Channels;
 using System.ServiceModel.Security;
 using System.ServiceModel.Security.Tokens;
 using System.Text;
+using System.IO;
+using System.Xml;
+using System.Net.Sockets;
 
 namespace System.ServiceModel.Dispatcher
 {
@@ -24,8 +27,34 @@ namespace System.ServiceModel.Dispatcher
                        using (new OperationContextScope (mrc.OperationContext)) {
                                try {
                                        process_handlers_chain.ProcessRequestChain (mrc);
-                               }
-                               catch (Exception e) {
+                               } catch (IOException e) {
+                                       // FIXME?: On dropped connection do not
+                                       // dump a stacktrace, but should be safe
+                                       // to dump a console message as in
+                                       // default exception handler and 
+                                       // call error_handlers_chain
+                                       Console.WriteLine ("I/O Error (Dropped Connection?): " + e.Message);
+                                       mrc.ProcessingException = e;
+                                       error_handlers_chain.ProcessRequestChain (mrc);
+                               } catch (SocketException e) {
+                                       // FIXME?: On dropped connection do not
+                                       // dump a stacktrace, but should be safe
+                                       // to dump a console message as in
+                                       // default exception handler and 
+                                       // call error_handlers_chain
+                                       Console.WriteLine ("SocketExcpetion (Dropped Connection?): " + e.Message);
+                                       mrc.ProcessingException = e;
+                                       error_handlers_chain.ProcessRequestChain (mrc);
+                               } catch (XmlException e) {
+                                       // FIXME?: On dropped connection do not
+                                       // dump a stacktrace, but should be safe
+                                       // to dump a console message as in
+                                       // default exception handler and 
+                                       // call error_handlers_chain
+                                       Console.WriteLine ("XmlException (Dropped Connection?): " + e.Message);
+                                       mrc.ProcessingException = e;
+                                       error_handlers_chain.ProcessRequestChain (mrc);                         
+                               } catch (Exception e) {
                                        // FIXME: this is not really expected use of ChannelDispatcher.ErrorHandlers.
                                        // They are now correctly used in process_handler_chain (namely OperationInvokerHandler).
                                        // For this kind of "outsider" exceptions are actually left thrown
index 15731e65a3a594d4909d5bdf3a59236debb2f5ab..ca5e2e34c81bbd40723ec97a1865f59a52b58207 100644 (file)
@@ -35,6 +35,9 @@ using System.Threading;
 using System.Transactions;
 using System.ServiceModel;
 using System.ServiceModel.Description;
+using System.Net.Sockets;
+using System.Xml;
+using System.IO;
 
 namespace System.ServiceModel.Dispatcher
 {
@@ -598,7 +601,10 @@ namespace System.ServiceModel.Dispatcher
                                        if (ProcessErrorWithHandlers (reply, ex, out res))
                                                return;
 
-                                       rc.Reply (res);
+                                       if ((!(ex is SocketException)) && 
+                                           (!(ex is XmlException)) &&
+                                           (!(ex is IOException)))
+                                               rc.Reply (res);
                                        
                                        reply.Close (owner.DefaultCloseTimeout); // close the channel
                                } finally {