New test.
[mono.git] / mcs / class / System / System.Net / HttpWebResponse.jvm.cs
1 using System;\r
2 using System.Collections.Specialized;\r
3 using System.Globalization;\r
4 using System.IO;\r
5 using System.Runtime;\r
6 using System.Runtime.Serialization;\r
7 using System.Security.Cryptography.X509Certificates;\r
8 \r
9 namespace System.Net\r
10 {\r
11         \r
12         [Serializable]\r
13         public class HttpWebResponse : WebResponse,  IDisposable\r
14         {\r
15                 #region Fields\r
16                 private mainsoft.apache.commons.httpclient.HttpMethod _httpMethod;\r
17                 private CookieCollection _cookies;\r
18                 private WebHeaderCollection _headers;\r
19                 private string _statusDescription;\r
20                 private Version _version = null;\r
21                 private Uri _uri;\r
22                 private string _method;\r
23                 private Stream _responseStream;\r
24                 private mainsoft.apache.commons.httpclient.HttpState _state;\r
25                 private HttpStateCache _stateCache;\r
26                 private HttpStatusCode _statusCode;\r
27                 private bool _isStatusCodeInitialized = false;\r
28 \r
29                 private Type _httpStatusCodeType = typeof(HttpStatusCode);\r
30 \r
31                 private sbyte [] _responseBody;\r
32                 private bool _isHttpMethodClosed = false;\r
33                 #endregion\r
34 \r
35                 #region Constructors\r
36 \r
37                 internal HttpWebResponse(mainsoft.apache.commons.httpclient.HttpMethod httpMethod,\r
38                         mainsoft.apache.commons.httpclient.HttpState state,\r
39                         HttpStateCache stateCache,\r
40                         Uri uri, string method)\r
41                 {\r
42                         _httpMethod = httpMethod;\r
43                         _uri = uri;\r
44                         _method = method;\r
45                         _state = state;\r
46                         _stateCache = stateCache;\r
47                 }\r
48 \r
49                 #endregion\r
50 \r
51                 #region Properties\r
52 \r
53                 public CookieCollection Cookies\r
54                 {\r
55                         get\r
56                         {\r
57                                 if(_cookies == null)\r
58                                 {\r
59                                         _cookies = new CookieCollection();\r
60                                         FillCookies();\r
61 \r
62                                 }\r
63                                 return _cookies;\r
64                         }\r
65 \r
66                         set\r
67                         {\r
68                                 _cookies = value;\r
69                         }\r
70                 }\r
71 \r
72                 public override WebHeaderCollection Headers\r
73                 {\r
74                         get\r
75                         {\r
76                                 if(_headers == null)\r
77                                 {\r
78                                         _headers = new WebHeaderCollection();\r
79                                         FillHeaders();\r
80                                 }\r
81                                 return _headers;\r
82                         }\r
83                 }\r
84                 public override long ContentLength\r
85                 {\r
86                         get\r
87                         {\r
88                                 string val = Headers["Content-Length"];\r
89                                 if(val == null || val.Trim().Equals(""))\r
90                                         return -1L;\r
91                                 try\r
92                                 {\r
93                                         return Int64.Parse(val);\r
94                                 }\r
95                                 catch\r
96                                 {\r
97                                         return -1L;\r
98                                 }\r
99                         }\r
100                 }\r
101 \r
102 \r
103                 public string ContentEncoding\r
104                 {\r
105                         get\r
106                         {\r
107                                 return Headers["Content-Encoding"];\r
108                         }\r
109                 }\r
110 \r
111                 public override string ContentType\r
112                 {\r
113                         get\r
114                         {\r
115                                 return  Headers["Content-Type"];\r
116                         }\r
117                 }\r
118 \r
119                 public string CharacterSet\r
120                 {\r
121                         get\r
122                         {\r
123                                 string contentType = ContentType;
124                                 if (contentType == null)
125                                         return "ISO-8859-1";
126                                 string val = contentType.ToLower ();                                    
127                                 int pos = val.IndexOf ("charset=");
128                                 if (pos == -1)
129                                         return "ISO-8859-1";
130                                 pos += 8;
131                                 int pos2 = val.IndexOf (';', pos);
132                                 return (pos2 == -1)
133                                         ? contentType.Substring (pos) 
134                                         : contentType.Substring (pos, pos2 - pos);\r
135                         }\r
136                 }\r
137 \r
138                 public string Server\r
139                 {\r
140                         get\r
141                         {\r
142                                 return Headers ["Server"];\r
143                         }\r
144                 }\r
145 \r
146                 public DateTime LastModified\r
147                 {\r
148                         get\r
149                         {\r
150                                 try\r
151                                 {\r
152                                         string val =  Headers["Last-Modified"];\r
153                                         return MonoHttpDate.Parse(val);\r
154                                 }\r
155                                 catch\r
156                                 {\r
157                                         return DateTime.Now;\r
158                                 }\r
159                         }\r
160                 }\r
161 \r
162                 public HttpStatusCode StatusCode\r
163                 {\r
164                         get\r
165                         {\r
166                                 if(_isStatusCodeInitialized == false)\r
167                                 {\r
168                                         int status = _httpMethod.getStatusCode();\r
169                                         _statusCode = (HttpStatusCode)Enum.Parse(_httpStatusCodeType, \r
170                                                 Enum.GetName(_httpStatusCodeType, status));\r
171                                         _isStatusCodeInitialized = true;\r
172                                 }\r
173 \r
174                                 return _statusCode;\r
175                         }\r
176                 }\r
177 \r
178                 public string StatusDescription\r
179                 {\r
180                         get\r
181                         {\r
182                                 if(_statusDescription == null)\r
183                                         _statusDescription = _httpMethod.getStatusText();\r
184                                 return _statusDescription;\r
185                         }\r
186                 }\r
187 \r
188                 public Version ProtocolVersion\r
189                 {\r
190                         get\r
191                         {\r
192                                 if(_version == null)\r
193                                         ParseVersion();\r
194                                 return _version;\r
195                         }\r
196                 }\r
197 \r
198                 public override Uri ResponseUri\r
199                 {\r
200                         get\r
201                         {\r
202                                 return _uri;\r
203                         }\r
204                 }\r
205 \r
206                 public string Method\r
207                 {\r
208                         get\r
209                         {\r
210                                 return _method;\r
211                         }\r
212                 }\r
213                 #endregion\r
214 \r
215                 #region Methods\r
216 \r
217                 internal void ReadAllAndClose()\r
218                 {\r
219                         if (_responseBody != null)\r
220                                 return;\r
221 \r
222                         object temp = null;\r
223                         if(_cookies == null)\r
224                         {\r
225                 temp = this.Cookies;\r
226                         }\r
227                         if(_headers == null)\r
228                         {\r
229                                 temp = this.Headers;\r
230                         }\r
231                         if(_isStatusCodeInitialized == false)\r
232                         {\r
233                                 temp = this.StatusCode;\r
234                         }\r
235                         if(_statusDescription == null)\r
236                         {\r
237                                 temp = this.StatusDescription;\r
238                         }\r
239                         if(_version == null)\r
240                         {\r
241                                 temp = this.ProtocolVersion;\r
242                         }\r
243 \r
244                         _responseBody = _httpMethod.getResponseBody();\r
245 #if DEBUG\r
246                         Console.WriteLine("The response body as string == {0}", System.Text.Encoding.UTF8.GetString((byte[])vmw.common.TypeUtils.ToByteArray(_responseBody)));\r
247 #endif\r
248                         this.Close();\r
249                 }\r
250 \r
251                 public override Stream GetResponseStream()\r
252                 {\r
253                         try\r
254                         {\r
255                                 if(_responseStream == null)\r
256                                 {\r
257                                         Type t = Type.GetType("System.IO.ConsoleReadStream", true);\r
258                                         object [] param = null;\r
259                                         if (_responseBody == null)\r
260                                         {\r
261                                                 param = new object[]{_httpMethod.getResponseBodyAsStream()};\r
262                                         }\r
263                                         else\r
264                                         {\r
265                                                 param = new object[]{new java.io.ByteArrayInputStream(_responseBody)};\r
266                                         }\r
267                                         _responseStream = (Stream) Activator.CreateInstance(t, param);\r
268                                 }\r
269                                 return _responseStream;\r
270                         }\r
271                         catch(Exception e)\r
272                         {\r
273                                 Console.WriteLine("Exception caught!");\r
274                                 Console.WriteLine(e.GetType() + ":" + e.Message + "\n" + e.StackTrace);\r
275                                 throw e;\r
276                         }\r
277                 }\r
278 \r
279                 public override void Close()\r
280                 {\r
281                         try\r
282                         {\r
283                                 if(_responseStream != null)\r
284                                         _responseStream.Close();\r
285                         }\r
286                         finally\r
287                         {\r
288                                 _responseStream = null;\r
289 \r
290                                 if (!_isHttpMethodClosed)\r
291                                 {\r
292                                         _httpMethod.releaseConnection();\r
293                                         if(_stateCache != null && _state != null)\r
294                                         {\r
295                                                 _stateCache.ReleaseHttpState(_state);\r
296                                                 _state = null;\r
297                                                 _stateCache = null;\r
298                                         }\r
299                                         _isHttpMethodClosed = true;\r
300                                 }\r
301                         }\r
302                 }\r
303 \r
304                 public string GetResponseHeader(string headerName)\r
305                 {\r
306                         return Headers[headerName];\r
307                 }\r
308 \r
309                 public override int GetHashCode()\r
310                 {\r
311                         return base.GetHashCode();\r
312                 }\r
313 \r
314 \r
315                 protected virtual void Dispose(bool disposing)\r
316                 {\r
317                         try\r
318                         {\r
319                                 if(_responseStream != null)\r
320                                         _responseStream.Close();\r
321                         }\r
322                         finally\r
323                         {\r
324                                 _responseStream = null;\r
325 \r
326                                 if (!_isHttpMethodClosed)\r
327                                 {\r
328                                         _httpMethod.releaseConnection();\r
329                                         _isHttpMethodClosed = true;\r
330                                 }\r
331                         }\r
332                 }\r
333 \r
334                 private void FillHeaders()\r
335                 {\r
336                         mainsoft.apache.commons.httpclient.Header[] respHeaders =\r
337                                 _httpMethod.getResponseHeaders();\r
338                         if(respHeaders == null)\r
339                                 return;\r
340                         for(int i = 0; i < respHeaders.Length; i++)\r
341                         {\r
342                                 \r
343                                 mainsoft.apache.commons.httpclient.HeaderElement[] elements = respHeaders[i].getElements();     \r
344                                 for(int j = 0; j < elements.Length; j++)\r
345                                 {\r
346                                         string key = elements[j].getName();\r
347                                         string val = elements[j].getValue();\r
348                                         string pair = (key == null) ? ((val == null) ? "" : val) : ((val==null) ? key : key + "=" + val);\r
349                                         _headers.Add(respHeaders[i].getName(), pair);                                                   \r
350                                 }\r
351 \r
352                         }\r
353                         ParseVersion();\r
354                 }\r
355 \r
356                 private void ParseVersion()\r
357                 {\r
358                         mainsoft.apache.commons.httpclient.StatusLine statusLine =\r
359                                 _httpMethod.getStatusLine();\r
360                         string ver = statusLine.getHttpVersion().Trim().ToUpper();\r
361                         if(ver == "HTTP/1.1")\r
362                                _version = HttpVersion.Version11;\r
363                         else if(ver == "HTTP/1.0")\r
364                                 _version = HttpVersion.Version10;\r
365                         else\r
366                                 _version = null;\r
367                 }\r
368         \r
369                 private void FillCookies()
370                 {
371                         if(_state == null)
372                                 return;
373
374                         mainsoft.apache.commons.httpclient.Cookie[] javaCookies =
375                                 _state.getCookies();
376
377                         if(javaCookies == null)
378                                 return;
379
380                         for(int i = 0; i < javaCookies.Length; i++)
381                         {
382                                 bool httpsProtocol = _httpMethod.getURI().ToString().StartsWith("https");
383                                 if(!httpsProtocol && javaCookies[i].getSecure())
384                                         continue;
385                                 Cookie c = new Cookie(javaCookies[i].getName(), 
386                                         javaCookies[i].getValue(), 
387                                         (javaCookies[i].getPath() == null) ? "" : javaCookies[i].getPath(),
388                                         (javaCookies[i].getDomain() == null) ? "" : javaCookies[i].getDomain());
389                                 java.util.Calendar jCalendar = java.util.Calendar.getInstance();
390                                 java.util.Date jDate = javaCookies[i].getExpiryDate();
391                                 if(jDate != null)
392                                 {
393                                         jCalendar.setTime(javaCookies[i].getExpiryDate());
394                                         c.Expires = (DateTime) vmw.common.DateTimeUtils.CalendarToDateTime(jCalendar);
395                                 }
396                                 
397                                 _cookies.Add(c);
398                         }
399
400                 }
401
402                 //todo remove unused methods
403                 private void FillCookies_old ()
404                 {
405                         
406                         string val = Headers["Set-Cookie"];
407                         if (val != null && val.Trim () != "")
408                                 SetCookie (val);
409
410                         val = Headers["Set-Cookie2"];
411                         if (val != null && val.Trim () != "")
412                                 SetCookie2 (val);
413                 }\r
414 \r
415                 static string [] SplitValue (string input)
416                 {
417                         string [] result = new string [2];
418                         int eq = input.IndexOf ('=');
419                         if (eq == -1) \r
420                         {
421                                 result [0] = "invalid";
422                         } \r
423                         else \r
424                         {
425                                 result [0] = input.Substring (0, eq).Trim ().ToUpper ();
426                                 result [1] = input.Substring (eq + 1);
427                         }
428                         
429                         return result;
430                 }\r
431 \r
432                 private void SetCookie(string val)\r
433                 {\r
434 //                      Console.WriteLine("in set cookie 1 - got value : " + val);
435                         string[] parts = null;
436                         Collections.Queue options = null;
437                         Cookie cookie = null;
438
439                         options = new Collections.Queue (val.Split (';'));
440                         parts = SplitValue ((string) options.Dequeue()); // NAME=VALUE must be first
441
442                         cookie = new Cookie (parts[0], parts[1]);
443
444                         while (options.Count > 0) \r
445                         {
446                                 parts = SplitValue ((string) options.Dequeue());
447                                 switch (parts [0]) \r
448                                 {
449                                         case "COMMENT":
450                                                 if (cookie.Comment == null)
451                                                         cookie.Comment = parts[1];
452                                                 break;
453                                         case "COMMENTURL":
454                                                 if (cookie.CommentUri == null)
455                                                         cookie.CommentUri = new Uri(parts[1]);
456                                                 break;
457                                         case "DISCARD":
458                                                 cookie.Discard = true;
459                                                 break;
460                                         case "DOMAIN":
461                                                 if (cookie.Domain == "")
462                                                         cookie.Domain = parts[1];
463                                                 break;
464                                         case "MAX-AGE": // RFC Style Set-Cookie2
465                                                 if (cookie.Expires == DateTime.MinValue)
466                                                         cookie.Expires = cookie.TimeStamp.AddSeconds (Int32.Parse (parts[1]));
467                                                 break;
468                                         case "EXPIRES": // Netscape Style Set-Cookie
469                                                 if (cookie.Expires == DateTime.MinValue) \r
470                                                 {
471                                                         //FIXME: Does DateTime parse something like: "Sun, 17-Jan-2038 19:14:07 GMT"?
472                                                         //cookie.Expires = DateTime.ParseExact (parts[1]);
473                                                         cookie.Expires = DateTime.Now.AddDays (1);
474                                                 }
475                                                 break;
476                                         case "PATH":
477                                                 cookie.Path = parts[1];
478                                                 break;
479                                         case "PORT":
480                                                 if (cookie.Port == null)
481                                                         cookie.Port = parts[1];
482                                                 break;
483                                         case "SECURE":
484                                                 cookie.Secure = true;
485                                                 break;
486                                         case "VERSION":
487                                                 cookie.Version = Int32.Parse (parts[1]);
488                                                 break;
489                                 } // switch
490                         } // while
491
492                         if (_cookies == null)
493                                 _cookies = new CookieCollection();
494
495                         if (cookie.Domain == "")
496                                 cookie.Domain = _uri.Host;
497
498 //                      Console.WriteLine("adding cookie " + cookie + " to collection");
499                         _cookies.Add (cookie);
500 //                      Console.WriteLine("exit from method...");
501                 }               \r
502                 \r
503                 private void SetCookie2 (string cookies_str)
504                 {
505                         string [] cookies = cookies_str.Split (',');
506                         foreach (string cookie_str in cookies)
507                                 SetCookie (cookie_str);
508                 }\r
509                 #endregion\r
510 \r
511         }\r
512 \r
513 }\r
514 \r
515 \r