2004-06-09 Pedro Mart�nez Juli� <yoros@wanadoo.es>
[mono.git] / mcs / class / System.Web / System.Web.Hosting / SimpleWorkerRequest.cs
1 // 
2 // System.Web.Hosting.SimpleWorkerRequest.cs
3 //
4 // Authors:
5 //      Patrik Torstensson (Patrik.Torstensson@labs2.com)
6 //      (class signature from Bob Smith <bob@thestuff.net> (C) )
7 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 //
9 using System;
10 using System.IO;
11 using System.Text;
12 using System.Runtime.InteropServices;
13 using System.Web.Util;
14
15 namespace System.Web.Hosting
16 {
17         [MonoTODO("Implement security demands on the path usage functions (and review)")]
18         [ComVisible (false)]
19         public class SimpleWorkerRequest : HttpWorkerRequest
20         {
21                 private string _Page;
22                 private string _Query;
23                 private string _PathInfo = String.Empty;
24                 private string _AppVirtualPath;
25                 private string _AppPhysicalPath;
26                 private string _AppInstallPath;
27                 private TextWriter _Output;
28                 private bool _HasInstallInfo;
29
30                 private SimpleWorkerRequest ()
31                 {
32                 }
33
34                 public SimpleWorkerRequest (string Page, string Query, TextWriter Output)
35                 {
36                         _Page = Page;
37
38                         _Query = Query;
39                         AppDomain current = AppDomain.CurrentDomain;
40                         object o = current.GetData (".appPath");
41                         if (o == null)
42                                 throw new HttpException ("Cannot get .appPath");
43                         _AppPhysicalPath = o.ToString ();
44
45                         o = current.GetData (".hostingVirtualPath");
46                         if (o == null)
47                                 throw new HttpException ("Cannot get .hostingVirtualPath");
48                         _AppVirtualPath = o.ToString ();
49
50                         o = current.GetData (".hostingInstallDir");
51                         if (o == null)
52                                 throw new HttpException ("Cannot get .hostingInstallDir");
53                         _AppInstallPath = o.ToString ();
54                         _Output = Output;
55
56                         if (_AppPhysicalPath == null)
57                                 throw new HttpException ("Invalid app domain");
58
59                         _HasInstallInfo = true;
60
61                         ExtractPagePathInfo();
62                 }
63
64                 public SimpleWorkerRequest (string AppVirtualPath,
65                                             string AppPhysicalPath,
66                                             string Page,
67                                             string Query,
68                                             TextWriter Output)
69                 {
70                         if (AppDomain.CurrentDomain.GetData (".appPath") == null)
71                                 throw new HttpException ("Invalid app domain");
72
73                         _Page = Page;
74                         _Query = Query;
75                         _AppVirtualPath = AppVirtualPath;
76                         _AppPhysicalPath = CheckAndAddSlash (AppPhysicalPath);
77                         _Output = Output;
78                         _HasInstallInfo = false;
79
80                         ExtractPagePathInfo();
81                 }
82
83                 [MonoTODO("Implement security")]
84                 public override string MachineInstallDirectory
85                 {
86                         get {
87                                 if (_HasInstallInfo)
88                                         return _AppInstallPath;
89
90                                 return ICalls.GetMachineInstallDirectory ();
91                         }
92                 }
93
94                 public override string MachineConfigPath
95                 {
96                         get { return ICalls.GetMachineConfigPath (); }
97                 }
98
99                 public override void EndOfRequest ()
100                 {
101                 }
102
103                 public override void FlushResponse (bool finalFlush)
104                 {
105                 }
106
107                 public override string GetAppPath ()
108                 {
109                         return _AppVirtualPath;
110                 }
111
112                 public override string GetAppPathTranslated ()
113                 {
114                         return _AppPhysicalPath;
115                 }
116
117                 public override string GetFilePath ()
118                 {
119                         return CreatePath (false);
120                 }
121
122                 public override string GetFilePathTranslated ()
123                 {
124                         string page = _Page;
125
126                         if (Path.DirectorySeparatorChar != '/')
127                                 page = _Page.Replace ('/', Path.DirectorySeparatorChar);
128
129                         if (page [0] == Path.DirectorySeparatorChar)
130                                 page = page.Substring (1);
131                         
132                         return (Path.Combine (_AppPhysicalPath, page));
133                 }
134
135                 public override string GetHttpVerbName ()
136                 {
137                         return "GET";
138                 }
139
140                 public override string GetHttpVersion ()
141                 {
142                         return "HTTP/1.0";
143                 }
144
145                 public override string GetLocalAddress ()
146                 {
147                         return "127.0.0.1";
148                 }
149
150                 public override int GetLocalPort ()
151                 {
152                         return 80;
153                 }
154
155                 public override string GetPathInfo ()
156                 {
157                         return _PathInfo;
158                 }
159
160                 public override string GetQueryString ()
161                 {
162                         return _Query;
163                 }
164
165                 public override string GetRawUrl ()
166                 {
167                         string path = CreatePath (true);
168                         if (null != _Query && _Query.Length > 0)
169                                 return path + "?" + _Query;
170
171                         return path;
172                 }
173
174                 public override string GetRemoteAddress()
175                 {
176                         return "127.0.0.1";
177                 }
178
179                 public override int GetRemotePort()
180                 {
181                         return 0;
182                 }
183
184                 public override string GetServerVariable(string name)
185                 {
186                         return String.Empty;
187                 }
188
189                 public override string GetUriPath()
190                 {
191                         return CreatePath (true);
192                 }
193
194                 public override IntPtr GetUserToken()
195                 {
196                         return IntPtr.Zero;
197                 }
198
199                 public override string MapPath (string path)
200                 {
201                         string sPath = _AppPhysicalPath.Substring (0, _AppPhysicalPath.Length - 1);
202                         if (path != null && path.Length > 0 && path [0] != '/')
203                                 return sPath;
204  
205                         char sep = Path.DirectorySeparatorChar;
206                         if (path.StartsWith(_AppVirtualPath)) {
207                                 if (sep == '/')
208                                         return sPath + path.Substring (_AppVirtualPath.Length);
209                                 else
210                                         return sPath + path.Substring (_AppVirtualPath.Length).Replace ('/', sep);
211                         }
212
213                         return null;
214                 }
215
216                 public override void SendKnownResponseHeader (int index, string value)
217                 {
218                 }
219
220                 public override void SendResponseFromFile (IntPtr handle, long offset, long length)
221                 {
222                 }
223
224                 public override void SendResponseFromFile (string filename, long offset, long length)
225                 {
226                 }
227
228                 public override void SendResponseFromMemory (byte [] data, int length)
229                 {
230                         _Output.Write (Encoding.Default.GetChars (data, 0, length));
231                 }
232
233                 public override void SendStatus(int statusCode, string statusDescription)
234                 {
235                 }
236
237                 public override void SendUnknownResponseHeader(string name, string value)
238                 {
239                 }
240
241                 // Create's a path string
242                 private string CheckAndAddSlash(string sPath)
243                 {
244                         if (null == sPath)
245                                 return null;
246
247                         if (!sPath.EndsWith ("" + Path.DirectorySeparatorChar))
248                                 return sPath + Path.DirectorySeparatorChar;
249
250                         return sPath;
251                 }
252
253                 // Create's a path string
254                 private string CreatePath (bool bIncludePathInfo)
255                 {
256                         string sPath = Path.Combine (_AppVirtualPath, _Page);
257
258                         if (bIncludePathInfo)
259                         {
260                                 sPath += _PathInfo;
261                         }
262
263                         return sPath;
264                 }
265
266                 //  "The extra path information, as given by the client. In
267                 //  other words, scripts can be accessed by their virtual
268                 //  pathname, followed by extra information at the end of this
269                 //  path. The extra information is sent as PATH_INFO."
270                 private void ExtractPagePathInfo ()
271                 {
272                         if (_Page == null || _Page == String.Empty)
273                                 return;
274
275                         string FullPath = GetFilePathTranslated ();
276                         int PathInfoLength = 0;
277                         string LastFile = String.Empty;
278
279                         while (PathInfoLength < _Page.Length) {
280                                 if (LastFile.Length > 0) {
281                                         // increase it by the length of the file plus 
282                                         // a "/"
283                                         //
284                                         PathInfoLength += LastFile.Length + 1;
285                                 }
286
287                                 if (File.Exists (FullPath) == true)
288                                         break;
289
290                                 if (Directory.Exists (FullPath) == true) {
291                                         PathInfoLength -= (LastFile.Length + 1);
292                                         break;
293                                 }
294
295                                 LastFile = Path.GetFileName (FullPath);
296                                 FullPath = Path.GetDirectoryName (FullPath);
297                         }
298
299                         if (PathInfoLength <= 0 || PathInfoLength > _Page.Length)
300                                 return;
301
302                         _PathInfo = _Page.Substring (_Page.Length - PathInfoLength);
303                         _Page = _Page.Substring (0, _Page.Length - PathInfoLength);
304                 }
305         }
306 }
307