2004-12-17 Lluis Sanchez Gual <lluis@ximian.com>
[mono.git] / mcs / class / System.Runtime.Remoting / System.Runtime.Remoting.Channels.Http / HttpServer.cs
1 //==========================================================================
2 //  File:       HttpServer.cs
3 //
4 //  Summary:       Implements an HttpServer to be used by the HttpServerChannel class
5 //                               
6 //
7 //  Classes:    internal sealed HttpServer
8 //              internal  sealed   ReqMessageParser
9 //              private RequestArguments
10 //
11 //      By :
12 //              Ahmad    Tantawy        popsito82@hotmail.com
13 //              Ahmad    Kadry          kadrianoz@hotmail.com
14 //              Hussein  Mehanna        hussein_mehanna@hotmail.com
15 //
16 //==========================================================================
17
18 //
19 // Permission is hereby granted, free of charge, to any person obtaining
20 // a copy of this software and associated documentation files (the
21 // "Software"), to deal in the Software without restriction, including
22 // without limitation the rights to use, copy, modify, merge, publish,
23 // distribute, sublicense, and/or sell copies of the Software, and to
24 // permit persons to whom the Software is furnished to do so, subject to
25 // the following conditions:
26 // 
27 // The above copyright notice and this permission notice shall be
28 // included in all copies or substantial portions of the Software.
29 // 
30 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
33 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
34 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
35 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 //
38 using System;
39 using System.Net.Sockets;
40 using System.Text;
41 using System.Text.RegularExpressions;
42 using System.Collections;
43
44 using System.Runtime.Remoting.Channels;
45 using System.IO;
46 using System.Net;
47 using System.Runtime.Remoting.Messaging;
48
49 namespace System.Runtime.Remoting.Channels.Http
50 {
51
52         internal class RequestArguments
53         {
54                 public RequestArguments (Socket socket, HttpServerTransportSink sink)
55                 {
56                         NetworkStream ns = new NetworkStream (socket);
57                         InputStream = ns;
58                         OutputStream = ns;
59                         Sink = sink;
60                 }
61                 
62                 public Stream InputStream;
63                 public Stream OutputStream;
64                 public HttpServerTransportSink Sink;
65         }
66
67         internal sealed class HttpServer
68         {
69                 public static void ProcessRequest (object reqInfo)
70                 {
71                         if(reqInfo as RequestArguments == null)
72                                 return;
73
74                         RequestArguments reqArg = (RequestArguments)reqInfo;
75                 
76                         //Step (1) Start Reciceve the header
77                         ArrayList  Headers = RecieveHeader (reqArg);
78                                 
79                         //Step (2) Start Parse the header
80                         IDictionary HeaderFields = new Hashtable();
81                         IDictionary CustomHeaders = new Hashtable();
82                         if (!ParseHeader (reqArg, Headers, HeaderFields, CustomHeaders))
83                                 return;
84
85                         //Step (3)
86                         if (!CheckRequest (reqArg, HeaderFields, CustomHeaders))
87                                 return;
88
89                         //Step (4) Recieve the entity body
90                         
91                         byte[] buffer;
92                         object len = HeaderFields["content-length"];
93                         if (len != null)
94                         {
95                                 buffer = new byte [(int)len];
96                                 if (!RecieveEntityBody (reqArg, buffer))
97                                         return;
98                         }
99                         else
100                                 buffer = new byte [0];
101                                 
102                         //Step (5)
103                         SendRequestForChannel (reqArg, HeaderFields, CustomHeaders, buffer);
104                 }
105
106                 private static ArrayList RecieveHeader (RequestArguments reqArg)
107                 {
108                         bool bLastLine = false;
109                         bool bEndOfLine = false;
110         
111                         byte[] buffer = new byte[1024];
112                         ArrayList  Headers = new ArrayList();
113                         
114                         Stream ist = reqArg.InputStream;
115
116                         int index =0;
117                         while (!bLastLine)
118                         { 
119                                 //recieve line by line 
120                                 index = 0;
121                                 bEndOfLine = false;
122
123                                 //Step (1) is it an empty line?
124                                 ist.Read (buffer, index, 1);
125                                 
126                                 if(buffer[index++]==13)
127                                 {
128                                         ist.Read (buffer, index, 1);
129                                         bLastLine=true;
130                                         bEndOfLine = true;
131                                 }
132                                 
133                                 //Step (2) recieve line bytes
134                                 while (!bEndOfLine)
135                                 {
136                                         ist.Read (buffer, index, 1);
137
138                                         if(buffer [index++]==13)
139                                         {
140                                                 bEndOfLine = true;
141                                                 ist.Read (buffer,index,1);
142                                         }
143                                 }
144
145                                 //Step (3) convert bytes to a string
146                                 if (bLastLine)
147                                         continue;
148                                         
149                 Headers.Add (Encoding.ASCII.GetString (buffer,0,index));
150
151                         }//end while loop
152                         
153                         return Headers;
154                 }
155                 
156                 private static bool ParseHeader (RequestArguments reqArg, ArrayList Headers, IDictionary HeaderFields, IDictionary CustomHeaders)
157                 {
158                         for (int i=0;i<Headers.Count;i++)
159                         {
160                                 if (ReqMessageParser.ParseHeaderField ((string)Headers[i],HeaderFields))
161                                         continue;
162                                         
163                                 if (!ReqMessageParser.IsCustomHeader((string)Headers[i],CustomHeaders ) )
164                                 {
165                                         SendResponse (reqArg, 400, null, null);
166                                         return false;
167                                 }
168                         }
169
170                         return true;
171                 }
172
173                 private static bool CheckRequest (RequestArguments reqArg, IDictionary HeaderFields, IDictionary CustomHeaders)
174                 {
175                         string temp;
176                         
177                         if (HeaderFields["expect"] as string == "100-continue")
178                                 SendResponse (reqArg, 100, null, null);
179
180                         //Check the method
181                         temp = HeaderFields["method"].ToString();
182                         if (temp != "POST")
183                 return true;
184
185                         //Check for the content-length field
186                         if (HeaderFields["content-length"]==null)
187                         {
188                                 SendResponse (reqArg, 411, null, null);
189                                 return false;
190                         }
191                         return true;
192                 }
193
194                 
195                 private static bool RecieveEntityBody (RequestArguments reqArg, byte[] buffer)
196                 {
197                         try
198                         {
199                                 int nr = 0;
200                                 while (nr < buffer.Length)
201                                         nr += reqArg.InputStream.Read (buffer, nr, buffer.Length - nr);
202                         }
203                         catch (SocketException e)
204                         {
205                                 switch(e.ErrorCode)
206                                 {
207                                         case 10060 : //TimeOut
208                                                 SendResponse (reqArg, 408, null, null);
209                                                 break;
210                                         default :
211                                                 throw e;
212                                 }
213                                 
214                                 return false;
215                         }//end catch
216
217                         return true;
218                 }
219         
220                 private static bool SendRequestForChannel (RequestArguments reqArg, IDictionary HeaderFields, IDictionary CustomHeaders, byte[] buffer)
221                 {
222                         TransportHeaders THeaders = new TransportHeaders();
223
224                         Stream stream = new MemoryStream(buffer);
225
226                         if(stream.Position !=0)
227                                 stream.Seek(0,SeekOrigin.Begin);
228
229                         THeaders[CommonTransportKeys.RequestUri] = FixURI((string)HeaderFields["request-url"]);
230                         THeaders[CommonTransportKeys.ContentType]= HeaderFields["content-type"];
231                         THeaders[CommonTransportKeys.RequestVerb]= HeaderFields["method"];
232                         THeaders[CommonTransportKeys.HttpVersion] = HeaderFields["http-version"];
233                         THeaders[CommonTransportKeys.UserAgent] = HeaderFields["user-agent"];
234                         THeaders[CommonTransportKeys.Host] = HeaderFields["host"];
235                         THeaders[CommonTransportKeys.SoapAction] = HeaderFields["SOAPAction"];
236
237                         foreach(DictionaryEntry DictEntry in CustomHeaders)
238                         {
239                                 THeaders[DictEntry.Key.ToString()] = DictEntry.Value.ToString();
240                         }
241
242                         reqArg.Sink.ServiceRequest (reqArg, stream, THeaders);
243                         return true;
244                 }
245
246                 private static string FixURI(string RequestURI)
247                 {
248
249                         if(RequestURI.IndexOf ( '.' ) == -1)
250                                 return RequestURI;
251                         else
252                                 return RequestURI.Substring(1);
253                         
254                 }
255                 
256                 public static void SendResponse (RequestArguments reqArg, int httpStatusCode, ITransportHeaders headers, Stream responseStream)
257                 {
258                         byte [] headersBuffer = null;
259                         byte [] entityBuffer = null;
260
261                         StringBuilder responseStr;
262                         String reason = null;
263
264                         if (headers != null && headers[CommonTransportKeys.HttpStatusCode] != null) {
265                                 // The formatter can override the result code
266                                 httpStatusCode = int.Parse ((string)headers [CommonTransportKeys.HttpStatusCode]);
267                                 reason = (string) headers [CommonTransportKeys.HttpReasonPhrase];
268                         }
269
270                         if (reason == null)
271                                 reason = GetReasonPhrase (httpStatusCode);
272                         
273                         //Response Line 
274                         responseStr = new StringBuilder ("HTTP/1.0 " + httpStatusCode + " " + reason + "\r\n" );
275                         
276                         if (headers != null)
277                         {
278                                 foreach (DictionaryEntry entry in headers)
279                                 {
280                                         string key = entry.Key.ToString();
281                                         if (key != CommonTransportKeys.HttpStatusCode && key != CommonTransportKeys.HttpReasonPhrase)
282                                                 responseStr.Append(key + ": " + entry.Value.ToString() + "\r\n");
283                                 }
284                         }
285                         
286                         responseStr.Append("Server: Mono Remoting, Mono CLR " + System.Environment.Version.ToString() + "\r\n");
287
288                         if(responseStream != null && responseStream.Length!=0)
289                         {
290                                 responseStr.Append("Content-Length: "+responseStream.Length.ToString()+"\r\n"); 
291                                 entityBuffer  = new byte[responseStream.Length];
292                                 responseStream.Seek(0 , SeekOrigin.Begin);
293                                 responseStream.Read(entityBuffer,0,entityBuffer.Length);
294                         }
295                         else
296                                 responseStr.Append("Content-Length: 0\r\n"); 
297
298                         responseStr.Append("X-Powered-By: Mono\r\n"); 
299                         responseStr.Append("Connection: close\r\n"); 
300                         responseStr.Append("\r\n");
301                 
302                         headersBuffer = Encoding.ASCII.GetBytes (responseStr.ToString());
303
304                         //send headersBuffer
305                         reqArg.OutputStream.Write (headersBuffer, 0, headersBuffer.Length);
306
307                         if (entityBuffer != null)
308                                 reqArg.OutputStream.Write (entityBuffer, 0, entityBuffer.Length);
309                 }
310
311                 internal static string GetReasonPhrase (int HttpStatusCode)
312                 {
313                         switch (HttpStatusCode)
314                         {
315                                 case 100 : return "Continue" ;
316                                 case 101  :return "Switching Protocols";
317                                 case 200  :return "OK";
318                                 case 201  :return "Created";
319                                 case 202  :return "Accepted";
320                                 case 203   :return "Non-Authoritative Information";
321                                 case 204  :return "No Content";
322                                 case 205   :return "Reset Content";
323                                 case 206   :return "Partial Content";
324                                 case 300   :return "Multiple Choices";
325                                 case 301   :return "Moved Permanently";
326                                 case 302   :return  "Found";
327                                 case 303   :return  "See Other";
328                                 case 304   :return  "Not Modified";
329                                 case 305  :return   "Use Proxy";
330                                 case 307   :return  "Temporary Redirect";
331                                 
332                                 case 400   :return  "Bad Request";
333                                 case 401   :return  "Unauthorized";
334                                 case 402   :return  "Payment Required";
335                                 case 403   :return  "Forbidden";
336                                 case 404   :return  "Not Found";
337                                 case 405   :return  "Method Not Allowed";
338                                 case 406   :return  "Not Acceptable";
339                                                                                          
340                                 case 407   :return  "Proxy Authentication Required";
341                                 case 408   :return  "Request Time-out";
342                                 case 409   :return  "Conflict";
343                                 case 410   :return  "Gone";
344                                 case 411   :return  "Length Required";
345                                 case 412   :return  "Precondition Failed";
346                                 case 413   :return  "Request Entity Too Large";
347                                 case 414   :return  "Request-URI Too Large";
348                                 case 415   :return  "Unsupported Media Type";
349                                 case 416   :return  "Requested range not satisfiable";
350                                 case 417   :return  "Expectation Failed";
351                                 
352                                 case 500  :return   "Internal Server Error";
353                                 case 501  :return   "Not Implemented";
354                                 case 502   :return  "Bad Gateway";
355                                 case 503  :return   "Service Unavailable";
356                                 case 504   :return  "Gateway Time-out";
357                                 case 505   :return  "HTTP Version not supported";
358                                 default: return "";
359
360                         }
361                 }
362                 
363         }
364         
365         
366         internal sealed class ReqMessageParser
367         {
368                 private  const int nCountReq = 14;
369                 private  const int nCountEntity = 15;
370                 
371                 private static bool bInitialized = false;
372                 
373                 private static String [] ReqRegExpString = new String [nCountReq ];
374                 private static String [] EntityRegExpString = new String[nCountEntity]; 
375                 
376                 private static Regex [] ReqRegExp = new Regex[nCountReq];
377                 private static Regex [] EntityRegExp = new Regex[nCountEntity];
378                  
379
380                  
381                 public ReqMessageParser ()
382                 {
383                 }
384
385                  public static bool ParseHeaderField(string buffer,IDictionary headers)
386                  {
387                          try
388                          {
389                                  if(!bInitialized)
390                                  {
391                                          Initialize();
392                                          bInitialized =true;
393                                  }
394
395                                  if(IsRequestField(buffer,headers))
396                                          return true;
397                                  if(IsEntityField(buffer,headers))
398                                          return true ;
399                          
400                          }
401                          catch(Exception )
402                          {
403                                  //<Exception>
404                          }
405
406                          //Exception
407
408                          return false;
409                  }
410                  
411                  private static bool Initialize()
412                  {
413                          if(bInitialized)
414                                  return true;
415
416                          bInitialized = true;
417
418                          //initialize array
419                          //Create all the Regular expressions
420                          InitializeRequestRegExp();
421                          InitiazeEntityRegExp();
422
423                          for(int i=0;i<nCountReq;i++)
424                                  ReqRegExp[i] = new Regex(ReqRegExpString[i],RegexOptions.Compiled|RegexOptions.IgnoreCase);
425                         
426                          for(int i=0;i<nCountEntity;i++)
427                                  EntityRegExp[i] = new Regex(EntityRegExpString[i],RegexOptions.Compiled|RegexOptions.IgnoreCase);
428
429                          return true;
430
431                  }
432
433                  private static void InitializeRequestRegExp()
434                  {
435                          //Request Header Fields
436                          //
437                          ReqRegExpString[0] = "^accept(\\s*:\\s*)(?<accept>\\S+)(\\s*|)(\\s*)$";
438                          ReqRegExpString[1] = "^accept-charset(\\s*:\\s*)(?<accept_charset>\\S+(\\s|\\S)*\\S)(\\s*)$";
439                          ReqRegExpString[2] = "^accept-encoding(\\s*:\\s*)(?<accept_Encoding>\\S+(\\s|\\S)*\\S)(\\s*)$";
440                          ReqRegExpString[3] = "^authorization(\\s*:\\s*)(?<authorization>\\S+(\\s|\\S)*\\S)(\\s*)$";
441                          ReqRegExpString[4] = "^accept-language(\\s*:\\s*)(?<accept_Language>\\S+(\\s|\\S)*\\S)(\\s*)$";
442                          ReqRegExpString[5] = "^from(\\s*:\\s*)(?<from>\\S+(\\s|\\S)*\\S)(\\s*)$";
443                          ReqRegExpString[6] = "^host(\\s*:\\s*)(?<host>\\S+(\\s|\\S)*\\S)(\\s*)$";
444                          ReqRegExpString[7] = "^if-modified-since(\\s*:\\s*)(?<if_modified>\\S+(\\s|\\S)*\\S)(\\s*)$";
445                          ReqRegExpString[8] = "^proxy-authorization(\\s*:\\s*)(?<proxy_auth>\\S+(\\s|\\S)*\\S)(\\s*)$";
446                          ReqRegExpString[9] = "^range(\\s*:\\s*)(?<range>\\S+(\\s|\\S)*\\S)(\\s*)$";
447                          ReqRegExpString[10] = "^user-agent(\\s*:\\s*)(?<user_agent>\\S+(\\s|\\S)*\\S)(\\s*)$";
448                          ReqRegExpString[11] = "^expect(\\s*:\\s*)(?<expect>\\S+(\\s|\\S)*\\S)(\\s*)$";
449                          ReqRegExpString[12] = "^connection(\\s*:\\s*)(?<connection>\\S+(\\s|\\S)*\\S)(\\s*)$";
450                          ReqRegExpString[13] = "^(?<method>\\w+)(\\s+)(?<request_url>\\S+)(\\s+)(?<http_version>\\S+)(\\s*)$";
451                         // ReqRegExpString[14] = "";                     
452                  }
453
454                  private static void InitiazeEntityRegExp()
455                  {
456                         EntityRegExpString[0] = "^allow(\\s*:\\s*)(?<allow>[0-9]+)(\\s*)$";
457                     EntityRegExpString[1] = "^content-encoding(\\s*:\\s*)(?<content_encoding>\\S+(\\s|\\S)*\\S)(\\s*)$";
458                         EntityRegExpString[2] = "^content-language(\\s*:\\s*)(?<content_language>\\S+(\\s|\\S)*\\S)(\\s*)$";
459                         EntityRegExpString[3] = "^content-length(\\s*:\\s*)(?<content_length>[0-9]+)(\\s*)$";
460                         EntityRegExpString[4] = "^content-range(\\s*:\\s*)(?<content_range>\\S+(\\s|\\S)*\\S)(\\s*)$";
461                         EntityRegExpString[5] = "^content-type(\\s*:\\s*)(?<content_type>\\S+(\\s|\\S)*\\S)(\\s*)$";
462                         EntityRegExpString[6] = "^content-version(\\s*:\\s*)(?<content_version>\\S+(\\s|\\S)*\\S)(\\s*)$";
463                         EntityRegExpString[7] = "^derived-from(\\s*:\\s*)(?<derived_from>\\S+(\\s|\\S)*\\S)(\\s*)$";
464                         EntityRegExpString[8] = "^expires(\\s*:\\s*)(?<expires>\\S+(\\s|\\S)*\\S)(\\s*)$";//date
465                         EntityRegExpString[9] = "^last-modified(\\s*:\\s*)(?<last_modified>\\S+(\\s|\\S)*\\S)(\\s*)$";//date
466                         EntityRegExpString[10] = "^link(\\s*:\\s*)(?<link>\\S+(\\s|\\S)*\\S)(\\s*)$";
467                         EntityRegExpString[11] = "^title(\\s*:\\s*)(?<title>\\S+(\\s|\\S)*\\S)(\\s*)$";
468                     EntityRegExpString[12] = "^transfere-encoding(\\s*:\\s*)(?<transfere_encoding>\\S+(\\s|\\S)*\\S)(\\s*)$";
469                     EntityRegExpString[13] = "^url-header(\\s*:\\s*)(?<url_header>\\S+(\\s|\\S)*\\S)(\\s*)$";
470                         EntityRegExpString[14] = "^extension-header(\\s*:\\s*)(?<extension_header>\\S+(\\s|\\S)*\\S)(\\s*)$";
471                  }
472                                 
473                  private static void CopyGroupNames(Regex regEx , Match m , IDictionary headers)
474                  {
475                          
476                          if(!m.Success)
477                                  return;
478
479                          string [] ar = regEx.GetGroupNames();
480                          GroupCollection gc = m.Groups;
481
482                          for(int i=0;i<ar.Length;i++)
483                          {
484                                  if(! char.IsLetter(ar[i],0))
485                                          continue;
486                  
487                                 headers.Add(ar[i],gc[ar[i]].Value);
488                          }
489                  }
490                  
491
492                  private static bool IsRequestField(string buffer , IDictionary HeaderItems)
493                  {
494                          
495                          if(Request_accept(buffer , HeaderItems))
496                                  return true;
497
498                          if(Request_accept_charset(buffer , HeaderItems))
499                                  return true;
500
501                          if(Request_accept_encoding(buffer , HeaderItems))
502                                  return true;
503
504                          if(Request_accept_language(buffer , HeaderItems))
505                                  return true;
506
507                          if(Request_authorization(buffer , HeaderItems))
508                                  return true;
509
510                          if(Request_connection(buffer , HeaderItems))
511                                  return true;
512
513                          if(Request_expect(buffer , HeaderItems))
514                                  return true;
515
516                          if(Request_from(buffer , HeaderItems))
517                                  return true;
518
519                          if(Request_host(buffer , HeaderItems))
520                                  return true;
521
522                          if(Request_modified(buffer , HeaderItems))
523                                  return true;
524
525                          if(Request_proxy_authorization(buffer , HeaderItems))
526                                  return true;
527
528                          if(Request_user_agent(buffer , HeaderItems))
529                                  return true;
530
531                          if(Request_request_line(buffer , HeaderItems))
532                                  return true;
533
534                          return false;
535                  }
536
537                  private static bool IsEntityField(string buffer , IDictionary HeaderItems)
538                  {
539                          if(Entity_allow(buffer , HeaderItems))
540                                  return true;
541
542                          if(Entity_content_encoding(buffer , HeaderItems))
543                                  return true;
544
545                          if(Entity_content_language(buffer , HeaderItems))
546                                  return true;
547
548                          if(Entity_content_length(buffer , HeaderItems))
549                                  return true;
550
551                          if(Entity_content_range(buffer , HeaderItems))
552                                  return true;
553
554                          if(Entity_content_type(buffer , HeaderItems))
555                                  return true;
556
557                          if(Entity_content_version(buffer , HeaderItems))
558                                  return true;
559
560                          if(Entity_dervied_from(buffer , HeaderItems))
561                                  return true;
562
563                          if(Entity_expires(buffer , HeaderItems))
564                                  return true;
565
566                          if(Entity_extension_header(buffer , HeaderItems))
567                                  return true;
568
569                          if(Entity_last_modified(buffer , HeaderItems))
570                                  return true;
571
572                          if(Entity_link(buffer , HeaderItems))
573                                  return true;
574
575                          if(Entity_title(buffer , HeaderItems))
576                                  return true;
577
578                          if(Entity_transfere_encoding(buffer , HeaderItems))
579                                  return true;
580                          
581                          if(Entity_url_header(buffer , HeaderItems))           
582                                  return true;
583
584                          return false;
585
586                  }
587                 
588                  public static bool IsCustomHeader(string buffer,IDictionary CustomHeader)
589                  {
590                          Regex CustomHeaderEx = new Regex("^(?<header>\\S+)(\\s*:\\s*)(?<field>\\S+(\\s|\\S)*\\S)(\\s*)",RegexOptions.Compiled);
591                         
592                          Match m = CustomHeaderEx.Match(buffer);
593                          if(!m.Success)
594                                  return false;
595
596                          CustomHeader.Add(m.Groups["header"].Value,m.Groups["field"].Value);
597                          return true;
598
599                  }
600                 
601                  //********************************************************
602                  //REQUEST
603                  private static bool Request_accept(string buffer,IDictionary HeaderItems)
604                  {
605                          Match m = ReqRegExp[0].Match(buffer);
606                          if(!m.Success)
607                                  return false;
608                         
609                          HeaderItems.Add("accept",m.Groups["accept"].Value);
610                          return true;
611                  }
612
613                  private static bool Request_accept_charset(string buffer,IDictionary HeaderItems)
614                  {
615                          Match m = ReqRegExp[1].Match(buffer);
616                          if(!m.Success)
617                                  return false;
618                         
619                          HeaderItems.Add("accept-charset",m.Groups["accept_charset"].Value);
620                          return true;
621
622                  }
623                  private static bool Request_accept_encoding(string buffer,IDictionary HeaderItems)
624                  {
625                          Match m = ReqRegExp[2].Match(buffer);
626                          if(!m.Success)
627                                  return false;
628                         
629                          HeaderItems.Add("accept-encoding",m.Groups["accept_encoding"].Value);
630                          return true;
631                  }
632                  private static bool Request_authorization(string buffer,IDictionary HeaderItems)
633                  {
634                          Match m = ReqRegExp[3].Match(buffer);
635                          if(!m.Success)
636                                  return false;
637                         
638                          HeaderItems.Add("authorization",m.Groups["authorization"].Value);
639                          return true;
640                  }
641                  private static bool Request_accept_language(string buffer,IDictionary HeaderItems)
642                  {
643                          Match m = ReqRegExp[4].Match(buffer);
644                          if(!m.Success)
645                                  return false;
646                         
647                          HeaderItems.Add("accept-language",m.Groups["accept_language"].Value);
648                          return true;
649                  }
650                  private static bool Request_from(string buffer,IDictionary HeaderItems)
651                  {
652                          Match m = ReqRegExp[5].Match(buffer);
653                          if(!m.Success)
654                                  return false;
655                         
656                          HeaderItems.Add("from",m.Groups["from"].Value);
657                          return true;
658                  }
659                  private static bool Request_host(string buffer,IDictionary HeaderItems)
660                  {
661                          Match m = ReqRegExp[6].Match(buffer);
662                          if(!m.Success)
663                                  return false;
664                         
665                          HeaderItems.Add("host",m.Groups["host"].Value);
666                          return true;
667                  }
668                  private static bool Request_modified(string buffer,IDictionary HeaderItems)
669                  {
670                          Match m = ReqRegExp[7].Match(buffer);
671                          if(!m.Success)
672                                  return false;
673                         
674                          HeaderItems.Add("modified",m.Groups["modified"].Value);
675                          return true;
676                  }
677                  private static bool Request_proxy_authorization(string buffer,IDictionary HeaderItems)
678                  {
679                          Match m = ReqRegExp[8].Match(buffer);
680                          if(!m.Success)
681                                  return false;
682                         
683                          HeaderItems.Add("proxy-authorization",m.Groups["proxy_authorization"].Value);
684                          return true;
685                  }
686                  private static bool Request_range(string buffer , IDictionary HeaderItems)
687                  {
688                          Match m = ReqRegExp[9].Match(buffer);
689                          if(!m.Success)
690                                  return false;
691                         
692                          HeaderItems.Add("range",m.Groups["range"].Value);
693                          return true;
694                          
695                  }
696                  private static bool Request_user_agent(string buffer,IDictionary HeaderItems)
697                  {
698                          Match m = ReqRegExp[10].Match(buffer);
699                          if(!m.Success)
700                                  return false;
701                         
702                          HeaderItems.Add("user-agent",m.Groups["user_agent"].Value);
703                          return true;
704                  }
705                  private static bool Request_expect(string buffer,IDictionary HeaderItems)
706                  {
707                          Match m = ReqRegExp[11].Match(buffer);
708                          if(!m.Success)
709                                  return false;
710                         
711                          HeaderItems.Add("expect",m.Groups["expect"].Value);
712                          return true;
713                  }
714
715                  private static bool Request_connection(string buffer,IDictionary HeaderItems)
716                  {
717                          Match m = ReqRegExp[12].Match(buffer);
718                          if(!m.Success)
719                                  return false;
720                         
721                          HeaderItems.Add("connection",m.Groups["connection"].Value);
722                          return true;
723                  }
724
725                  private static bool Request_request_line(string buffer, IDictionary HeaderItems)
726                  {
727                          Match m = ReqRegExp[13].Match(buffer);
728                          if(!m.Success)
729                                  return false;
730                         //ReqRegExpString[13] = "(?<method>\\w+)(\\s+)(?<request_url>\\S+)(\\s+)(?<http_version>\\S+)";
731                          
732                          HeaderItems.Add("method",m.Groups["method"].Value);
733                          HeaderItems.Add("request-url",m.Groups["request_url"].Value);
734                          HeaderItems.Add("http-version",m.Groups["http_version"].Value);
735                          return true;
736                  }
737                 //********************************************************
738
739                 
740                  //********************************************************
741                  //ENTITY
742                  private static bool Entity_allow(string buffer,IDictionary HeaderItems)
743                  {
744                          Match m = EntityRegExp[0].Match(buffer);
745                          if(!m.Success)
746                                  return false;
747                         
748                          HeaderItems.Add("allow",m.Groups["allow"].Value);
749                          return true;
750                  }
751
752                  
753                  private static bool Entity_content_encoding(string buffer,IDictionary HeaderItems)
754                  {
755                          Match m = EntityRegExp[1].Match(buffer);
756                          if(!m.Success)
757                                  return false;
758                         
759                          HeaderItems.Add("content-encoding",m.Groups["content_encoding"].Value);
760                          return true;
761                  }
762                  private static bool Entity_content_language(string buffer,IDictionary HeaderItems)
763                  {
764                          Match m = EntityRegExp[2].Match(buffer);
765                          if(!m.Success)
766                                  return false;
767                         
768                          HeaderItems.Add("content-language",m.Groups["content_language"].Value);
769                          return true;
770                  }
771                  private static bool Entity_content_length(string buffer,IDictionary HeaderItems)
772                  {
773                          Match m = EntityRegExp[3].Match(buffer);
774                          if(!m.Success)
775                                  return false;
776                         
777                         int length;
778                          try
779                          {
780                                  length = Int32.Parse(m.Groups["content_length"].ToString());
781                          }
782                          catch (Exception )
783                          {
784                                  //<Exception>
785                                  return false;
786                          }
787
788                          HeaderItems.Add("content-length",length);
789                          return true;
790                  }
791                  private static bool Entity_content_range(string buffer,IDictionary HeaderItems)
792                  {
793                          Match m = EntityRegExp[4].Match(buffer);
794                          if(!m.Success)
795                                  return false;
796                         
797                          HeaderItems.Add("content-range",m.Groups["content_range"].Value);
798                          return true;
799                  }
800                  private static bool Entity_content_type(string buffer,IDictionary HeaderItems)
801                  {
802                          Match m = EntityRegExp[5].Match(buffer);
803                          if(!m.Success)
804                                  return false;
805                         
806                          HeaderItems.Add("content-type",m.Groups["content_type"].Value);
807                          return true;
808                  }
809
810                  private static bool Entity_content_version(string buffer,IDictionary HeaderItems)
811                  {
812                          Match m = EntityRegExp[6].Match(buffer);
813                          if(!m.Success)
814                                  return false;
815                         
816                          HeaderItems.Add("content-version",m.Groups["content_version"].Value);
817                          return true;
818                  }
819                  private static bool Entity_dervied_from(string buffer,IDictionary HeaderItems)
820                  {
821                          Match m = EntityRegExp[7].Match(buffer);
822                          if(!m.Success)
823                                  return false;
824                         
825                          HeaderItems.Add("dervied-from",m.Groups["dervied_from"].Value);
826                          return true;
827                  }
828                  private static bool Entity_expires(string buffer,IDictionary HeaderItems)
829                  {
830                          Match m = EntityRegExp[8].Match(buffer);
831                          if(!m.Success)
832                                  return false;
833                         
834                          HeaderItems.Add("expires",m.Groups["expires"].Value);
835                          return true;
836                  }
837                  private static bool Entity_last_modified(string buffer,IDictionary HeaderItems)
838                  {
839                          Match m = EntityRegExp[9].Match(buffer);
840                          if(!m.Success)
841                                  return false;
842                         
843                          HeaderItems.Add("last-modified",m.Groups["last_modified"].Value);
844                          return true;
845                  }
846                  private static bool Entity_link(string buffer,IDictionary HeaderItems)
847                  {
848                          Match m = EntityRegExp[10].Match(buffer);
849                          if(!m.Success)
850                                  return false;
851                         
852                          HeaderItems.Add("link",m.Groups["link"].Value);
853                          return true;
854                  }
855                  private static bool Entity_title(string buffer,IDictionary HeaderItems)
856                  {
857                          Match m = EntityRegExp[11].Match(buffer);
858                          if(!m.Success)
859                                  return false;
860                         
861                          HeaderItems.Add("title",m.Groups["title"].Value);
862                          return true;
863                  }
864
865                  private static bool Entity_transfere_encoding(string buffer,IDictionary HeaderItems)
866                  {
867                          Match m = EntityRegExp[12].Match(buffer);
868                          if(!m.Success)
869                                  return false;
870                         
871                          HeaderItems.Add("transfere-encoding",m.Groups["transfere_encoding"].Value);
872                          return true;
873                  }
874                  private static bool Entity_url_header(string buffer,IDictionary HeaderItems)
875                  {
876                          Match m = EntityRegExp[13].Match(buffer);
877                          if(!m.Success)
878                                  return false;
879                         
880                          HeaderItems.Add("url-header",m.Groups["url_header"].Value);
881                          return true;
882                  }
883
884                  private static bool Entity_extension_header(string buffer,IDictionary HeaderItems)
885                  {
886                          Match m = EntityRegExp[14].Match(buffer);
887                          if(!m.Success)
888                                  return false;
889                         
890                          HeaderItems.Add("extension-header",m.Groups["extension_header"].Value);
891                          return true;
892                  }
893
894                  //********************************************************              
895         }
896
897 }
898
899