示例#1
0
        /// <summary>
        /// Gets a byte representation of the data requested in this HttpListenerContext request
        /// </summary>
        /// <param name="sender">Sender of the call</param>
        /// <param name="context">Context of the HTTP request</param>
        /// <param name="controllers">Relevant controllers to be searched for methods</param>
        /// <returns>a byte representation of the data requested in this HttpListenerContext request</returns>
        public static byte[] handleResponse(SaneServer sender, HttpListenerContext context, List <Type> controllers)
        {
            List <HttpArgument> arguments = new List <HttpArgument>();

            MethodInfo[][]    info    = controllers.Select((g) => (g.GetMethods().Where((x) => (x.GetCustomAttribute <ControllerAttribute>() != null || x.GetCustomAttribute <DataBoundViewAttribute>() != null)).ToArray())).ToArray();
            List <MethodInfo> methods = new List <MethodInfo>();

            for (int i = 0; i < info.Length; i++)
            {
                for (int j = 0; j < info[i].Length; j++)
                {
                    methods.Add(info[i][j]);
                }
            }
            foreach (String key in context.Request.QueryString.AllKeys)
            {
                arguments.Add(new HttpArgument(key, context.Request.QueryString.GetValues(key).First()));
            }
            byte[] returned = new byte[] { };
            foreach (MethodInfo method in methods)
            {
                ControllerAttribute attribute = method.GetCustomAttribute <ControllerAttribute>();
                if (attribute == null)
                {
                    continue;
                }
                String trimmed = context.Request.RawUrl.Substring(0, context.Request.RawUrl.LastIndexOf("/") + 1);
                if ((attribute.path.Substring(0).Equals(trimmed)) && (attribute.verb.Equals(context.Request.HttpMethod)))
                {
                    try
                    {
                        ParameterInfo[] parameters = method.GetParameters();
                        Dictionary <ParameterInfo, String> match = new Dictionary <ParameterInfo, String>();
                        foreach (ParameterInfo parameter in parameters)
                        {
                            foreach (HttpArgument argument in arguments)
                            {
                                if (argument.key.Equals(parameter.Name))
                                {
                                    match[parameter] = argument.value;
                                }
                            }
                        }
                        object[] finalized = new object[parameters.Length];
                        finalized[0] = context;
                        if (context.Request.HasEntityBody)
                        {
                            finalized[1] = new StreamReader(context.Request.InputStream).ReadToEnd();
                        }
                        else
                        {
                            finalized[1] = String.Empty;
                        }
                        for (int i = 2; i < parameters.Length; i++)
                        {
                            finalized[i] = (match.ContainsKey(parameters[i])) ? match[parameters[i]] : null;
                        }
                        context.Response.ContentType = attribute.contentType;
                        if (method.ReturnType.Equals((new byte[] { }).GetType()))
                        {
                            return((byte[])method.Invoke(null, finalized));
                        }
                        else
                        {
                            return(Encoding.UTF8.GetBytes(method.Invoke(null, finalized) + ""));
                        }
                    }
                    catch (Exception e)
                    {
                        context.Response.ContentType = attribute.contentType;
                        if (sender.GetErrorHandler() != null)
                        {
                            context.Response.StatusCode = 400;
                            SaneErrorEventArgs args = new SaneErrorEventArgs(ResponseErrorReason.INTERNAL_API_THROW, e, false, "");
                            sender.GetErrorHandler()(null, args);
                            if (args.Propogate)
                            {
                                return(Encoding.UTF8.GetBytes(args.Response));
                            }
                            else
                            {
                                return(new byte[] { });
                            }
                        }
                        else
                        {
                            context.Response.StatusCode = 400;
                            return(Encoding.UTF8.GetBytes("An error occured processing your request, and no error handler is currently set!"));
                        }
                    }
                }
                else if ((attribute.path.Substring(0).Equals(trimmed)))
                {
                    if (sender.GetErrorHandler() != null)
                    {
                        context.Response.StatusCode = 400;
                        SaneErrorEventArgs args = new SaneErrorEventArgs(ResponseErrorReason.INCORRECT_API_TYPE, new Exception("Incorrect API request type! Got " + context.Request.HttpMethod + ", expected " + attribute.verb + "!"), false, "");
                        sender.GetErrorHandler()(null, args);
                        if (args.Propogate)
                        {
                            return(Encoding.UTF8.GetBytes(args.Response));
                        }
                        else
                        {
                            return(new byte[] { });
                        }
                    }
                    else
                    {
                        context.Response.StatusCode = 400;
                        return(Encoding.UTF8.GetBytes("An error occured processing your request, and no error handler is currently set!"));
                    }
                }
            }
            Assembly    assembly  = Assembly.GetEntryAssembly();
            XmlDocument structure = sender.GetViewStructure();
            XmlNodeList resources = structure.SelectNodes("view/resource");
            String      request   = context.Request.RawUrl.Substring(1).Replace("/", ".");
            XmlNode     homePage  = null;
            XmlNode     notFound  = null;

            foreach (XmlNode node in resources)
            {
                if (request.Equals(node.Attributes["path"].Value.Replace("/", ".")))
                {
                    context.Response.ContentType = node.Attributes["content-type"].Value;
                    byte[] clientData = Utility.fetchForClient(assembly, node.Attributes["location"].Value);
                    foreach (MethodInfo method in methods)
                    {
                        DataBoundViewAttribute attribute = method.GetCustomAttribute <DataBoundViewAttribute>();
                        if (attribute == null)
                        {
                            continue;
                        }
                        if ((attribute.path.Equals(context.Request.RawUrl)))
                        {
                            Object        binding   = method.Invoke(null, new object[] { context });
                            DataBoundView boundView = new DataBoundView(clientData, binding);
                            return(Encoding.UTF8.GetBytes(boundView.html));
                        }
                    }
                    return(clientData);
                }
                if (node.Attributes["situational"] != null)
                {
                    String value = node.Attributes["situational"].Value;
                    if (value.Equals("homepage"))
                    {
                        homePage = node;
                    }
                    else if (value.Equals("404"))
                    {
                        notFound = node;
                    }
                }
            }
            if (context.Request.RawUrl.Trim().Length <= 1)
            {
                context.Response.ContentType = "text/html";
                byte[] clientData = new byte[] { };
                if (homePage != null)
                {
                    clientData = Utility.fetchForClient(assembly, homePage.Attributes["location"].Value.Replace("/", "."));
                    foreach (MethodInfo method in methods)
                    {
                        DataBoundViewAttribute attribute = method.GetCustomAttribute <DataBoundViewAttribute>();
                        if (attribute == null)
                        {
                            continue;
                        }
                        if ((attribute.path.Substring(1).Equals(homePage.Attributes["path"].Value)))
                        {
                            Object        binding   = method.Invoke(null, new object[] { context });
                            DataBoundView boundView = new DataBoundView(clientData, binding);
                            return(Encoding.UTF8.GetBytes(boundView.html));
                        }
                    }
                }
                return(clientData);
            }
            context.Response.StatusCode  = 404;
            context.Response.ContentType = "text/html";
            byte[] ret = new byte[] { };
            if (notFound != null)
            {
                ret = Utility.fetchForClient(assembly, notFound.Attributes["location"].Value.Replace("/", "."));
                foreach (MethodInfo method in methods)
                {
                    DataBoundViewAttribute attribute = method.GetCustomAttribute <DataBoundViewAttribute>();
                    if (attribute == null)
                    {
                        continue;
                    }
                    if ((attribute.path.Substring(1).Equals(notFound.Attributes["path"].Value)))
                    {
                        Object        binding   = method.Invoke(null, new object[] { context });
                        DataBoundView boundView = new DataBoundView(ret, binding);
                        return(Encoding.UTF8.GetBytes(boundView.html));
                    }
                }
            }
            return(ret);
        }
 public static void ErrorHandler(Object sender, SaneErrorEventArgs e)
 {
     Logger.Error("Unexpected error - " + e.Exception.Message + e.Exception.StackTrace);
     e.Propogate = false;
 }