//========================================================================== // File: HttpServer.cs // // Summary: Implements an HttpServer to be used by the HttpServerChannel class // // // Classes: internal sealed HttpServer // internal sealed ReqMessageParser // private RequestArguments // // By : // Ahmad Tantawy popsito82@hotmail.com // Ahmad Kadry kadrianoz@hotmail.com // Hussein Mehanna hussein_mehanna@hotmail.com // //========================================================================== // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Net.Sockets; using System.Text; using System.Text.RegularExpressions; using System.Collections; using System.Runtime.Remoting.Channels; using System.IO; using System.Net; using System.Runtime.Remoting.Messaging; namespace System.Runtime.Remoting.Channels.Http { internal class RequestArguments { static int count; Socket socket; public RequestArguments (Socket socket, HttpServerTransportSink sink) { Id = count++; NetworkStream ns = new NetworkStream (socket); this.Stream = ns; this.socket = socket; Sink = sink; } public void Process () { HttpServer.ProcessRequest (this); } public IPAddress ClientAddress { get { IPEndPoint ep = socket.RemoteEndPoint as IPEndPoint; if (ep != null) return ep.Address; else return null; } } public int Id; public Stream Stream; public HttpServerTransportSink Sink; } internal sealed class HttpServer { public static void ProcessRequest (RequestArguments reqArg) { //Step (1) Start Reciceve the header ArrayList Headers = RecieveHeader (reqArg); //Step (2) Start Parse the header IDictionary HeaderFields = new Hashtable(); IDictionary CustomHeaders = new Hashtable(); if (!ParseHeader (reqArg, Headers, HeaderFields, CustomHeaders)) return; //Step (3) if (!CheckRequest (reqArg, HeaderFields, CustomHeaders)) return; //Step (4) Recieve the entity body byte[] buffer; object len = HeaderFields["content-length"]; if (len != null) { buffer = new byte [(int)len]; if (!RecieveEntityBody (reqArg, buffer)) return; } else buffer = new byte [0]; //Step (5) SendRequestForChannel (reqArg, HeaderFields, CustomHeaders, buffer); } private static ArrayList RecieveHeader (RequestArguments reqArg) { bool bLastLine = false; bool bEndOfLine = false; byte[] buffer = new byte[1024]; ArrayList Headers = new ArrayList(); Stream ist = reqArg.Stream; int index =0; while (!bLastLine) { //recieve line by line index = 0; bEndOfLine = false; //Step (1) is it an empty line? ist.Read (buffer, index, 1); if(buffer[index++]==13) { ist.Read (buffer, index, 1); bLastLine=true; bEndOfLine = true; } //Step (2) recieve line bytes while (!bEndOfLine) { ist.Read (buffer, index, 1); if(buffer [index++]==13) { bEndOfLine = true; ist.Read (buffer,index,1); } } //Step (3) convert bytes to a string if (bLastLine) continue; Headers.Add (Encoding.ASCII.GetString (buffer,0,index)); }//end while loop return Headers; } private static bool ParseHeader (RequestArguments reqArg, ArrayList Headers, IDictionary HeaderFields, IDictionary CustomHeaders) { for (int i=0;i } //Exception return false; } private static bool Initialize() { if(bInitialized) return true; bInitialized = true; //initialize array //Create all the Regular expressions InitializeRequestRegExp(); InitiazeEntityRegExp(); for(int i=0;i\\S+)(\\s*:\\s*)(?\\S+(\\s|\\S)*\\S)(\\s*)",RegexOptions.Compiled); Match m = CustomHeaderEx.Match(buffer); if(!m.Success) return false; CustomHeader.Add(m.Groups["header"].Value,m.Groups["field"].Value); return true; } //******************************************************** //REQUEST private static bool Request_accept(string buffer,IDictionary HeaderItems) { Match m = ReqRegExp[0].Match(buffer); if(!m.Success) return false; HeaderItems.Add("accept",m.Groups["accept"].Value); return true; } private static bool Request_accept_charset(string buffer,IDictionary HeaderItems) { Match m = ReqRegExp[1].Match(buffer); if(!m.Success) return false; HeaderItems.Add("accept-charset",m.Groups["accept_charset"].Value); return true; } private static bool Request_accept_encoding(string buffer,IDictionary HeaderItems) { Match m = ReqRegExp[2].Match(buffer); if(!m.Success) return false; HeaderItems.Add("accept-encoding",m.Groups["accept_encoding"].Value); return true; } private static bool Request_authorization(string buffer,IDictionary HeaderItems) { Match m = ReqRegExp[3].Match(buffer); if(!m.Success) return false; HeaderItems.Add("authorization",m.Groups["authorization"].Value); return true; } private static bool Request_accept_language(string buffer,IDictionary HeaderItems) { Match m = ReqRegExp[4].Match(buffer); if(!m.Success) return false; HeaderItems.Add("accept-language",m.Groups["accept_language"].Value); return true; } private static bool Request_from(string buffer,IDictionary HeaderItems) { Match m = ReqRegExp[5].Match(buffer); if(!m.Success) return false; HeaderItems.Add("from",m.Groups["from"].Value); return true; } private static bool Request_host(string buffer,IDictionary HeaderItems) { Match m = ReqRegExp[6].Match(buffer); if(!m.Success) return false; HeaderItems.Add("host",m.Groups["host"].Value); return true; } private static bool Request_modified(string buffer,IDictionary HeaderItems) { Match m = ReqRegExp[7].Match(buffer); if(!m.Success) return false; HeaderItems.Add("modified",m.Groups["modified"].Value); return true; } private static bool Request_proxy_authorization(string buffer,IDictionary HeaderItems) { Match m = ReqRegExp[8].Match(buffer); if(!m.Success) return false; HeaderItems.Add("proxy-authorization",m.Groups["proxy_authorization"].Value); return true; } private static bool Request_range(string buffer , IDictionary HeaderItems) { Match m = ReqRegExp[9].Match(buffer); if(!m.Success) return false; HeaderItems.Add("range",m.Groups["range"].Value); return true; } private static bool Request_user_agent(string buffer,IDictionary HeaderItems) { Match m = ReqRegExp[10].Match(buffer); if(!m.Success) return false; HeaderItems.Add("user-agent",m.Groups["user_agent"].Value); return true; } private static bool Request_expect(string buffer,IDictionary HeaderItems) { Match m = ReqRegExp[11].Match(buffer); if(!m.Success) return false; HeaderItems.Add("expect",m.Groups["expect"].Value); return true; } private static bool Request_connection(string buffer,IDictionary HeaderItems) { Match m = ReqRegExp[12].Match(buffer); if(!m.Success) return false; HeaderItems.Add("connection",m.Groups["connection"].Value); return true; } private static bool Request_request_line(string buffer, IDictionary HeaderItems) { Match m = ReqRegExp[13].Match(buffer); if(!m.Success) return false; //ReqRegExpString[13] = "(?\\w+)(\\s+)(?\\S+)(\\s+)(?\\S+)"; HeaderItems.Add("method",m.Groups["method"].Value); HeaderItems.Add("request-url",m.Groups["request_url"].Value); HeaderItems.Add("http-version",m.Groups["http_version"].Value); return true; } //******************************************************** //******************************************************** //ENTITY private static bool Entity_allow(string buffer,IDictionary HeaderItems) { Match m = EntityRegExp[0].Match(buffer); if(!m.Success) return false; HeaderItems.Add("allow",m.Groups["allow"].Value); return true; } private static bool Entity_content_encoding(string buffer,IDictionary HeaderItems) { Match m = EntityRegExp[1].Match(buffer); if(!m.Success) return false; HeaderItems.Add("content-encoding",m.Groups["content_encoding"].Value); return true; } private static bool Entity_content_language(string buffer,IDictionary HeaderItems) { Match m = EntityRegExp[2].Match(buffer); if(!m.Success) return false; HeaderItems.Add("content-language",m.Groups["content_language"].Value); return true; } private static bool Entity_content_length(string buffer,IDictionary HeaderItems) { Match m = EntityRegExp[3].Match(buffer); if(!m.Success) return false; int length; try { length = Int32.Parse(m.Groups["content_length"].ToString()); } catch (Exception ) { // return false; } HeaderItems.Add("content-length",length); return true; } private static bool Entity_content_range(string buffer,IDictionary HeaderItems) { Match m = EntityRegExp[4].Match(buffer); if(!m.Success) return false; HeaderItems.Add("content-range",m.Groups["content_range"].Value); return true; } private static bool Entity_content_type(string buffer,IDictionary HeaderItems) { Match m = EntityRegExp[5].Match(buffer); if(!m.Success) return false; HeaderItems.Add("content-type",m.Groups["content_type"].Value); return true; } private static bool Entity_content_version(string buffer,IDictionary HeaderItems) { Match m = EntityRegExp[6].Match(buffer); if(!m.Success) return false; HeaderItems.Add("content-version",m.Groups["content_version"].Value); return true; } private static bool Entity_dervied_from(string buffer,IDictionary HeaderItems) { Match m = EntityRegExp[7].Match(buffer); if(!m.Success) return false; HeaderItems.Add("dervied-from",m.Groups["dervied_from"].Value); return true; } private static bool Entity_expires(string buffer,IDictionary HeaderItems) { Match m = EntityRegExp[8].Match(buffer); if(!m.Success) return false; HeaderItems.Add("expires",m.Groups["expires"].Value); return true; } private static bool Entity_last_modified(string buffer,IDictionary HeaderItems) { Match m = EntityRegExp[9].Match(buffer); if(!m.Success) return false; HeaderItems.Add("last-modified",m.Groups["last_modified"].Value); return true; } private static bool Entity_link(string buffer,IDictionary HeaderItems) { Match m = EntityRegExp[10].Match(buffer); if(!m.Success) return false; HeaderItems.Add("link",m.Groups["link"].Value); return true; } private static bool Entity_title(string buffer,IDictionary HeaderItems) { Match m = EntityRegExp[11].Match(buffer); if(!m.Success) return false; HeaderItems.Add("title",m.Groups["title"].Value); return true; } private static bool Entity_transfere_encoding(string buffer,IDictionary HeaderItems) { Match m = EntityRegExp[12].Match(buffer); if(!m.Success) return false; HeaderItems.Add("transfere-encoding",m.Groups["transfere_encoding"].Value); return true; } private static bool Entity_url_header(string buffer,IDictionary HeaderItems) { Match m = EntityRegExp[13].Match(buffer); if(!m.Success) return false; HeaderItems.Add("url-header",m.Groups["url_header"].Value); return true; } private static bool Entity_extension_header(string buffer,IDictionary HeaderItems) { Match m = EntityRegExp[14].Match(buffer); if(!m.Success) return false; HeaderItems.Add("extension-header",m.Groups["extension_header"].Value); return true; } //******************************************************** } }