2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / System.Web / System.Web / HttpWorkerRequest.cs
1 // 
2 // System.Web.HttpWorkerRequest
3 //
4 // Authors:
5 //      Patrik Torstensson (Patrik.Torstensson@labs2.com)
6 //      (constants from Bob Smith (bob@thestuff.net))
7 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 //
9 // (c) Patrik Torstensson
10 // (c) 2002 Ximian, Inc. (http://www.ximian.com)
11 //
12
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33 using System;
34 using System.Collections;
35 using System.Globalization;
36 using System.Runtime.InteropServices;
37
38 namespace System.Web
39 {
40         [ComVisible (false)]
41         public abstract class HttpWorkerRequest : IHttpMapPath
42         {
43                 public delegate void EndOfSendNotification (HttpWorkerRequest wr, object extraData);
44
45                 public const int HeaderAccept = 20;
46                 public const int HeaderAcceptCharset = 21;
47                 public const int HeaderAcceptEncoding = 22;
48                 public const int HeaderAcceptLanguage = 23;
49                 public const int HeaderAcceptRanges = 20;
50                 public const int HeaderAge = 21;
51                 public const int HeaderAllow = 10;
52                 public const int HeaderAuthorization = 24;
53                 public const int HeaderCacheControl = 0;
54                 public const int HeaderConnection = 1;
55                 public const int HeaderContentEncoding = 13;
56                 public const int HeaderContentLanguage = 14;
57                 public const int HeaderContentLength = 11;
58                 public const int HeaderContentLocation = 15;
59                 public const int HeaderContentMd5 = 16;
60                 public const int HeaderContentRange = 17;
61                 public const int HeaderContentType = 12;
62                 public const int HeaderCookie = 25;
63                 public const int HeaderDate = 2;
64                 public const int HeaderEtag = 22;
65                 public const int HeaderExpect = 26;
66                 public const int HeaderExpires = 18;
67                 public const int HeaderFrom = 27;
68                 public const int HeaderHost = 28;
69                 public const int HeaderIfMatch = 29;
70                 public const int HeaderIfModifiedSince = 30;
71                 public const int HeaderIfNoneMatch = 31;
72                 public const int HeaderIfRange = 32;
73                 public const int HeaderIfUnmodifiedSince = 33;
74                 public const int HeaderKeepAlive = 3;
75                 public const int HeaderLastModified = 19;
76                 public const int HeaderLocation = 23;
77                 public const int HeaderMaxForwards = 34;
78                 public const int HeaderPragma = 4;
79                 public const int HeaderProxyAuthenticate = 24;
80                 public const int HeaderProxyAuthorization = 35;
81                 public const int HeaderRange = 37;
82                 public const int HeaderReferer = 36;
83                 public const int HeaderRetryAfter = 25;
84                 public const int HeaderServer = 26;
85                 public const int HeaderSetCookie = 27;
86                 public const int HeaderTe = 38;
87                 public const int HeaderTrailer = 5;
88                 public const int HeaderTransferEncoding = 6;
89                 public const int HeaderUpgrade = 7;
90                 public const int HeaderUserAgent = 39;
91                 public const int HeaderVary = 28;
92                 public const int HeaderVia = 8;
93                 public const int HeaderWarning = 9;
94                 public const int HeaderWwwAuthenticate = 29;
95                 public const int ReasonCachePolicy = 2;
96                 public const int ReasonCacheSecurity = 3;
97                 public const int ReasonClientDisconnect = 4;
98                 public const int ReasonDefault = 0;
99                 public const int ReasonFileHandleCacheMiss = 1;
100                 public const int ReasonResponseCacheMiss = 0;
101                 public const int RequestHeaderMaximum = 40;
102                 public const int ResponseHeaderMaximum = 30;
103
104                 static string [][] s_HttpStatusDescriptions;
105                 static string [] s_HttpRequestHeaderNames;
106                 static string [] s_HttpResponseHeaderNames;
107
108                 static Hashtable s_HttpResponseHeadersTable;
109                 static Hashtable s_HttpRequestHeaderTable;
110
111                 static HttpWorkerRequest ()
112                 {
113                         string [] sSubCodes;
114
115                         s_HttpStatusDescriptions = new string [6][];
116
117                         sSubCodes = new String [3];
118                         sSubCodes [0] = "Continue";
119                         sSubCodes [1] = "Switching Protocols";
120                         sSubCodes [2] = "Processing";
121                         s_HttpStatusDescriptions [1] = sSubCodes;
122
123                         sSubCodes = new String [8];
124                         sSubCodes [0] = "OK";
125                         sSubCodes [1] = "Created";
126                         sSubCodes [2] = "Accepted";
127                         sSubCodes [3] = "Non-Authoritative Information";
128                         sSubCodes [4] = "No Content";
129                         sSubCodes [5] = "Reset Content";
130                         sSubCodes [6] = "Partial Content";
131                         sSubCodes [7] = "Multi-Status";
132                         s_HttpStatusDescriptions [2] = sSubCodes;
133
134                         sSubCodes = new String [8];
135                         sSubCodes [0] = "Multiple Choices";
136                         sSubCodes [1] = "Moved Permanently";
137                         sSubCodes [2] = "Found";
138                         sSubCodes [3] = "See Other";
139                         sSubCodes [4] = "Not Modified";
140                         sSubCodes [5] = "Use Proxy";
141                         sSubCodes [6] = String.Empty;
142                         sSubCodes [7] = "Temporary Redirect";
143                         s_HttpStatusDescriptions [3] = sSubCodes;
144
145                         sSubCodes = new String [24];
146                         sSubCodes [0] = "Bad Request";
147                         sSubCodes [1] = "Unauthorized";
148                         sSubCodes [2] = "Payment Required";
149                         sSubCodes [3] = "Forbidden";
150                         sSubCodes [4] = "Not Found";
151                         sSubCodes [5] = "Method Not Allowed";
152                         sSubCodes [6] = "Not Acceptable";
153                         sSubCodes [7] = "Proxy Authentication Required";
154                         sSubCodes [8] = "Request Timeout";
155                         sSubCodes [9] = "Conflict";
156                         sSubCodes [10] = "Gone";
157                         sSubCodes [11] = "Length Required";
158                         sSubCodes [12] = "Precondition Failed";
159                         sSubCodes [13] = "Request Entity Too Large";
160                         sSubCodes [14] = "Request-Uri Too Long";
161                         sSubCodes [15] = "Unsupported Media Type";
162                         sSubCodes [16] = "Requested Range Not Satisfiable";
163                         sSubCodes [17] = "Expectation Failed";
164                         sSubCodes [18] = String.Empty;
165                         sSubCodes [19] = String.Empty;
166                         sSubCodes [20] = String.Empty;
167                         sSubCodes [21] = "Unprocessable Entity";
168                         sSubCodes [22] = "Locked";
169                         sSubCodes [23] = "Failed Dependency";
170                         s_HttpStatusDescriptions [4] = sSubCodes;
171
172                         sSubCodes = new String [8];
173                         sSubCodes [0] = "Internal Server Error";
174                         sSubCodes [1] = "Not Implemented";
175                         sSubCodes [2] = "Bad Gateway";
176                         sSubCodes [3] = "Service Unavailable";
177                         sSubCodes [4] = "Gateway Timeout";
178                         sSubCodes [5] = "Http Version Not Supported";
179                         sSubCodes [6] = String.Empty;
180                         sSubCodes [7] = "Insufficient Storage";
181                         s_HttpStatusDescriptions [5] = sSubCodes;     
182
183                         InitLookupTables ();
184                 }
185
186                 public HttpWorkerRequest ()
187                 {
188                 }
189
190                 static private void InitLookupTables ()
191                 {
192                         // Performance arrays
193                         s_HttpRequestHeaderNames = new string [40];
194                         s_HttpResponseHeaderNames = new string [30];
195
196                         // Lookup tables (name -> id)
197                         CaseInsensitiveHashCodeProvider hprovider;
198                         hprovider = new CaseInsensitiveHashCodeProvider (CultureInfo.InvariantCulture);
199                         CaseInsensitiveComparer hcomparer;
200                         hcomparer = new CaseInsensitiveComparer (CultureInfo.InvariantCulture);
201                         s_HttpRequestHeaderTable = new Hashtable (hprovider, hcomparer);
202                         s_HttpResponseHeadersTable = new Hashtable (hprovider, hcomparer);
203
204                         AddHeader (true, true, 0, "Cache-Control");
205                         AddHeader (true, true, 1, "Connection");
206                         AddHeader (true, true, 2, "Date");
207                         AddHeader (true, true, 3, "Keep-Alive");
208                         AddHeader (true, true, 4, "Pragma");
209                         AddHeader (true, true, 5, "Trailer");
210                         AddHeader (true, true, 6, "Transfer-Encoding");
211                         AddHeader (true, true, 7, "Upgrade");
212                         AddHeader (true, true, 8, "Via");
213                         AddHeader (true, true, 9, "Warning");
214                         AddHeader (true, true, 10, "Allow");
215                         AddHeader (true, true, 11, "Content-Length");
216                         AddHeader (true, true, 12, "Content-Type");
217                         AddHeader (true, true, 13, "Content-Encoding");
218                         AddHeader (true, true, 14, "Content-Language");
219                         AddHeader (true, true, 15, "Content-Location");
220                         AddHeader (true, true, 16, "Content-MD5");
221                         AddHeader (true, true, 17, "Content-Range");
222                         AddHeader (true, true, 18, "Expires");
223                         AddHeader (true, true, 19, "Last-Modified");
224                         AddHeader (true, false, 20, "Accept");
225                         AddHeader (true, false, 21, "Accept-Charset");
226                         AddHeader (true, false, 22, "Accept-Encoding");
227                         AddHeader (true, false, 23, "Accept-Language");
228                         AddHeader (true, false, 24, "Authorization");
229                         AddHeader (true, false, 25, "Cookie");
230                         AddHeader (true, false, 26, "Expect");
231                         AddHeader (true, false, 27, "From");
232                         AddHeader (true, false, 28, "Host");
233                         AddHeader (true, false, 29, "If-Match");
234                         AddHeader (true, false, 30, "If-Modified-Since");
235                         AddHeader (true, false, 31, "If-None-Match");
236                         AddHeader (true, false, 32, "If-Range");
237                         AddHeader (true, false, 33, "If-Unmodified-Since");
238                         AddHeader (true, false, 34, "Max-Forwards");
239                         AddHeader (true, false, 35, "Proxy-Authorization");
240                         AddHeader (true, false, 36, "Referer");
241                         AddHeader (true, false, 37, "Range");
242                         AddHeader (true, false, 38, "TE");
243                         AddHeader (true, false, 39, "User-Agent");
244                         AddHeader (false, true, 20, "Accept-Ranges");
245                         AddHeader (false, true, 21, "Age");
246                         AddHeader (false, true, 22, "ETag");
247                         AddHeader (false, true, 23, "Location");
248                         AddHeader (false, true, 24, "Proxy-Authenticate");
249                         AddHeader (false, true, 25, "Retry-After");
250                         AddHeader (false, true, 26, "Server");
251                         AddHeader (false, true, 27, "Set-Cookie");
252                         AddHeader (false, true, 28, "Vary");
253                         AddHeader (false, true, 29, "WWW-Authenticate");
254                 }
255
256                 static private void AddHeader(bool bRequest, bool bResponse, int iID, string sHeader)
257                 {
258                         if (bResponse) {
259                                 s_HttpResponseHeaderNames [iID] = sHeader;
260                                 s_HttpResponseHeadersTable.Add (sHeader, iID);
261                         }
262
263                         if (bRequest) {
264                                 s_HttpRequestHeaderNames [iID] = sHeader;
265                                 s_HttpRequestHeaderTable.Add (sHeader, iID);
266                         }
267                 }
268
269                 public virtual void CloseConnection ()
270                 {
271                 }
272                 
273                 public abstract void EndOfRequest ();
274                 public abstract void FlushResponse (bool finalFlush);
275
276                 public virtual string GetAppPath ()
277                 {
278                         return null;
279                 }
280
281                 public virtual string GetAppPathTranslated ()
282                 {
283                         return null;
284                 }
285
286                 public virtual string GetAppPoolID ()
287                 {
288                         return null;
289                 }
290
291                 public virtual long GetBytesRead ()
292                 {
293                         return 0;
294                 }
295
296                 public virtual byte[] GetClientCertificate ()
297                 {
298                         return new byte[0];
299                 }
300
301                 public virtual byte[] GetClientCertificateBinaryIssuer ()
302                 {
303                         return new byte[0];
304                 }
305
306                 public virtual int GetClientCertificateEncoding ()
307                 {
308                         return 0;
309                 }
310
311                 public virtual byte[] GetClientCertificatePublicKey ()
312                 {
313                         return new byte[0];
314                 }
315
316                 public virtual DateTime GetClientCertificateValidFrom ()
317                 {
318                         return DateTime.Now;
319                 }
320
321                 public virtual DateTime GetClientCertificateValidUntil ()
322                 {
323                         return DateTime.Now;
324                 }
325
326                 public virtual long GetConnectionID ()
327                 {
328                         return 0;
329                 }
330
331                 public virtual string GetFilePath ()
332                 {
333                         return GetUriPath();
334                 }
335
336                 public virtual string GetFilePathTranslated ()
337                 {
338                         return null;
339                 }
340
341                 public abstract string GetHttpVerbName ();
342                 public abstract string GetHttpVersion ();
343
344                 public virtual string GetKnownRequestHeader (int index)
345                 {
346                         return null;
347                 }
348
349                 public static int GetKnownRequestHeaderIndex (string header)
350                 {
351                         object index;
352                         index = s_HttpRequestHeaderTable [header];
353                         if (null != index)
354                                 return (Int32) index;
355
356                         return -1;
357                 }
358
359                 public static string GetKnownRequestHeaderName (int index)
360                 {
361                         return s_HttpRequestHeaderNames [index];
362                 }
363
364                 public static int GetKnownResponseHeaderIndex (string header)
365                 {
366                         object index;
367
368                         index = s_HttpResponseHeadersTable [header];
369                         if (null != index)
370                                 return (Int32) index;
371
372                         return -1;
373                 }
374
375                 public static string GetKnownResponseHeaderName(int index)
376                 {
377                         return s_HttpResponseHeaderNames [index];
378                 }
379
380                 public abstract string GetLocalAddress ();
381                 public abstract int GetLocalPort ();
382
383                 public virtual string GetPathInfo ()
384                 {
385                         return String.Empty;
386                 }
387
388                 public virtual byte [] GetPreloadedEntityBody ()
389                 {
390                         return null;
391                 }
392
393                 public virtual string GetProtocol ()
394                 {
395                         return (IsSecure ()) ? "https" : "http";
396                 }
397
398                 public abstract string GetQueryString ();
399
400                 public virtual byte[] GetQueryStringRawBytes ()
401                 {
402                         return null;
403                 }
404
405                 public abstract string GetRawUrl ();
406                 public abstract string GetRemoteAddress ();
407
408                 public virtual string GetRemoteName ()
409                 {
410                         return GetRemoteAddress();
411                 }
412
413                 public abstract int GetRemotePort ();
414
415                 public virtual int GetRequestReason ()
416                 {
417                         return 0;
418                 }
419
420                 public virtual string GetServerName ()
421                 {
422                         return GetLocalAddress();  
423                 }
424
425                 public virtual string GetServerVariable (string name)
426                 {
427                         return null;
428                 }
429
430                 public static string GetStatusDescription (int code)
431                 {
432                         if (code>= 100 && code < 600) {
433                                 int iMajor = code / 100;
434                                 int iMinor = code % 100;
435                                 if (iMinor < (int) s_HttpStatusDescriptions [iMajor].Length)
436                                         return s_HttpStatusDescriptions [iMajor][iMinor];
437                         }
438
439                         return String.Empty;
440                 }
441
442                 public virtual string GetUnknownRequestHeader (string name)
443                 {
444                         return null;
445                 }
446
447                 [CLSCompliant(false)]
448                 public virtual string [][] GetUnknownRequestHeaders ()
449                 {
450                         return null;
451                 }
452
453                 public abstract string GetUriPath ();
454
455                 public virtual long GetUrlContextID ()
456                 {
457                         return 0;
458                 }
459
460                 public virtual IntPtr GetUserToken ()
461                 {
462                         throw new NotSupportedException ();
463                 }
464
465                 public virtual IntPtr GetVirtualPathToken ()
466                 {
467                         throw new NotSupportedException ();
468                 }
469
470                 public bool HasEntityBody ()
471                 {
472                         string sContentLength = GetKnownRequestHeader (HeaderContentLength);
473                         if (null != sContentLength && sContentLength != "0")
474                                 return true;
475
476                         if (null != GetKnownRequestHeader (HeaderTransferEncoding))
477                                 return true;
478
479                         if (null != GetPreloadedEntityBody () || IsEntireEntityBodyIsPreloaded ())
480                                 return true;
481
482                         return false;
483                 }
484
485                 public virtual bool HeadersSent ()
486                 {
487                         return true;
488                 }
489
490                 public virtual bool IsClientConnected ()
491                 {
492                         return true;
493                 }
494
495                 public virtual bool IsEntireEntityBodyIsPreloaded ()
496                 {
497                         return false;
498                 }
499
500                 public virtual bool IsSecure () 
501                 {
502                         return false;
503                 }
504
505                 public virtual string MapPath (string virtualPath)
506                 {
507                         return null;
508                 }
509
510                 public virtual int ReadEntityBody (byte[] buffer, int size)
511                 {
512                         return 0;
513                 }
514
515                 public virtual void SendCalculatedContentLength (int contentLength)
516                 {
517                 }
518
519                 public abstract void SendKnownResponseHeader (int index, string value);
520                 public abstract void SendResponseFromFile (IntPtr handle, long offset, long length);
521                 public abstract void SendResponseFromFile (string filename, long offset, long length);
522                 public abstract void SendResponseFromMemory (byte [] data, int length);
523
524                 public virtual void SendResponseFromMemory (IntPtr data, int length)
525                 {
526                         if (length <= 0)
527                                 return;
528
529                         byte [] dataBytes = new byte [length];
530                         Marshal.Copy (data, dataBytes, 0, length);
531                         SendResponseFromMemory (dataBytes, length);
532                 }
533
534                 public abstract void SendStatus (int statusCode, string statusDescription);
535                 public abstract void SendUnknownResponseHeader (string name, string value);
536
537                 public virtual void SetEndOfSendNotification (EndOfSendNotification callback, object extraData)
538                 {
539                 }
540
541                 public virtual string MachineConfigPath
542                 {
543                         get {
544                                 return null;
545                         }
546                 }
547
548                 public virtual string MachineInstallDirectory
549                 {
550                         get {
551                                 return null;
552                         }
553                 }
554         }
555 }
556