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