Ejemplo n.º 1
0
        public static bool RegisterRESTfulClasses()
        {
            RESTfulElements  = new List <RESTfulElement>();
            RESTfulProtected = new List <RESTfulElement>();

            foreach (MethodInfo method in GetTypesWithHelpAttribute(Assembly.GetExecutingAssembly()))
            {
                VulpesRESTful  vr = method.GetCustomAttribute <VulpesRESTful>();
                RESTfulElement re = new RESTfulElement();
                re.Method            = method;
                re.URL               = vr.URL;
                re.Verb              = vr.Verb;
                re.RequireNi         = vr.RequireNi;
                re.ReturnValueName   = vr.ReturnValueName;
                re.GetValues         = vr.GetValues;
                re.UseLock           = vr.UseLock;
                re.RawDataProcessing = vr.RawDataProcessing;
                re.PutIPAddress      = vr.PutIPAddress;
                re.WithQueryString   = vr.WithQueryString;

                if (re.Method.ReturnType != typeof(RESTStatus))
                {
                    throw new Exception("Return type != RESTStatus (here: " + method.ToString() + "  )");
                }

                if (re.URL.StartsWith("/") == true || re.URL.EndsWith("/") == true)
                {
                    throw new Exception("URL in VulpesRESTful must not start/end with '/' (here: " + method.ToString() + "  )");
                }

                foreach (RESTfulElement ele in RESTfulElements)
                {
                    if (ele.GetValues == re.GetValues && ele.URL == re.URL && ele.Verb == re.Verb)
                    {
                        throw new Exception("Multiple registration for " + ele.Verb.ToString() + " " + ele.URL + " " + ele.GetValues);
                    }
                }

                RESTfulElements.Add(re);
                if (method.GetCustomAttribute <VulpesRESTProtected>() != null)
                {
                    RESTfulProtected.Add(re);
                }
            }

#if DEBUG
            foreach (RESTfulElement ele in RESTfulElements)
            {
                if (RESTfulProtected.Contains(ele) == true)
                {
                    Console.Write("[P] ");
                }
                Console.WriteLine(ele.Verb.ToString() + " " + ele.URL + " " + ele.GetValues);
            }
#endif

            return(true);
        }
Ejemplo n.º 2
0
        public static bool RunRESTful(HttpListenerRequest request, HttpListenerResponse response)
        {
            byte[] data = new byte[0];
            try
            {
                StreamReader read        = new StreamReader(request.InputStream, Encoding.UTF8);
                string       OriginalXML = read.ReadToEnd();

                VulpesRESTfulVerb verb;
                switch (request.HttpMethod.ToLower())
                {
                case "get": verb = VulpesRESTfulVerb.GET; break;

                case "put": verb = VulpesRESTfulVerb.PUT; break;

                case "delete": verb = VulpesRESTfulVerb.DELETE; break;

                case "head": verb = VulpesRESTfulVerb.HEAD; break;

                case "post": verb = VulpesRESTfulVerb.POST; break;

                case "patch": verb = VulpesRESTfulVerb.PATCH; break;

                default:
                    response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
                    response.StatusCode        = 501;
                    response.StatusDescription = "Not implemented";
                    //data = Encoding.UTF8.GetBytes("501 - Not implemented.");
                    return(true);
                }

                string URL = request.Url.LocalPath;
                Console.WriteLine(verb.ToString() + " " + URL);
                string CuttedParameters = "";
                if (URL.ToLower().StartsWith(Settings.Default.URLPart.ToLower()) == true)
                {
                    URL = URL.Substring(Settings.Default.URLPart.Length, URL.Length - Settings.Default.URLPart.Length);
                }
                string Auth = request.Headers["Authorization"];
                if (Auth == null)
                {
                    Auth = "";
                }
                Auth = Auth.ToLower();
                if (Auth.StartsWith("bearer ") == true)
                {
                    Auth = Auth.Substring(6, Auth.Length - 6).Trim();
                }
                else
                {
                    Auth = "";
                }

                string ClientIPAddress   = GetClientIP(request);
                NetworkConnectionInfo ni = NetworkConnection.GetSession(Auth);
                if (ni != null)
                {
                    ni.IPAddress = ClientIPAddress;
                }
                RESTfulElement CurrentR = null;
                foreach (RESTfulElement r in RESTfulElements)
                {
                    if (URL.ToLower().StartsWith(r.URL.ToLower()) == true && r.Verb == verb)
                    {
                        CuttedParameters = URL.Substring(r.URL.Length, URL.Length - r.URL.Length);
                        if (CuttedParameters.StartsWith("/") == true && r.GetValues != "")
                        {
                            CuttedParameters = CuttedParameters.Substring(1, CuttedParameters.Length - 1);
                        }
                        else
                        if (CuttedParameters.StartsWith("/") == true && r.GetValues == "")
                        {
                            continue;
                        }
                        else
                        if (CuttedParameters == "" && r.GetValues != "")
                        {
                            continue;
                        }

                        if (r.RequireNi == true && ni == null)
                        {
                            response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
                            response.StatusCode        = 403;
                            response.StatusDescription = "Forbidden";
                            //data = Encoding.UTF8.GetBytes("403 - Forbidden.");
                            return(true);
                        }
                        else
                        {
                            CurrentR = r;
                            break;
                        }
                    }
                }

                if (CurrentR == null)
                {
                    response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
                    response.StatusCode        = 404;
                    response.StatusDescription = "Not found";
                    //data = Encoding.UTF8.GetBytes("404 - Not found.");
                    return(true);
                }

                if (RESTfulProtected.Contains(CurrentR) == true)
                {
                    if (string.IsNullOrWhiteSpace(SettingsManager.Settings.AdminIPAddresses) == false)
                    {
                        IPAddress ip = request.RemoteEndPoint.Address;
                        if (ip.ToString() != IPAddress.Loopback.ToString() && ip.ToString() != IPAddress.IPv6Loopback.ToString())
                        {
                            bool IPInRange = false;
                            foreach (string s in SettingsManager.Settings.AdminIPAddresses.Split(','))
                            {
                                if (s.Contains("/") == true)
                                {
                                    IPNetwork ipn;
                                    if (IPNetwork.TryParse(s, out ipn) == true)
                                    {
                                        IPNetwork ipnn = IPNetwork.Parse(ip, IPAddress.Broadcast);
                                        if (ipn.Overlap(ipnn) == true)
                                        {
                                            IPInRange = true;
                                            break;
                                        }
                                    }
                                }
                            }
                            if (IPInRange == false)
                            {
                                response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
                                response.StatusCode        = 403;
                                response.StatusDescription = "Forbidden";
                                return(true);
                            }
                        }
                    }
                }

                ParameterInfo Param = CurrentR.Method.GetParameters()[1];

                List <object> Params = new List <object>();
                Params.Add(ni == null ? null : ni.sql);
                if (CurrentR.RawDataProcessing == true)
                {
                    Params.Add(request);
                    Params.Add(response);
                }
                Params.Add(JsonConvert.DeserializeObject(OriginalXML, Param.ParameterType));
                Params.Add(ni);
                if (CurrentR.PutIPAddress == true)
                {
                    Params.Add(ClientIPAddress);
                }
                if (CurrentR.WithQueryString == true)
                {
                    Params.Add(request.QueryString);
                }

                if (CurrentR.GetValues != "")
                {
                    ParameterInfo[] paramsi = CurrentR.Method.GetParameters();
                    if (paramsi.Length < 4)
                    {
                        response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
                        response.StatusCode        = 404;
                        response.StatusDescription = "Not found";
                        //data = Encoding.UTF8.GetBytes("404 - Not found.");
                        return(true);
                    }

                    int      CurrentParam         = 3 + (CurrentR.RawDataProcessing == true ? 2 : 0);
                    string[] CuttedParametersList = CuttedParameters.Split('/');
                    string[] ParamsDef            = CurrentR.GetValues.Split('/');

                    if (CuttedParametersList.Length != ParamsDef.Length)
                    {
                        response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
                        response.StatusCode        = 404;
                        response.StatusDescription = "Not found";
                        //data = Encoding.UTF8.GetBytes("404 - Not found.");
                        return(true);
                    }

                    foreach (string g in ParamsDef)
                    {
                        if (paramsi.Length < CurrentParam + 1)
                        {
                            response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
                            response.StatusCode        = 404;
                            response.StatusDescription = "Not found";
                            //data = Encoding.UTF8.GetBytes("404 - Not found.");
                            return(true);
                        }
                        if (g != paramsi[CurrentParam].Name)
                        {
                            response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
                            response.StatusCode        = 500;
                            response.StatusDescription = "Server Error";
#if DEBUG
                            data = Encoding.UTF8.GetBytes("500 - Server Error. Bad param definition");
#else
                            //data = Encoding.UTF8.GetBytes("500 - Server Error.");
#endif
                            return(true);
                        }
                        try
                        {
                            Params.Add(Convert.ChangeType(CuttedParametersList[CurrentParam - (CurrentR.RawDataProcessing == true ? 5 : 3)], paramsi[CurrentParam].ParameterType));
                        }
                        catch (Exception ee)
                        {
                            Debug.WriteLine(ee.ToString());
                            response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
                            response.StatusCode        = 404;
                            response.StatusDescription = "Not found";
#if DEBUG
                            data = Encoding.UTF8.GetBytes("404 - Not found. " + ee.ToString());
#else
                            //data = Encoding.UTF8.GetBytes("404 - Not found.");
#endif
                            return(true);
                        }
                        CurrentParam++;
                    }
                }

                object     instance = Activator.CreateInstance(CurrentR.Method.DeclaringType);
                RESTStatus res;
                if (ni == null)
                {
                    res = (RESTStatus)(CurrentR.Method.Invoke(instance, Params.ToArray()));
                }
                else
                {
                    if (CurrentR.UseLock == false)
                    {
                        res = (RESTStatus)(CurrentR.Method.Invoke(instance, Params.ToArray()));
                    }
                    else
                    {
                        try
                        {
                            ni.RWLock.EnterReadLock();
                            res = (RESTStatus)(CurrentR.Method.Invoke(instance, Params.ToArray()));
                        }
                        catch (Exception ee)
                        {
                            Debug.WriteLine(ee.ToString());
                            throw;
                        }
                        finally
                        {
                            ni.RWLock.ExitReadLock();
                        }
                    }
                }
                if (CurrentR.RawDataProcessing == true)
                {
                    data = new byte[0];
                    return(true);
                }

                switch (res)
                {
                case RESTStatus.Created:
                    response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
                    response.StatusCode        = 201;
                    response.StatusDescription = "Created";
                    if (CurrentR.ReturnValueName != "")
                    {
                        foreach (FieldInfo f in CurrentR.Method.DeclaringType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
                        {
                            VulpesRESTfulRet ret = f.GetCustomAttribute <VulpesRESTfulRet>();
                            if (ret != null)
                            {
                                if (ret.Name == CurrentR.ReturnValueName)
                                {
                                    data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(f.GetValue(instance)));
                                    break;
                                }
                            }
                        }
                    }
                    return(true);

                case RESTStatus.Fail:
                    response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
                    response.StatusCode        = 490;
                    response.StatusDescription = "Did not work";
                    if (CurrentR.ReturnValueName != "")
                    {
                        foreach (FieldInfo f in CurrentR.Method.DeclaringType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
                        {
                            VulpesRESTfulRet ret = f.GetCustomAttribute <VulpesRESTfulRet>();
                            if (ret != null)
                            {
                                if (ret.Name == CurrentR.ReturnValueName)
                                {
                                    data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(f.GetValue(instance)));
                                    break;
                                }
                            }
                        }
                    }
                    //if (data.Length == 0)
                    //    data = Encoding.UTF8.GetBytes("490 - Did not work.");
                    return(true);

                case RESTStatus.NoContent:
                    response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
                    response.StatusCode        = 204;
                    response.StatusDescription = "No Content";
                    return(true);

                case RESTStatus.NotFound:
                    response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
                    response.StatusCode        = 404;
                    response.StatusDescription = "Not found";
                    //data = Encoding.UTF8.GetBytes("404 - Not found.");
                    return(true);

                case RESTStatus.ServerError:
                    response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
                    response.StatusCode        = 500;
                    response.StatusDescription = "Server Error";
                    //data = Encoding.UTF8.GetBytes("500 - Server Error.");
                    return(true);

                case RESTStatus.Denied:
                    response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
                    response.StatusCode        = 403;
                    response.StatusDescription = "Forbidden";
                    //data = Encoding.UTF8.GetBytes("403 - Forbidden.");
                    return(true);

                case RESTStatus.Success:
                    if (CurrentR.ReturnValueName != "")
                    {
                        foreach (FieldInfo f in CurrentR.Method.DeclaringType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
                        {
                            VulpesRESTfulRet ret = f.GetCustomAttribute <VulpesRESTfulRet>();
                            if (ret != null)
                            {
                                if (ret.Name == CurrentR.ReturnValueName)
                                {
                                    data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(f.GetValue(instance)));
                                    break;
                                }
                            }
                        }
                    }
                    return(true);
                }
            }
            catch (Exception ee)
            {
                FoxEventLog.WriteEventLog("REST SEH: " + ee.ToString(), EventLogEntryType.Error);

                Debug.WriteLine(ee.ToString());
                try
                {
                    response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
                    response.StatusCode        = 500;
                    response.StatusDescription = "Server Error";
#if DEBUG
                    data = Encoding.UTF8.GetBytes("500 - Server Error. " + ee.ToString());
#else
                    //data = Encoding.UTF8.GetBytes("500 - Server Error.");
#endif
                }
                catch (Exception eee)
                {
                    Debug.WriteLine(eee.ToString());
                }
                return(true);
            }
            finally
            {
                if (data.Length > 0)
                {
                    response.ContentLength64 = data.LongLength;
                    Stream output = response.OutputStream;
                    output.Write(data, 0, data.Length);
                }
            }

            return(true);
        }