Esempio n. 1
0
        // Handles an incoming request
        private void HandleRequest(HttpListenerContext HttpContext)
        {
            string Result = "";

            try
            {
                // Get request information
                var    Request     = HttpContext.Request;
                string RequestType = Request.HttpMethod;
                string Password    = Request.Headers["Password"];
                string MethodName  = Request.Url.Segments[2].Replace("/", "").ToUpper();
                int    Version     = int.Parse(Request.Url.Segments[1].Replace("/", ""));

                // Check if requested method exists
                var Methods = MethodContexts.GetMethods(MethodName);
                if (!Methods.Any())
                {
                    throw new InvalidOperationException("Invalid API method");
                }

                // Loop through found methods
                // TODO - also check # of params needed when getting methods
                foreach (var Entry in Methods)
                {
                    // Check request type
                    // TODO - This looks ugly... Clean it up
                    if ((Entry.Type == ApiRequestType.POST && RequestType != "POST") ||
                        (Entry.Type == ApiRequestType.GET && RequestType != "GET"))
                    {
                        continue;
                    }

                    // Check request version against context version
                    if (!Entry.Context.CheckVersion(Version))
                    {
                        continue;
                    }

                    // Check request validation
                    if (Entry.RequiresValidation && Password != this.Password)
                    {
                        continue;
                    }

                    // Get method parameters
                    var MethodParams = Entry.Method.GetParameters();

                    // Get request parameters
                    object[] Params = new object[MethodParams.Length];
                    if (RequestType == "GET")
                    {
                        // Get our request's params directly from URL string
                        string[] RequestParams = Request.Url.Segments.Skip(3).Select(x => x.Replace("/", "")).ToArray();

                        // Populate our parameters
                        for (int i = 0; i < MethodParams.Length; i++)
                        {
                            // Check if this parameter is present in the request
                            if (i < RequestParams.Length)
                            {
                                // Convert to method parameter type
                                Params[i] = Convert.ChangeType(RequestParams[i], MethodParams[i].ParameterType);
                            }

                            // Otherwise default to a null value
                            else
                            {
                                continue;
                            }
                        }
                    }
                    else if (RequestType == "POST")
                    {
                        // Get our request's params from the stream data
                        var RequestParams = new Dictionary <string, dynamic>();
                        using (var Reader = new StreamReader(Request.InputStream, Request.ContentEncoding))
                        {
                            var Json = JsonConvert.DeserializeObject <JObject>(Reader.ReadToEnd());
                            RequestParams = new Dictionary <string, object>(
                                Json.ToObject <IDictionary <string, object> >(), StringComparer.CurrentCultureIgnoreCase);
                        }

                        // Populate our parameters
                        for (int i = 0; i < MethodParams.Length; i++)
                        {
                            // Check if this parameter is present in the request
                            if (RequestParams.ContainsKey(MethodParams[i].Name))
                            {
                                // Convert to method parameter type
                                Params[i] = Convert.ChangeType(RequestParams[MethodParams[i].Name], MethodParams[i].ParameterType);
                            }

                            // Otherwise default to a null value
                            else
                            {
                                continue;
                            }
                        }
                    }

                    // Try invoke method
                    var Output = (string)Entry.Method.Invoke(Entry.Context, Params);

                    // TODO - better (more efficient) way to catch errors, yikes
                    if (JsonConvert.DeserializeObject <JObject>(Output).TryGetValue("error", out _))
                    {
                        continue;
                    }
                    Result = Output;
                    break;
                }

                // Check if result is empty
                if (string.IsNullOrEmpty(Result))
                {
                    throw new InvalidOperationException("Invalid API method");
                }
            }

            // A known error was caught
            catch (InvalidOperationException e)
            {
                Result = new JObject
                {
                    ["error"] = e.Message
                }.ToString();
            }

            // Unable to parse this request
            catch
            {
                Result = new JObject
                {
                    ["error"] = "Invalid request"
                }.ToString();
            }

            // Populate a new HTTP header and send our response
            var Buffer   = Encoding.UTF8.GetBytes(Result);
            var Response = HttpContext.Response;

            Response.ContentLength64 = Buffer.Length;
            using (var st = Response.OutputStream)
                st.Write(Buffer, 0, Buffer.Length);
            Response.Close();
        }
Esempio n. 2
0
        // Finds a method in the list of method contexts


        // Handles an incoming request
        private void HandleRequest(HttpListenerContext HttpContext)
        {
            string Result = "";

            try
            {
                // Get request information
                var    Request     = HttpContext.Request;
                string RequestType = Request.HttpMethod;
                string Password    = Request.Headers["Password"];

                // Check if requested method exists
                string MethodName = Request.Url.Segments[2].Replace("/", "").ToUpper();
                if (!MethodContexts.TryGetMethod(MethodName, out var Method, out var Context, out var Validate))
                {
                    throw new InvalidOperationException("Invalid API method");
                }

                // Check request's API version
                if (!int.TryParse(Request.Url.Segments[1].Replace("/", ""), out int Version) ||
                    !Context.CheckVersion(Version))
                {
                    throw new InvalidOperationException("Invalid API version");
                }

                // Check request validation
                if (Validate && Password != this.Password)
                {
                    throw new InvalidOperationException("Invalid password");
                }

                // "GET" request
                if (RequestType == "GET")
                {
                    // Get our request's params directly from URL string
                    string[] Params = Request.Url.Segments.Skip(3).Select(x => x.Replace("/", "")).ToArray();
                    Logger.Debug($"[{Request.RemoteEndPoint.Address.ToString()} API] " +
                                 $"/{Version}/{MethodName}/{string.Join("/", Request.Url.Segments.Skip(3))}");

                    // Populate our parameters
                    var      Parameters   = Method.GetParameters();
                    object[] MethodParams = new object[Parameters.Length];
                    for (int i = 0; i < Parameters.Length; i++)
                    {
                        if (i < Params.Length)
                        {
                            MethodParams[i] = Convert.ChangeType(Params[i], Parameters[i].ParameterType);
                        }
                        else
                        {
                            MethodParams[i] = null;
                        }
                    }

                    // Invoke the requested method
                    Result = (string)Method.Invoke(Context, MethodParams);
                }

                // "POST" request
                else if (RequestType == "POST")
                {
                    // Get our request's params from the stream data
                    string RequestBody = "";
                    using (var Reader = new StreamReader(Request.InputStream, Request.ContentEncoding))
                        RequestBody = Reader.ReadToEnd();
                    JObject Params = JsonConvert.DeserializeObject <JObject>(RequestBody);
                    Logger.Debug($"[{Request.RemoteEndPoint.Address.ToString()} API] /{Version}/{MethodName}/");

                    // Invoke the requested method
                    Result = (string)Method.Invoke(this, new object[] { Params });
                }
            }

            // A known error was caught
            catch (InvalidOperationException e)
            {
                Result = $"{{'error':'{e.Message}'}}";
            }

            // Unable to parse this request
            catch
            {
                Result = "{'error':'Invalid request'}";
            }

            // Populate a new HTTP header and send our response
            var Buffer   = Encoding.UTF8.GetBytes(Result);
            var Response = HttpContext.Response;

            Response.ContentLength64 = Buffer.Length;
            using (var st = Response.OutputStream)
                st.Write(Buffer, 0, Buffer.Length);
            Response.Close();
        }