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