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