2003-01-10 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web / HttpRequest.cs
1 // \r
2 // System.Web.HttpRequest\r
3 //\r
4 // Authors:\r
5 //      Patrik Torstensson (Patrik.Torstensson@labs2.com)\r
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)\r
7 // \r
8 // (c) 2001, 2002 Patrick Torstensson\r
9 // (c) 2002 Ximian, Inc. (http://www.ximian.com)\r
10 // \r
11 using System;\r
12 using System.Collections;\r
13 using System.Collections.Specialized;\r
14 using System.IO;\r
15 using System.Text;\r
16 using System.Web.Configuration;\r
17 using System.Web.Util;\r
18 \r
19 namespace System.Web {\r
20         [MonoTODO("Review security in all path access function")]\r
21         public sealed class HttpRequest {\r
22                 private string []       _arrAcceptTypes;\r
23                 private string []       _arrUserLanguages;\r
24 \r
25                 private byte [] _arrRawContent;\r
26                 private int     _iContentLength;\r
27 \r
28                 private string  _sContentType;\r
29                 private string  _sHttpMethod;\r
30                 private string  _sRawUrl;\r
31                 private string  _sUserAgent;\r
32                 private string  _sUserHostAddress;\r
33                 private string  _sUserHostName;\r
34                 private string  _sPath;\r
35                 private string  _sPathInfo;\r
36                 private string _sFilePath;\r
37                 private string _sPathTranslated;\r
38                 private string _sQueryStringRaw;\r
39                 private string _sRequestType;\r
40                 private string _sRequestRootVirtualDir;\r
41 \r
42                 private Encoding _oContentEncoding;\r
43 \r
44                 private Uri _oUriReferrer;\r
45                 private Uri _oUrl;\r
46 \r
47                 private int     _iTotalBytes;\r
48 \r
49                 private HttpContext     _oContext;\r
50 \r
51                 private HttpWorkerRequest _WorkerRequest;\r
52                 private HttpRequestStream       _oInputStream;\r
53                 private HttpClientCertificate _ClientCert;\r
54 \r
55                 private HttpValueCollection _oServerVariables;\r
56                 private HttpValueCollection _oHeaders;\r
57                 private HttpValueCollection _oQueryString;\r
58                 private HttpValueCollection _oFormData;\r
59                 private HttpValueCollection _oParams;\r
60 \r
61                 private HttpBrowserCapabilities _browser;\r
62 \r
63                 private HttpCookieCollection cookies;\r
64                 private bool rewritten;\r
65 \r
66                 public HttpRequest(string Filename, string Url, string Querystring) {\r
67                         _iContentLength = -1;\r
68                         _iTotalBytes = -1;\r
69 \r
70                         _WorkerRequest = null;\r
71                         _sPathTranslated = Filename;\r
72                         _sRequestType = "GET";\r
73 \r
74                         _oUrl = new Uri(Url);\r
75                         _sPath = _oUrl.AbsolutePath;\r
76 \r
77                         _sQueryStringRaw = Querystring;\r
78                         _oQueryString = new HttpValueCollection(Querystring, true, WebEncoding.Encoding);\r
79                 }\r
80 \r
81                 internal HttpRequest(HttpWorkerRequest WorkRequest, HttpContext Context) {\r
82                         _WorkerRequest = WorkRequest;\r
83                         _oContext = Context;\r
84 \r
85                         _iContentLength = -1;\r
86                         _iTotalBytes = -1;\r
87                 }\r
88 \r
89                 static private string MakeServerVariableFromHeader(string header) {\r
90                         return "HTTP_" + header.ToUpper().Replace("-", "_");\r
91                 }\r
92 \r
93                 [MonoTODO("Need to support non-raw mode also..")]\r
94                 private string GetAllHeaders(bool Raw) {\r
95                         StringBuilder oData;\r
96 \r
97                         if (null == _WorkerRequest) {\r
98                                 return null;\r
99                         }\r
100 \r
101                         oData = new StringBuilder(512);\r
102 \r
103                         string sHeaderValue;\r
104                         string sHeaderName;\r
105                         int iCount = 0;\r
106 \r
107                         // Add all know headers\r
108                         for (; iCount != 40; iCount++) {\r
109                                 sHeaderValue = _WorkerRequest.GetKnownRequestHeader(iCount);\r
110                                 if (null != sHeaderValue && sHeaderValue.Length > 0) {\r
111                                         sHeaderName = _WorkerRequest.GetKnownRequestHeader(iCount);\r
112                                         if (null != sHeaderName && sHeaderName.Length > 0) {\r
113                                                 oData.Append(sHeaderName);\r
114                                                 oData.Append(": ");\r
115                                                 oData.Append(sHeaderValue);\r
116                                                 oData.Append("\r\n");\r
117                                         }\r
118                                 }\r
119                         }\r
120 \r
121                         // Get all other headers\r
122                         string [][] arrUnknownHeaders = _WorkerRequest.GetUnknownRequestHeaders();\r
123                         if (null != arrUnknownHeaders) {\r
124                                 for (iCount = 0; iCount != arrUnknownHeaders.Length; iCount++) {\r
125                                         oData.Append(arrUnknownHeaders[iCount][0]);\r
126                                         oData.Append(": ");\r
127                                         oData.Append(arrUnknownHeaders[iCount][1]);\r
128                                         oData.Append("\r\n");\r
129                                 }\r
130                         }\r
131 \r
132                         return oData.ToString();\r
133                 }\r
134       \r
135                 [MonoTODO("We need to handly 'dynamic' variables like AUTH_USER, that can be changed during runtime... special collection")]\r
136                 private void ParseServerVariables() {\r
137                         if (null == _WorkerRequest) {\r
138                                 return;\r
139                         }\r
140 \r
141                         if (_oServerVariables == null) {\r
142                                 string sTmp;\r
143 \r
144                                 _oServerVariables = new HttpValueCollection();\r
145                                 \r
146                                 _oServerVariables.Add("ALL_HTTP", GetAllHeaders(false));\r
147                                 _oServerVariables.Add("ALL_RAW", GetAllHeaders(true));\r
148 \r
149                                 _oServerVariables.Add("APPL_MD_PATH", _WorkerRequest.GetServerVariable("APPL_MD_PATH"));\r
150                                 _oServerVariables.Add("AUTH_PASSWORD", _WorkerRequest.GetServerVariable("AUTH_PASSWORD"));\r
151                                 _oServerVariables.Add("CERT_COOKIE", _WorkerRequest.GetServerVariable("CERT_COOKIE"));\r
152                                 _oServerVariables.Add("CERT_FLAGS", _WorkerRequest.GetServerVariable("CERT_FLAGS"));\r
153                                 _oServerVariables.Add("CERT_ISSUER", _WorkerRequest.GetServerVariable("CERT_ISSUER"));\r
154                                 _oServerVariables.Add("CERT_KEYSIZE", _WorkerRequest.GetServerVariable("CERT_KEYSIZE"));\r
155                                 _oServerVariables.Add("CERT_SECRETKEYSIZE", _WorkerRequest.GetServerVariable("CERT_SECRETKEYSIZE"));\r
156                                 _oServerVariables.Add("CERT_SERIALNUMBER", _WorkerRequest.GetServerVariable("CERT_SERIALNUMBER"));\r
157                                 _oServerVariables.Add("CERT_SERVER_ISSUER", _WorkerRequest.GetServerVariable("CERT_SERVER_ISSUER"));\r
158                                 _oServerVariables.Add("CERT_SERVER_SUBJECT", _WorkerRequest.GetServerVariable("CERT_SERVER_SUBJECT"));\r
159                                 _oServerVariables.Add("CERT_SUBJECT", _WorkerRequest.GetServerVariable("CERT_SUBJECT"));\r
160 \r
161                                 _oServerVariables.Add("GATEWAY_INTERFACE", _WorkerRequest.GetServerVariable("GATEWAY_INTERFACE"));\r
162                                 _oServerVariables.Add("HTTPS", _WorkerRequest.GetServerVariable("HTTPS"));\r
163                                 _oServerVariables.Add("HTTPS_KEYSIZE", _WorkerRequest.GetServerVariable("HTTPS_KEYSIZE"));\r
164                                 _oServerVariables.Add("HTTPS_SECRETKEYSIZE", _WorkerRequest.GetServerVariable("HTTPS_SECRETKEYSIZE"));\r
165 \r
166                                 _oServerVariables.Add("CONTENT_TYPE", ContentType);\r
167                                 _oServerVariables.Add("HTTPS_SERVER_ISSUER", _WorkerRequest.GetServerVariable("HTTPS_SERVER_ISSUER"));\r
168                                 _oServerVariables.Add("HTTPS_SERVER_SUBJECT", _WorkerRequest.GetServerVariable("HTTPS_SERVER_SUBJECT"));\r
169                                 _oServerVariables.Add("INSTANCE_ID", _WorkerRequest.GetServerVariable("INSTANCE_ID"));\r
170                                 _oServerVariables.Add("INSTANCE_META_PATH", _WorkerRequest.GetServerVariable("INSTANCE_META_PATH"));\r
171                                 _oServerVariables.Add("LOCAL_ADDR", _WorkerRequest.GetLocalAddress());\r
172                                 _oServerVariables.Add("REMOTE_ADDR", UserHostAddress);\r
173                                 _oServerVariables.Add("REMOTE_HOST", UserHostName);\r
174                                 _oServerVariables.Add("REQUEST_METHOD", HttpMethod);\r
175                                 _oServerVariables.Add("SERVER_NAME", _WorkerRequest.GetServerName());\r
176                                 _oServerVariables.Add("SERVER_PORT", _WorkerRequest.GetLocalPort().ToString());\r
177                                 _oServerVariables.Add("SERVER_PROTOCOL", _WorkerRequest.GetHttpVersion());\r
178                                 _oServerVariables.Add("SERVER_SOFTWARE", _WorkerRequest.GetServerVariable("SERVER_SOFTWARE"));\r
179 \r
180                                 if (_WorkerRequest.IsSecure()) {\r
181                                         _oServerVariables.Add("SERVER_PORT_SECURE", "1");\r
182                                 } else {\r
183                                         _oServerVariables.Add("SERVER_PORT_SECURE", "0");\r
184                                 }\r
185 \r
186                                 sTmp = _WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength);\r
187                                 if (null != sTmp) {\r
188                                         _oServerVariables.Add("CONTENT_LENGTH", sTmp);\r
189                                 }\r
190 \r
191                                 // TODO: Should be dynamic\r
192                                 if (null != _oContext.User && _oContext.User.Identity.IsAuthenticated) {\r
193                                         _oServerVariables.Add("AUTH_TYPE", _oContext.User.Identity.AuthenticationType);\r
194                                         _oServerVariables.Add("AUTH_USER", _oContext.User.Identity.Name);\r
195                                 } else {\r
196                                         _oServerVariables.Add("AUTH_TYPE", "");\r
197                                         _oServerVariables.Add("AUTH_USER", "");\r
198                                 }\r
199 \r
200                                 _oServerVariables.Add("PATH_INFO", PathInfo);\r
201                                 _oServerVariables.Add("PATH_TRANSLATED", PhysicalPath);\r
202                                 _oServerVariables.Add("QUERY_STRING", QueryStringRaw);\r
203                                 _oServerVariables.Add("SCRIPT_NAME", FilePath);\r
204                                 // end dynamic\r
205             \r
206                                 _oServerVariables.MakeReadOnly();\r
207                         }\r
208                 }\r
209 \r
210                 [MonoTODO("Handle multipart/form-data")]\r
211                 private void ParseFormData ()\r
212                 {\r
213                         if (_oFormData != null)\r
214                                 return;\r
215 \r
216                         string contentType = ContentType;\r
217                         if (0 != String.Compare (contentType, "application/x-www-form-urlencoded", true)) {\r
218                                 Console.WriteLine ("Content-Type -> {0} not supported", contentType);\r
219                                 _oFormData = new HttpValueCollection ();\r
220                                 return;\r
221                         }\r
222 \r
223                         byte [] arrData = GetRawContent ();\r
224                         Encoding enc = ContentEncoding;\r
225                         string data = enc.GetString (arrData);\r
226                         _oFormData = new HttpValueCollection (data, true, enc);\r
227                 }\r
228 \r
229                 [MonoTODO("void Dispose")]\r
230                 internal void Dispose() {                       \r
231                 }\r
232 \r
233                 private byte [] GetRawContent ()\r
234                 {\r
235                         if (_arrRawContent != null)\r
236                                 return _arrRawContent;\r
237 \r
238                         if (null == _WorkerRequest) {\r
239                                 if (QueryStringRaw == null)\r
240                                         return null;\r
241                                 char [] q = QueryStringRaw.ToCharArray ();\r
242                                 _arrRawContent = new byte [q.Length];\r
243                                 for (int i = 0; i < q.Length; i++)\r
244                                         _arrRawContent [i] = (byte) q [i];\r
245                                 return _arrRawContent;\r
246                         }\r
247 \r
248                         _arrRawContent = _WorkerRequest.GetPreloadedEntityBody ();\r
249                         if (_arrRawContent == null)\r
250                                 _arrRawContent = new byte [0];\r
251 \r
252                         int length = ContentLength;\r
253                         if (_WorkerRequest.IsEntireEntityBodyIsPreloaded () || length <= _arrRawContent.Length)\r
254                                 return _arrRawContent;\r
255 \r
256                         byte [] arrBuffer = new byte [Math.Min (16384, length)];\r
257                         MemoryStream ms = new MemoryStream (arrBuffer.Length);\r
258                         ms.Write (_arrRawContent, 0, _arrRawContent.Length);\r
259                         int read = 0;\r
260                         for (int loaded = _arrRawContent.Length; loaded < length; loaded += read) {\r
261                                 read = _WorkerRequest.ReadEntityBody (arrBuffer, arrBuffer.Length);\r
262                                 if (read == 0)\r
263                                         break;\r
264 \r
265                                 ms.Write (arrBuffer, 0, read);\r
266                         }\r
267 \r
268                         _arrRawContent = ms.GetBuffer ();\r
269                         return _arrRawContent;\r
270                 }\r
271 \r
272                 public string [] AcceptTypes {\r
273                         get {\r
274                                 if (null == _arrAcceptTypes && null != _WorkerRequest) {\r
275                                         _arrAcceptTypes = HttpHelper.ParseMultiValueHeader(_WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderAccept));\r
276                                 } \r
277 \r
278                                 return _arrAcceptTypes;\r
279                                 \r
280                         }\r
281                 }\r
282 \r
283                 public string ApplicationPath {\r
284                         get {\r
285                                 if (null != _WorkerRequest) {\r
286                                         return _WorkerRequest.GetAppPath();\r
287                                 }\r
288 \r
289                                 return null;\r
290                         }\r
291                 }\r
292 \r
293                 public HttpBrowserCapabilities Browser {\r
294                         get {\r
295                                 if (_browser == null)\r
296                                         _browser = new HttpBrowserCapabilities ();\r
297 \r
298                                 return _browser;\r
299                         }\r
300 \r
301                         set { _browser = value; }\r
302                 }\r
303 \r
304                 public HttpClientCertificate ClientCertificate {\r
305                         get {\r
306                                 if (null == _ClientCert) {\r
307                                         _ClientCert = new HttpClientCertificate(_oContext);\r
308                                 }\r
309 \r
310                                 return _ClientCert;\r
311                         }\r
312                 }\r
313 \r
314                 private string GetValueFromHeader (string header, string attr)\r
315                 {\r
316                         int where = header.IndexOf (attr + '=');\r
317                         if (where == -1)\r
318                                 return null;\r
319 \r
320                         where += attr.Length + 1;\r
321                         int max = header.Length;\r
322                         if (where >= max)\r
323                                 return String.Empty;\r
324 \r
325                         char ending = header [where];\r
326                         if (ending != '"')\r
327                                 ending = ' ';\r
328 \r
329                         int end = header.Substring (where + 1).IndexOf (ending);\r
330                         if (end == -1)\r
331                                 return (ending == '"') ? null : header.Substring (where);\r
332 \r
333                         return header.Substring (where, end);\r
334                 }\r
335                 \r
336                 public Encoding ContentEncoding\r
337                 {\r
338                         get {\r
339                                 if (_oContentEncoding == null) {\r
340                                         if (_WorkerRequest != null && \r
341                                             (!_WorkerRequest.HasEntityBody () || ContentType != String.Empty)) {\r
342                                                 _oContentEncoding = WebEncoding.Encoding;\r
343                                         } else  {\r
344                                                 string charset;\r
345                                                 charset = GetValueFromHeader (_sContentType, "charset");\r
346                                                 try {\r
347                                                         _oContentEncoding = Encoding.GetEncoding (charset);\r
348                                                 } catch {\r
349                                                         _oContentEncoding = WebEncoding.Encoding;\r
350                                                 }\r
351                                         }\r
352                                 }\r
353 \r
354                                 return _oContentEncoding;\r
355                         }\r
356 \r
357                         set {\r
358                                 _oContentEncoding = value;\r
359                         }\r
360                 }\r
361 \r
362                 public int ContentLength {\r
363                         get {\r
364                                 if (_iContentLength == -1 && null != _WorkerRequest) {\r
365                                         string sLength = _WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength);\r
366                                         if (sLength != null) {\r
367                                                 try {\r
368                                                         _iContentLength = Int32.Parse(sLength);\r
369                                                 }\r
370                                                 catch(Exception) {\r
371                                                 }\r
372                                         } \r
373                                 }\r
374 \r
375                                 if (_iContentLength < 0) {\r
376                                         _iContentLength = 0;\r
377                                 }\r
378 \r
379                                 return _iContentLength;\r
380                         }\r
381                 }\r
382 \r
383                 public string ContentType {\r
384                         get {\r
385                                 if (null == _sContentType) {\r
386                                         if (null != _WorkerRequest) {\r
387                                                 _sContentType = _WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentType);\r
388                                         }\r
389 \r
390                                         if (null == _sContentType) {\r
391                                                 _sContentType = string.Empty;\r
392                                         }\r
393                                 }\r
394 \r
395                                 return _sContentType;\r
396                         }\r
397                 }\r
398 \r
399                 static private string GetCookieValue (string str, int length, ref int i)\r
400                 {\r
401                         if (i >= length)\r
402                                 return null;\r
403 \r
404                         int k = i;\r
405                         while (k < length && Char.IsWhiteSpace (str [k]))\r
406                                 k++;\r
407 \r
408                         int begin = k;\r
409                         while (k < length && str [k] != ';')\r
410                                 k++;\r
411 \r
412                         i = k;\r
413                         return str.Substring (begin, i - begin).Trim ();\r
414                 }\r
415 \r
416                 static private string GetCookieName (string str, int length, ref int i)\r
417                 {\r
418                         if (i >= length)\r
419                                 return null;\r
420 \r
421                         int k = i;\r
422                         while (k < length && Char.IsWhiteSpace (str [k]))\r
423                                 k++;\r
424 \r
425                         int begin = k;\r
426                         while (k < length && str [k] != ';' &&  str [k] != '=')\r
427                                 k++;\r
428 \r
429                         i = k + 1;\r
430                         return str.Substring (begin, k - begin).Trim ();\r
431                 }\r
432 \r
433                 private void GetCookies ()\r
434                 {\r
435                         string header = _WorkerRequest.GetKnownRequestHeader (HttpWorkerRequest.HeaderCookie);\r
436                         if (header == null || header.Length == 0)\r
437                                 return;\r
438 \r
439                         /* RFC 2109\r
440                          *      cookie          =       "Cookie:" cookie-version\r
441                          *                                 1*((";" | ",") cookie-value)\r
442                          *      cookie-value    =       NAME "=" VALUE [";" path] [";" domain]\r
443                          *      cookie-version  =       "$Version" "=" value\r
444                          *      NAME            =       attr\r
445                          *      VALUE           =       value\r
446                          *      path            =       "$Path" "=" value\r
447                          *      domain          =       "$Domain" "=" value\r
448                          *\r
449                          *      MS ignores $Version! \r
450                          *      ',' as a separator produces errors.\r
451                          */\r
452 \r
453                         string [] name_values = header.Trim ().Split (';');\r
454                         int length = name_values.Length;\r
455                         HttpCookie cookie = null;\r
456                         int pos;\r
457                         for (int i = 0; i < length; i++) {\r
458                                 pos = 0;\r
459                                 string name_value = name_values [i].Trim ();\r
460                                 string name = GetCookieName (name_value, name_value.Length, ref pos);\r
461                                 string value = GetCookieValue (name_value, name_value.Length, ref pos);\r
462                                 if (cookie != null) {\r
463                                         if (name == "$Path") {\r
464                                                 cookie.Path = value;\r
465                                                 continue;\r
466                                         } else if (name == "$Domain") {\r
467                                                 cookie.Domain = value;\r
468                                                 continue;\r
469                                         } else {\r
470                                                 cookies.Add (cookie);\r
471                                                 cookie = null;\r
472                                         }\r
473                                 }\r
474                                 cookie = new HttpCookie (name, value);\r
475                         }\r
476 \r
477                         if (cookie != null)\r
478                                 cookies.Add (cookie);\r
479                 }\r
480 \r
481                 public HttpCookieCollection Cookies\r
482                 {\r
483                         get {\r
484                                 if (cookies == null) {\r
485                                         cookies = new HttpCookieCollection (null, false);\r
486                                         if (_WorkerRequest != null)\r
487                                                 GetCookies ();\r
488                                 }\r
489 \r
490                                 return cookies;\r
491                         }\r
492                 }\r
493 \r
494                 [MonoTODO()]\r
495                 public string CurrentExecutionFilePath {\r
496                         get {\r
497                                 throw new NotImplementedException();\r
498                         }\r
499                 }\r
500 \r
501                 public string FilePath {\r
502                         get {\r
503                                 if (null == _sFilePath && null != _WorkerRequest) {\r
504                                         _sFilePath = _WorkerRequest.GetFilePath();\r
505                                 }\r
506 \r
507                                 return _sFilePath;\r
508                         }\r
509                 }\r
510 \r
511                 [MonoTODO()]\r
512                 public HttpFileCollection Files {\r
513                         get {\r
514                                 throw new NotImplementedException();\r
515                         }\r
516                 }\r
517 \r
518                 [MonoTODO("Use stream filter in the request stream")]\r
519                 public Stream Filter {\r
520                         get {\r
521                                 throw new NotImplementedException();\r
522                         }\r
523 \r
524                         set {\r
525                                 throw new NotImplementedException();\r
526                         }\r
527                 }\r
528 \r
529 \r
530                 public NameValueCollection Form {\r
531                         get {\r
532                                 ParseFormData();\r
533 \r
534                                 return (NameValueCollection) _oFormData;\r
535                         }\r
536                 }\r
537 \r
538                 public NameValueCollection Headers {\r
539                         get {\r
540                                 if (_oHeaders == null) {\r
541                                         _oHeaders = new HttpValueCollection();\r
542 \r
543                                         if (null != _WorkerRequest) {\r
544                                                 string sHeaderValue;\r
545                                                 string sHeaderName;\r
546                                                 int iCount = 0;\r
547 \r
548                                                 // Add all know headers\r
549                                                 for (; iCount != 40; iCount++) {\r
550                                                         sHeaderValue = _WorkerRequest.GetKnownRequestHeader(iCount);\r
551                                                         if (null != sHeaderValue && sHeaderValue.Length > 0) {\r
552                                                                 sHeaderName = _WorkerRequest.GetKnownRequestHeader(iCount);\r
553                                                                 if (null != sHeaderName && sHeaderName.Length > 0) {\r
554                                                                         _oHeaders.Add(sHeaderName, sHeaderValue);\r
555                                                                 }\r
556                                                         }\r
557                                                 }\r
558 \r
559                                                 // Get all other headers\r
560                                                 string [][] arrUnknownHeaders = _WorkerRequest.GetUnknownRequestHeaders();\r
561                                                 if (null != arrUnknownHeaders) {\r
562                                                         for (iCount = 0; iCount != arrUnknownHeaders.Length; iCount++) {\r
563                                                                 _oHeaders.Add(arrUnknownHeaders[iCount][0], arrUnknownHeaders[iCount][1]);\r
564                                                         }\r
565                                                 }\r
566                                         }\r
567 \r
568                                         // Make headers read-only\r
569                                         _oHeaders.MakeReadOnly();\r
570                                 }\r
571 \r
572                                 return (NameValueCollection) _oHeaders;\r
573                         }\r
574                 }\r
575 \r
576                 public string HttpMethod {\r
577                         get {\r
578                                 if (null == _sHttpMethod) {\r
579                                         if (null != _WorkerRequest) {\r
580                                                 _sHttpMethod = _WorkerRequest.GetHttpVerbName().ToUpper();\r
581                                         }\r
582                \r
583                                         if (_sHttpMethod == null) {\r
584                                                 if (RequestType != null)\r
585                                                         _sHttpMethod = RequestType;\r
586                                                 else\r
587                                                         _sHttpMethod = "GET";\r
588                                         }\r
589                                 }\r
590 \r
591                                 return _sHttpMethod;\r
592                         }\r
593                 }\r
594 \r
595                 public Stream InputStream {\r
596                         get {\r
597                                 if (_oInputStream == null) {\r
598                                         byte [] arrInputData = GetRawContent ();\r
599 \r
600                                         if (null != arrInputData) {\r
601                                                 _oInputStream = new HttpRequestStream(arrInputData, 0, arrInputData.Length);\r
602                                         } else {\r
603                                                 _oInputStream = new HttpRequestStream(null, 0, 0);\r
604                                         }\r
605                                 }\r
606 \r
607                                 return _oInputStream;\r
608                         } \r
609                 }\r
610 \r
611                 public bool IsAuthenticated {\r
612                         get {\r
613                                 if (_oContext != null && _oContext.User != null && _oContext.User.Identity != null) {\r
614                                         return _oContext.User.Identity.IsAuthenticated;\r
615                                 }\r
616 \r
617                                 return false;\r
618                         }\r
619                 }\r
620 \r
621                 public bool IsSecureConnection {\r
622                         get {\r
623                                 if (null != _WorkerRequest) {\r
624                                         return _WorkerRequest.IsSecure();\r
625                                 }\r
626 \r
627                                 return false;\r
628                         }\r
629                 }\r
630 \r
631                 [MonoTODO("Call item in querystring, form, cookie and servervariables")]\r
632                 public string this [string sKey] {\r
633                         get {\r
634                                 throw new NotImplementedException();\r
635                         }\r
636                 }\r
637 \r
638                 [MonoTODO("Add cookie collection to our Params collection via merge")]\r
639                 public NameValueCollection Params {\r
640                         get {\r
641                                 if (_oParams == null) {\r
642                                         _oParams = new HttpValueCollection();\r
643                                         \r
644                                         _oParams.Merge(QueryString);\r
645                                         _oParams.Merge(Form);\r
646                                         _oParams.Merge(ServerVariables);\r
647                                         // TODO: Cookie\r
648 \r
649                                         _oParams.MakeReadOnly();\r
650                                 }\r
651 \r
652                                 return (NameValueCollection) _oParams;\r
653                         }\r
654                 }\r
655                 \r
656                 public string Path {\r
657                         get {\r
658                                 if (_sPath == null) {\r
659                                         if (null != _WorkerRequest) {\r
660                                                 _sPath = _WorkerRequest.GetUriPath();\r
661                                         }\r
662 \r
663                                         if (_sPath == null) {\r
664                                                 _sPath = string.Empty;\r
665                                         }\r
666                                 }\r
667 \r
668                                 return _sPath;\r
669                         }\r
670                 }\r
671                 \r
672                 public string PathInfo {\r
673                         get {\r
674                                 if (_sPathInfo == null) {\r
675                                         if (null != _WorkerRequest) {\r
676                                                 _sPathInfo = _WorkerRequest.GetPathInfo();\r
677                                         }\r
678 \r
679                                         if (_sPathInfo == null) {\r
680                                                 _sPathInfo = string.Empty;\r
681                                         }\r
682                                 }\r
683                                 \r
684                                 return _sPathInfo;\r
685                         }\r
686                 }\r
687 \r
688                 public string PhysicalApplicationPath {\r
689                         get {\r
690                                 if (null != _WorkerRequest) {\r
691                                         return _WorkerRequest.GetAppPathTranslated();\r
692                                 }\r
693 \r
694                                 return null;\r
695                         }\r
696                 }\r
697 \r
698                 public string PhysicalPath {\r
699                         get {\r
700                                 if (_sPathTranslated == null && _WorkerRequest != null) {\r
701                                         if (rewritten)\r
702                                                 _sPathTranslated = _WorkerRequest.GetFilePathTranslated ();\r
703 \r
704                                         if (null == _sPathTranslated)\r
705                                                 _sPathTranslated = _WorkerRequest.MapPath (FilePath);\r
706                                 }\r
707 \r
708                                 return _sPathTranslated;\r
709                         }\r
710                 }\r
711 \r
712                 public NameValueCollection QueryString {\r
713                         get {\r
714                                 if (_oQueryString == null) {\r
715                                         _oQueryString = new HttpValueCollection(QueryStringRaw, true,\r
716                                                                                 WebEncoding.Encoding);\r
717                                 }\r
718 \r
719                                 return _oQueryString;\r
720                         }\r
721                 }\r
722 \r
723                 // Used to parse the querystring\r
724                 internal string QueryStringRaw {\r
725                         get {\r
726                                 if (_sQueryStringRaw == null && null != _WorkerRequest) {\r
727                                         byte [] arrQuerystringBytes = _WorkerRequest.GetQueryStringRawBytes();\r
728                                         if (null != arrQuerystringBytes && arrQuerystringBytes.Length > 0) {\r
729                                                 _sQueryStringRaw = ContentEncoding.GetString(arrQuerystringBytes);\r
730                                         } else {\r
731                                                 _sQueryStringRaw = _WorkerRequest.GetQueryString();   \r
732                                         }\r
733                                 }\r
734 \r
735                                 if (_sQueryStringRaw == null) {\r
736                                         _sQueryStringRaw = string.Empty;\r
737                                 }\r
738 \r
739                                 return _sQueryStringRaw;\r
740                         }\r
741                 }\r
742 \r
743                 public string RawUrl {\r
744                         get {\r
745                                 if (null == _sRawUrl) {\r
746                                         if (null != _WorkerRequest) {\r
747                                                 _sRawUrl = _WorkerRequest.GetRawUrl();\r
748                                         } else {\r
749                                                 _sRawUrl = Path;\r
750                                                 if (QueryStringRaw != null && QueryStringRaw.Length > 0) {\r
751                                                         _sRawUrl = _sRawUrl + "?" + QueryStringRaw;\r
752                                                 }\r
753                                         }\r
754                                 }\r
755 \r
756                                 return _sRawUrl;\r
757                         }\r
758                 }\r
759 \r
760                 public string RequestType {\r
761                         get {\r
762                                 if (null == _sRequestType) {\r
763                                         return HttpMethod;\r
764                                 }\r
765          \r
766                                 return _sRequestType;\r
767                         }\r
768 \r
769                         set {\r
770                                 _sRequestType = value;\r
771                         }\r
772                 }\r
773                 \r
774       \r
775                 public NameValueCollection ServerVariables {\r
776                         get {\r
777                                 ParseServerVariables();\r
778 \r
779                                 return (NameValueCollection) _oServerVariables;\r
780                         }\r
781                 }      \r
782 \r
783                 public int TotalBytes {\r
784                         get {\r
785                                 if (_iTotalBytes == -1) {\r
786                                         if (null != InputStream) {\r
787                                                 _iTotalBytes = (int) InputStream.Length;\r
788                                         } else {\r
789                                                 _iTotalBytes = 0;\r
790                                         }\r
791                                 }\r
792 \r
793                                 return _iTotalBytes;\r
794                         }\r
795                 }\r
796 \r
797                 public Uri Url {\r
798                         get {\r
799                                 if (null == _oUrl) {\r
800                                         _oUrl = new Uri(RawUrl);\r
801                                 }\r
802 \r
803                                 return _oUrl;\r
804                         }\r
805                 }\r
806 \r
807                 public Uri UrlReferrer {\r
808                         get {\r
809                                 if (null == _oUriReferrer && null != _WorkerRequest) {\r
810                                         string sReferrer = _WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderReferer);\r
811                                         if (null != sReferrer && sReferrer.Length > 0) {\r
812                                                 try {\r
813                                                         if (sReferrer.IndexOf("://") >= 0) {\r
814                                                                 _oUriReferrer = new Uri(sReferrer);\r
815                                                         } else {\r
816                                                                 _oUriReferrer = new Uri(this.Url, sReferrer);\r
817                                                         }\r
818                                                 }\r
819                                                 catch (Exception) {\r
820                                                 }\r
821                                         }\r
822                                 }\r
823 \r
824                                 return _oUriReferrer;\r
825                         }\r
826                 }\r
827 \r
828                 public string UserAgent {\r
829                         get {\r
830                                 if (_sUserAgent == null && _WorkerRequest != null) {\r
831                                         _sUserAgent = _WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderUserAgent);\r
832                                 }\r
833 \r
834                                 if (_sUserAgent == null) {\r
835                                         _sUserAgent = string.Empty;\r
836                                 }\r
837 \r
838                                 return _sUserAgent;\r
839                         }\r
840                 }\r
841 \r
842                 public string UserHostAddress {\r
843                         get {\r
844                                 if (_sUserHostAddress == null && null != _WorkerRequest) {\r
845                                         _sUserHostAddress = _WorkerRequest.GetRemoteAddress();\r
846                                 }\r
847 \r
848                                 if (_sUserHostAddress == null || _sUserHostAddress.Length == 0) {\r
849                                         _sUserHostAddress = "127.0.0.1";\r
850                                 }\r
851 \r
852                                 return _sUserHostAddress;\r
853                         }\r
854                 }\r
855                 \r
856                 public string UserHostName {\r
857                         get {\r
858                                 if (_sUserHostName == null && null != _WorkerRequest) {\r
859                                         _sUserHostName = _WorkerRequest.GetRemoteName();\r
860                                 }\r
861 \r
862                                 if (_sUserHostName == null || _sUserHostName.Length == 0) {\r
863                                         _sUserHostName = UserHostAddress;\r
864                                 }\r
865 \r
866                                 return _sUserHostName;\r
867                         }\r
868                 }\r
869                 \r
870                 public string [] UserLanguages {\r
871                         get {\r
872                                 if (_arrUserLanguages == null && null != _WorkerRequest) {\r
873                                         _arrUserLanguages = HttpHelper.ParseMultiValueHeader(_WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderAcceptLanguage));\r
874                                 }\r
875 \r
876                                 return _arrUserLanguages;\r
877                         }\r
878                 }\r
879 \r
880                 internal string RootVirtualDir {\r
881                         get {\r
882                                 if (_sRequestRootVirtualDir == null) {\r
883                                         _sRequestRootVirtualDir = FilePath;\r
884                                         int pos = _sRequestRootVirtualDir.LastIndexOf ('/');\r
885                                         if (pos == -1 || pos == 0)\r
886                                                 _sRequestRootVirtualDir = "/";\r
887                                         else\r
888                                                 _sRequestRootVirtualDir = _sRequestRootVirtualDir.Substring (0, pos);\r
889                                 }\r
890 \r
891                                 return _sRequestRootVirtualDir;\r
892                         }\r
893                 }\r
894                 \r
895                 public byte [] BinaryRead(int count) {\r
896                         int iSize = TotalBytes;\r
897                         if (iSize == 0) {\r
898                                 throw new ArgumentException();\r
899                         }\r
900 \r
901                         byte [] arrData = new byte[iSize];\r
902                         \r
903                         int iRetSize = InputStream.Read(arrData, 0, iSize);\r
904                         if (iRetSize != iSize) {\r
905                                 byte [] tmpData = new byte[iRetSize];\r
906                                 if (iRetSize > 0) {\r
907                                         Array.Copy(arrData, 0, tmpData, 0, iRetSize);\r
908                                 }\r
909 \r
910                                 arrData = tmpData;\r
911                         }\r
912 \r
913                         return arrData;\r
914                 }\r
915 \r
916                 public int [] MapImageCoordinates(string ImageFieldName) {\r
917                         NameValueCollection oItems;\r
918 \r
919                         if (HttpMethod == "GET" || HttpMethod == "HEAD") {\r
920                                 oItems = QueryString;\r
921                         } else if (HttpMethod == "POST") {\r
922                                 oItems = Form;\r
923                         } else {\r
924                                 return null;\r
925                         }\r
926 \r
927                         int [] arrRet = null;\r
928                         try {\r
929                                 string sX = oItems.Get(ImageFieldName + ".x");\r
930                                 string sY = oItems.Get(ImageFieldName + ".y");\r
931 \r
932                                 if (null != sX && null != sY) {\r
933                                         int [] arrTmp = new Int32[2];\r
934                                         arrRet[0] = Int32.Parse(sX);\r
935                                         arrRet[1] = Int32.Parse(sY);\r
936 \r
937                                         arrRet = arrTmp;\r
938                                 }\r
939                         }\r
940                         catch (Exception) {\r
941                         }\r
942 \r
943                         return arrRet;\r
944                 }\r
945 \r
946                 public string MapPath (string VirtualPath)\r
947                 {\r
948                         return MapPath (VirtualPath, RootVirtualDir, true);\r
949                 }\r
950 \r
951                 [MonoTODO("allowCrossAppMapping?")]\r
952                 public string MapPath (string virtualPath, string baseVirtualDir, bool allowCrossAppMapping)\r
953                 {\r
954                         if (_WorkerRequest == null)\r
955                                 throw new HttpException ("No HttpWorkerRequest!!!");\r
956 \r
957                         if (virtualPath == null || virtualPath.Length == 0)\r
958                                 virtualPath = ".";\r
959                         else\r
960                                 virtualPath = virtualPath.Trim ();\r
961 \r
962                         if (System.IO.Path.DirectorySeparatorChar != '/')\r
963                                 virtualPath = virtualPath.Replace (System.IO.Path.DirectorySeparatorChar, '/');\r
964 \r
965                         if (UrlUtils.IsRooted (virtualPath)) {\r
966                                 virtualPath = UrlUtils.Reduce (virtualPath);\r
967                         } else {\r
968                                 if (baseVirtualDir == null)\r
969                                         virtualPath = UrlUtils.Combine (RootVirtualDir, virtualPath);\r
970                                 else\r
971                                         virtualPath = UrlUtils.Combine (baseVirtualDir, virtualPath);\r
972                         }\r
973 \r
974                         return _WorkerRequest.MapPath (virtualPath);\r
975                 }\r
976 \r
977                 public void SaveAs(string filename, bool includeHeaders) {\r
978                         FileStream oFile;\r
979                         TextWriter oWriter;\r
980                         HttpRequestStream oData;\r
981 \r
982                         oFile = new FileStream(filename, FileMode.CreateNew);\r
983                         if (includeHeaders) {\r
984                                 oWriter = new StreamWriter(oFile);\r
985                                 oWriter.Write(HttpMethod + " " + Path);\r
986 \r
987                                 if (QueryStringRaw != null && QueryStringRaw.Length > 0)\r
988                                         oWriter.Write("?" + QueryStringRaw);\r
989                                 if (_WorkerRequest != null) {\r
990                                         oWriter.Write(" " + _WorkerRequest.GetHttpVersion() + "\r\n");\r
991                                         oWriter.Write(GetAllHeaders(true));\r
992                                 } else {\r
993                                         oWriter.Write("\r\n");\r
994                                 }\r
995 \r
996                                 oWriter.Write("\r\n");\r
997                                 oWriter.Flush();\r
998                         }\r
999 \r
1000                         oData = (HttpRequestStream) InputStream;\r
1001 \r
1002                         if (oData.DataLength > 0) {\r
1003                                 oFile.Write(oData.Data, oData.DataOffset, oData.DataLength);\r
1004                         }\r
1005 \r
1006                         oFile.Flush();\r
1007                         oFile.Close();\r
1008                 }\r
1009         }\r
1010 }\r