Provides a mechanism to get information about an HTTP Request made by a client.

This class is created internally by the Web Server and thus cannot be created from outside code. To handle requests and response, the WebServer.IHTTPRouteHandler interface or the delegate methods in RouteSolver which is available from the WebServer.WebServer.Routes property.

コード例 #1
0
        public void HandleRequest(HTTPRequest request, HTTPResponse response)
        {
            if (request.Subroute == "")
            {
                //If there really is no file requested, then we send a 404!
                response.WriteError(HTTPStatusCode.NotFound, "Not Found");
                return;
            }

            //Find the requested file
            string requestedFile = _baseDirectory + request.Subroute.Replace(WoopsaConst.UrlSeparator, Path.DirectorySeparatorChar);

            if (!IsFileAllowed(requestedFile))
            {
                response.WriteError(HTTPStatusCode.NotFound, "Not Found");
                return;
            }

            //Does this file exist?
            if (File.Exists(requestedFile))
            {
                ServeFile(requestedFile, response);
            }
            else if (Directory.Exists(requestedFile))
            {
                //Try to find the index.html file
                requestedFile = requestedFile + "index.html";
                if (File.Exists(requestedFile))
                {
                    ServeFile(requestedFile, response);
                }
                else
                {
                    response.WriteError(HTTPStatusCode.NotFound, "Not Found");
                }
            }
            else
            {
                response.WriteError(HTTPStatusCode.NotFound, "Not Found");
            }
        }
コード例 #2
0
 public void HandleRequest(HTTPRequest request, HTTPResponse response)
 {
     string subRoute = request.Subroute;
     if (_assembly != null)
         RespondResource(response, _assembly, subRoute);
     else
     {
         Assembly assembly;
         // First element = initial /
         string[] pathParts = subRoute.Split(new char[] { WoopsaConst.UrlSeparator }, 3);
         if (pathParts.Length == 3 && pathParts[1] != "")
             assembly = AssemblyByName(pathParts[1]);
         else
             assembly = null;
         if (assembly != null)
             RespondResource(response, assembly, WoopsaConst.UrlSeparator + pathParts[2]);
         else
             response.WriteError(HTTPStatusCode.NotFound,
                 string.Format("Assembly not Found at '{0}'", subRoute));
     }
 }
コード例 #3
0
 public bool Process(HTTPRequest request, HTTPResponse response)
 {
     bool authenticated;
     _currentUserName = null;
     if (request.Headers.ContainsKey(HTTPHeader.Authorization))
     {
         string authString = request.Headers[HTTPHeader.Authorization].Split(' ')[1];
         authString = Encoding.GetEncoding("ISO-8859-1").GetString(Convert.FromBase64String(authString));
         string[] parts = authString.Split(':');
         string username = parts[0];
         string password = parts[1];
         authenticated = Authenticate(username, password);
         if (authenticated)
             _currentUserName = username;
     }
     else
         authenticated = false;
     if (!authenticated)
     {
         response.SetHeader(HTTPHeader.WWWAuthenticate, "Basic Realm=\"" + Realm + "\"");
         response.WriteError(HTTPStatusCode.Unauthorized, "Unauthorized");
     }
     return authenticated;
 }
コード例 #4
0
ファイル: WebServer.cs プロジェクト: woopsa-protocol/Woopsa
 private void ExtractPOST(HTTPRequest request, StreamReader reader, Encoding clientEncoding)
 {
     if (request.Method == HTTPMethod.POST)
     {
         if (!request.Headers.ContainsKey(HTTPHeader.ContentLength))
         {
             throw new HandlingException(HTTPStatusCode.LengthRequired, "Length Required");
         }
         int contentLength = Convert.ToInt32(request.Headers[HTTPHeader.ContentLength]);
         if (contentLength != 0)
         {
             if (!request.Headers.ContainsKey(HTTPHeader.ContentType))
             {
                 throw new HandlingException(HTTPStatusCode.BadRequest, "Bad Request");
             }
             if (request.Headers[HTTPHeader.ContentType].StartsWith(MIMETypes.Application.XWWWFormUrlEncoded))
             {
                 // We might still be receiving client data at this point,
                 // which means that the reader.Read call will not always
                 // be able to read -all- of the data. So we loop until all
                 // the content is received!
                 char[] requestBody = new char[contentLength];
                 int charsRead = 0;
                 while (charsRead < contentLength)
                 {
                     int amountOfCharsRead = reader.Read(requestBody, charsRead, contentLength - charsRead);
                     charsRead += amountOfCharsRead;
                     if (amountOfCharsRead == 0 && charsRead != contentLength)
                         throw new HandlingException(HTTPStatusCode.BadRequest, "Wrong Content-Length");
                 }
                 string bodyAsString = new String(requestBody);
                 NameValueCollection body = HttpUtility.ParseQueryString(bodyAsString, clientEncoding);
                 request.Body = body;
             }
             else
             {
                 throw new HandlingException(HTTPStatusCode.NotImplemented, "Not Supported");
             }
         }
     }
 }
コード例 #5
0
ファイル: WebServer.cs プロジェクト: woopsa-protocol/Woopsa
 public LogEventArgs(HTTPRequest request, HTTPResponse response)
 {
     Request = request;
     Response = response;
 }
コード例 #6
0
ファイル: WebServer.cs プロジェクト: woopsa-protocol/Woopsa
 protected virtual void OnLog(HTTPRequest request, HTTPResponse response)
 {
     if (Log != null)
     {
         Log(this, new LogEventArgs(request, response));
     }
 }
コード例 #7
0
ファイル: RouteSolver.cs プロジェクト: woopsa-protocol/Woopsa
 protected virtual void OnError(RoutingErrorType errorType, string message, HTTPRequest request)
 {
     if (Error != null)
         Error(this, new RoutingErrorEventArgs(errorType, message, request));
 }
コード例 #8
0
ファイル: Exceptions.cs プロジェクト: woopsa-protocol/Woopsa
 public RoutingErrorEventArgs(RoutingErrorType type, string error, HTTPRequest request)
 {
     Type = type;
     Error = error;
     Request = request;
 }
コード例 #9
0
 public LogEventArgs(HTTPRequest request, HTTPResponse response) : base(request, response)
 {
 }
コード例 #10
0
ファイル: RouteSolver.cs プロジェクト: woopsa-protocol/Woopsa
        internal void HandleRequest(HTTPRequest request, HTTPResponse response, Stream stream)
        {
            try
            {
                bool matchFound = false;
                RouteMapper mapper = null;
                int i = 0;

                for (;;)
                {
                    lock (_routes)
                    {
                        if (i < _routes.Count)
                            mapper = _routes[i++];
                        else
                            break;
                    }
                    string regex = "^" + mapper.Route;
                    if (!mapper.AcceptSubroutes)
                    {
                        regex += "$";
                    }
                    if (Regex.IsMatch(request.BaseURL, regex))
                    {
                        if ((mapper.Methods & request.Method) != 0)
                        {
                            if (mapper.AcceptSubroutes)
                            {
                                int pos = request.BaseURL.IndexOf(mapper.Route);
                                request.Subroute = request.BaseURL.Substring(0, pos) + request.BaseURL.Substring(pos + mapper.Route.Length);
                            }
                            matchFound = true;
                            break;
                        }
                    }
                }

                if (!matchFound)
                {
                    response.WriteError(HTTPStatusCode.NotFound, "Not Found");
                    response.Respond(stream);
                    OnError(RoutingErrorType.NO_MATCHES, "No route found for request", request);
                }
                else
                {
                    mapper.HandleRequest(request, response);
                    response.Respond(stream);
                }
            }
            catch (Exception e)
            {
                response.WriteError(HTTPStatusCode.InternalServerError, String.Format("Internal Server Error {0}", e.Message));
                response.Respond(stream);
                OnError(RoutingErrorType.INTERNAL, "A RouteHandler threw an exception.", request);
            }
        }
コード例 #11
0
ファイル: WebServer.cs プロジェクト: woopsa-protocol/Woopsa
        private void HandleClient(TcpClient client)
        {
            lock (_openTcpClients)
                _openTcpClients.Add(client);
            try
            {
                Stream stream = client.GetStream();
                try
                {
                    foreach (PreRouteProcessor processor in PreRouteProcessors)
                    {
                        stream = processor.ProcessStream(stream);
                    }
                    bool leaveOpen = true;
                    HTTPResponse response = null;
                    HTTPRequest request = null;
                    StreamReader reader = new StreamReader(stream, Encoding.UTF8, false, 4096);
                    try
                    {
                        while (leaveOpen && !_aborted)
                        {
                            response = new HTTPResponse();
                            /*
                                * Parse the first line of the HTTP Request
                                * Examples:
                                *      GET / HTTP/1.1
                                *      POST /submit HTTP/1.1
                                */
                            string requestString;
                            try
                            {
                                requestString = reader.ReadLine();
                            }
                            catch (Exception)
                            {
                                requestString = null;
                                leaveOpen = false;
                                break;
                            }
                            if (requestString == null)
                                break;

                            string[] parts = requestString.Split(' ');
                            if (parts.Length != 3)
                            {
                                throw new HandlingException(HTTPStatusCode.BadRequest, "Bad Request");
                            }
                            string method = parts[0].ToUpper();
                            string url = parts[1];
                            string version = parts[2].ToUpper();

                            //Check if the version is what we expect
                            if (version != "HTTP/1.1" && version != "HTTP/1.0")
                            {
                                throw new HandlingException(HTTPStatusCode.HttpVersionNotSupported, "HTTP Version Not Supported");
                            }

                            //Check if the method is supported
                            if (!_supportedMethods.ContainsKey(method))
                            {
                                throw new HandlingException(HTTPStatusCode.NotImplemented, method + " Method Not Implemented");
                            }
                            HTTPMethod httpMethod = _supportedMethods[method];

                            url = HttpUtility.UrlDecode(url);

                            //Build the request object
                            request = new HTTPRequest(httpMethod, url);

                            //Add all headers to the request object
                            FillHeaders(request, reader);

                            //Handle encoding for this request
                            Encoding clientEncoding = InferEncoding(request);

                            //Extract all the data from the URL (base and query)
                            ExtractQuery(request, clientEncoding);

                            //Extract and decode all the POST data
                            ExtractPOST(request, reader, clientEncoding);

                            bool keepAlive = false;
                            // According to spec, Keep-Alive is ON by default
                            if (version == "HTTP/1.1")
                                keepAlive = true;
                            if (request.Headers.ContainsKey(HTTPHeader.Connection))
                            {
                                if (request.Headers[HTTPHeader.Connection].ToLower().Equals("close"))
                                {
                                    keepAlive = false;
                                    response.SetHeader(HTTPHeader.Connection, "close");
                                }
                            }

                            //Keep-Alive can only work on a multithreaded server!
                            if (!keepAlive || !MultiThreaded)
                            {
                                leaveOpen = false;
                                response.SetHeader(HTTPHeader.Connection, "close");
                            }
                            //Pass this on to the route solver
                            OnLog(request, null);
                            Routes.HandleRequest(request, response, stream);
                            OnLog(request, response);
                        }
                    }
                    catch (HandlingException e)
                    {
                        if (response != null)
                        {
                            try
                            {
                                // try to return the response
                                response.WriteError(e.Status, e.ErrorMessage);
                                response.Respond(stream);
                            }
                            catch
                            {
                                // ignore silently if it is not posible
                            }
                            OnLog(request, response);
                        }
                    }
                    catch (ThreadAbortException)
                    {
                        // Do nothing, server is terminating
                    }
                    catch (Exception e)
                    {
                        if (response != null)
                        {
                            try
                            {
                                // try to return the response
                                response.WriteError(HTTPStatusCode.InternalServerError, "Internal Server Error. " + e.Message);
                                response.Respond(stream);
                            }
                            catch
                            {
                                // ignore silently if it is not posible
                            }
                            OnLog(request, response);
                        }
                    }
                    finally
                    {
                        reader.Close();
                    }
                }
                finally
                {
                    stream.Dispose();
                }
            }
            finally
            {
                lock (_openTcpClients)
                    _openTcpClients.Remove(client);
            }
        }
コード例 #12
0
 public WebServerEventArgs(HTTPRequest request, HTTPResponse response)
 {
     Request  = request;
     Response = response;
 }
コード例 #13
0
ファイル: WoopsaServer.cs プロジェクト: xxGL1TCHxx/Woopsa
 public bool Process(HTTPRequest request, HTTPResponse response)
 {
     // Make IE stop cacheing AJAX requests
     response.SetHeader("Cache-Control", "no-cache, no-store");
     return(true);
 }
コード例 #14
0
 public void HandleRequest(HTTPRequest request, HTTPResponse response)
 {
     _delegate(request, response);
 }
コード例 #15
0
ファイル: WoopsaServer.cs プロジェクト: xxGL1TCHxx/Woopsa
        private void HandleRequest(WoopsaVerb verb, HTTPRequest request, HTTPResponse response)
        {
            try
            {
                _currentWoopsaServer = this;
                try
                {
                    string result = null;
                    using (new WoopsaServerModelAccessLockedSection(this))
                    {
                        switch (verb)
                        {
                        case WoopsaVerb.Meta:
                            result = GetMetadata(request.Subroute);
                            break;

                        case WoopsaVerb.Read:
                            result = ReadValue(request.Subroute);
                            break;

                        case WoopsaVerb.Write:
                            result = WriteValue(request.Subroute, request.Body["value"]);
                            break;

                        case WoopsaVerb.Invoke:
                            result = InvokeMethod(request.Subroute, request.Body);
                            break;
                        }
                    }
                    response.SetHeader(HTTPHeader.ContentType, MIMETypes.Application.JSON);
                    if (result != null)
                    {
                        response.WriteString(result);
                    }
                }
                finally
                {
                    _currentWoopsaServer = null;
                }
            }
            catch (WoopsaNotFoundException e)
            {
                response.WriteError(HTTPStatusCode.NotFound, e.GetFullMessage(), e.Serialize(), MIMETypes.Application.JSON);
                OnHandledException(e);
            }
            catch (WoopsaInvalidOperationException e)
            {
                response.WriteError(HTTPStatusCode.BadRequest, e.GetFullMessage(), e.Serialize(), MIMETypes.Application.JSON);
                OnHandledException(e);
            }
            catch (WoopsaException e)
            {
                response.WriteError(HTTPStatusCode.InternalServerError, e.GetFullMessage(), e.Serialize(), MIMETypes.Application.JSON);
                OnHandledException(e);
            }
            catch (Exception e)
            {
                response.WriteError(HTTPStatusCode.InternalServerError, e.GetFullMessage(), e.Serialize(), MIMETypes.Application.JSON);
                OnHandledException(e);
            }
        }
コード例 #16
0
ファイル: RouteMapper.cs プロジェクト: woopsa-protocol/Woopsa
 internal void HandleRequest(HTTPRequest request, HTTPResponse response)
 {
     foreach (IRequestProcessor processor in _requestProcessors)
     {
         if (!processor.Process(request, response))
         {
             return;
         }
     }
     _handler.HandleRequest(request, response);
     foreach(IResponseProcessor processor in _responseProcessors)
     {
         processor.Process(request, response);
     }
 }
コード例 #17
0
 public CorsRequestArgs(HTTPRequest request, HTTPResponse response, Stream stream) :
     base(request, response, stream)
 {
 }
コード例 #18
0
ファイル: WebServer.cs プロジェクト: woopsa-protocol/Woopsa
 private void ExtractQuery(HTTPRequest request, Encoding clientEncoding)
 {
     string url = request.FullURL;
     string baseUrl, queryString;
     if (url.IndexOf('?') != -1)
     {
         NameValueCollection queryArguments;
         string[] queryParts = url.Split('?');
         baseUrl = queryParts[0];
         queryString = queryParts[1];
         queryArguments = HttpUtility.ParseQueryString(queryString, clientEncoding);
         request.Query = queryArguments;
     }
     else
     {
         baseUrl = Uri.UnescapeDataString(url);
         queryString = "";
     }
     request.BaseURL = baseUrl;
 }
コード例 #19
0
 protected virtual void OnLog(HTTPRequest request, HTTPResponse response)
 {
     Log?.Invoke(this, new LogEventArgs(request, response));
 }
コード例 #20
0
ファイル: WebServer.cs プロジェクト: woopsa-protocol/Woopsa
 private void FillHeaders(HTTPRequest request, StreamReader reader)
 {
     string headerLine;
     while ((headerLine = reader.ReadLine()) != null && !headerLine.Equals(""))
     {
         if (headerLine.IndexOf(':') == -1)
         {
             throw new HandlingException(HTTPStatusCode.BadRequest, "Bad Request");
         }
         string[] newHeader = headerLine.Split(':');
         request._headers.Add(newHeader[0].Replace(" ", "").ToLower(), newHeader[1].Trim());
     }
 }
コード例 #21
0
 public WebServerStreamEventArgs(HTTPRequest request, HTTPResponse response, Stream stream) :
     base(request, response)
 {
     Stream = stream;
 }
コード例 #22
0
ファイル: WebServer.cs プロジェクト: woopsa-protocol/Woopsa
 private Encoding InferEncoding(HTTPRequest request)
 {
     //According to the HTTP spec, ISO-8859-1 is the default encoding when dealing with the web.
     //However, UTF-8 has shown way more versatile and is thus used in most places.
     Encoding clientEncoding = Encoding.GetEncoding("ISO-8859-1");
     if (request.Headers.ContainsKey(HTTPHeader.ContentType))
     {
         string[] typeParts = request.Headers[HTTPHeader.ContentType].Split(';');
         string clientEncodingString = "ISO-8859-1";
         foreach (string typePart in typeParts)
         {
             if (typePart.IndexOf("charset") != -1)
             {
                 clientEncodingString = typePart.Split('=')[1].Replace(" ", "");
                 break;
             }
         }
         clientEncoding = Encoding.GetEncoding(clientEncodingString);
     }
     return clientEncoding;
 }
コード例 #23
0
 private void HandleRequest(WoopsaVerb verb, HTTPRequest request, HTTPResponse response)
 {
     try
     {
         // This is the first thing we do, that way even 404 errors have the right headers
         if (AllowCrossOrigin)
             // TODO: constantes symboliques
             response.SetHeader("Access-Control-Allow-Origin", "*");
         string result = null;
         ExecuteBeforeWoopsaModelAccess();
         try
         {
             switch (verb)
             {
                 case WoopsaVerb.Meta:
                     result = GetMetadata(request.Subroute);
                     break;
                 case WoopsaVerb.Read:
                     result = ReadValue(request.Subroute);
                     break;
                 case WoopsaVerb.Write:
                     result = WriteValue(request.Subroute, request.Body["value"]);
                     break;
                 case WoopsaVerb.Invoke:
                     result = InvokeMethod(request.Subroute, request.Body);
                     break;
             }
         }
         finally
         {
             ExecuteAfterWoopsaModelAccess();
         }
         response.SetHeader(HTTPHeader.ContentType, MIMETypes.Application.JSON);
         if (result != null)
             response.WriteString(result);
     }
     catch (WoopsaNotFoundException e)
     {
         response.WriteError(HTTPStatusCode.NotFound, e.Message, WoopsaFormat.Serialize(e), MIMETypes.Application.JSON);
     }
     catch (WoopsaInvalidOperationException e)
     {
         response.WriteError(HTTPStatusCode.BadRequest, e.Message, WoopsaFormat.Serialize(e), MIMETypes.Application.JSON);
     }
     catch (WoopsaException e)
     {
         response.WriteError(HTTPStatusCode.InternalServerError, e.Message, WoopsaFormat.Serialize(e), MIMETypes.Application.JSON);
     }
     catch (Exception e)
     {
         response.WriteError(HTTPStatusCode.InternalServerError, e.Message, WoopsaFormat.Serialize(e), MIMETypes.Application.JSON);
     }
 }
コード例 #24
0
 public bool Process(HTTPRequest request, HTTPResponse response)
 {
     response.SetHeader("Access-Control-Allow-Headers", "Authorization");
     // TODO : constante symbolique + déterminer si AllowCrossOrigin doit être utilisé ici
     response.SetHeader("Access-Control-Allow-Origin", "*");
     response.SetHeader("Access-Control-Allow-Credentials", "true");
     response.SetHeader("Access-Control-Max-Age", MaxAge.TotalSeconds.ToString(CultureInfo.InvariantCulture));
     // Make IE stop cacheing AJAX requests
     response.SetHeader("Cache-Control", "no-cache, no-store");
     return true;
 }
コード例 #25
0
        private void HandleClient(TcpClient client)
        {
            lock (_openTcpClients)
                _openTcpClients.Add(client);
            try
            {
                Stream stream = client.GetStream();
                try
                {
                    foreach (PreRouteProcessor processor in PreRouteProcessors)
                    {
                        stream = processor.ProcessStream(stream);
                    }
                    bool         leaveOpen = true;
                    HTTPResponse response  = null;
                    HTTPRequest  request   = null;
                    StreamReader reader    = new StreamReader(stream, Encoding.UTF8, false, 4096);
                    try
                    {
                        while (leaveOpen && !_aborted)
                        {
                            response = new HTTPResponse();

                            /*
                             * Parse the first line of the HTTP Request
                             * Examples:
                             *      GET / HTTP/1.1
                             *      POST /submit HTTP/1.1
                             */
                            string requestString;
                            try
                            {
                                requestString = reader.ReadLine();
                            }
                            catch (Exception)
                            {
                                requestString = null;
                                leaveOpen     = false;
                                break;
                            }
                            if (requestString == null)
                            {
                                break;
                            }

                            string[] parts = requestString.Split(' ');
                            if (parts.Length != 3)
                            {
                                throw new HandlingException(HTTPStatusCode.BadRequest, "Bad Request");
                            }
                            string method  = parts[0].ToUpper();
                            string url     = parts[1];
                            string version = parts[2].ToUpper();

                            //Check if the version is what we expect
                            if (version != "HTTP/1.1" && version != "HTTP/1.0")
                            {
                                throw new HandlingException(HTTPStatusCode.HttpVersionNotSupported, "HTTP Version Not Supported");
                            }

                            //Check if the method is supported
                            if (!_supportedMethods.ContainsKey(method))
                            {
                                throw new HandlingException(HTTPStatusCode.NotImplemented, method + " Method Not Implemented");
                            }
                            HTTPMethod httpMethod = _supportedMethods[method];

                            url = HttpUtility.UrlDecode(url);

                            //Build the request object
                            request = new HTTPRequest(httpMethod, url);

                            //Add all headers to the request object
                            FillHeaders(request, reader);

                            //Handle encoding for this request
                            Encoding clientEncoding = InferEncoding(request);

                            //Extract all the data from the URL (base and query)
                            ExtractQuery(request, clientEncoding);

                            //Extract and decode all the POST data
                            ExtractPOST(request, reader, clientEncoding);

                            bool keepAlive = false;
                            // According to spec, Keep-Alive is ON by default
                            if (version == "HTTP/1.1")
                            {
                                keepAlive = true;
                            }
                            if (request.Headers.ContainsKey(HTTPHeader.Connection))
                            {
                                if (request.Headers[HTTPHeader.Connection].ToLower().Equals("close"))
                                {
                                    keepAlive = false;
                                    response.SetHeader(HTTPHeader.Connection, "close");
                                }
                            }

                            //Keep-Alive can only work on a multithreaded server!
                            if (!keepAlive || !MultiThreaded)
                            {
                                leaveOpen = false;
                                response.SetHeader(HTTPHeader.Connection, "close");
                            }
                            //Pass this on to the route solver
                            OnLog(request, null);
                            HandleRequest(request, response, stream);
                            response.Respond(stream);
                            OnLog(request, response);
                        }
                    }
                    catch (HandlingException e)
                    {
                        if (response != null)
                        {
                            try
                            {
                                // try to return the response
                                response.WriteError(e.Status, e.ErrorMessage);
                                response.Respond(stream);
                                OnLog(request, response);
                            }
                            catch
                            {
                                // ignore silently if it is not posible
                            }
                        }
                    }
                    catch (ThreadAbortException)
                    {
                        // Do nothing, server is terminating
                    }
                    catch (Exception e)
                    {
                        if (response != null)
                        {
                            try
                            {
                                // try to return the response
                                response.WriteError(HTTPStatusCode.InternalServerError, "Internal Server Error. " + e.Message);
                                response.Respond(stream);
                                OnLog(request, response);
                            }
                            catch
                            {
                                // ignore silently if it is not posible
                            }
                        }
                    }
                    finally
                    {
                        reader.Close();
                    }
                }
                finally
                {
                    stream.Dispose();
                }
            }
            finally
            {
                lock (_openTcpClients)
                    _openTcpClients.Remove(client);
            }
        }