예제 #1
0
        private static void HttpListenHandler(IAsyncResult result)
        {
            HttpListenerContext context = null;

            if (HttpListener == null)
            {
                return;
            }
            if (result != ApiListener.result)
            {
                return;
            }
            try
            {
                context = HttpListener.EndGetContext(result);

                string body = null;
                if (context.Request.HasEntityBody)
                {
                    using (System.IO.Stream bodyStream = context.Request.InputStream)
                    {
                        using (System.IO.StreamReader reader = new System.IO.StreamReader(bodyStream, context.Request.ContentEncoding))
                        {
                            body = reader.ReadToEnd();
                        }
                    }
                }

                byte[] responseBuffer;

                var    response = "ok";
                string command  = "Unknown Command";
                try
                {
                    var urlParams = new List <string>(context.Request.RawUrl.Split(new char[] { '/' })).Select(us => Uri.UnescapeDataString(us)).ToList();
                    if (!string.IsNullOrWhiteSpace(body))
                    {
                        urlParams.Add(body);
                    }
                    if (string.IsNullOrWhiteSpace(urlParams.FirstOrDefault()))
                    {
                        urlParams.RemoveAt(0);
                    }
                    if (string.IsNullOrWhiteSpace(urlParams.LastOrDefault()) && urlParams.Any())
                    {
                        urlParams.RemoveAt(urlParams.Count - 1);
                    }

                    if (!urlParams.Any())
                    {
                        response = Documentation.Function(null);
                    }
                    else if (urlParams[0] == "favicon.ico")
                    {
                        context.Response.StatusCode = 404;
                        response = "Not found.";
                    }
                    else
                    {
                        command = urlParams[0];
                        urlParams.RemoveAt(0);

                        if (!Commands.ContainsKey(command))
                        {
                            throw new ApiError($"Invalid Command \"{command}\"");
                        }

                        command  = Commands[command]?.Name; //normalize name for display during errors
                        response = Commands[command].Function(urlParams) ?? response;
                    }
                }
                catch (Exception e)
                {
                    response = $"{command}: {e.Message}";
                    context.Response.StatusCode = e is ApiError ? 400 : 500;
                }
                responseBuffer = Encoding.UTF8.GetBytes(response);
                context.Response.ContentType = "application/json; charset=utf-8";
                // Get a response stream and write the response to it.
                context.Response.ContentLength64 = responseBuffer.Length;
                using (System.IO.Stream output = context.Response.OutputStream)
                {
                    output.Write(responseBuffer, 0, responseBuffer.Length);
                    output.Close();
                }
                Log(Debug($"{context.Request.RawUrl} => {context.Response.StatusCode}: {response}"));
            }
            catch (Exception e) {
                Log(Critical($"{context?.Request?.RawUrl ?? "(Error getting accessed URL)"} => {e.Message}"));
            }
            finally
            {
                try
                {
                    if (HttpListener.IsListening)
                    {
                        Listen();
                    }
                }
                catch (ObjectDisposedException)
                { }
            }
        }