Ejemplo n.º 1
0
    public void Run()
    {
        ThreadPool.QueueUserWorkItem(o =>
        {
            Print(ConsoleColor.Green, "Webserver is now listening for connections...");

            while (m_Listener.IsListening)
            {
                ThreadPool.QueueUserWorkItem(async c =>
                {
                    var ctx = c as HttpListenerContext;
                    try
                    {
                        if (ctx == null)
                        {
                            return;
                        }

                        // Do we have auth header?
                        if (ctx.Request.Headers.Get("Authorization") == null)
                        {
                            ctx.Response.StatusCode = 401;
                            Print(ConsoleColor.Yellow, "Blocked Unauthorized request from {0} (No Auth Header)", ctx.Request.UserHostAddress);
                            return;
                        }

                        string requestAuthToken = ctx.Request.Headers["Authorization"].Replace("Bearer ", "");;
                        if (requestAuthToken != AuthToken)
                        {
                            ctx.Response.StatusCode = 401;
                            Print(ConsoleColor.Yellow, "Blocked Unauthorized request from {0} (Invalid Auth Token)", ctx.Request.UserHostAddress);
                            return;
                        }

                        string[] explodedUri = ctx.Request.RawUrl.Split('/');
                        string funcName      = explodedUri[1];

                        long paramsLen      = explodedUri.Length - 2;
                        string[] parameters = new string[paramsLen];
                        Array.Copy(explodedUri, 2, parameters, 0, paramsLen);
                        parameters = parameters.Where(x => !string.IsNullOrEmpty(x)).ToArray();

                        string reqBody = new StreamReader(ctx.Request.InputStream).ReadToEnd();
                        string respStr = String.Empty;

                        // Do we have a handler?
                        if (m_Handlers.ContainsKey(funcName))
                        {
                            BaseHandler handler = m_Handlers[funcName];

                            // Do we have the expected security authorization?
                            bool bMeetsSecurityReq  = false;
                            Player associatedPlayer = null;
                            if (handler.EndpointSecurity != EndpointSecurityType.None)
                            {
                                switch (handler.EndpointSecurity)
                                {
                                case EndpointSecurityType.RequiresUserSession:
                                    {
                                        // attempt to read the UserSession from the JSON body
                                        // any exception here will trigger the finally and catch block below, terminating the request and cleaning up nicely
                                        dynamic reqBodyDeserialized = Newtonsoft.Json.Linq.JObject.Parse(reqBody);
                                        string UserSessionID        = reqBodyDeserialized.user_session;
                                        if (UserSessionID == null)
                                        {
                                            bMeetsSecurityReq = false;
                                        }
                                        else
                                        {
                                            // Is the session valid?
                                            associatedPlayer = Program.g_PlayerManager.GetPlayerFromSession(UserSessionID);
                                            if (associatedPlayer != null)
                                            {
                                                bMeetsSecurityReq = true;
                                            }
                                            else
                                            {
                                                bMeetsSecurityReq = false;
                                            }
                                        }
                                        break;
                                    }

                                default:
                                    {
                                        bMeetsSecurityReq = false;
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                bMeetsSecurityReq = true;
                            }

                            if (!bMeetsSecurityReq)
                            {
                                ctx.Response.StatusCode = 403;
                                string errorStr         = String.Format("-> {0} expected auth type {1}. A valid session was not provided.", handler.GetType().Name, handler.EndpointSecurity);
                                Print(ConsoleColor.Green, errorStr);
                                respStr = errorStr;
                            }
                            else
                            {
                                if (handler.NumExpectedParameters() == parameters.Length || handler.NumExpectedParameters() == -1)
                                {
                                    Print(ConsoleColor.Green, "-> Routing {2} request {0} to {1}", funcName, handler.GetType().Name, ctx.Request.HttpMethod);

                                    if (ctx.Request.HttpMethod == "GET")
                                    {
                                        respStr = await handler.ProcessRequest_Get(associatedPlayer, ctx.Request, parameters);
                                    }
                                    else if (ctx.Request.HttpMethod == "PUT")
                                    {
                                        respStr = await handler.ProcessRequest_Put(associatedPlayer, ctx.Request, parameters, reqBody);
                                    }
                                    else
                                    {
                                        Print(ConsoleColor.Green, "-> Request {0} with method {1} was not handled.", funcName, ctx.Request.HttpMethod);
                                    }
                                }
                                else
                                {
                                    string errorStr = String.Format("-> Invalid number of parameters for {0}. Expected: {1}. Got: {2}", handler.GetType().Name, handler.NumExpectedParameters(), parameters.Length);
                                    Print(ConsoleColor.Green, errorStr);
                                    respStr = errorStr;
                                }
                            }
                        }
                        else
                        {
                            respStr = "Function not registered.";
                        }

                        ctx.Response.ContentType = "application/json";
                        var buf = Encoding.UTF8.GetBytes(respStr);
                        ctx.Response.ContentLength64 = buf.Length;
                        ctx.Response.OutputStream.Write(buf, 0, buf.Length);
                    }
                    catch (Exception ex)
                    {
                        Print(ConsoleColor.Red, "Ctx Exception: {0}", ex.Message);
                    }
                    finally
                    {
                        // always close stream
                        if (ctx != null)
                        {
                            try { ctx.Response.OutputStream.Close(); } catch { };
                        }
                    }
                }, m_Listener.GetContext());
            }
        });
    }