2002-06-04 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 // Author:\r
5 //   Patrik Torstensson (Patrik.Torstensson@labs2.com)\r
6 //\r
7 using System;\r
8 using System.Collections;\r
9 using System.Collections.Specialized;\r
10 using System.IO;\r
11 using System.Text;\r
12 using System.Web.Configuration;\r
13 \r
14 namespace System.Web {\r
15    [MonoTODO("Review security in all path access function")]\r
16    public sealed class HttpRequest {\r
17       private string [] _arrAcceptTypes;\r
18       private string [] _arrUserLanguages;\r
19 \r
20       private byte [] _arrRawContent;\r
21       private int       _iContentLength;\r
22 \r
23       private string    _sContentType;\r
24       private string    _sHttpMethod;\r
25       private string    _sRawUrl;\r
26       private string    _sUserAgent;\r
27       private string    _sUserHostAddress;\r
28       private string    _sUserHostName;\r
29       private string    _sPath;\r
30       private string    _sPathInfo;\r
31       private string _sFilePath;\r
32       private string _sPathTranslated;\r
33       private string _sQueryStringRaw;\r
34       private string _sRequestType;\r
35       private string _sRequestRootVirtualDir;\r
36 \r
37       private Encoding _oContentEncoding;\r
38 \r
39       private Uri _oUriReferrer;\r
40       private Uri _oUrl;\r
41 \r
42       private int       _iTotalBytes;\r
43 \r
44       private HttpContext       _oContext;\r
45 \r
46       private HttpWorkerRequest _WorkerRequest;\r
47       private HttpRequestStream _oInputStream;\r
48       private HttpClientCertificate _ClientCert;\r
49 \r
50       private HttpValueCollection _oServerVariables;\r
51       private HttpValueCollection _oHeaders;\r
52       private HttpValueCollection _oQueryString;\r
53       private HttpValueCollection _oFormData;\r
54       private HttpValueCollection _oParams;\r
55 \r
56       private HttpBrowserCapabilities _browser;\r
57 \r
58       public HttpRequest(string Filename, string Url, string Querystring) {\r
59          _iContentLength = -1;\r
60          _iTotalBytes = -1;\r
61 \r
62          _WorkerRequest = null;\r
63          _sPathTranslated = Filename;\r
64          _sRequestType = "GET";\r
65          _sHttpMethod = "GET";\r
66          _oUrl = new Uri(Url);\r
67          _sPath = _oUrl.AbsolutePath;\r
68 \r
69          _sQueryStringRaw = Querystring;\r
70          _oQueryString = new HttpValueCollection(Querystring, true, Encoding.Default);\r
71       }\r
72 \r
73       internal HttpRequest(HttpWorkerRequest WorkRequest, HttpContext Context) {\r
74          _WorkerRequest = WorkRequest;\r
75          _oContext = Context;\r
76 \r
77          _iContentLength = -1;\r
78          _iTotalBytes = -1;\r
79       }\r
80 \r
81       static private string MakeServerVariableFromHeader(string header) {\r
82          return "HTTP_" + header.ToUpper().Replace("-", "_");\r
83       }\r
84 \r
85       [MonoTODO("Need to support non-raw mode also..")]\r
86       private string GetAllHeaders(bool Raw) {\r
87          StringBuilder oData;\r
88 \r
89          if (null == _WorkerRequest) {\r
90             return null;\r
91          }\r
92 \r
93          oData = new StringBuilder(512);\r
94 \r
95          string sHeaderValue;\r
96          string sHeaderName;\r
97          int iCount = 0;\r
98 \r
99          // Add all know headers\r
100          for (; iCount != 40; iCount++) {\r
101             sHeaderValue = _WorkerRequest.GetKnownRequestHeader(iCount);\r
102             if (null != sHeaderValue && sHeaderValue.Length > 0) {\r
103                sHeaderName = _WorkerRequest.GetKnownRequestHeader(iCount);\r
104                if (null != sHeaderName && sHeaderName.Length > 0) {\r
105                   oData.Append(sHeaderName);\r
106                   oData.Append(": ");\r
107                   oData.Append(sHeaderValue);\r
108                   oData.Append("\r\n");\r
109                }\r
110             }\r
111          }\r
112 \r
113          // Get all other headers\r
114          string [][] arrUnknownHeaders = _WorkerRequest.GetUnknownRequestHeaders();\r
115          if (null != arrUnknownHeaders) {\r
116             for (iCount = 0; iCount != arrUnknownHeaders.Length; iCount++) {\r
117                oData.Append(arrUnknownHeaders[iCount][0]);\r
118                oData.Append(": ");\r
119                oData.Append(arrUnknownHeaders[iCount][1]);\r
120                oData.Append("\r\n");\r
121             }\r
122          }\r
123 \r
124          return oData.ToString();\r
125       }\r
126       \r
127       [MonoTODO("We need to handly 'dynamic' variables like AUTH_USER, that can be changed during runtime... special collection")]\r
128       private void ParseServerVariables() {\r
129          if (null == _WorkerRequest) {\r
130             return;\r
131          }\r
132 \r
133          if (_oServerVariables == null) {\r
134             string sTmp;\r
135 \r
136             _oServerVariables = new HttpValueCollection();\r
137                                 \r
138             _oServerVariables.Add("ALL_HTTP", GetAllHeaders(false));\r
139             _oServerVariables.Add("ALL_RAW", GetAllHeaders(true));\r
140 \r
141             _oServerVariables.Add("APPL_MD_PATH", _WorkerRequest.GetServerVariable("APPL_MD_PATH"));\r
142             _oServerVariables.Add("AUTH_PASSWORD", _WorkerRequest.GetServerVariable("AUTH_PASSWORD"));\r
143             _oServerVariables.Add("CERT_COOKIE", _WorkerRequest.GetServerVariable("CERT_COOKIE"));\r
144             _oServerVariables.Add("CERT_FLAGS", _WorkerRequest.GetServerVariable("CERT_FLAGS"));\r
145             _oServerVariables.Add("CERT_ISSUER", _WorkerRequest.GetServerVariable("CERT_ISSUER"));\r
146             _oServerVariables.Add("CERT_KEYSIZE", _WorkerRequest.GetServerVariable("CERT_KEYSIZE"));\r
147             _oServerVariables.Add("CERT_SECRETKEYSIZE", _WorkerRequest.GetServerVariable("CERT_SECRETKEYSIZE"));\r
148             _oServerVariables.Add("CERT_SERIALNUMBER", _WorkerRequest.GetServerVariable("CERT_SERIALNUMBER"));\r
149             _oServerVariables.Add("CERT_SERVER_ISSUER", _WorkerRequest.GetServerVariable("CERT_SERVER_ISSUER"));\r
150             _oServerVariables.Add("CERT_SERVER_SUBJECT", _WorkerRequest.GetServerVariable("CERT_SERVER_SUBJECT"));\r
151             _oServerVariables.Add("CERT_SUBJECT", _WorkerRequest.GetServerVariable("CERT_SUBJECT"));\r
152 \r
153             _oServerVariables.Add("GATEWAY_INTERFACE", _WorkerRequest.GetServerVariable("GATEWAY_INTERFACE"));\r
154             _oServerVariables.Add("HTTPS", _WorkerRequest.GetServerVariable("HTTPS"));\r
155             _oServerVariables.Add("HTTPS_KEYSIZE", _WorkerRequest.GetServerVariable("HTTPS_KEYSIZE"));\r
156             _oServerVariables.Add("HTTPS_SECRETKEYSIZE", _WorkerRequest.GetServerVariable("HTTPS_SECRETKEYSIZE"));\r
157 \r
158             _oServerVariables.Add("CONTENT_TYPE", ContentType);\r
159             _oServerVariables.Add("HTTPS_SERVER_ISSUER", _WorkerRequest.GetServerVariable("HTTPS_SERVER_ISSUER"));\r
160             _oServerVariables.Add("HTTPS_SERVER_SUBJECT", _WorkerRequest.GetServerVariable("HTTPS_SERVER_SUBJECT"));\r
161             _oServerVariables.Add("INSTANCE_ID", _WorkerRequest.GetServerVariable("INSTANCE_ID"));\r
162             _oServerVariables.Add("INSTANCE_META_PATH", _WorkerRequest.GetServerVariable("INSTANCE_META_PATH"));\r
163             _oServerVariables.Add("LOCAL_ADDR", _WorkerRequest.GetLocalAddress());\r
164             _oServerVariables.Add("REMOTE_ADDR", UserHostAddress);\r
165             _oServerVariables.Add("REMOTE_HOST", UserHostName);\r
166             _oServerVariables.Add("REQUEST_METHOD", HttpMethod);\r
167             _oServerVariables.Add("SERVER_NAME", _WorkerRequest.GetServerName());\r
168             _oServerVariables.Add("SERVER_PORT", _WorkerRequest.GetLocalPort().ToString());\r
169             _oServerVariables.Add("SERVER_PROTOCOL", _WorkerRequest.GetHttpVersion());\r
170             _oServerVariables.Add("SERVER_SOFTWARE", _WorkerRequest.GetServerVariable("SERVER_SOFTWARE"));\r
171 \r
172             if (_WorkerRequest.IsSecure()) {\r
173                _oServerVariables.Add("SERVER_PORT_SECURE", "1");\r
174             } else {\r
175                _oServerVariables.Add("SERVER_PORT_SECURE", "0");\r
176             }\r
177 \r
178             sTmp = _WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength);\r
179             if (null != sTmp) {\r
180                _oServerVariables.Add("CONTENT_LENGTH", sTmp);\r
181             }\r
182 \r
183             // TODO: Should be dynamic\r
184             if (null != _oContext.User && _oContext.User.Identity.IsAuthenticated) {\r
185                _oServerVariables.Add("AUTH_TYPE", _oContext.User.Identity.AuthenticationType);\r
186                _oServerVariables.Add("AUTH_USER", _oContext.User.Identity.Name);\r
187             } else {\r
188                _oServerVariables.Add("AUTH_TYPE", "");\r
189                _oServerVariables.Add("AUTH_USER", "");\r
190             }\r
191 \r
192             _oServerVariables.Add("PATH_INFO", PathInfo);\r
193             _oServerVariables.Add("PATH_TRANSLATED", PhysicalPath);\r
194             _oServerVariables.Add("QUERY_STRING", QueryStringRaw);\r
195             _oServerVariables.Add("SCRIPT_NAME", FilePath);\r
196             // end dynamic\r
197             \r
198             _oServerVariables.MakeReadOnly();\r
199          }\r
200       }\r
201 \r
202       [MonoTODO("Handle Multipart data also, content-encoding check")]\r
203       private void ParseFormData() {\r
204          if (_oFormData == null) {\r
205             byte [] arrData = GetRawContent();\r
206             _oFormData = new HttpValueCollection(ContentEncoding.GetString(arrData), true, ContentEncoding);\r
207          }\r
208       }\r
209 \r
210       void Dispose() {\r
211                         \r
212       }\r
213 \r
214       [MonoTODO("Handle Multipart data, max content length?")]\r
215       private byte [] GetRawContent() {\r
216          if (null == _arrRawContent) {\r
217             if (null == _WorkerRequest) {\r
218                return null;\r
219             }\r
220 \r
221             // TODO: Check max length?\r
222             _arrRawContent = _WorkerRequest.GetPreloadedEntityBody();\r
223             if (!_WorkerRequest.IsEntireEntityBodyIsPreloaded()) {\r
224                byte [] arrTemp;\r
225                byte [] arrBuffer;\r
226                                         \r
227                arrBuffer = new byte[16384];\r
228                int iLoaded = 16384;\r
229 \r
230                while (iLoaded == arrBuffer.Length) {\r
231                   iLoaded = _WorkerRequest.ReadEntityBody(arrBuffer, arrBuffer.Length);\r
232                                                 \r
233                   // Save data\r
234                   arrTemp = new byte[_arrRawContent.Length + iLoaded];\r
235                                                 \r
236                   Array.Copy(_arrRawContent, 0, arrTemp, 0, _arrRawContent.Length);\r
237                   Array.Copy(arrBuffer, 0, arrTemp, _arrRawContent.Length, iLoaded);\r
238 \r
239                   _arrRawContent = arrTemp;\r
240                }\r
241             }\r
242          }\r
243 \r
244          return _arrRawContent;\r
245       }\r
246 \r
247       public string [] AcceptTypes {\r
248          get {\r
249             if (null == _arrAcceptTypes && null != _WorkerRequest) {\r
250                _arrAcceptTypes = HttpHelper.ParseMultiValueHeader(_WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderAccept));\r
251             } \r
252 \r
253             return _arrAcceptTypes;\r
254                                 \r
255          }\r
256       }\r
257 \r
258       public string ApplicationPath {\r
259          get {\r
260             if (null != _WorkerRequest) {\r
261                return _WorkerRequest.GetAppPath();\r
262             }\r
263 \r
264             return null;\r
265          }\r
266       }\r
267 \r
268       public HttpBrowserCapabilities Browser\r
269       {\r
270         get { return _browser; }\r
271 \r
272         set { _browser = value; }\r
273       }\r
274 \r
275       public HttpClientCertificate ClientCertificate {\r
276          get {\r
277             if (null == _ClientCert) {\r
278                _ClientCert = new HttpClientCertificate(_oContext);\r
279             }\r
280 \r
281             return _ClientCert;\r
282          }\r
283       }\r
284 \r
285       [MonoTODO("Get content encoding from Syste.Web.Configuration namespace")]\r
286       public Encoding ContentEncoding {\r
287          get {\r
288             if (_oContentEncoding == null) {\r
289                // TODO: Get from config what is the default encoding\r
290                // TODO: Should we get encoding from HttpHeaders? Just get charset from ContentType and the get encoding..\r
291                _oContentEncoding = Encoding.Default;\r
292             }\r
293 \r
294             return _oContentEncoding;\r
295          }\r
296 \r
297          set {\r
298             _oContentEncoding = value;\r
299          }\r
300       }\r
301 \r
302       public int ContentLength {\r
303          get {\r
304             if (_iContentLength == -1 && null != _WorkerRequest) {\r
305                string sLength = _WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength);\r
306                if (sLength != null) {\r
307                   try {\r
308                      _iContentLength = Int32.Parse(sLength);\r
309                   }\r
310                   catch(Exception) {\r
311                   }\r
312                } \r
313             }\r
314 \r
315             if (_iContentLength < 0) {\r
316                _iContentLength = 0;\r
317             }\r
318 \r
319             return _iContentLength;\r
320          }\r
321       }\r
322 \r
323       public string ContentType {\r
324          get {\r
325             if (null == _sContentType) {\r
326                if (null != _WorkerRequest) {\r
327                   _sContentType = _WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentType);\r
328                }\r
329 \r
330                if (null == _sContentType) {\r
331                   _sContentType = string.Empty;\r
332                }\r
333             }\r
334 \r
335             return _sContentType;\r
336          }\r
337       }\r
338 \r
339       [MonoTODO()]\r
340       public HttpCookieCollection Cookies {\r
341          get {\r
342             throw new NotImplementedException();\r
343          }\r
344       }\r
345 \r
346       [MonoTODO()]\r
347       public string CurrentExecutionFilePath {\r
348          get {\r
349             throw new NotImplementedException();\r
350          }\r
351       }\r
352 \r
353       public string FilePath {\r
354          get {\r
355             if (null == _sFilePath && null != _WorkerRequest) {\r
356                _sFilePath = _WorkerRequest.GetFilePath();\r
357             }\r
358 \r
359             return _sFilePath;\r
360          }\r
361       }\r
362 \r
363       [MonoTODO()]\r
364       public HttpFileCollection Files {\r
365          get {\r
366             throw new NotImplementedException();\r
367          }\r
368       }\r
369 \r
370       [MonoTODO("Use stream filter in the request stream")]\r
371       public Stream Filter {\r
372          get {\r
373             throw new NotImplementedException();\r
374          }\r
375 \r
376          set {\r
377             throw new NotImplementedException();\r
378          }\r
379       }\r
380 \r
381 \r
382       public NameValueCollection Form {\r
383          get {\r
384             ParseFormData();\r
385 \r
386             return (NameValueCollection) _oFormData;\r
387          }\r
388       }\r
389 \r
390       public NameValueCollection Headers {\r
391          get {\r
392             if (_oHeaders == null) {\r
393                _oHeaders = new HttpValueCollection();\r
394 \r
395                if (null != _WorkerRequest) {\r
396                   string sHeaderValue;\r
397                   string sHeaderName;\r
398                   int iCount = 0;\r
399 \r
400                   // Add all know headers\r
401                   for (; iCount != 40; iCount++) {\r
402                      sHeaderValue = _WorkerRequest.GetKnownRequestHeader(iCount);\r
403                      if (null != sHeaderValue && sHeaderValue.Length > 0) {\r
404                         sHeaderName = _WorkerRequest.GetKnownRequestHeader(iCount);\r
405                         if (null != sHeaderName && sHeaderName.Length > 0) {\r
406                            _oHeaders.Add(sHeaderName, sHeaderValue);\r
407                         }\r
408                      }\r
409                   }\r
410 \r
411                   // Get all other headers\r
412                   string [][] arrUnknownHeaders = _WorkerRequest.GetUnknownRequestHeaders();\r
413                   if (null != arrUnknownHeaders) {\r
414                      for (iCount = 0; iCount != arrUnknownHeaders.Length; iCount++) {\r
415                         _oHeaders.Add(arrUnknownHeaders[iCount][0], arrUnknownHeaders[iCount][1]);\r
416                      }\r
417                   }\r
418                }\r
419 \r
420                // Make headers read-only\r
421                _oHeaders.MakeReadOnly();\r
422             }\r
423 \r
424             return (NameValueCollection) _oHeaders;\r
425          }\r
426       }\r
427 \r
428       public string HttpMethod {\r
429          get {\r
430             if (null == _sHttpMethod) {\r
431                if (null != _WorkerRequest) {\r
432                   _sHttpMethod = _WorkerRequest.GetHttpVerbName().ToUpper();\r
433                }\r
434                \r
435                if (_sHttpMethod == null) {\r
436                   _sHttpMethod = "GET";\r
437                }\r
438             }\r
439 \r
440             return _sHttpMethod;\r
441          }\r
442       }\r
443 \r
444       public Stream InputStream {\r
445          get {\r
446             if (_oInputStream == null) {\r
447                byte [] arrInputData = GetRawContent();\r
448 \r
449                if (null != arrInputData) {\r
450                   _oInputStream = new HttpRequestStream(arrInputData, 0, arrInputData.Length);\r
451                } else {\r
452                   _oInputStream = new HttpRequestStream(null, 0, 0);\r
453                }\r
454             }\r
455 \r
456             return _oInputStream;\r
457          } \r
458       }\r
459 \r
460       public bool IsAuthenticated {\r
461          get {\r
462             if (_oContext != null && _oContext.User != null && _oContext.User.Identity != null) {\r
463                  return _oContext.User.Identity.IsAuthenticated;\r
464             }\r
465 \r
466             return false;\r
467          }\r
468       }\r
469 \r
470       public bool IsSecureConnection {\r
471          get {\r
472             if (null != _WorkerRequest) {\r
473                return _WorkerRequest.IsSecure();\r
474             }\r
475 \r
476             return false;\r
477          }\r
478       }\r
479 \r
480       [MonoTODO("Call item in querystring, form, cookie and servervariables")]\r
481       public string this [string sKey] {\r
482          get {\r
483             throw new NotImplementedException();\r
484          }\r
485       }\r
486 \r
487       [MonoTODO("Add cookie collection to our Params collection via merge")]\r
488       public NameValueCollection Params {\r
489          get {\r
490             if (_oParams == null) {\r
491                _oParams = new HttpValueCollection();\r
492                                         \r
493                _oParams.Merge(QueryString);\r
494                _oParams.Merge(Form);\r
495                _oParams.Merge(ServerVariables);\r
496                // TODO: Cookie\r
497 \r
498                _oParams.MakeReadOnly();\r
499             }\r
500 \r
501             return (NameValueCollection) _oParams;\r
502          }\r
503       }\r
504                 \r
505       public string Path {\r
506          get {\r
507             if (_sPath == null) {\r
508                if (null != _WorkerRequest) {\r
509                   _sPath = _WorkerRequest.GetUriPath();\r
510                }\r
511 \r
512                if (_sPath == null) {\r
513                   _sPath = string.Empty;\r
514                }\r
515             }\r
516 \r
517             return _sPath;\r
518          }\r
519       }\r
520                 \r
521       public string PathInfo {\r
522          get {\r
523             if (_sPathInfo == null) {\r
524                if (null != _WorkerRequest) {\r
525                   _sPathInfo = _WorkerRequest.GetPathInfo();\r
526                }\r
527 \r
528                if (_sPathInfo == null) {\r
529                   _sPathInfo = string.Empty;\r
530                }\r
531             }\r
532                                 \r
533             return _sPathInfo;\r
534          }\r
535       }\r
536 \r
537       public string PhysicalApplicationPath {\r
538          get {\r
539             if (null != _WorkerRequest) {\r
540                return _WorkerRequest.GetAppPathTranslated();\r
541             }\r
542 \r
543             return null;\r
544          }\r
545       }\r
546 \r
547       public string PhysicalPath {\r
548          get {\r
549             if (null != _WorkerRequest) {\r
550                _sPathTranslated = _WorkerRequest.GetFilePathTranslated();\r
551                if (null == _sPathTranslated) {\r
552                   _sPathTranslated = _WorkerRequest.MapPath(FilePath);\r
553                }\r
554             }\r
555 \r
556             return _sPathTranslated;\r
557          }\r
558       }\r
559 \r
560       public NameValueCollection QueryString {\r
561          get {\r
562             if (_oQueryString == null) {\r
563                _oQueryString = new HttpValueCollection(QueryStringRaw, true, Encoding.UTF8);\r
564             }\r
565 \r
566             return _oQueryString;\r
567          }\r
568       }\r
569 \r
570       // Used to parse the querystring\r
571       internal string QueryStringRaw {\r
572          get {\r
573             if (_sQueryStringRaw == null && null != _WorkerRequest) {\r
574                byte [] arrQuerystringBytes = _WorkerRequest.GetQueryStringRawBytes();\r
575                if (null != arrQuerystringBytes && arrQuerystringBytes.Length > 0) {\r
576                   _sQueryStringRaw = ContentEncoding.GetString(arrQuerystringBytes);\r
577                } else {\r
578                   _sQueryStringRaw = _WorkerRequest.GetQueryString();   \r
579                }\r
580             }\r
581 \r
582             if (_sQueryStringRaw == null) {\r
583                _sQueryStringRaw = string.Empty;\r
584             }\r
585 \r
586             return _sQueryStringRaw;\r
587          }\r
588       }\r
589 \r
590       public string RawUrl {\r
591          get {\r
592             if (null == _sRawUrl) {\r
593                if (null != _WorkerRequest) {\r
594                   _sRawUrl = _WorkerRequest.GetRawUrl();\r
595                } else {\r
596                   _sRawUrl = Path;\r
597                   if (QueryStringRaw != null && QueryStringRaw.Length > 0) {\r
598                      _sRawUrl = _sRawUrl + "?" + QueryStringRaw;\r
599                   }\r
600                }\r
601             }\r
602 \r
603             return _sRawUrl;\r
604          }\r
605       }\r
606 \r
607       public string RequestType {\r
608          get {\r
609             if (null == _sRequestType) {\r
610                return HttpMethod;\r
611             }\r
612          \r
613             return _sRequestType;\r
614          }\r
615 \r
616          set {\r
617             _sRequestType = value;\r
618          }\r
619       }\r
620                 \r
621       \r
622       public NameValueCollection ServerVariables {\r
623          get {\r
624             ParseServerVariables();\r
625 \r
626             return (NameValueCollection) _oServerVariables;\r
627          }\r
628       }      \r
629 \r
630       public int TotalBytes {\r
631          get {\r
632             if (_iTotalBytes == -1) {\r
633                if (null != InputStream) {\r
634                   _iTotalBytes = (int) InputStream.Length;\r
635                } else {\r
636                   _iTotalBytes = 0;\r
637                }\r
638             }\r
639 \r
640             return _iTotalBytes;\r
641          }\r
642       }\r
643 \r
644       public Uri Url {\r
645          get {\r
646             if (null == _oUrl) {\r
647                _oUrl = new Uri(RawUrl);\r
648             }\r
649 \r
650             return _oUrl;\r
651          }\r
652       }\r
653 \r
654       public Uri UrlReferrer {\r
655          get {\r
656             if (null == _oUriReferrer && null != _WorkerRequest) {\r
657                string sReferrer = _WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderReferer);\r
658                if (null != sReferrer && sReferrer.Length > 0) {\r
659                   try {\r
660                      if (sReferrer.IndexOf("://") >= 0) {\r
661                         _oUriReferrer = new Uri(sReferrer);\r
662                      } else {\r
663                         _oUriReferrer = new Uri(this.Url, sReferrer);\r
664                      }\r
665                   }\r
666                   catch (Exception) {\r
667                   }\r
668                }\r
669             }\r
670 \r
671             return _oUriReferrer;\r
672          }\r
673       }\r
674 \r
675       public string UserAgent {\r
676          get {\r
677             if (_sUserAgent == null && _WorkerRequest != null) {\r
678                _sUserAgent = _WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderUserAgent);\r
679             }\r
680 \r
681             if (_sUserAgent == null) {\r
682                _sUserAgent = string.Empty;\r
683             }\r
684 \r
685             return _sUserAgent;\r
686          }\r
687       }\r
688 \r
689       public string UserHostAddress {\r
690          get {\r
691             if (_sUserHostAddress == null && null != _WorkerRequest) {\r
692                _sUserHostAddress = _WorkerRequest.GetRemoteAddress();\r
693             }\r
694 \r
695             if (_sUserHostAddress == null || _sUserHostAddress.Length == 0) {\r
696                _sUserHostAddress = "127.0.0.1";\r
697             }\r
698 \r
699             return _sUserHostAddress;\r
700          }\r
701       }\r
702                 \r
703       public string UserHostName {\r
704          get {\r
705             if (_sUserHostName == null && null != _WorkerRequest) {\r
706                _sUserHostName = _WorkerRequest.GetRemoteName();\r
707             }\r
708 \r
709             if (_sUserHostName == null || _sUserHostName.Length == 0) {\r
710                _sUserHostName = UserHostAddress;\r
711             }\r
712 \r
713             return _sUserHostName;\r
714          }\r
715       }\r
716                 \r
717       public string [] UserLanguages {\r
718          get {\r
719             if (_arrUserLanguages == null && null != _WorkerRequest) {\r
720                _arrUserLanguages = HttpHelper.ParseMultiValueHeader(_WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderAcceptLanguage));\r
721             }\r
722 \r
723             return _arrUserLanguages;\r
724          }\r
725       }\r
726 \r
727       public byte [] BinaryRead(int count) {\r
728          int iSize = TotalBytes;\r
729          if (iSize == 0) {\r
730             throw new ArgumentException();\r
731          }\r
732 \r
733          byte [] arrData = new byte[iSize];\r
734                         \r
735          int iRetSize = InputStream.Read(arrData, 0, iSize);\r
736          if (iRetSize != iSize) {\r
737             byte [] tmpData = new byte[iRetSize];\r
738             if (iRetSize > 0) {\r
739                Array.Copy(arrData, 0, tmpData, 0, iRetSize);\r
740             }\r
741 \r
742             arrData = tmpData;\r
743          }\r
744 \r
745          return arrData;\r
746       }\r
747 \r
748       public int [] MapImageCoordinates(string ImageFieldName) {\r
749          NameValueCollection oItems;\r
750 \r
751          if (HttpMethod == "GET" || HttpMethod == "HEAD") {\r
752             oItems = QueryString;\r
753          } else if (HttpMethod == "POST") {\r
754             oItems = Form;\r
755          } else {\r
756             return null;\r
757          }\r
758 \r
759          int [] arrRet = null;\r
760          try {\r
761             string sX = oItems.Get(ImageFieldName + ".x");\r
762             string sY = oItems.Get(ImageFieldName + ".y");\r
763 \r
764             if (null != sX && null != sY) {\r
765                int [] arrTmp = new Int32[2];\r
766                arrRet[0] = Int32.Parse(sX);\r
767                arrRet[1] = Int32.Parse(sY);\r
768 \r
769                arrRet = arrTmp;\r
770             }\r
771          }\r
772          catch (Exception) {\r
773          }\r
774 \r
775          return arrRet;\r
776       }\r
777 \r
778       public string MapPath(string VirtualPath) {\r
779          if (null == _sRequestRootVirtualDir) {\r
780             if (null == FilePath || FilePath.Length == 0) {\r
781                throw new ArgumentException("Filepath can't be empty");\r
782             }\r
783 \r
784             if (FilePath[0] != '/') {\r
785                throw new ArgumentException("Filepath must be a root");\r
786             }\r
787 \r
788             _sRequestRootVirtualDir = FilePath.Substring(0, FilePath.LastIndexOf('/'));\r
789             if (_sRequestRootVirtualDir.Length == 0) {\r
790                _sRequestRootVirtualDir = "/";\r
791             }\r
792          }\r
793 \r
794          return MapPath(VirtualPath, _sRequestRootVirtualDir, true);\r
795       }\r
796 \r
797       [MonoTODO("Build a path to send to MapPath in the workerrequest")]\r
798       public string MapPath(string virtualPath, string baseVirtualDir, bool allowCrossAppMapping) {\r
799          throw new NotImplementedException();\r
800       }\r
801 \r
802       public void SaveAs(string filename, bool includeHeaders) {\r
803          FileStream oFile;\r
804          TextWriter oWriter;\r
805          HttpRequestStream oData;\r
806 \r
807          oFile = new FileStream(filename, FileMode.CreateNew);\r
808          if (includeHeaders) {\r
809             oWriter = new StreamWriter(oFile);\r
810             oWriter.Write(HttpMethod + " " + Path);\r
811 \r
812             if (QueryStringRaw != null && QueryStringRaw.Length > 0)\r
813                oWriter.Write("?" + QueryStringRaw);\r
814             if (_WorkerRequest != null) {\r
815                oWriter.Write(" " + _WorkerRequest.GetHttpVersion() + "\r\n");\r
816                oWriter.Write(GetAllHeaders(true));\r
817             } else {\r
818                oWriter.Write("\r\n");\r
819             }\r
820 \r
821             oWriter.Write("\r\n");\r
822             oWriter.Flush();\r
823          }\r
824 \r
825          oData = (HttpRequestStream) InputStream;\r
826 \r
827          if (oData.DataLength > 0) {\r
828             oFile.Write(oData.Data, oData.DataOffset, oData.DataLength);\r
829          }\r
830 \r
831          oFile.Flush();\r
832          oFile.Close();\r
833       }\r
834    }\r
835 }\r