Merge pull request #5194 from xmcclure/orbis-freeswept
[mono.git] / mcs / class / System.Web.Services / System.Web.Services.Protocols / SoapHttpClientProtocol.cs
index d8c9ad37e388653f2db85bbd977ebbd4df2a9d1c..349b41fe8eaabbf73f894218c4b7ea7a48f43605 100644 (file)
@@ -1,14 +1,14 @@
-// \r
-// System.Web.Services.Protocols.SoapHttpClientProtocol.cs\r
-//\r
-// Author:\r
-//   Tim Coleman (tim@timcoleman.com)\r
-//   Miguel de Icaza (miguel@ximian.com)\r
-//   Lluis Sanchez Gual (lluis@ximian.com)\r
-//\r
-// Copyright (C) Tim Coleman, 2002\r
-// Copyright (C) Ximian, Inc, 2003\r
-//\r
+// 
+// System.Web.Services.Protocols.SoapHttpClientProtocol.cs
+//
+// Author:
+//   Tim Coleman (tim@timcoleman.com)
+//   Miguel de Icaza (miguel@ximian.com)
+//   Lluis Sanchez Gual (lluis@ximian.com)
+//
+// Copyright (C) Tim Coleman, 2002
+// Copyright (C) Ximian, Inc, 2003
+//
 
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-\r
-using System.IO;\r
-using System.Net;\r
-using System.Web;\r
-using System.Xml;\r
-using System.Text;\r
-using System.Reflection;\r
-using System.Web.Services;\r
-using System.Diagnostics;\r
-using System.Runtime.CompilerServices;\r
-using System.Web.Services.Description;\r
-using System.Web.Services.Discovery;\r
-using System.Xml.Serialization;\r
-using System.Xml.Schema;\r
-using System.Collections;\r
-using System.Threading;\r
-\r
-namespace System.Web.Services.Protocols \r
-{\r
-       public class SoapHttpClientProtocol : HttpWebClientProtocol \r
-       {\r
-               SoapTypeStubInfo type_info;\r
-#if NET_2_0\r
-               WsiClaims conformanceClaims;\r
-               SoapProtocolVersion soapVersion;\r
-#endif\r
-\r
-               #region SoapWebClientAsyncResult class\r
-\r
-               internal class SoapWebClientAsyncResult: WebClientAsyncResult\r
-               {\r
-                       public SoapWebClientAsyncResult (WebRequest request, AsyncCallback callback, object asyncState)\r
-                       : base (request, callback, asyncState)\r
-                       {\r
-                       }\r
-               \r
-                       public SoapClientMessage Message;\r
-                       public SoapExtension[] Extensions;\r
-               }\r
-               #endregion\r
-\r
-               #region Constructors\r
-\r
-               public SoapHttpClientProtocol () \r
-               {\r
-                       type_info = (SoapTypeStubInfo) TypeStubManager.GetTypeStub (this.GetType (), "Soap");\r
-               }\r
-\r
-               #endregion // Constructors\r
-\r
-               #region Methods\r
-\r
-               protected IAsyncResult BeginInvoke (string methodName, object[] parameters, AsyncCallback callback, object asyncState)\r
-               {\r
-                       SoapMethodStubInfo msi = (SoapMethodStubInfo) type_info.GetMethod (methodName);\r
-\r
-                       SoapWebClientAsyncResult ainfo = null;\r
-                       try\r
-                       {\r
-                               SoapClientMessage message = new SoapClientMessage (this, msi, Url, parameters);\r
-                               message.CollectHeaders (this, message.MethodStubInfo.Headers, SoapHeaderDirection.In);\r
-                               \r
-                               WebRequest request = GetRequestForMessage (uri, message);\r
-                               \r
-                               ainfo = new SoapWebClientAsyncResult (request, callback, asyncState);\r
-                               ainfo.Message = message;\r
-                               ainfo.Extensions = SoapExtension.CreateExtensionChain (type_info.SoapExtensions[0], msi.SoapExtensions, type_info.SoapExtensions[1]);\r
-\r
-                               ainfo.Request.BeginGetRequestStream (new AsyncCallback (AsyncGetRequestStreamDone), ainfo);\r
-                       }\r
-                       catch (Exception ex)\r
-                       {\r
-                               if (ainfo != null)\r
-                                       ainfo.SetCompleted (null, ex, false);\r
-                       }\r
-\r
-                       return ainfo;\r
-               }\r
-\r
-               void AsyncGetRequestStreamDone (IAsyncResult ar)\r
-               {\r
-                       SoapWebClientAsyncResult ainfo = (SoapWebClientAsyncResult) ar.AsyncState;\r
-                       try\r
-                       {\r
-                               SendRequest (ainfo.Request.EndGetRequestStream (ar), ainfo.Message, ainfo.Extensions);\r
-                               ainfo.Request.BeginGetResponse (new AsyncCallback (AsyncGetResponseDone), ainfo);\r
-                       }\r
-                       catch (Exception ex)\r
-                       {\r
-                               ainfo.SetCompleted (null, ex, true);\r
-                       }\r
-               }\r
-\r
-               void AsyncGetResponseDone (IAsyncResult ar)\r
-               {\r
-                       SoapWebClientAsyncResult ainfo = (SoapWebClientAsyncResult) ar.AsyncState;\r
-                       WebResponse response = null;\r
-\r
-                       try {\r
-                               response = GetWebResponse (ainfo.Request, ar);\r
-                       }\r
-                       catch (WebException ex) {\r
-                               response = ex.Response;\r
-                               HttpWebResponse http_response = response as HttpWebResponse;\r
-                               if (http_response == null || http_response.StatusCode != HttpStatusCode.InternalServerError) {\r
-                                       ainfo.SetCompleted (null, ex, true);\r
-                                       return;\r
-                               }\r
-                       }\r
-                       catch (Exception ex) {\r
-                               ainfo.SetCompleted (null, ex, true);\r
-                               return;\r
-                       }\r
-\r
-                       try {\r
-                               object[] result = ReceiveResponse (response, ainfo.Message, ainfo.Extensions);\r
-                               ainfo.SetCompleted (result, null, true);\r
-                       }\r
-                       catch (Exception ex) {\r
-                               ainfo.SetCompleted (null, ex, true);\r
-                       }\r
+
+using System.ComponentModel;
+using System.Globalization;
+using System.IO;
+using System.Net;
+using System.Web;
+using System.Xml;
+using System.Text;
+using System.Reflection;
+using System.Web.Services;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Web.Services.Description;
+using System.Web.Services.Discovery;
+using System.Xml.Serialization;
+using System.Xml.Schema;
+using System.Collections;
+using System.Threading;
+
+namespace System.Web.Services.Protocols 
+{
+       [System.Runtime.InteropServices.ComVisible (true)]
+       public class SoapHttpClientProtocol : HttpWebClientProtocol 
+       {
+               SoapTypeStubInfo type_info;
+               SoapProtocolVersion soapVersion;
+
+               #region SoapWebClientAsyncResult class
+
+               internal class SoapWebClientAsyncResult: WebClientAsyncResult
+               {
+                       public SoapWebClientAsyncResult (WebRequest request, AsyncCallback callback, object asyncState)
+                       : base (request, callback, asyncState)
+                       {
+                       }
+               
+                       public SoapClientMessage Message;
+                       public SoapExtension[] Extensions;
+               }
+               #endregion
+
+               #region Constructors
+
+               public SoapHttpClientProtocol () 
+               {
+                       type_info = (SoapTypeStubInfo) TypeStubManager.GetTypeStub (this.GetType (), "Soap");
+               }
+
+               #endregion // Constructors
+
+               #region Methods
+
+               protected IAsyncResult BeginInvoke (string methodName, object[] parameters, AsyncCallback callback, object asyncState)
+               {
+                       SoapMethodStubInfo msi = (SoapMethodStubInfo) type_info.GetMethod (methodName);
+
+                       SoapWebClientAsyncResult ainfo = null;
+                       try
+                       {
+                               SoapClientMessage message = new SoapClientMessage (this, msi, Url, parameters);
+                               message.CollectHeaders (this, message.MethodStubInfo.Headers, SoapHeaderDirection.In);
+                               
+                               WebRequest request = GetRequestForMessage (uri, message);
+                               
+                               ainfo = new SoapWebClientAsyncResult (request, callback, asyncState);
+                               ainfo.Message = message;
+                               ainfo.Extensions = SoapExtension.CreateExtensionChain (type_info.SoapExtensions[0], msi.SoapExtensions, type_info.SoapExtensions[1]);
+
+                               ainfo.Request.BeginGetRequestStream (new AsyncCallback (AsyncGetRequestStreamDone), ainfo);
+                               RegisterMapping (asyncState, ainfo);
+                       }
+                       catch (Exception ex)
+                       {
+                               if (ainfo != null)
+                                       ainfo.SetCompleted (null, ex, false);
+                       }
+
+                       return ainfo;
+               }
+
+               void AsyncGetRequestStreamDone (IAsyncResult ar)
+               {
+                       SoapWebClientAsyncResult ainfo = (SoapWebClientAsyncResult) ar.AsyncState;
+                       try
+                       {
+                               SendRequest (ainfo.Request.EndGetRequestStream (ar), ainfo.Message, ainfo.Extensions);
+                               ainfo.Request.BeginGetResponse (new AsyncCallback (AsyncGetResponseDone), ainfo);
+                       }
+                       catch (Exception ex)
+                       {
+                               ainfo.SetCompleted (null, ex, true);
+                       }
+               }
+
+               void AsyncGetResponseDone (IAsyncResult ar)
+               {
+                       SoapWebClientAsyncResult ainfo = (SoapWebClientAsyncResult) ar.AsyncState;
+                       WebResponse response = null;
+
+                       try {
+                               response = GetWebResponse (ainfo.Request, ar);
+                       }
+                       catch (WebException ex) {
+                               response = ex.Response;
+                               HttpWebResponse http_response = response as HttpWebResponse;
+                               if (http_response == null || http_response.StatusCode != HttpStatusCode.InternalServerError) {
+                                       ainfo.SetCompleted (null, ex, true);
+                                       return;
+                               }
+                       }
+                       catch (Exception ex) {
+                               ainfo.SetCompleted (null, ex, true);
+                               return;
+                       }
+
+                       try {
+                               object[] result = ReceiveResponse (response, ainfo.Message, ainfo.Extensions);
+                               ainfo.SetCompleted (result, null, true);
+                       }
+                       catch (Exception ex) {
+                               ainfo.SetCompleted (null, ex, true);
+                       }
                        finally {
                                response.Close();
                        }
-               }\r
-\r
-               protected object[] EndInvoke (IAsyncResult asyncResult)\r
-               {\r
-                       if (!(asyncResult is SoapWebClientAsyncResult)) throw new ArgumentException ("asyncResult is not the return value from BeginInvoke");\r
-\r
-                       SoapWebClientAsyncResult ainfo = (SoapWebClientAsyncResult) asyncResult;\r
-                       lock (ainfo)\r
-                       {\r
-                               if (!ainfo.IsCompleted) ainfo.WaitForComplete ();\r
-                               if (ainfo.Exception != null) throw ainfo.Exception;\r
-                               else return (object[]) ainfo.Result;\r
-                       }\r
-               }\r
-\r
-               public void Discover ()\r
-               {\r
-                       BindingInfo bnd = (BindingInfo) type_info.Bindings [0];\r
-                       \r
-                       DiscoveryClientProtocol discoverer = new DiscoveryClientProtocol ();\r
-                       discoverer.Discover (Url);\r
-                       \r
-                       foreach (object info in discoverer.AdditionalInformation)\r
-                       {\r
-                               System.Web.Services.Discovery.SoapBinding sb = info as System.Web.Services.Discovery.SoapBinding;\r
-                               if (sb != null && sb.Binding.Name == bnd.Name && sb.Binding.Namespace == bnd.Namespace) {\r
-                                       Url = sb.Address;\r
-                                       return;\r
-                               }\r
-                       }\r
-                       \r
-                       string msg = string.Format ("The binding named '{0}' from namespace '{1}' was not found in the discovery document at '{2}'", bnd.Name, bnd.Namespace, Url);\r
-                       throw new Exception (msg);\r
-               }\r
-\r
-               protected override WebRequest GetWebRequest (Uri uri)\r
-               {\r
-                       return base.GetWebRequest (uri);\r
-               }\r
-\r
-               WebRequest GetRequestForMessage (Uri uri, SoapClientMessage message)\r
-               {\r
-                       WebRequest request = GetWebRequest (uri);\r
-                       request.Method = "POST";\r
-                       WebHeaderCollection headers = request.Headers;\r
-                       headers.Add ("SOAPAction", "\"" + message.Action + "\"");\r
-                       request.ContentType = message.ContentType + "; charset=utf-8";\r
-                       return request;\r
-               }\r
-               \r
-               void SendRequest (Stream s, SoapClientMessage message, SoapExtension[] extensions)\r
-               {\r
-                       using (s) {\r
-\r
-                               if (extensions != null) {\r
-                                       s = SoapExtension.ExecuteChainStream (extensions, s);\r
-                                       message.SetStage (SoapMessageStage.BeforeSerialize);\r
+               }
+
+               protected object[] EndInvoke (IAsyncResult asyncResult)
+               {
+                       if (!(asyncResult is SoapWebClientAsyncResult)) throw new ArgumentException ("asyncResult is not the return value from BeginInvoke");
+
+                       SoapWebClientAsyncResult ainfo = (SoapWebClientAsyncResult) asyncResult;
+                       lock (ainfo)
+                       {
+                               if (!ainfo.IsCompleted)
+                                       ainfo.WaitForComplete ();
+
+                               UnregisterMapping (ainfo.AsyncState);
+                               
+                               if (ainfo.Exception != null)
+                                       throw ainfo.Exception;
+                               else
+                                       return (object[]) ainfo.Result;
+                       }
+               }
+
+               public void Discover ()
+               {
+                       BindingInfo bnd = (BindingInfo) type_info.Bindings [0];
+                       
+                       DiscoveryClientProtocol discoverer = new DiscoveryClientProtocol ();
+                       discoverer.Discover (Url);
+                       
+                       foreach (object info in discoverer.AdditionalInformation)
+                       {
+                               System.Web.Services.Discovery.SoapBinding sb = info as System.Web.Services.Discovery.SoapBinding;
+                               if (sb != null && sb.Binding.Name == bnd.Name && sb.Binding.Namespace == bnd.Namespace) {
+                                       Url = sb.Address;
+                                       return;
+                               }
+                       }
+                       
+                       string msg = string.Format (
+                               "The binding named '{0}' from namespace '{1}' was not found in the discovery document at '{2}'",
+                               bnd.Name, bnd.Namespace, Url);
+                       throw new Exception (msg);
+               }
+
+               protected override WebRequest GetWebRequest (Uri uri)
+               {
+                       return base.GetWebRequest (uri);
+               }
+
+               WebRequest GetRequestForMessage (Uri uri, SoapClientMessage message)
+               {
+                       WebRequest request = GetWebRequest (uri);
+                       request.Method = "POST";
+                       WebHeaderCollection headers = request.Headers;
+                       request.ContentType = message.ContentType + "; charset=utf-8";
+                       if (!message.IsSoap12) {
+                               headers.Add ("SOAPAction", "\"" + message.Action + "\"");
+                       } else {
+                               request.ContentType += "; action=\"" + message.Action + "\"";
+                       }
+                       return request;
+               }
+
+               [MonoTODO]
+               protected virtual
+               XmlReader GetReaderForMessage (
+                       SoapClientMessage message, int bufferSize)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               protected virtual
+               XmlWriter GetWriterForMessage (
+                       SoapClientMessage message, int bufferSize)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               void SendRequest (Stream s, SoapClientMessage message, SoapExtension[] extensions)
+               {
+                       using (s) {
+
+                               if (extensions != null) {
+                                       s = SoapExtension.ExecuteChainStream (extensions, s);
+                                       message.SetStage (SoapMessageStage.BeforeSerialize);
                                        SoapExtension.ExecuteProcessMessage (extensions, message, s, true);
                                }
-\r
-                               XmlTextWriter xtw = WebServiceHelper.CreateXmlWriter (s);\r
-                               \r
-                               WebServiceHelper.WriteSoapMessage (xtw, message.MethodStubInfo, SoapHeaderDirection.In, message.Parameters, message.Headers);\r
-\r
-                               if (extensions != null) {\r
-                                       message.SetStage (SoapMessageStage.AfterSerialize);\r
+
+                               XmlTextWriter xtw = WebServiceHelper.CreateXmlWriter (s);
+                               WebServiceHelper.WriteSoapMessage (xtw, message.MethodStubInfo, SoapHeaderDirection.In, message.Parameters, message.Headers, message.IsSoap12);
+
+                               if (extensions != null) {
+                                       message.SetStage (SoapMessageStage.AfterSerialize);
                                        SoapExtension.ExecuteProcessMessage (extensions, message, s, true);
                                }
-\r
-                               xtw.Flush ();\r
-                               xtw.Close ();\r
-                        }\r
-               }\r
-\r
-\r
-               //\r
-               // TODO:\r
-               //    Handle other web responses (multi-output?)\r
-               //    \r
-               object [] ReceiveResponse (WebResponse response, SoapClientMessage message, SoapExtension[] extensions)\r
-               {\r
-                       SoapMethodStubInfo msi = message.MethodStubInfo;\r
-                       HttpWebResponse http_response = response as HttpWebResponse;\r
-                       \r
-                       if (http_response != null)\r
-                       {\r
-                               HttpStatusCode code = http_response.StatusCode;\r
-       \r
-                               if (!(code == HttpStatusCode.Accepted || code == HttpStatusCode.OK || code == HttpStatusCode.InternalServerError)) {\r
-                                       string msg = "The request failed with HTTP status {0}: {1}";\r
-                                       msg = String.Format (msg, (int) code, code);\r
-                                       throw new WebException (msg, null, WebExceptionStatus.ProtocolError, http_response);\r
+
+                               xtw.Flush ();
+                               xtw.Close ();
+                        }
+               }
+
+
+               //
+               // TODO:
+               //    Handle other web responses (multi-output?)
+               //    
+               object [] ReceiveResponse (WebResponse response, SoapClientMessage message, SoapExtension[] extensions)
+               {
+                       SoapMethodStubInfo msi = message.MethodStubInfo;
+                       HttpWebResponse http_response = response as HttpWebResponse;
+
+                       if (http_response != null)
+                       {
+                               HttpStatusCode code = http_response.StatusCode;
+       
+                               if (!(code == HttpStatusCode.Accepted || code == HttpStatusCode.OK || code == HttpStatusCode.InternalServerError)) {
+                                       string msg = "The request failed with HTTP status {0}: {1}";
+                                       msg = String.Format (msg, (int) code, code);
+                                       throw new WebException (msg, null, WebExceptionStatus.ProtocolError, http_response);
+                               }
+                               if (message.OneWay && response.ContentLength <= 0 && (code == HttpStatusCode.Accepted || code == HttpStatusCode.OK)) {
+                                       return new object[0];
                                }
-                               if (message.OneWay && response.ContentLength <= 0 && (code == HttpStatusCode.Accepted || code == HttpStatusCode.OK)) {\r
-                                       return new object[0];\r
-                               }\r
-                       }\r
-                       \r
-                       //\r
-                       // Remove optional encoding\r
-                       //\r
+                       }
+                       
+                       //
+                       // Remove optional encoding
+                       //
                        string ctype;
-                       Encoding encoding = WebServiceHelper.GetContentEncoding (response.ContentType, out ctype);\r
-                       if (ctype != "text/xml")
+                       Encoding encoding = WebServiceHelper.GetContentEncoding (response.ContentType, out ctype);
+                       ctype = ctype.ToLower (CultureInfo.InvariantCulture);
+                       if ((!message.IsSoap12 || ctype != "application/soap+xml") && ctype != "text/xml")
                                WebServiceHelper.InvalidOperation (
-                                       "Content is not 'text/xml' but '" + response.ContentType + "'",
+                                       String.Format ("Not supported Content-Type in the response: '{0}'", response.ContentType),
                                        response, encoding);
-\r
-                       message.ContentType = ctype;\r
-                       message.ContentEncoding = encoding.WebName;\r
-                       \r
-                       Stream stream = response.GetResponseStream ();\r
-\r
-                       if (extensions != null) {\r
-                               stream = SoapExtension.ExecuteChainStream (extensions, stream);\r
-                               message.SetStage (SoapMessageStage.BeforeDeserialize);\r
+
+                       message.ContentType = ctype;
+                       message.ContentEncoding = encoding.WebName;
+                       
+                       Stream stream = response.GetResponseStream ();
+
+                       if (extensions != null) {
+                               stream = SoapExtension.ExecuteChainStream (extensions, stream);
+                               message.SetStage (SoapMessageStage.BeforeDeserialize);
                                SoapExtension.ExecuteProcessMessage (extensions, message, stream, false);
                        }
-                       \r
-                       // Deserialize the response\r
-\r
-                       SoapHeaderCollection headers;\r
-                       object content;\r
-\r
+                       
+                       // Deserialize the response
+
+                       SoapHeaderCollection headers;
+                       object content;
+
                        using (StreamReader reader = new StreamReader (stream, encoding, false)) {
                                XmlTextReader xml_reader = new XmlTextReader (reader);
 
-                               WebServiceHelper.ReadSoapMessage (xml_reader, msi, SoapHeaderDirection.Out, out content, out headers);
+                               WebServiceHelper.ReadSoapMessage (xml_reader, msi, SoapHeaderDirection.Out, message.IsSoap12, out content, out headers);
                        }
 
-                       \r
-                       if (content is Fault)\r
-                       {\r
-                               Fault fault = (Fault) content;\r
-                               SoapException ex = new SoapException (fault.faultstring, fault.faultcode, fault.faultactor, fault.detail);\r
-                               message.SetException (ex);\r
-                       }\r
-                       else\r
-                               message.OutParameters = (object[]) content;\r
-                       \r
-                       message.SetHeaders (headers);\r
-                       message.UpdateHeaderValues (this, message.MethodStubInfo.Headers);\r
-\r
-                       if (extensions != null) {\r
-                               message.SetStage (SoapMessageStage.AfterDeserialize);\r
+                       if (content is Soap12Fault) {
+                               SoapException ex = WebServiceHelper.Soap12FaultToSoapException ((Soap12Fault) content);
+                               message.SetException (ex);
+                       }
+                       else
+                       if (content is Fault) {
+                               Fault fault = (Fault) content;
+                               SoapException ex = new SoapException (fault.faultstring, fault.faultcode, fault.faultactor, fault.detail);
+                               message.SetException (ex);
+                       }
+                       else
+                               message.OutParameters = (object[]) content;
+                       
+                       message.SetHeaders (headers);
+                       message.UpdateHeaderValues (this, message.MethodStubInfo.Headers);
+
+                       if (extensions != null) {
+                               message.SetStage (SoapMessageStage.AfterDeserialize);
                                SoapExtension.ExecuteProcessMessage (extensions, message, stream, false);
                        }
-\r
-                       if (message.Exception == null)\r
-                               return message.OutParameters;\r
-                       else\r
-                               throw message.Exception;\r
-               }\r
-\r
-               protected object[] Invoke (string method_name, object[] parameters)\r
-               {\r
-                       SoapMethodStubInfo msi = (SoapMethodStubInfo) type_info.GetMethod (method_name);\r
-                       \r
-                       SoapClientMessage message = new SoapClientMessage (this, msi, Url, parameters);\r
-                       message.CollectHeaders (this, message.MethodStubInfo.Headers, SoapHeaderDirection.In);\r
-\r
-                       SoapExtension[] extensions = SoapExtension.CreateExtensionChain (type_info.SoapExtensions[0], msi.SoapExtensions, type_info.SoapExtensions[1]);\r
-\r
-                       WebResponse response;\r
-                       try\r
-                       {\r
-                               WebRequest request = GetRequestForMessage (uri, message);\r
-                               SendRequest (request.GetRequestStream (), message, extensions);\r
-                               response = GetWebResponse (request);\r
-                       }\r
-                       catch (WebException ex)\r
-                       {\r
-                               response = ex.Response;\r
-                               HttpWebResponse http_response = response as HttpWebResponse;\r
-                               if (http_response == null || http_response.StatusCode != HttpStatusCode.InternalServerError)\r
-                                       throw ex;\r
-                       }\r
-\r
+
+                       if (message.Exception == null)
+                               return message.OutParameters;
+                       else
+                               throw message.Exception;
+               }
+
+               protected object[] Invoke (string method_name, object[] parameters)
+               {
+                       SoapMethodStubInfo msi = (SoapMethodStubInfo) type_info.GetMethod (method_name);
+                       
+                       SoapClientMessage message = new SoapClientMessage (this, msi, Url, parameters);
+                       message.CollectHeaders (this, message.MethodStubInfo.Headers, SoapHeaderDirection.In);
+
+                       SoapExtension[] extensions = SoapExtension.CreateExtensionChain (type_info.SoapExtensions[0], msi.SoapExtensions, type_info.SoapExtensions[1]);
+
+                       WebResponse response;
+                       try
+                       {
+                               WebRequest request = GetRequestForMessage (uri, message);
+                               SendRequest (request.GetRequestStream (), message, extensions);
+                               response = GetWebResponse (request);
+                       }
+                       catch (WebException ex)
+                       {
+                               response = ex.Response;
+                               HttpWebResponse http_response = response as HttpWebResponse;
+                               if (http_response == null || http_response.StatusCode != HttpStatusCode.InternalServerError)
+                                       throw ex;
+                       }
+
                        try {
-                               return ReceiveResponse (response, message, extensions);\r
+                               return ReceiveResponse (response, message, extensions);
                        }
                        finally {
                                response.Close();
                        }
-               }\r
-               \r
-#if NET_2_0\r
-\r
-               [MonoTODO ("Do something with this")]\r
-               [System.Runtime.InteropServices.ComVisible(false)]\r
-               [Obsolete]\r
-               public WsiClaims ConformanceClaims {\r
-                       get { return conformanceClaims; }\r
-                       set { conformanceClaims = value; }\r
-               }\r
-               \r
-               [MonoTODO ("Do something with this")]\r
-               [System.Runtime.InteropServices.ComVisible(false)]\r
-               public SoapProtocolVersion SoapVersion {\r
-                       get { return soapVersion; }\r
-                       set { soapVersion = value; }\r
-               }\r
-               \r
-               protected void InvokeAsync (string methodName, object[] parameters, SendOrPostCallback callback)\r
-               {\r
-                       InvokeAsync (methodName, parameters, callback, null);\r
-               }\r
-\r
-               protected void InvokeAsync (string methodName, object[] parameters, SendOrPostCallback callback, object userState)\r
-               {\r
-                       InvokeAsyncInfo info = new InvokeAsyncInfo (callback, userState);\r
-                       BeginInvoke (methodName, parameters, new AsyncCallback (InvokeAsyncCallback), info);\r
-               }\r
-               \r
-               void InvokeAsyncCallback (IAsyncResult ar)\r
-               {\r
-                       InvokeAsyncInfo info = (InvokeAsyncInfo) ar.AsyncState;\r
-                       SoapWebClientAsyncResult sar = (SoapWebClientAsyncResult) ar;\r
-                       InvokeCompletedEventArgs args = new InvokeCompletedEventArgs (sar.Exception, false, info.UserState, (object[]) sar.Result);\r
-                       if (info.Context != null)\r
-                               info.Context.Send (info.Callback, args);\r
-                       else\r
-                               info.Callback (args);\r
-               }\r
-\r
-#endif\r
-\r
-               #endregion // Methods\r
-       }\r
+               }
+               
+
+               [MonoTODO ("Do something with this")]
+               [System.Runtime.InteropServices.ComVisible(false)]
+               [DefaultValue (SoapProtocolVersion.Default)]
+               public SoapProtocolVersion SoapVersion {
+                       get { return soapVersion; }
+                       set { soapVersion = value; }
+               }
+               
+               protected void InvokeAsync (string methodName, object[] parameters, SendOrPostCallback callback)
+               {
+                       InvokeAsync (methodName, parameters, callback, null);
+               }
+
+               protected void InvokeAsync (string methodName, object[] parameters, SendOrPostCallback callback, object userState)
+               {
+                       InvokeAsyncInfo info = new InvokeAsyncInfo (callback, userState);
+                       BeginInvoke (methodName, parameters, new AsyncCallback (InvokeAsyncCallback), info);
+               }
+               
+               void InvokeAsyncCallback (IAsyncResult ar)
+               {
+                       InvokeAsyncInfo info = (InvokeAsyncInfo) ar.AsyncState;
+                       SoapWebClientAsyncResult sar = (SoapWebClientAsyncResult) ar;
+                       InvokeCompletedEventArgs args = new InvokeCompletedEventArgs (sar.Exception, false, info.UserState, (object[]) sar.Result);
+                       UnregisterMapping (ar.AsyncState);
+                       if (info.Context != null)
+                               info.Context.Send (info.Callback, args);
+                       else
+                               info.Callback (args);
+               }
+
+
+               #endregion // Methods
+       }
 }
-\r
+