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