Ejemplo n.º 1
0
        /// <summary>
        /// Read in what is basically a text file and return a ResponsePacket with the text UTF8 encoded.
        /// </summary>
        protected ResponsePacket FileLoader(Route routeHandler, Session session, Dictionary <string, object> kvParams, string fullPath, string ext, ExtensionInfo extInfo)
        {
            ResponsePacket ret;

            if (!File.Exists(fullPath))
            {
                ret = new ResponsePacket()
                {
                    Error = Server.ServerError.FileNotFound
                };
                Console.WriteLine("!!! File not found: " + fullPath);
            }
            else
            {
                string text = File.ReadAllText(fullPath);
                ret = new ResponsePacket()
                {
                    Data = Encoding.UTF8.GetBytes(text), ContentType = extInfo.ContentType, Encoding = Encoding.UTF8
                };
            }

            return(ret);
        }
Ejemplo n.º 2
0
        private void Respond(HttpListenerRequest request, HttpListenerResponse response, ResponsePacket resp)
        {
            // Are we redirecting?
            if (String.IsNullOrEmpty(resp.Redirect))
            {
                // No redirect.
                // Do we have a response?
                if (resp.Data != null)
                {
                    // Yes we do.
                    response.ContentType     = resp.ContentType;
                    response.ContentLength64 = resp.Data.Length;
                    response.OutputStream.Write(resp.Data, 0, resp.Data.Length);
                    response.ContentEncoding = resp.Encoding;
                }

                // Whether we do or not, no error occurred, so the response code is OK.
                // For example, we may have just processed an AJAX callback that does not have a data response.
                // Use the status code in the response packet, so the controller has an opportunity to set the response.
                response.StatusCode = (int)resp.StatusCode;
            }
            else
            {
                response.StatusCode = (int)HttpStatusCode.Redirect;

                if (String.IsNullOrEmpty(publicIP))
                {
                    string redirectUrl = request.Url.Scheme + "://" + request.Url.Host + resp.Redirect;
                    response.Redirect(redirectUrl);
                }
                else
                {
                    // response.Redirect("http://" + publicIP + resp.Redirect);
                    string redirectUrl = request.Url.Scheme + "://" + request.Url.Host + resp.Redirect;
                    response.Redirect(redirectUrl);
                }
            }

            response.OutputStream.Close();
        }
Ejemplo n.º 3
0
        public ResponsePacket Route(Session session, string verb, string path, Dictionary <string, object> kvParams)
        {
            string         ext = path.RightOfRightmostOf('.');
            ExtensionInfo  extInfo;
            ResponsePacket ret = null;

            verb = verb.ToLower();
            path = path.ToLower();

            if (extFolderMap.TryGetValue(ext, out extInfo))
            {
                string fullPath = Path.Combine(WebsitePath, path.Substring(1));

                Route routeHandler = routes.SingleOrDefault(r => verb == r.Verb.ToLower() && path == r.Path.ToLower());

                if (routeHandler != null)
                {
                    // Application has a handler for this route.
                    ResponsePacket handlerResponse = null;

                    // If a handler exists:
                    routeHandler.Handler.IfNotNull((h) => handlerResponse = h.Handle(session, kvParams));

                    // If multiple handlers exist, see which one, if any, is willing to handle the request.
                    // We stop after the first handler.
                    // This behavior is useful for web services or other types of routes where the data determines the route, not the URL.
                    if (routeHandler.Handlers.Count > 0)
                    {
                        foreach (RouteHandler h in routeHandler.Handlers)
                        {
                            if (h.CanHandle(session, kvParams))
                            {
                                handlerResponse = h.Handle(session, kvParams);
                                break;
                            }
                        }
                    }

                    if (handlerResponse == null)
                    {
                        // Respond with default content loader.
                        ret = extInfo.Loader(routeHandler, session, kvParams, fullPath, ext, extInfo);
                    }
                    else
                    {
                        // Respond with redirect.
                        ret = handlerResponse;
                    }
                }
                else
                {
                    // Attempt default behavior
                    ret = extInfo.Loader(null, session, kvParams, fullPath, ext, extInfo);
                }
            }
            else
            {
                ret = new ResponsePacket()
                {
                    Error = Server.ServerError.UnknownType
                };
            }

            return(ret);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Await connections.
        /// </summary>
        private async void StartConnectionListener(HttpListener listener)
        {
            ResponsePacket resp = null;

            // Wait for a connection.  Return to caller while we wait.
            HttpListenerContext context = await listener.GetContextAsync();

            Session session = sessionManager.GetSession(context.Request.RemoteEndPoint);

            OnRequest.IfNotNull(r => r(session, context));

            // Release the semaphore so that another listener can be immediately started up.
            sem.Release();
            Log(context.Request);

            HttpListenerRequest request = context.Request;

            try
            {
                string path  = request.RawUrl.LeftOf("?");                                      // Only the path, not any of the parameters
                string verb  = request.HttpMethod;                                              // get, post, delete, etc.
                string parms = request.RawUrl.RightOf("?");                                     // Params on the URL itself follow the URL and are separated by a ?
                Dictionary <string, object> kvParams = GetKeyValues(parms);                     // Extract into key-value entries.
                string data = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding).ReadToEnd();
                GetKeyValues(data, kvParams);
                Log(kvParams);

                if (!VerifyCsrf(session, verb, kvParams))
                {
                    Console.WriteLine("CSRF did not match.  Terminating connection.");
                    context.Response.OutputStream.Close();
                }
                else
                {
                    resp = router.Route(session, verb, path, kvParams);

                    // Update session last connection after getting the response, as the router itself validates session expiration only on pages requiring authentication.
                    session.UpdateLastConnectionTime();

                    if (resp.Error != ServerError.OK)
                    {
                        resp.Redirect = OnError(resp.Error);
                    }

                    // TODO: Nested exception: is this best?

                    try
                    {
                        Respond(request, context.Response, resp);
                    }
                    catch (Exception reallyBadException)
                    {
                        // The response failed!
                        // TODO: We need to put in some decent logging!
                        Console.WriteLine(reallyBadException.Message);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
                resp = new ResponsePacket()
                {
                    Redirect = OnError(ServerError.ServerError)
                };
            }
        }