2009-06-02 Gonzalo Paniagua Javier <gonzalo@novell.com>
[mono.git] / mcs / class / System / System.Net / VMWHttpProvider.jvm.cs
index 689ba3aa307989894b1254160e2e93e5348f0086..38470440dd4890c35ba5837451f592c208b12a34 100644 (file)
@@ -6,6 +6,13 @@ using mainsoft.apache.commons.httpclient;
 using mainsoft.apache.commons.httpclient.methods;\r
 using mainsoft.apache.commons.httpclient.@params;\r
 using mainsoft.apache.commons.httpclient.auth;\r
+using mainsoft.apache.commons.httpclient.auth.negotiate;\r
+using javax.security.auth;\r
+using org.ietf.jgss;\r
+using java.security;\r
+using System.Collections.Specialized;\r
+using System.Collections;\r
+using mainsoft.apache.commons.httpclient.cookie;\r
 \r
 namespace System.Net\r
 {\r
@@ -14,12 +21,13 @@ namespace System.Net
        /// </summary>\r
        internal class VMWHttpProvider : HttpProvider\r
        {\r
-               protected static HttpClient _client;     //todo init it in static constructor\r
+               protected static HttpClient _sclient;\r
                protected static HttpStateCache _stateCache = new HttpStateCache();\r
 \r
                protected static object LOCK_OBJECT = new object();\r
                \r
-               \r
+               protected HttpClient _client;\r
+               protected bool _disableHttpConnectionPooling = false;\r
 \r
                protected HttpMethod _method;\r
                protected HttpState _state;\r
@@ -29,8 +37,7 @@ namespace System.Net
                protected bool _hasResponse;\r
                protected bool _hasRequest;\r
                protected Stream _writeStream;\r
-               private GHWebAsyncResult _asyncWrite;\r
-               private GHWebAsyncResult _asyncRead;\r
+               private GHWebAsyncResult _asyncWrite;           \r
 \r
                private bool _isConnectionOpened;\r
                \r
@@ -57,6 +64,13 @@ namespace System.Net
                }\r
                public VMWHttpProvider(Uri uri) : base (uri)\r
                {\r
+                       string s = System.Configuration.ConfigurationSettings.AppSettings["disableHttpConnectionPooling"];\r
+                       if (s != null) \r
+                       {\r
+                               _disableHttpConnectionPooling = bool.Parse(s);\r
+                       }\r
+                       InitDefaultCredentialsProvider ();\r
+                       InitSPNProviders ();\r
                }\r
 \r
                internal override ServicePoint ServicePoint\r
@@ -93,7 +107,6 @@ namespace System.Net
 \r
                private void SetJavaCredential(NetworkCredential nc, string type, bool proxyCredentials)\r
                {\r
-                       type = type.ToLower();\r
                        string host = null;\r
                        \r
                        if(!proxyCredentials)\r
@@ -103,7 +116,7 @@ namespace System.Net
 \r
                        string domain = (nc.Domain == null) ? host : nc.Domain;\r
 \r
-                       if(type.Equals("any"))\r
+                       if(String.Compare (type, "any", StringComparison.InvariantCultureIgnoreCase) == 0)\r
                        {\r
                                if(!proxyCredentials)\r
                                {\r
@@ -120,7 +133,7 @@ namespace System.Net
                                                new NTCredentials(nc.UserName, nc.Password, host, domain));\r
                                }\r
                        }\r
-                       else if(type.Equals("basic"))\r
+                       else if(String.Compare (type, "basic", StringComparison.InvariantCultureIgnoreCase) == 0)\r
                        {\r
                                if(!proxyCredentials)\r
                                {\r
@@ -135,7 +148,7 @@ namespace System.Net
                                                new UsernamePasswordCredentials(nc.UserName, nc.Password));\r
                                }\r
                        }\r
-                       else if(type.Equals("digest"))\r
+                       else if(String.Compare (type, "digest", StringComparison.InvariantCultureIgnoreCase) == 0)\r
                        {\r
                                if(!proxyCredentials)\r
                                {\r
@@ -150,7 +163,7 @@ namespace System.Net
                                                new UsernamePasswordCredentials(nc.UserName, nc.Password));\r
                                }\r
                        }\r
-                       else if(type.Equals("ntlm"))\r
+                       else if(String.Compare (type, "ntlm", StringComparison.InvariantCultureIgnoreCase) == 0)\r
                        {\r
                                if(!proxyCredentials)\r
                                {\r
@@ -165,6 +178,10 @@ namespace System.Net
                                                new NTCredentials(nc.UserName, nc.Password, host, domain));\r
                                }\r
                        }\r
+                       else if(String.Compare (type, "negotiate", StringComparison.InvariantCultureIgnoreCase) == 0)\r
+                       {\r
+                               SetAuthenticationScheme (AuthPolicy.NEGOTIATE);\r
+                       }\r
                        else\r
                        {\r
                                if(!proxyCredentials)\r
@@ -179,18 +196,92 @@ namespace System.Net
                                                AuthScope.ANY_PORT, AuthScope.ANY_REALM, type),\r
                                                new UsernamePasswordCredentials(nc.UserName, nc.Password));\r
                                }\r
-                       }\r
+                       }                                               \r
+               }\r
 \r
+               private void SetAuthenticationScheme (string type) {                    \r
+                       _method.getHostAuthState ().setAuthScheme (AuthPolicy.getAuthScheme (type));                                                            \r
+                       if (type != null && type.ToLower () == AuthPolicy.NEGOTIATE.ToLower ()) {                                       \r
+                               _method.getParams ().setParameter (CredentialsProvider__Finals.PROVIDER, new HTTPClientCredentialsBridge( DefaultCredentialsProvider));\r
+                               _method.getParams ().setParameter (NegotiateScheme.SPN_LIST_PARAM, SPNProviders);\r
+                       }                       \r
                }\r
-               private void InitProxyCredentials()\r
-               {\r
-                       if(this.Proxy == null)\r
+\r
+               private java.util.ArrayList SPNProviders {\r
+                       get {\r
+                               return (java.util.ArrayList) AppDomain.CurrentDomain.GetData ("GH$SPNProviders");\r
+                       }\r
+                       set {\r
+                               AppDomain.CurrentDomain.SetData ("GH$SPNProviders", value);\r
+                       }\r
+               }\r
+\r
+               private void InitSPNProviders () {\r
+                       if (SPNProviders != null)\r
                                return;\r
+                       java.util.ArrayList spnProviders = new java.util.ArrayList ();\r
+                       NameValueCollection configAttributes = System.Configuration.ConfigurationSettings.AppSettings;\r
+                       string providersList = configAttributes ["SPNProviders"];\r
+                       if (providersList == null)\r
+                               return;\r
+                       string[] tokens = providersList.Split (',');\r
+                       foreach (string spnClass in tokens) {\r
+                               try {\r
+                                       spnProviders.add (Activator.CreateInstance (Type.GetType (spnClass)));\r
+                               }\r
+                               catch (Exception) { }\r
+                       }\r
+                       SPNProviders = spnProviders;\r
+               }\r
 \r
-                       if(!(this.Proxy is WebProxy))\r
+               private vmw.@internal.auth.CredentialsProvider DefaultCredentialsProvider {\r
+                       get {\r
+                               return (vmw.@internal.auth.CredentialsProvider) AppDomain.CurrentDomain.GetData ("GH$DefaultCredentialsProvider");\r
+                       }\r
+                       set {\r
+                               AppDomain.CurrentDomain.SetData ("GH$DefaultCredentialsProvider", value);\r
+                       }\r
+               }\r
+\r
+               private void InitDefaultCredentialsProvider () {\r
+                       if (DefaultCredentialsProvider != null)\r
                                return;\r
+                       vmw.@internal.auth.CredentialsProvider defaultProvider = null;\r
+                       NameValueCollection configAttributes = System.Configuration.ConfigurationSettings.AppSettings;\r
                        \r
-                       WebProxy proxy = (WebProxy)this.Proxy;\r
+                       string defaultProviderClass = configAttributes ["DefaultCredentialsProvider"];\r
+                       if (defaultProviderClass != null) {\r
+                               try {                                   \r
+                                       defaultProvider = (vmw.@internal.auth.CredentialsProvider)\r
+                                               Activator.CreateInstance (Type.GetType (defaultProviderClass));\r
+                               }\r
+                               catch (Exception e) {\r
+                                       Console.WriteLine ("Failed to initialize Credentials Provider: " + defaultProviderClass + " Message: " + e.Message);                                    \r
+                               }\r
+                       }                       \r
+\r
+                       if (defaultProvider == null) \r
+                               defaultProvider = new vmw.@internal.auth.SubjectCredentialsPrvider ();\r
+\r
+                       defaultProvider.init (ConvertToTable (configAttributes));\r
+                       DefaultCredentialsProvider = defaultProvider;\r
+               }\r
+\r
+               private java.util.Properties ConvertToTable (NameValueCollection col) {\r
+                       java.util.Properties table = new java.util.Properties ();\r
+                       foreach (String key in col.Keys)\r
+                               table.put (key, col [key]);\r
+                       return table;\r
+               }\r
+\r
+               private void InitProxyCredentials () {\r
+                       if (this.Proxy == null)\r
+                               return;\r
+\r
+                       if (!(this.Proxy is WebProxy))\r
+                               return;\r
+\r
+                       WebProxy proxy = (WebProxy) this.Proxy;\r
                        ICredentials creds = proxy.Credentials;\r
 \r
                        if(creds == null)\r
@@ -208,6 +299,10 @@ namespace System.Net
                                        {\r
                                                type = "ntlm";\r
                                                nc = ((CredentialCache)creds).GetCredential(proxy.Address, "ntlm");\r
+                                               if (nc == null) {\r
+                                                       nc = ((CredentialCache) _credentials).GetCredential (GetOriginalAddress (), "negotiate");\r
+                                                       type = "negotiate";\r
+                                               }\r
                                        }\r
                                }\r
                                if(nc != null)\r
@@ -227,9 +322,11 @@ namespace System.Net
                {\r
                        if(_credentials == null)\r
                                return;\r
-                       if(_credentials is CredentialCache)\r
-                       {\r
-                               NetworkCredential nc = ((CredentialCache)_credentials).GetCredential(GetOriginalAddress(), "basic");\r
+                       if (_credentials == CredentialCache.DefaultCredentials) {\r
+                               SetAuthenticationScheme (AuthPolicy.NEGOTIATE);\r
+                       }\r
+                       else if (_credentials is CredentialCache) {\r
+                               NetworkCredential nc = ((CredentialCache) _credentials).GetCredential (GetOriginalAddress (), "basic");\r
                                string type = "basic";\r
                                if(nc == null)\r
                                {\r
@@ -239,6 +336,10 @@ namespace System.Net
                                        {\r
                                                nc = ((CredentialCache)_credentials).GetCredential(GetOriginalAddress(), "ntlm");\r
                                                type = "ntlm";\r
+                                               if (nc == null) {\r
+                                                       nc = ((CredentialCache) _credentials).GetCredential (GetOriginalAddress (), "negotiate");\r
+                                                       type = "negotiate";\r
+                                               }\r
                                        }\r
                                }\r
                                if(nc != null)\r
@@ -256,7 +357,7 @@ namespace System.Net
 \r
                private void InitHostConfig()\r
                {\r
-                       if(this.Proxy == null)\r
+                       if (this.Proxy == null || this.Proxy == WebRequest.DefaultWebProxy)\r
                                return;\r
                        if(this.Proxy.IsBypassed(GetOriginalAddress()))\r
                                return;\r
@@ -344,7 +445,7 @@ namespace System.Net
                        \r
                        foreach(string k in Headers)\r
                        {       \r
-                               if(k.ToLower().Equals("connection"))\r
+                               if(String.Compare (k, "connection", StringComparison.InvariantCultureIgnoreCase) == 0)\r
                                        continue;\r
                                string val = Headers[k];\r
                                val = (val == null) ? "" : val;\r
@@ -352,10 +453,10 @@ namespace System.Net
                        }\r
 \r
                        if (this.CookieContainer != null) \r
-                       {
-                               string cookieHeader = this.CookieContainer.GetCookieHeader (this.GetOriginalAddress());
-                               if (cookieHeader != "")
-                                       _method.setRequestHeader("Cookie", cookieHeader);
+                       {\r
+                               string cookieHeader = this.CookieContainer.GetCookieHeader (this.GetOriginalAddress());\r
+                               if (cookieHeader != "")\r
+                                       _method.setRequestHeader("Cookie", cookieHeader);\r
                        }\r
                        SetConnectionHeader(Headers["Connection"]);\r
                        \r
@@ -365,15 +466,19 @@ namespace System.Net
                        \r
                }\r
 \r
-               private static void InitClient()\r
+               private void InitClient()\r
                {\r
                        lock(LOCK_OBJECT)\r
                        {\r
+                               if((!_disableHttpConnectionPooling) && (_client == null))\r
+                               {\r
+                                       _client = _sclient;\r
+                               }\r
                                if(_client == null)\r
                                {\r
                                        mainsoft.apache.commons.httpclient.MultiThreadedHttpConnectionManager manager =\r
                                                new mainsoft.apache.commons.httpclient.MultiThreadedHttpConnectionManager();\r
-                                       manager.setConnectionStaleCheckingEnabled(true);\r
+                                       manager.setConnectionStaleCheckingEnabled(false);\r
                                        manager.setMaxTotalConnections(200);\r
                                        //by some reasons RFC something - the default \r
                                        //value will be 2 , so we need to change it ...\r
@@ -384,6 +489,16 @@ namespace System.Net
                                        _client.getParams().setParameter(HttpClientParams.CONNECTION_MANAGER_TIMEOUT, new java.lang.Long(30000));\r
                                        _client.getParams().setParameter(HttpClientParams.USER_AGENT, \r
                                                        "VMW4J HttpClient (based on Jakarta Commons HttpClient)");\r
+                                       _client.getParams ().setBooleanParameter (HttpClientParams.SINGLE_COOKIE_HEADER, true);\r
+                                       java.util.ArrayList schemas = new java.util.ArrayList ();\r
+                                       schemas.add ("Ntlm");\r
+                                       schemas.add ("Digest");\r
+                                       schemas.add ("Basic");\r
+                                       schemas.add ("Negotiate");\r
+                                       _client.getParams ().setParameter (AuthPolicy.AUTH_SCHEME_PRIORITY, schemas);\r
+                                       if (!_disableHttpConnectionPooling) {\r
+                                               _sclient = _client;\r
+                                       }\r
                                }\r
                        }\r
                }\r
@@ -406,8 +521,14 @@ namespace System.Net
                                        switch(name)\r
                                        {\r
                                                case "GET" : _method = new GetMethod(uriString); break;\r
-                                               case "PUT" : _method = new PutMethod(uriString); break;\r
-                                               case "POST": _method = new PostMethod(uriString); break;\r
+                                               case "PUT" : _method = new PutMethod(uriString);\r
+                                                       if (ServicePointManager.Expect100Continue)\r
+                                                               _method.getParams ().setBooleanParameter (HttpMethodParams.USE_EXPECT_CONTINUE, true);\r
+                                                       break;\r
+                                               case "POST": _method = new PostMethod(uriString);\r
+                                                       if (ServicePointManager.Expect100Continue)\r
+                                                               _method.getParams ().setBooleanParameter (HttpMethodParams.USE_EXPECT_CONTINUE, true);\r
+                                                       break;\r
                                                case "HEAD": _method = new HeadMethod(uriString); break;\r
                                                case "TRACE": _method = new TraceMethod(uriString);break;\r
                                                case "DELETE": _method = new DeleteMethod(uriString);break;\r
@@ -439,6 +560,8 @@ namespace System.Net
                                throw new ProtocolViolationException();\r
                        lock(this)\r
                        {\r
+                               if (_isAborted)\r
+                                       throw new WebException ("The operation has been aborted.", WebExceptionStatus.RequestCanceled);\r
                                if(_writeStream != null)\r
                                        return _writeStream;\r
                                this.OpenConnection();\r
@@ -464,7 +587,7 @@ namespace System.Net
                                return _writeStream;\r
                        }\r
                }\r
-               private bool isRedirectNeeded(HttpMethod method)\r
+               private static bool isRedirectNeeded(HttpMethod method)\r
                {\r
                        switch (method.getStatusCode()) \r
                        {\r
@@ -472,10 +595,7 @@ namespace System.Net
                                case 301:\r
                                case 303:\r
                                case 307:\r
-                                       if (method.getFollowRedirects()) \r
-                                               return true;\r
-                                       else \r
-                                               return false;\r
+                                       return true;\r
                                default:\r
                                        return false;\r
                        } //end of switch\r
@@ -484,8 +604,8 @@ namespace System.Net
                private void synchHeaders()\r
                {\r
                        foreach(string k in Headers)\r
-                       {       \r
-                               if(k.ToLower().Equals("connection"))\r
+                       {\r
+                               if (String.Compare (k, "connection", StringComparison.InvariantCultureIgnoreCase) == 0)\r
                                        continue;\r
                                string val = Headers[k];\r
                                val = (val == null) ? "" : val;\r
@@ -493,10 +613,81 @@ namespace System.Net
                        }\r
                }\r
 \r
+               delegate WebResponse GetResponseDelegate();\r
+               private sealed class AsyncContext\r
+               {\r
+                       public readonly AsyncCallback AsyncCallback;\r
+                       public readonly Delegate AsyncDelegate;\r
+                       public readonly object AsyncState;\r
+                       public readonly DelegateAsyncResult DelegateAsyncResult;\r
+\r
+                       public AsyncContext (Delegate @delegate, DelegateAsyncResult delegateAsyncResult, AsyncCallback asyncCallback, object userState) {\r
+                               AsyncDelegate = @delegate;\r
+                               AsyncCallback = asyncCallback;\r
+                               AsyncState = userState;\r
+                               DelegateAsyncResult = delegateAsyncResult;\r
+                       }\r
+               }\r
+               private sealed class DelegateAsyncResult : IAsyncResult\r
+               {\r
+                       \r
+                       IAsyncResult _asyncResult;\r
+\r
+                       public IAsyncResult AsyncResult {\r
+                               get { return _asyncResult; }\r
+                               set { _asyncResult = value; }\r
+                       }\r
+\r
+                       AsyncContext AsyncContext {\r
+                               get { return (AsyncContext) _asyncResult.AsyncState; }\r
+                       }\r
+\r
+                       public static void Callback (IAsyncResult result) {\r
+                               AsyncContext context = (AsyncContext) result.AsyncState;\r
+                               context.AsyncCallback.Invoke (context.DelegateAsyncResult);\r
+                       }\r
+\r
+                       public Delegate AsyncDelegate {\r
+                               get { return AsyncContext.AsyncDelegate; }\r
+                       }\r
+\r
+                       #region IAsyncResult Members\r
+\r
+                       public object AsyncState {\r
+                               get { return AsyncContext.AsyncState; }\r
+                       }\r
+\r
+                       public WaitHandle AsyncWaitHandle {\r
+                               get { return _asyncResult.AsyncWaitHandle; }\r
+                       }\r
+\r
+                       public bool CompletedSynchronously {\r
+                               get { return _asyncResult.CompletedSynchronously; }\r
+                       }\r
+\r
+                       public bool IsCompleted {\r
+                               get { return _asyncResult.IsCompleted; }\r
+                       }\r
+\r
+                       #endregion\r
+               }\r
+               \r
+               WebResponse GetAsyncResponse()\r
+               {\r
+                       try {\r
+                               return GetResponse ();\r
+                       }\r
+                       catch {\r
+                               return null;\r
+                       }\r
+               }\r
+\r
                public override WebResponse GetResponse()\r
                {\r
                        lock(this)\r
                        {\r
+                               if (_isAborted)\r
+                                       throw new WebException ("The operation has been aborted.", WebExceptionStatus.RequestCanceled);\r
                                if(!_isConnectionOpened)\r
                                        OpenConnection();\r
                                if(_response == null)\r
@@ -504,7 +695,14 @@ namespace System.Net
                                        try\r
                                        {       \r
                                                synchHeaders();\r
-                                               _client.executeMethod(_hostConfig, _method, _state);\r
+                                               InternalExecuteMethod ();                                               \r
+                                               int numOfRedirects = 0;\r
+                                               while (isRedirectNeeded (_method) && _allowAutoRedirect && numOfRedirects < MaxAutoRedirections) {\r
+                                                       if (!HandleManualyRedirect ())\r
+                                                               break;\r
+                                                       numOfRedirects++;\r
+                                               }\r
+                                               \r
                                                //todo right place to re-put all headers again...\r
                                                mainsoft.apache.commons.httpclient.Header hostHeader =\r
                                                        _method.getRequestHeader("Host");\r
@@ -540,7 +738,8 @@ namespace System.Net
                                                        //this.Abort();\r
                                                        throw new WebException("The remote server returned an error: (" + respCodeAsInt +") " +_response.StatusCode, null, WebExceptionStatus.ProtocolError, _response);\r
                                                }\r
-                                               if(isRedirectNeeded(_method) && _method.getResponseHeader("location") == null)\r
+                                               Header location = _method.getResponseHeader ("location");\r
+                                               if (isRedirectNeeded (_method) && location == null && _method.getFollowRedirects ())\r
                                                {\r
                                                        // See comments above for the error >= 400\r
                                                        _response.ReadAllAndClose();\r
@@ -570,19 +769,62 @@ namespace System.Net
 \r
                }\r
 \r
+               private void InternalExecuteMethod () {\r
+                       _client.executeMethod (_hostConfig, _method, _state);                   \r
+               }               \r
+\r
+               private bool HandleManualyRedirect () {                 \r
+                       Header redirectHeader = _method.getResponseHeader ("location");\r
+                       if (redirectHeader == null) {\r
+                               // See comments above for the error >= 400\r
+                               _response.ReadAllAndClose ();\r
+                               //this.Abort();\r
+                               throw new WebException ("Got response code " + _response.StatusCode + ", but no location provided", null, WebExceptionStatus.ProtocolError, _response);\r
+                       }\r
+\r
+                       mainsoft.apache.commons.httpclient.HttpMethod originalMethod = _method;\r
+                       try {\r
+                               string location = redirectHeader.getValue ();\r
+                               URI currentUri = _method.getURI ();\r
+                               URI redirectUri = null;\r
+\r
+                               redirectUri = new URI (location, true);\r
+                               if (redirectUri.isRelativeURI ()) {\r
+                                       //location is incomplete, use current values for defaults       \r
+                                       redirectUri = new URI (currentUri, redirectUri);\r
+                               }\r
+                               \r
+                               _method = new GetMethod ();\r
+                               foreach(Header h in originalMethod.getRequestHeaders())\r
+                                       _method.addRequestHeader(h);                            \r
+                               _method.setURI (redirectUri);                           \r
+                               InternalExecuteMethod ();\r
+                               return true;\r
+                       }\r
+                       catch (URIException e) {\r
+                               _method = originalMethod;\r
+                               return false;\r
+                       }\r
+               }\r
+\r
                public override void Abort()\r
                {\r
-                       _isAborted = true;\r
-                       try\r
-                       {\r
-                               if(_hasResponse)\r
-                               {\r
-                                       _response.Close();\r
+                       lock (this) {\r
+                               if (_isAborted)\r
+                                       return;\r
+                               _isAborted = true;\r
+                               try {\r
+                                       if (_hasResponse) {\r
+                                               _response.Close ();\r
+                                       }\r
+                               }\r
+                               finally {\r
+                                       if (_method != null)\r
+                                               _method.releaseConnection ();\r
+                                       _method = null;\r
+                                       _hasResponse = false;\r
+                                       _response = null;\r
                                }\r
-                       }\r
-                       finally\r
-                       {\r
-                               _method.releaseConnection();                            \r
                        }\r
                }\r
 \r
@@ -592,18 +834,18 @@ namespace System.Net
                        {\r
                                if(_asyncWrite != null)\r
                                {\r
-                                       throw new InvalidOperationException ("Cannot re-call start of asynchronous " +
-                                               "method while a previous call is still in progress.");
-                               }
-       
-                               _asyncWrite = new GHWebAsyncResult (this, callback, state);
-                               if (_hasRequest) 
-                               {
-                                       if (_writeStream != null) 
-                                       {
-                                               _asyncWrite.SetCompleted (true, _writeStream);
-                                               _asyncWrite.DoCallback ();
-                                               return _asyncWrite;
+                                       throw new InvalidOperationException ("Cannot re-call start of asynchronous " +\r
+                                               "method while a previous call is still in progress.");\r
+                               }\r
+       \r
+                               _asyncWrite = new GHWebAsyncResult (this, callback, state);\r
+                               if (_hasRequest) \r
+                               {\r
+                                       if (_writeStream != null) \r
+                                       {\r
+                                               _asyncWrite.SetCompleted (true, _writeStream);\r
+                                               _asyncWrite.DoCallback ();\r
+                                               return _asyncWrite;\r
                                        }\r
                                }\r
                                \r
@@ -615,10 +857,12 @@ namespace System.Net
                                catch(Exception e)\r
                                {\r
                                        _asyncWrite.SetCompleted(false, e);\r
+                                       _asyncWrite.DoCallback ();\r
+                                       return _asyncWrite;\r
                                }\r
 \r
-                               _asyncWrite.SetCompleted (true, _writeStream);
-                               _asyncWrite.DoCallback ();
+                               _asyncWrite.SetCompleted (true, _writeStream);\r
+                               _asyncWrite.DoCallback ();\r
                                return _asyncWrite;\r
                                \r
                        }\r
@@ -626,80 +870,46 @@ namespace System.Net
 \r
                public override Stream EndGetRequestStream(IAsyncResult asyncResult)\r
                {\r
-                       if (asyncResult == null)
-                               throw new ArgumentNullException ("asyncResult");
-
-                       GHWebAsyncResult result = asyncResult as GHWebAsyncResult;
-                       if (result == null)
-                               throw new ArgumentException ("Invalid IAsyncResult");
-
-                       _asyncWrite = result;
-
-                       result.WaitUntilComplete ();
-
-                       Exception e = result.Exception;
-                       
-                       if (e != null)
-                               throw e;
-
+                       if (asyncResult == null)\r
+                               throw new ArgumentNullException ("asyncResult");\r
+\r
+                       GHWebAsyncResult result = asyncResult as GHWebAsyncResult;\r
+                       if (result == null)\r
+                               throw new ArgumentException ("Invalid IAsyncResult");\r
+\r
+                       _asyncWrite = result;\r
+\r
+                       result.WaitUntilComplete ();\r
+\r
+                       Exception e = result.Exception;\r
+                       \r
+                       if (e != null)\r
+                               throw e;\r
+\r
                        return result.WriteStream;\r
                }\r
 \r
                public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state)\r
                {\r
-                       lock(this)\r
-                       {\r
-                               if(_asyncRead != null && !_hasResponse)\r
-                               {\r
-                                       throw new InvalidOperationException ("Cannot re-call start of asynchronous " +
-                                               "method while a previous call is still in progress.");
-                               }
-       
-                               _asyncRead = new GHWebAsyncResult (this, callback, state);
-                               if (_hasResponse) 
-                               {
-                                       if (_response != null) 
-                                       {
-                                               _asyncRead.SetCompleted (true, _writeStream);
-                                               _asyncRead.DoCallback ();
-                                               return _asyncRead;
-                                       }\r
-                               }\r
-                               \r
-\r
-                               try\r
-                               {\r
-                                       GetResponse();\r
-                               }\r
-                               catch(Exception e)\r
-                               {\r
-                                       _asyncRead.SetCompleted(false, e);\r
-                               }
-                               _asyncRead.SetCompleted (true, _writeStream);
-                               _asyncRead.DoCallback ();       
-                               return _asyncRead;\r
-                               \r
-                       }\r
+                       GetResponseDelegate d = new GetResponseDelegate (GetAsyncResponse);\r
+                       DelegateAsyncResult result = new DelegateAsyncResult ();\r
+                       AsyncContext userContext = new AsyncContext (d, result, callback, state);\r
+                       result.AsyncResult = d.BeginInvoke (new AsyncCallback (DelegateAsyncResult.Callback), userContext);\r
+                       return result;\r
                }\r
 \r
                public override WebResponse EndGetResponse(IAsyncResult asyncResult)\r
                {\r
-                       if (asyncResult == null)
-                               throw new ArgumentNullException ("asyncResult");
-
-                       GHWebAsyncResult result = asyncResult as GHWebAsyncResult;
-                       if (result == null)
-                               throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
-
-                       
-                       _asyncRead = result;
-                       if (!result.WaitUntilComplete (_timeout, false)) \r
-                       {
-                               Abort ();
-                               throw new WebException("The request timed out", WebExceptionStatus.Timeout);
-                       }
-                       
-                       return result.Response;\r
+                       if (_isAborted)\r
+                               throw new WebException ("The operation has been aborted.", WebExceptionStatus.RequestCanceled);\r
+                       if (asyncResult == null)\r
+                               throw new ArgumentNullException ("asyncResult");\r
+\r
+                       DelegateAsyncResult result = asyncResult as DelegateAsyncResult;\r
+                       if (result == null)\r
+                               throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");\r
+\r
+                       return ((GetResponseDelegate) result.AsyncDelegate).EndInvoke (result.AsyncResult);\r
                }\r
 \r
 \r
@@ -775,9 +985,14 @@ namespace System.Net
                                        {\r
                                                if(!_closed)\r
                                                {\r
-                                                       _closed = true;\r
-                                                       _javaOutput.flush();\r
-                                                       _javaOutput.close();\r
+                                                       try {\r
+                                                               _closed = true;\r
+                                                               _javaOutput.close ();\r
+                                                       }\r
+                                                       catch (Exception e) {\r
+                                                               throw new WebException ("The request was aborted: The request was canceled.",\r
+                                                               e, WebExceptionStatus.RequestCanceled, null);\r
+                                                       }\r
                                                }\r
                                        }\r
                                }\r
@@ -830,13 +1045,7 @@ namespace System.Net
 \r
                        void IDisposable.Dispose()\r
                        {\r
-                               try\r
-                               {\r
-                                       Close();\r
-                               }\r
-                               catch(Exception)\r
-                               {\r
-                               }\r
+                               Close ();\r
                        }\r
                }\r
                \r
@@ -891,20 +1100,20 @@ namespace System.Net
                        }\r
 \r
                        public WaitHandle AsyncWaitHandle \r
-                       {
+                       {\r
                                get \r
-                               {
+                               {\r
                                        if (_handle == null) \r
-                                       {
+                                       {\r
                                                lock (this) \r
-                                               {
-                                                       if (_handle == null)
-                                                               _handle = new ManualResetEvent (_isCompleted);
-                                               }
-                                       }
-                               
-                                       return _handle;
-                               }
+                                               {\r
+                                                       if (_handle == null)\r
+                                                               _handle = new ManualResetEvent (_isCompleted);\r
+                                               }\r
+                                       }\r
+                               \r
+                                       return _handle;\r
+                               }\r
                        }\r
 \r
                        public bool IsCompleted\r
@@ -964,9 +1173,9 @@ namespace System.Net
                        internal void DoCallback()\r
                        {\r
                                if (!_callbackDone && _callback != null) \r
-                               {
-                                       _callbackDone = true;
-                                       _callback (this);
+                               {\r
+                                       _callbackDone = true;\r
+                                       _callback (this);\r
                                }\r
                        }\r
 \r
@@ -977,12 +1186,12 @@ namespace System.Net
                                AsyncWaitHandle.WaitOne ();\r
                        }\r
 \r
-                       internal bool WaitUntilComplete (int timeout, bool exitContext)
-                       {
-                               if (_isCompleted)
-                                       return true;
-
-                               return AsyncWaitHandle.WaitOne (timeout, exitContext);
+                       internal bool WaitUntilComplete (int timeout, bool exitContext)\r
+                       {\r
+                               if (_isCompleted)\r
+                                       return true;\r
+\r
+                               return AsyncWaitHandle.WaitOne (timeout, exitContext);\r
                        }\r
                        #endregion\r
 \r
@@ -1057,6 +1266,15 @@ namespace System.Net
                                _out.write(i);\r
                        }\r
 \r
+                       public override void close () \r
+                       {\r
+                               int size = _out.size ();\r
+                               _out.close ();\r
+\r
+                               if (size < _contentLength) {\r
+                                       throw new IOException ("Cannot close stream until all bytes are written.");\r
+                               }\r
+                       }\r
                }\r
 \r
                #endregion\r
@@ -1067,5 +1285,21 @@ namespace System.Net
 \r
 \r
 \r
+       }\r
+\r
+       class HTTPClientCredentialsBridge : CredentialsProvider\r
+       {\r
+               private vmw.@internal.auth.CredentialsProvider m_internalProvider;\r
+\r
+               public HTTPClientCredentialsBridge (vmw.@internal.auth.CredentialsProvider internalProvider) {\r
+                       m_internalProvider = internalProvider;\r
+               }\r
+\r
+               public Credentials getCredentials (AuthScheme scheme, string __p2, int __p3, bool __p4) {\r
+                       if (scheme.isComplete ())\r
+                               return null;                    \r
+                       GSSCredential creds = m_internalProvider.getCredentials ();                     \r
+                       return new DelegatedCredentials (creds);\r
+               }\r
        }\r
 }\r