[System.Net] Add support for .pac proxy config scripts on mac
[mono.git] / mcs / class / System / System.Net / VMWHttpProvider.jvm.cs
1 using System;\r
2 using System.IO;\r
3 using System.Threading;\r
4 \r
5 using mainsoft.apache.commons.httpclient;\r
6 using mainsoft.apache.commons.httpclient.methods;\r
7 using mainsoft.apache.commons.httpclient.@params;\r
8 using mainsoft.apache.commons.httpclient.auth;\r
9 using mainsoft.apache.commons.httpclient.auth.negotiate;\r
10 using javax.security.auth;\r
11 using org.ietf.jgss;\r
12 using java.security;\r
13 using System.Collections.Specialized;\r
14 using System.Collections;\r
15 using mainsoft.apache.commons.httpclient.cookie;\r
16 \r
17 namespace System.Net\r
18 {\r
19         /// <summary>\r
20         /// Summary description for VMWHttpProvider.\r
21         /// </summary>\r
22         internal class VMWHttpProvider : HttpProvider\r
23         {\r
24                 protected static HttpClient _sclient;\r
25                 protected static HttpStateCache _stateCache = new HttpStateCache();\r
26 \r
27                 protected static object LOCK_OBJECT = new object();\r
28                 \r
29                 protected HttpClient _client;\r
30                 protected bool _disableHttpConnectionPooling = false;\r
31 \r
32                 protected HttpMethod _method;\r
33                 protected HttpState _state;\r
34                 protected HostConfiguration _hostConfig;\r
35                 \r
36                 protected HttpWebResponse _response;\r
37                 protected bool _hasResponse;\r
38                 protected bool _hasRequest;\r
39                 protected Stream _writeStream;\r
40                 private GHWebAsyncResult _asyncWrite;           \r
41 \r
42                 private bool _isConnectionOpened;\r
43                 \r
44                 static VMWHttpProvider()\r
45                 {\r
46                         if(java.lang.System.getProperty("mainsoft.apache.commons.logging.Log") == null)\r
47                                 java.lang.System.setProperty("mainsoft.apache.commons.logging.Log",\r
48                                         "mainsoft.apache.commons.logging.impl.SimpleLog");\r
49                         if(java.lang.System.getProperty("mainsoft.apache.commons.logging.simplelog.showdatetime") == null)\r
50                                 java.lang.System.setProperty("mainsoft.apache.commons.logging.simplelog.showdatetime",\r
51                                         "true");\r
52                         if(java.lang.System.getProperty("mainsoft.apache.commons.logging.simplelog.log.httpclient.wire") == null)\r
53                                 java.lang.System.setProperty("mainsoft.apache.commons.logging.simplelog.log.httpclient.wire",\r
54                                         "error");\r
55                         if(java.lang.System.getProperty("mainsoft.apache.commons.logging.simplelog.log.mainsoft.apache.commons.httpclient")\r
56                                 == null)\r
57                                 java.lang.System.setProperty("mainsoft.apache.commons.logging.simplelog.log.mainsoft.apache.commons.httpclient",\r
58                                         "error");\r
59                         if(java.lang.System.getProperty("mainsoft.apache.commons.logging.simplelog.log.httpclient.wire.header")\r
60                                 == null)\r
61                                 java.lang.System.setProperty("mainsoft.apache.commons.logging.simplelog.log.httpclient.wire.header", \r
62                                         "error");\r
63 \r
64                 }\r
65                 public VMWHttpProvider(Uri uri) : base (uri)\r
66                 {\r
67                         string s = System.Configuration.ConfigurationSettings.AppSettings["disableHttpConnectionPooling"];\r
68                         if (s != null) \r
69                         {\r
70                                 _disableHttpConnectionPooling = bool.Parse(s);\r
71                         }\r
72                         InitDefaultCredentialsProvider ();\r
73                         InitSPNProviders ();\r
74                 }\r
75 \r
76                 internal override ServicePoint ServicePoint\r
77                 {\r
78                         get {throw new NotImplementedException();}\r
79                 }\r
80 \r
81 \r
82 \r
83                 public override bool IsRequestStarted()\r
84                 {\r
85                         if(_method == null)\r
86                                 return false;\r
87                         return _method.isRequestSent();\r
88                 }\r
89 \r
90                 public override Uri GetAddress()\r
91                 {\r
92                         if(_method == null)\r
93                                 return GetOriginalAddress();\r
94                         mainsoft.apache.commons.httpclient.URI javaURI =  _method.getURI();\r
95                         return new Uri(javaURI.ToString());\r
96                 }\r
97 \r
98                 public override bool IsHaveResponse()\r
99                 {\r
100                         return _hasResponse;\r
101                 }\r
102 \r
103                 private void SetJavaCredential(NetworkCredential nc, string type)\r
104                 {\r
105                         SetJavaCredential(nc, type, false);\r
106                 }\r
107 \r
108                 private void SetJavaCredential(NetworkCredential nc, string type, bool proxyCredentials)\r
109                 {\r
110                         string host = null;\r
111                         \r
112                         if(!proxyCredentials)\r
113                                 host = GetOriginalAddress().Host;\r
114                         else\r
115                                 host = ((WebProxy)this.Proxy).Address.Host;\r
116 \r
117                         string domain = (nc.Domain == null) ? host : nc.Domain;\r
118 \r
119                         if(String.Compare (type, "any", StringComparison.InvariantCultureIgnoreCase) == 0)\r
120                         {\r
121                                 if(!proxyCredentials)\r
122                                 {\r
123                                         _state.setCredentials(AuthScope.ANY,\r
124                                                 new UsernamePasswordCredentials(nc.UserName, nc.Password));\r
125                                         _state.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, "Ntlm"),\r
126                                                 new NTCredentials(nc.UserName, nc.Password, host, domain));\r
127                                 }\r
128                                 else\r
129                                 {\r
130                                         _state.setProxyCredentials(AuthScope.ANY,\r
131                                                 new UsernamePasswordCredentials(nc.UserName, nc.Password));\r
132                                         _state.setProxyCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, "Ntlm"),\r
133                                                 new NTCredentials(nc.UserName, nc.Password, host, domain));\r
134                                 }\r
135                         }\r
136                         else if(String.Compare (type, "basic", StringComparison.InvariantCultureIgnoreCase) == 0)\r
137                         {\r
138                                 if(!proxyCredentials)\r
139                                 {\r
140                                         _state.setCredentials(new AuthScope(AuthScope.ANY_HOST,\r
141                                                 AuthScope.ANY_PORT, AuthScope.ANY_REALM, "basic"),\r
142                                                 new UsernamePasswordCredentials(nc.UserName, nc.Password));\r
143                                 }\r
144                                 else\r
145                                 {\r
146                                         _state.setProxyCredentials(new AuthScope(AuthScope.ANY_HOST,\r
147                                                 AuthScope.ANY_PORT, AuthScope.ANY_REALM, "basic"),\r
148                                                 new UsernamePasswordCredentials(nc.UserName, nc.Password));\r
149                                 }\r
150                         }\r
151                         else if(String.Compare (type, "digest", StringComparison.InvariantCultureIgnoreCase) == 0)\r
152                         {\r
153                                 if(!proxyCredentials)\r
154                                 {\r
155                                         _state.setCredentials(new AuthScope(AuthScope.ANY_HOST,\r
156                                                 AuthScope.ANY_PORT, AuthScope.ANY_REALM, "digest"),\r
157                                                 new UsernamePasswordCredentials(nc.UserName, nc.Password));\r
158                                 }\r
159                                 else\r
160                                 {\r
161                                         _state.setProxyCredentials(new AuthScope(AuthScope.ANY_HOST,\r
162                                                 AuthScope.ANY_PORT, AuthScope.ANY_REALM, "digest"),\r
163                                                 new UsernamePasswordCredentials(nc.UserName, nc.Password));\r
164                                 }\r
165                         }\r
166                         else if(String.Compare (type, "ntlm", StringComparison.InvariantCultureIgnoreCase) == 0)\r
167                         {\r
168                                 if(!proxyCredentials)\r
169                                 {\r
170                                         _state.setCredentials(new AuthScope(AuthScope.ANY_HOST,\r
171                                                 AuthScope.ANY_PORT, AuthScope.ANY_REALM, "ntlm"),\r
172                                                 new NTCredentials(nc.UserName, nc.Password, host, domain));\r
173                                 }\r
174                                 else\r
175                                 {\r
176                                         _state.setProxyCredentials(new AuthScope(AuthScope.ANY_HOST,\r
177                                                 AuthScope.ANY_PORT, AuthScope.ANY_REALM, "ntlm"),\r
178                                                 new NTCredentials(nc.UserName, nc.Password, host, domain));\r
179                                 }\r
180                         }\r
181                         else if(String.Compare (type, "negotiate", StringComparison.InvariantCultureIgnoreCase) == 0)\r
182                         {\r
183                                 SetAuthenticationScheme (AuthPolicy.NEGOTIATE);\r
184                         }\r
185                         else\r
186                         {\r
187                                 if(!proxyCredentials)\r
188                                 {\r
189                                         _state.setCredentials(new AuthScope(AuthScope.ANY_HOST,\r
190                                                 AuthScope.ANY_PORT, AuthScope.ANY_REALM, type),\r
191                                                 new UsernamePasswordCredentials(nc.UserName, nc.Password));\r
192                                 }\r
193                                 else\r
194                                 {\r
195                                         _state.setProxyCredentials(new AuthScope(AuthScope.ANY_HOST,\r
196                                                 AuthScope.ANY_PORT, AuthScope.ANY_REALM, type),\r
197                                                 new UsernamePasswordCredentials(nc.UserName, nc.Password));\r
198                                 }\r
199                         }                                               \r
200                 }\r
201 \r
202                 private void SetAuthenticationScheme (string type) {                    \r
203                         _method.getHostAuthState ().setAuthScheme (AuthPolicy.getAuthScheme (type));                                                            \r
204                         if (type != null && type.ToLower () == AuthPolicy.NEGOTIATE.ToLower ()) {                                       \r
205                                 _method.getParams ().setParameter (CredentialsProvider__Finals.PROVIDER, new HTTPClientCredentialsBridge( DefaultCredentialsProvider));\r
206                                 _method.getParams ().setParameter (NegotiateScheme.SPN_LIST_PARAM, SPNProviders);\r
207                         }                       \r
208                 }\r
209 \r
210                 private java.util.ArrayList SPNProviders {\r
211                         get {\r
212                                 return (java.util.ArrayList) AppDomain.CurrentDomain.GetData ("GH$SPNProviders");\r
213                         }\r
214                         set {\r
215                                 AppDomain.CurrentDomain.SetData ("GH$SPNProviders", value);\r
216                         }\r
217                 }\r
218 \r
219                 private void InitSPNProviders () {\r
220                         if (SPNProviders != null)\r
221                                 return;\r
222                         java.util.ArrayList spnProviders = new java.util.ArrayList ();\r
223                         NameValueCollection configAttributes = System.Configuration.ConfigurationSettings.AppSettings;\r
224                         string providersList = configAttributes ["SPNProviders"];\r
225                         if (providersList == null)\r
226                                 return;\r
227                         string[] tokens = providersList.Split (',');\r
228                         foreach (string spnClass in tokens) {\r
229                                 try {\r
230                                         spnProviders.add (Activator.CreateInstance (Type.GetType (spnClass)));\r
231                                 }\r
232                                 catch (Exception) { }\r
233                         }\r
234                         SPNProviders = spnProviders;\r
235                 }\r
236 \r
237                 private vmw.@internal.auth.CredentialsProvider DefaultCredentialsProvider {\r
238                         get {\r
239                                 return (vmw.@internal.auth.CredentialsProvider) AppDomain.CurrentDomain.GetData ("GH$DefaultCredentialsProvider");\r
240                         }\r
241                         set {\r
242                                 AppDomain.CurrentDomain.SetData ("GH$DefaultCredentialsProvider", value);\r
243                         }\r
244                 }\r
245 \r
246                 private void InitDefaultCredentialsProvider () {\r
247                         if (DefaultCredentialsProvider != null)\r
248                                 return;\r
249                         vmw.@internal.auth.CredentialsProvider defaultProvider = null;\r
250                         NameValueCollection configAttributes = System.Configuration.ConfigurationSettings.AppSettings;\r
251                         \r
252                         string defaultProviderClass = configAttributes ["DefaultCredentialsProvider"];\r
253                         if (defaultProviderClass != null) {\r
254                                 try {                                   \r
255                                         defaultProvider = (vmw.@internal.auth.CredentialsProvider)\r
256                                                 Activator.CreateInstance (Type.GetType (defaultProviderClass));\r
257                                 }\r
258                                 catch (Exception e) {\r
259                                         Console.WriteLine ("Failed to initialize Credentials Provider: " + defaultProviderClass + " Message: " + e.Message);                                    \r
260                                 }\r
261                         }                       \r
262 \r
263                         if (defaultProvider == null) \r
264                                 defaultProvider = new vmw.@internal.auth.SubjectCredentialsPrvider ();\r
265 \r
266                         defaultProvider.init (ConvertToTable (configAttributes));\r
267                         DefaultCredentialsProvider = defaultProvider;\r
268                 }\r
269 \r
270                 private java.util.Properties ConvertToTable (NameValueCollection col) {\r
271                         java.util.Properties table = new java.util.Properties ();\r
272                         foreach (String key in col.Keys)\r
273                                 table.put (key, col [key]);\r
274                         return table;\r
275                 }\r
276 \r
277                 private void InitProxyCredentials () {\r
278                         if (this.Proxy == null)\r
279                                 return;\r
280 \r
281                         if (!(this.Proxy is WebProxy))\r
282                                 return;\r
283 \r
284                         WebProxy proxy = (WebProxy) this.Proxy;\r
285                         ICredentials creds = proxy.Credentials;\r
286 \r
287                         if(creds == null)\r
288                                 return;\r
289 \r
290                         if(creds is CredentialCache)\r
291                         {\r
292                                 string type = "basic";\r
293                                 NetworkCredential nc = ((CredentialCache)creds).GetCredential(proxy.Address, "basic");\r
294                                 if(nc == null)\r
295                                 {\r
296                                         type = "digest";\r
297                                         nc = ((CredentialCache)creds).GetCredential(proxy.Address, "digest");\r
298                                         if(nc == null)\r
299                                         {\r
300                                                 type = "ntlm";\r
301                                                 nc = ((CredentialCache)creds).GetCredential(proxy.Address, "ntlm");\r
302                                                 if (nc == null) {\r
303                                                         nc = ((CredentialCache) _credentials).GetCredential (GetOriginalAddress (), "negotiate");\r
304                                                         type = "negotiate";\r
305                                                 }\r
306                                         }\r
307                                 }\r
308                                 if(nc != null)\r
309                                 {\r
310                                         SetJavaCredential(nc, type, true);\r
311                                 }\r
312                         }\r
313                         else if (creds is NetworkCredential)\r
314                         {\r
315                                 SetJavaCredential((NetworkCredential)creds, "any", true);\r
316                         }\r
317 \r
318                         _method.setDoAuthentication(true);\r
319                 }\r
320 \r
321                 private void InitCredentials()\r
322                 {\r
323                         if(_credentials == null)\r
324                                 return;\r
325                         if (_credentials == CredentialCache.DefaultCredentials) {\r
326                                 SetAuthenticationScheme (AuthPolicy.NEGOTIATE);\r
327                         }\r
328                         else if (_credentials is CredentialCache) {\r
329                                 NetworkCredential nc = ((CredentialCache) _credentials).GetCredential (GetOriginalAddress (), "basic");\r
330                                 string type = "basic";\r
331                                 if(nc == null)\r
332                                 {\r
333                                         nc = ((CredentialCache)_credentials).GetCredential(GetOriginalAddress(), "digest");\r
334                                         type = "digest";\r
335                                         if(nc == null)\r
336                                         {\r
337                                                 nc = ((CredentialCache)_credentials).GetCredential(GetOriginalAddress(), "ntlm");\r
338                                                 type = "ntlm";\r
339                                                 if (nc == null) {\r
340                                                         nc = ((CredentialCache) _credentials).GetCredential (GetOriginalAddress (), "negotiate");\r
341                                                         type = "negotiate";\r
342                                                 }\r
343                                         }\r
344                                 }\r
345                                 if(nc != null)\r
346                                 {\r
347                                         SetJavaCredential(nc, type);\r
348                                 }\r
349                         }\r
350                         else if(_credentials is NetworkCredential)\r
351                         {\r
352                                 SetJavaCredential((NetworkCredential)_credentials, "any");\r
353                         }\r
354 \r
355                         _method.setDoAuthentication(true);\r
356                 }\r
357 \r
358                 private void InitHostConfig()\r
359                 {\r
360                         if (this.Proxy == null || this.Proxy == WebRequest.DefaultWebProxy)\r
361                                 return;\r
362                         if(this.Proxy.IsBypassed(GetOriginalAddress()))\r
363                                 return;\r
364 \r
365                         _hostConfig = new HostConfiguration();                  \r
366                         _hostConfig.setHost(new HttpHost(_method.getURI()));\r
367 \r
368                         \r
369                         if(this.Proxy is WebProxy)\r
370                         {\r
371                                 WebProxy wp = (WebProxy) this.Proxy;\r
372                                 _hostConfig.setProxyHost(new ProxyHost(wp.Address.Host, wp.Address.Port));\r
373                         }\r
374                         else\r
375                                 throw new NotImplementedException("Cannot accept Proxy which is not System.Net.WebProxy instance");\r
376 \r
377                         \r
378                 }\r
379 \r
380                 private void SetConnectionHeader(string val)\r
381                 {\r
382                         string connectionHeader = (this.Proxy != null) ? "Proxy-Connection" : "Connection";\r
383                         Headers.RemoveInternal ((this.Proxy != null) ? "Proxy-Connection" : "Connection");\r
384                         \r
385                         if(val != null)\r
386                                 _method.setRequestHeader(connectionHeader, val);\r
387 \r
388                         if (_keepAlive) \r
389                         {\r
390                                 _method.addRequestHeader (connectionHeader, "keep-alive");\r
391                                 Headers.SetInternal(connectionHeader,"keep-alive");\r
392                         }\r
393                         else if (!_keepAlive && _version == HttpVersion.Version11) \r
394                         {\r
395                                 _method.addRequestHeader (connectionHeader, "close");\r
396                                 Headers.SetInternal(connectionHeader,"close");\r
397                         }\r
398 \r
399                 }\r
400                 private bool OpenConnection()\r
401                 {\r
402                         lock(this)\r
403                         {\r
404                                 if(_isConnectionOpened)\r
405                                         return false;\r
406                                 _isConnectionOpened = true;\r
407                         }\r
408                         InitClient();\r
409                         InitMethod();\r
410 \r
411                         _state = _stateCache.GetHttpState();\r
412 \r
413                         //todo insert needed Authontication, Cookies info to state!\r
414                         _method.setDoAuthentication(this.PreAuthenticate);\r
415                         \r
416                         InitHostConfig();\r
417                         InitCredentials();\r
418                         InitProxyCredentials();\r
419                         \r
420                         if(this.ProtocolVersion == HttpVersion.Version11)\r
421                                 _method.getParams().setVersion(mainsoft.apache.commons.httpclient.HttpVersion.HTTP_1_1);\r
422                         else if(ProtocolVersion == HttpVersion.Version10)\r
423                                 _method.getParams().setVersion(mainsoft.apache.commons.httpclient.HttpVersion.HTTP_1_0);\r
424                         else \r
425                                 throw new ProtocolViolationException("Unsupported protocol version: " + ProtocolVersion);\r
426 \r
427                         if(!(_method is mainsoft.apache.commons.httpclient.methods.EntityEnclosingMethod))\r
428                         {\r
429                                 _method.setFollowRedirects(this.AllowAutoRedirect);\r
430                         }\r
431                         else\r
432                         {\r
433                                 if(!AllowWriteStreamBuffering && _contentLength < 0 && !SendChunked)\r
434                                         throw new ProtocolViolationException();\r
435                                 if(SendChunked)\r
436                                         ((EntityEnclosingMethod)_method).setContentChunked(SendChunked);                                \r
437                         }\r
438                         if(MaxAutoRedirections != _defaultMaxRedirectsNum)\r
439                         {\r
440                                 _method.getParams().setParameter(HttpClientParams.MAX_REDIRECTS,\r
441                                         new java.lang.Integer(MaxAutoRedirections));\r
442                         }\r
443                         \r
444                         \r
445                         \r
446                         foreach(string k in Headers)\r
447                         {       \r
448                                 if(String.Compare (k, "connection", StringComparison.InvariantCultureIgnoreCase) == 0)\r
449                                         continue;\r
450                                 string val = Headers[k];\r
451                                 val = (val == null) ? "" : val;\r
452                                 _method.setRequestHeader(k, val);\r
453                         }\r
454 \r
455                         if (this.CookieContainer != null) \r
456                         {\r
457                                 string cookieHeader = this.CookieContainer.GetCookieHeader (this.GetOriginalAddress());\r
458                                 if (cookieHeader != "")\r
459                                         _method.setRequestHeader("Cookie", cookieHeader);\r
460                         }\r
461                         SetConnectionHeader(Headers["Connection"]);\r
462                         \r
463                         _method.getParams().setSoTimeout(ReadWriteTimeout);\r
464 \r
465                         return true;\r
466                         \r
467                 }\r
468 \r
469                 private void InitClient()\r
470                 {\r
471                         lock(LOCK_OBJECT)\r
472                         {\r
473                                 if((!_disableHttpConnectionPooling) && (_client == null))\r
474                                 {\r
475                                         _client = _sclient;\r
476                                 }\r
477                                 if(_client == null)\r
478                                 {\r
479                                         mainsoft.apache.commons.httpclient.MultiThreadedHttpConnectionManager manager =\r
480                                                 new mainsoft.apache.commons.httpclient.MultiThreadedHttpConnectionManager();\r
481                                         manager.setConnectionStaleCheckingEnabled(false);\r
482                                         manager.setMaxTotalConnections(200);\r
483                                         //by some reasons RFC something - the default \r
484                                         //value will be 2 , so we need to change it ...\r
485                                         manager.setMaxConnectionsPerHost(20);\r
486                                         _client = new HttpClient(manager);\r
487                                         _client.getParams().setIntParameter(HttpClientParams.MAX_REDIRECTS, _defaultMaxRedirectsNum);\r
488                                         _client.getParams().setParameter(HttpClientParams.ALLOW_CIRCULAR_REDIRECTS, new java.lang.Boolean(true));\r
489                                         _client.getParams().setParameter(HttpClientParams.CONNECTION_MANAGER_TIMEOUT, new java.lang.Long(30000));\r
490                                         _client.getParams().setParameter(HttpClientParams.USER_AGENT, \r
491                                                         "VMW4J HttpClient (based on Jakarta Commons HttpClient)");\r
492                                         _client.getParams ().setBooleanParameter (HttpClientParams.SINGLE_COOKIE_HEADER, true);\r
493                                         java.util.ArrayList schemas = new java.util.ArrayList ();\r
494                                         schemas.add ("Ntlm");\r
495                                         schemas.add ("Digest");\r
496                                         schemas.add ("Basic");\r
497                                         schemas.add ("Negotiate");\r
498                                         _client.getParams ().setParameter (AuthPolicy.AUTH_SCHEME_PRIORITY, schemas);\r
499                                         if (!_disableHttpConnectionPooling) {\r
500                                                 _sclient = _client;\r
501                                         }\r
502                                 }\r
503                         }\r
504                 }\r
505 \r
506                 private void InitMethod()\r
507                 {\r
508                         lock(this)\r
509                         {\r
510                                 if(_method == null)\r
511                                 {\r
512                                         string uriString = this.GetOriginalAddress().AbsoluteUri;\r
513 \r
514                                         if(this.MethodName == null || this.MethodName == "")\r
515                                         {\r
516                                                 this.MethodName = "GET";\r
517                                         }\r
518                         \r
519                                         string name = this.MethodName.ToUpper().Trim();\r
520 \r
521                                         switch(name)\r
522                                         {\r
523                                                 case "GET" : _method = new GetMethod(uriString); break;\r
524                                                 case "PUT" : _method = new PutMethod(uriString);\r
525                                                         if (ServicePointManager.Expect100Continue)\r
526                                                                 _method.getParams ().setBooleanParameter (HttpMethodParams.USE_EXPECT_CONTINUE, true);\r
527                                                         break;\r
528                                                 case "POST": _method = new PostMethod(uriString);\r
529                                                         if (ServicePointManager.Expect100Continue)\r
530                                                                 _method.getParams ().setBooleanParameter (HttpMethodParams.USE_EXPECT_CONTINUE, true);\r
531                                                         break;\r
532                                                 case "HEAD": _method = new HeadMethod(uriString); break;\r
533                                                 case "TRACE": _method = new TraceMethod(uriString);break;\r
534                                                 case "DELETE": _method = new DeleteMethod(uriString);break;\r
535                                                 case "OPTIONS": _method = new OptionsMethod(uriString);break;\r
536                                                 default: _method = new GenericMethod(uriString, MethodName); break;\r
537                                         }\r
538                                 }\r
539                         }\r
540                 }\r
541 \r
542                 private void InitHostConfiguration()\r
543                 {\r
544                         lock(this)\r
545                         {\r
546                                 if(_hostConfig == null)\r
547                                 {\r
548                                         _hostConfig = new HostConfiguration();\r
549                                 }\r
550                         }\r
551                 }\r
552 \r
553                 \r
554 \r
555                 public override Stream GetRequestStream()\r
556                 {\r
557                         bool isPutPost = String.Compare("post", MethodName, true) == 0 \r
558                                 || String.Compare("put", MethodName, true) == 0;\r
559                         if(!isPutPost)\r
560                                 throw new ProtocolViolationException();\r
561                         lock(this)\r
562                         {\r
563                                 if (_isAborted)\r
564                                         throw new WebException ("The operation has been aborted.", WebExceptionStatus.RequestCanceled);\r
565                                 if(_writeStream != null)\r
566                                         return _writeStream;\r
567                                 this.OpenConnection();\r
568 \r
569                                 //java.io.PipedInputStream inJavaStream = new java.io.PipedInputStream();\r
570                                 //java.io.PipedOutputStream outJavaStream = new java.io.PipedOutputStream(inJavaStream);\r
571                                                         \r
572                                 long contLen = _contentLength;\r
573                                 \r
574                                 OutputStreamRequestEntity reqEntity = new OutputStreamRequestEntity(contLen);\r
575 \r
576                                 _writeStream = new VMWRequestStream(reqEntity, contLen);\r
577                         \r
578                                 EntityEnclosingMethod method = (EntityEnclosingMethod)_method;\r
579                                 if(AllowWriteStreamBuffering )\r
580                                         method.setRequestEntity(reqEntity);\r
581                                 else if(!AllowWriteStreamBuffering && contLen < 0 && !SendChunked)\r
582                                         throw new ProtocolViolationException();\r
583                                 else\r
584                                         method.setRequestEntity(reqEntity);\r
585                         \r
586                                 _hasRequest = true;\r
587                                 return _writeStream;\r
588                         }\r
589                 }\r
590                 private static bool isRedirectNeeded(HttpMethod method)\r
591                 {\r
592                         switch (method.getStatusCode()) \r
593                         {\r
594                                 case 302:\r
595                                 case 301:\r
596                                 case 303:\r
597                                 case 307:\r
598                                         return true;\r
599                                 default:\r
600                                         return false;\r
601                         } //end of switch\r
602                 }\r
603 \r
604                 private void synchHeaders()\r
605                 {\r
606                         foreach(string k in Headers)\r
607                         {\r
608                                 if (String.Compare (k, "connection", StringComparison.InvariantCultureIgnoreCase) == 0)\r
609                                         continue;\r
610                                 string val = Headers[k];\r
611                                 val = (val == null) ? "" : val;\r
612                                 _method.setRequestHeader(k, val);\r
613                         }\r
614                 }\r
615 \r
616                 delegate WebResponse GetResponseDelegate();\r
617                 private sealed class AsyncContext\r
618                 {\r
619                         public readonly AsyncCallback AsyncCallback;\r
620                         public readonly Delegate AsyncDelegate;\r
621                         public readonly object AsyncState;\r
622                         public readonly DelegateAsyncResult DelegateAsyncResult;\r
623 \r
624                         public AsyncContext (Delegate @delegate, DelegateAsyncResult delegateAsyncResult, AsyncCallback asyncCallback, object userState) {\r
625                                 AsyncDelegate = @delegate;\r
626                                 AsyncCallback = asyncCallback;\r
627                                 AsyncState = userState;\r
628                                 DelegateAsyncResult = delegateAsyncResult;\r
629                         }\r
630                 }\r
631                 private sealed class DelegateAsyncResult : IAsyncResult\r
632                 {\r
633                         \r
634                         IAsyncResult _asyncResult;\r
635 \r
636                         public IAsyncResult AsyncResult {\r
637                                 get { return _asyncResult; }\r
638                                 set { _asyncResult = value; }\r
639                         }\r
640 \r
641                         AsyncContext AsyncContext {\r
642                                 get { return (AsyncContext) _asyncResult.AsyncState; }\r
643                         }\r
644 \r
645                         public static void Callback (IAsyncResult result) {\r
646                                 AsyncContext context = (AsyncContext) result.AsyncState;\r
647                                 context.AsyncCallback.Invoke (context.DelegateAsyncResult);\r
648                         }\r
649 \r
650                         public Delegate AsyncDelegate {\r
651                                 get { return AsyncContext.AsyncDelegate; }\r
652                         }\r
653 \r
654                         #region IAsyncResult Members\r
655 \r
656                         public object AsyncState {\r
657                                 get { return AsyncContext.AsyncState; }\r
658                         }\r
659 \r
660                         public WaitHandle AsyncWaitHandle {\r
661                                 get { return _asyncResult.AsyncWaitHandle; }\r
662                         }\r
663 \r
664                         public bool CompletedSynchronously {\r
665                                 get { return _asyncResult.CompletedSynchronously; }\r
666                         }\r
667 \r
668                         public bool IsCompleted {\r
669                                 get { return _asyncResult.IsCompleted; }\r
670                         }\r
671 \r
672                         #endregion\r
673                 }\r
674                 \r
675                 WebResponse GetAsyncResponse()\r
676                 {\r
677                         try {\r
678                                 return GetResponse ();\r
679                         }\r
680                         catch {\r
681                                 return null;\r
682                         }\r
683                 }\r
684 \r
685                 public override WebResponse GetResponse()\r
686                 {\r
687                         lock(this)\r
688                         {\r
689                                 if (_isAborted)\r
690                                         throw new WebException ("The operation has been aborted.", WebExceptionStatus.RequestCanceled);\r
691                                 if(!_isConnectionOpened)\r
692                                         OpenConnection();\r
693                                 if(_response == null)\r
694                                 {\r
695                                         try\r
696                                         {       \r
697                                                 synchHeaders();\r
698                                                 InternalExecuteMethod ();                                               \r
699                                                 int numOfRedirects = 0;\r
700                                                 while (isRedirectNeeded (_method) && _allowAutoRedirect && numOfRedirects < MaxAutoRedirections) {\r
701                                                         if (!HandleManualyRedirect ())\r
702                                                                 break;\r
703                                                         numOfRedirects++;\r
704                                                 }\r
705                                                 \r
706                                                 //todo right place to re-put all headers again...\r
707                                                 mainsoft.apache.commons.httpclient.Header hostHeader =\r
708                                                         _method.getRequestHeader("Host");\r
709                                                 if(hostHeader != null)\r
710                                                         Headers.SetInternal("Host", hostHeader.getValue());\r
711 \r
712                                                 _response = new HttpWebResponse(_method, _state, _stateCache, GetAddress(), this.MethodName);\r
713                                                 \r
714                                                 if(_response != null && \r
715                                                         _response.Cookies != null && \r
716                                                         _response.Cookies.Count > 0)\r
717                                                 {\r
718                                                         if(CookieContainer != null)\r
719                                                         {\r
720                                                                 foreach(Cookie cooky in _response.Cookies)\r
721                                                                 {\r
722                                                                         CookieContainer.Add(GetAddress(), cooky);\r
723                                                                 }\r
724                                                         }\r
725                                                 }\r
726 \r
727                                                 _hasResponse = true;\r
728                                                 int respCodeAsInt = (int) _response.StatusCode;\r
729                                                 if(respCodeAsInt >= 400)\r
730                                                 {\r
731                                                         // The WebException contains the readable (not closed) response stream.\r
732                                                         // So, in case of WebException, we should read all data from the \r
733                                                         // network response stream into the memory stream, and after that\r
734                                                         // close the underlying network stream. The following requests to read\r
735                                                         // from the stream will actually read from the memory stream.\r
736                                                         // So, the this.Abort() should not be called in this case.\r
737                                                         _response.ReadAllAndClose();\r
738                                                         //this.Abort();\r
739                                                         throw new WebException("The remote server returned an error: (" + respCodeAsInt +") " +_response.StatusCode, null, WebExceptionStatus.ProtocolError, _response);\r
740                                                 }\r
741                                                 Header location = _method.getResponseHeader ("location");\r
742                                                 if (isRedirectNeeded (_method) && location == null && _method.getFollowRedirects ())\r
743                                                 {\r
744                                                         // See comments above for the error >= 400\r
745                                                         _response.ReadAllAndClose();\r
746                                                         //this.Abort();\r
747                                                         throw new WebException("Got response code "+_response.StatusCode+", but no location provided", null, WebExceptionStatus.ProtocolError, _response);\r
748                                                 }\r
749                                         }\r
750                                         catch(ProtocolException e)\r
751                                         {\r
752                                                 throw new WebException("", e);\r
753                                         }\r
754                                         catch(java.net.ConnectException e)\r
755                                         {\r
756                                                 throw new WebException("Unable to connect to the remote server.", e);\r
757                                         }\r
758                                         catch(java.net.SocketTimeoutException e)\r
759                                         {\r
760                                                 throw new WebException("Timeout exceeded", e);\r
761                                         }\r
762                                         catch(java.io.IOException e)\r
763                                         {\r
764                                                 throw new WebException("", e);\r
765                                         }\r
766                                 }\r
767                                 return _response;\r
768                         }\r
769 \r
770                 }\r
771 \r
772                 private void InternalExecuteMethod () {\r
773                         _client.executeMethod (_hostConfig, _method, _state);                   \r
774                 }               \r
775 \r
776                 private bool HandleManualyRedirect () {                 \r
777                         Header redirectHeader = _method.getResponseHeader ("location");\r
778                         if (redirectHeader == null) {\r
779                                 // See comments above for the error >= 400\r
780                                 _response.ReadAllAndClose ();\r
781                                 //this.Abort();\r
782                                 throw new WebException ("Got response code " + _response.StatusCode + ", but no location provided", null, WebExceptionStatus.ProtocolError, _response);\r
783                         }\r
784 \r
785                         mainsoft.apache.commons.httpclient.HttpMethod originalMethod = _method;\r
786                         try {\r
787                                 string location = redirectHeader.getValue ();\r
788                                 URI currentUri = _method.getURI ();\r
789                                 URI redirectUri = null;\r
790 \r
791                                 redirectUri = new URI (location, true);\r
792                                 if (redirectUri.isRelativeURI ()) {\r
793                                         //location is incomplete, use current values for defaults       \r
794                                         redirectUri = new URI (currentUri, redirectUri);\r
795                                 }\r
796                                 \r
797                                 _method = new GetMethod ();\r
798                                 foreach(Header h in originalMethod.getRequestHeaders())\r
799                                         _method.addRequestHeader(h);                            \r
800                                 _method.setURI (redirectUri);                           \r
801                                 InternalExecuteMethod ();\r
802                                 return true;\r
803                         }\r
804                         catch (URIException e) {\r
805                                 _method = originalMethod;\r
806                                 return false;\r
807                         }\r
808                 }\r
809 \r
810                 public override void Abort()\r
811                 {\r
812                         lock (this) {\r
813                                 if (_isAborted)\r
814                                         return;\r
815                                 _isAborted = true;\r
816                                 try {\r
817                                         if (_hasResponse) {\r
818                                                 _response.Close ();\r
819                                         }\r
820                                 }\r
821                                 finally {\r
822                                         if (_method != null)\r
823                                                 _method.releaseConnection ();\r
824                                         _method = null;\r
825                                         _hasResponse = false;\r
826                                         _response = null;\r
827                                 }\r
828                         }\r
829                 }\r
830 \r
831                 public override IAsyncResult BeginGetRequestStream(AsyncCallback callback, object state)\r
832                 {\r
833                         lock(this)\r
834                         {\r
835                                 if(_asyncWrite != null)\r
836                                 {\r
837                                         throw new InvalidOperationException ("Cannot re-call start of asynchronous " +\r
838                                                 "method while a previous call is still in progress.");\r
839                                 }\r
840         \r
841                                 _asyncWrite = new GHWebAsyncResult (this, callback, state);\r
842                                 if (_hasRequest) \r
843                                 {\r
844                                         if (_writeStream != null) \r
845                                         {\r
846                                                 _asyncWrite.SetCompleted (true, _writeStream);\r
847                                                 _asyncWrite.DoCallback ();\r
848                                                 return _asyncWrite;\r
849                                         }\r
850                                 }\r
851                                 \r
852                                 \r
853                                 try\r
854                                 {\r
855                                         this.GetRequestStream();                                        \r
856                                 }\r
857                                 catch(Exception e)\r
858                                 {\r
859                                         _asyncWrite.SetCompleted(false, e);\r
860                                         _asyncWrite.DoCallback ();\r
861                                         return _asyncWrite;\r
862                                 }\r
863 \r
864                                 _asyncWrite.SetCompleted (true, _writeStream);\r
865                                 _asyncWrite.DoCallback ();\r
866                                 return _asyncWrite;\r
867                                 \r
868                         }\r
869                 }   \r
870 \r
871                 public override Stream EndGetRequestStream(IAsyncResult asyncResult)\r
872                 {\r
873                         if (asyncResult == null)\r
874                                 throw new ArgumentNullException ("asyncResult");\r
875 \r
876                         GHWebAsyncResult result = asyncResult as GHWebAsyncResult;\r
877                         if (result == null)\r
878                                 throw new ArgumentException ("Invalid IAsyncResult");\r
879 \r
880                         _asyncWrite = result;\r
881 \r
882                         result.WaitUntilComplete ();\r
883 \r
884                         Exception e = result.Exception;\r
885                         \r
886                         if (e != null)\r
887                                 throw e;\r
888 \r
889                         return result.WriteStream;\r
890                 }\r
891 \r
892                 public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state)\r
893                 {\r
894                         GetResponseDelegate d = new GetResponseDelegate (GetAsyncResponse);\r
895                         DelegateAsyncResult result = new DelegateAsyncResult ();\r
896                         AsyncContext userContext = new AsyncContext (d, result, callback, state);\r
897                         result.AsyncResult = d.BeginInvoke (new AsyncCallback (DelegateAsyncResult.Callback), userContext);\r
898                         return result;\r
899                 }\r
900 \r
901                 public override WebResponse EndGetResponse(IAsyncResult asyncResult)\r
902                 {\r
903                         if (_isAborted)\r
904                                 throw new WebException ("The operation has been aborted.", WebExceptionStatus.RequestCanceled);\r
905                         if (asyncResult == null)\r
906                                 throw new ArgumentNullException ("asyncResult");\r
907 \r
908                         DelegateAsyncResult result = asyncResult as DelegateAsyncResult;\r
909                         if (result == null)\r
910                                 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");\r
911 \r
912                         return ((GetResponseDelegate) result.AsyncDelegate).EndInvoke (result.AsyncResult);\r
913                 }\r
914 \r
915 \r
916 \r
917 \r
918 \r
919 \r
920 \r
921                 \r
922 \r
923 \r
924 \r
925 \r
926                 #region VMWRequestStream class\r
927                 internal class VMWRequestStream : Stream, IDisposable\r
928                 {\r
929 \r
930                         private java.io.OutputStream _javaOutput;\r
931                         private long _len;\r
932                         private long _contentLength;\r
933 \r
934                         internal VMWRequestStream (java.io.OutputStream stream) :\r
935                                 this(stream , -1L)\r
936                         {\r
937                         }\r
938 \r
939                         internal VMWRequestStream (java.io.OutputStream stream, long contentLength)\r
940                         {\r
941                                 _javaOutput = stream;\r
942                                 _contentLength = contentLength;\r
943                                 _len = 0;\r
944                         }\r
945                         public override bool CanRead\r
946                         {\r
947                                 get    {return false;}\r
948                         }\r
949 \r
950                         public override bool CanWrite\r
951                         {\r
952                                 get{return true;}\r
953                         }\r
954 \r
955                         public override bool CanSeek\r
956                         {\r
957                                 get { return false;}\r
958                         }\r
959 \r
960                         public override long Length\r
961                         {\r
962                                 get{ return _len;}\r
963                         }\r
964 \r
965                         public override long Position\r
966                         {\r
967                                 get\r
968                                 {\r
969                                         return _len;\r
970                                 }\r
971 \r
972                                 set\r
973                                 {\r
974                                         throw new NotSupportedException();\r
975                                 }\r
976                         }\r
977 \r
978                         private volatile bool _closed = false;\r
979 \r
980                         public override void Close()\r
981                         {\r
982                                 if(!_closed)\r
983                                 {\r
984                                         lock(this)\r
985                                         {\r
986                                                 if(!_closed)\r
987                                                 {\r
988                                                         try {\r
989                                                                 _closed = true;\r
990                                                                 _javaOutput.close ();\r
991                                                         }\r
992                                                         catch (Exception e) {\r
993                                                                 throw new WebException ("The request was aborted: The request was canceled.",\r
994                                                                 e, WebExceptionStatus.RequestCanceled, null);\r
995                                                         }\r
996                                                 }\r
997                                         }\r
998                                 }\r
999                         }\r
1000 \r
1001                         public override void Flush()\r
1002                         {\r
1003                                 _javaOutput.flush();\r
1004                         }\r
1005 \r
1006                         public override int ReadByte()\r
1007                         {\r
1008                                 throw new NotSupportedException();\r
1009                         }\r
1010 \r
1011                         public override int Read(byte[] buffer, int offset, int count)\r
1012                         {\r
1013                                 throw new NotSupportedException();\r
1014                         }\r
1015 \r
1016                         public override void Write(byte[] buffer, int offset, int count)\r
1017                         {\r
1018                                 if(_contentLength >= 0)\r
1019                                 {\r
1020                                         _len += count;\r
1021                                         if(_len > _contentLength)\r
1022                                         {\r
1023                                                 throw new  System.Net.ProtocolViolationException(\r
1024                                                         "Bytes to be written to the stream exceed Content-Length bytes size specified.");\r
1025                                         }\r
1026                                 }\r
1027                                 _javaOutput.write(vmw.common.TypeUtils.ToSByteArray(buffer), offset, count);\r
1028 \r
1029                                 if(_contentLength == _len)\r
1030                                 {\r
1031                                         _javaOutput.flush();\r
1032                                         _javaOutput.close();\r
1033                                 }\r
1034                         }\r
1035 \r
1036                         public override long Seek(long offset, SeekOrigin origin)\r
1037                         {\r
1038                                 throw new NotSupportedException();\r
1039                         }\r
1040 \r
1041                         public override void SetLength(long length)\r
1042                         {\r
1043                                 throw new NotSupportedException();\r
1044                         }\r
1045 \r
1046                         void IDisposable.Dispose()\r
1047                         {\r
1048                                 Close ();\r
1049                         }\r
1050                 }\r
1051                 \r
1052                 #endregion\r
1053 \r
1054                 #region GHWebAsyncResult\r
1055                 internal class GHWebAsyncResult  : IAsyncResult\r
1056                 {\r
1057                         private object _state;\r
1058                         private AsyncCallback _callback;\r
1059                         private ManualResetEvent _handle;\r
1060                         private bool _isCompleted = false;\r
1061                         private bool _callbackDone;\r
1062                         private Stream _writeStream;\r
1063                         private HttpProvider _provider;\r
1064 \r
1065                         private Exception _exception;\r
1066 \r
1067                         #region   Constructors\r
1068 \r
1069                         public GHWebAsyncResult(HttpProvider provider, \r
1070                                 AsyncCallback callback, object state) : \r
1071                                 this(state, callback)\r
1072                         {\r
1073                                 _provider = provider;\r
1074                         }\r
1075 \r
1076                         public GHWebAsyncResult(object state, AsyncCallback callback)\r
1077                         {\r
1078                                 _state = state;\r
1079                                 _callback = callback;\r
1080                         }\r
1081                         #endregion\r
1082 \r
1083                         #region IAsyncResult Members\r
1084 \r
1085                         public object AsyncState\r
1086                         {\r
1087                                 get\r
1088                                 {\r
1089                                         return _state;\r
1090                                 }\r
1091                         }\r
1092 \r
1093                         public bool CompletedSynchronously\r
1094                         {\r
1095                                 get\r
1096                                 {\r
1097                                         // TODO:  Add HWebAsyncResult.CompletedSynchronously getter implementation\r
1098                                         return false;\r
1099                                 }\r
1100                         }\r
1101 \r
1102                         public WaitHandle AsyncWaitHandle \r
1103                         {\r
1104                                 get \r
1105                                 {\r
1106                                         if (_handle == null) \r
1107                                         {\r
1108                                                 lock (this) \r
1109                                                 {\r
1110                                                         if (_handle == null)\r
1111                                                                 _handle = new ManualResetEvent (_isCompleted);\r
1112                                                 }\r
1113                                         }\r
1114                                 \r
1115                                         return _handle;\r
1116                                 }\r
1117                         }\r
1118 \r
1119                         public bool IsCompleted\r
1120                         {\r
1121                                 get\r
1122                                 {\r
1123                                         return _isCompleted;    \r
1124                                 }\r
1125                         }\r
1126 \r
1127                         #endregion\r
1128 \r
1129                         #region Internal Properties\r
1130 \r
1131                         internal Stream WriteStream\r
1132                         {\r
1133                                 get\r
1134                                 {\r
1135                                         return _writeStream;\r
1136                                 }\r
1137                         }\r
1138 \r
1139                         internal Exception Exception\r
1140                         {\r
1141                                 get\r
1142                                 {\r
1143                                         return _exception;\r
1144                                 }\r
1145                         }\r
1146 \r
1147                         internal HttpWebResponse Response\r
1148                         {\r
1149                                 get\r
1150                                 {\r
1151                                         return ((VMWHttpProvider)_provider)._response;\r
1152                                 }\r
1153                         }\r
1154 \r
1155                         #endregion\r
1156 \r
1157                         #region Internal Methods\r
1158 \r
1159                         internal void SetCompleted(bool res, Stream writeStream)\r
1160                         {\r
1161                                 _isCompleted = res;\r
1162                                 _writeStream = writeStream;\r
1163                                 ((ManualResetEvent) AsyncWaitHandle).Set ();\r
1164                         }\r
1165 \r
1166                         internal void SetCompleted(bool res, Exception exc)\r
1167                         {\r
1168                                 _isCompleted = res;\r
1169                                 _exception = exc;\r
1170                                 ((ManualResetEvent) AsyncWaitHandle).Set ();\r
1171                         }\r
1172 \r
1173                         internal void DoCallback()\r
1174                         {\r
1175                                 if (!_callbackDone && _callback != null) \r
1176                                 {\r
1177                                         _callbackDone = true;\r
1178                                         _callback (this);\r
1179                                 }\r
1180                         }\r
1181 \r
1182                         internal void WaitUntilComplete()\r
1183                         {\r
1184                                 if(_isCompleted)\r
1185                                         return;\r
1186                                 AsyncWaitHandle.WaitOne ();\r
1187                         }\r
1188 \r
1189                         internal bool WaitUntilComplete (int timeout, bool exitContext)\r
1190                         {\r
1191                                 if (_isCompleted)\r
1192                                         return true;\r
1193 \r
1194                                 return AsyncWaitHandle.WaitOne (timeout, exitContext);\r
1195                         }\r
1196                         #endregion\r
1197 \r
1198                 }\r
1199 \r
1200                 #endregion\r
1201 \r
1202                 #region OutputStreamRequestEntity\r
1203 \r
1204                 internal class OutputStreamRequestEntity : java.io.OutputStream, RequestEntity\r
1205                 {\r
1206                         private long _contentLength;\r
1207                         private java.io.ByteArrayOutputStream _out;\r
1208                         private sbyte[] _buffer;\r
1209 \r
1210                         internal OutputStreamRequestEntity(): this(-1)\r
1211                         {\r
1212                         }\r
1213 \r
1214                         internal OutputStreamRequestEntity(long length)\r
1215                         {\r
1216                                 _contentLength = length;\r
1217                                 int tmp = (int) _contentLength;\r
1218 \r
1219                                 if(tmp <=0)\r
1220                                         tmp = 4096;\r
1221                                 _out = new java.io.ByteArrayOutputStream(tmp);\r
1222                         }\r
1223 \r
1224                         #region RequestEntity Members\r
1225 \r
1226                         public bool isRepeatable()\r
1227                         {\r
1228                                 return ((_out != null) || (_buffer != null));\r
1229                         }\r
1230 \r
1231                         public long getContentLength()\r
1232                         {\r
1233                                 if(_out != null)\r
1234                                 {\r
1235                                         _buffer = _out.toByteArray();\r
1236                                 }\r
1237                                 if(_buffer != null)\r
1238                                 {\r
1239                                         _contentLength = _buffer.Length;\r
1240                                         _out = null;\r
1241                                 }\r
1242                                 return _contentLength;\r
1243                         }\r
1244 \r
1245                         public void writeRequest(java.io.OutputStream output)\r
1246                         {\r
1247                                 if(_out != null)\r
1248                                         _buffer = _out.toByteArray();\r
1249                                 if(_buffer != null)\r
1250                                 {\r
1251                                         output.write(_buffer, 0, _buffer.Length);\r
1252                                         _out = null;\r
1253                                 }\r
1254                                 else throw new ApplicationException();\r
1255                         }\r
1256 \r
1257                         public string getContentType()\r
1258                         {\r
1259                                 return null;\r
1260                         }\r
1261 \r
1262                         #endregion\r
1263 \r
1264                         public override void write(int i)\r
1265                         {\r
1266                                 _out.write(i);\r
1267                         }\r
1268 \r
1269                         public override void close () \r
1270                         {\r
1271                                 int size = _out.size ();\r
1272                                 _out.close ();\r
1273 \r
1274                                 if (size < _contentLength) {\r
1275                                         throw new IOException ("Cannot close stream until all bytes are written.");\r
1276                                 }\r
1277                         }\r
1278                 }\r
1279 \r
1280                 #endregion\r
1281 \r
1282 \r
1283 \r
1284 \r
1285 \r
1286 \r
1287 \r
1288         }\r
1289 \r
1290         class HTTPClientCredentialsBridge : CredentialsProvider\r
1291         {\r
1292                 private vmw.@internal.auth.CredentialsProvider m_internalProvider;\r
1293 \r
1294                 public HTTPClientCredentialsBridge (vmw.@internal.auth.CredentialsProvider internalProvider) {\r
1295                         m_internalProvider = internalProvider;\r
1296                 }\r
1297 \r
1298                 public Credentials getCredentials (AuthScheme scheme, string __p2, int __p3, bool __p4) {\r
1299                         if (scheme.isComplete ())\r
1300                                 return null;                    \r
1301                         GSSCredential creds = m_internalProvider.getCredentials ();                     \r
1302                         return new DelegatedCredentials (creds);\r
1303                 }\r
1304         }\r
1305 }\r