Example #1
0
        public bool FindService(ActionName wanted, string envelope, string ident, out ServiceInfo si, out ActionInfo ai)
        {
            lock (stateLock) {
                TimeCheck (DateTime.UtcNow);

                var cand = new List<ServiceInfo> ();
                foreach (var ssi in services.Values) {
                    if (ident != null && ident != ssi.Identity)
                        continue;
                    ActionInfo sai = ssi.LookupAction (wanted);
                    if (sai == null)
                        continue;

                    if (!auth.IsAuthorized (ssi, wanted))
                        continue;
                    if (!ssi.IsSignatureValid)
                        continue;
                    if (!ssi.Envelopes.Contains (envelope))
                        continue;

                    cand.Add (ssi);
                }

                si = null;
                ai = null;
                if (cand.Count == 0)
                    return false;

                si = cand [new Random ().Next (cand.Count)];
                ai = si.LookupAction (wanted);
                return true;
            }
        }
Example #2
0
        // the JS requestor uses a "forwardRequest" concept which is almost certainly a premature optimization and not duplicated here
        public static void MakeRequest(RequestLocalOptions opts, ActionName act, string envelope, Message req, Action<Message> on_rpy)
        {
            ServiceInfo si;
            ActionInfo ai;

            if (!discovery.FindService (act, envelope, opts.TargetIdent, out si, out ai)) {
                req.Discard ();
                Message.StreamToCallback (on_rpy, new RPCException ("transport", "Action {0} not found", act).AsHeader ());
                return;
            }

            // important: aliases are processed here
            req.Header ["action"] = ai.Name.Namespace + '.' + ai.Name.Name;
            req.Header ["version"] = (double)ai.Name.Version;

            SOAClient client;
            try {
                client = GetConnection (si);
            } catch (Exception ex) {
                RPCException rpcex = RPCException.Wrap (ex);
                req.Discard ();
                Message.StreamToCallback (on_rpy,
                    new RPCException ("transport", "Cannot establish connection", rpcex,
                        RPCException.DispatchFailure ()).AsHeader ());
                return;
            }

            if (opts.Timeout == 0)
                opts.Timeout = ai.Timeout;

            client.Request (opts, req, on_rpy);
        }
Example #3
0
 public static bool TryParse(string inp, out ActionName ret)
 {
     ret = null;
     int colon = inp.IndexOf (':');
     int tilde = inp.LastIndexOf ('~', inp.Length - 1, inp.Length - (colon + 1));
     if (tilde < 0)
         return false;
     int ldot = inp.LastIndexOf ('.', tilde - 1, tilde - (colon + 1));
     if (ldot < 0)
         return false;
     uint ver;
     if (!uint.TryParse (inp.Substring (tilde + 1), out ver))
         return false;
     if (ver == 0)
         return false;
     try {
         ret = new ActionName (colon >= 0 ? inp.Substring (0, colon) : "main",
             inp.Substring (colon + 1, ldot - (colon + 1)),
             inp.Substring (ldot + 1, tilde - (ldot + 1)),
             ver);
     } catch (Exception) {
         return false;
     }
     return true;
 }
Example #4
0
 public bool IsAuthorized(ServiceInfo inf, ActionName act)
 {
     var cert = inf.Certificate;
     if (cert == null)
         return false;
     Regex checker;
     if (!compiledAuth.TryGetValue (CryptoUtils.Fingerprint (cert), out checker))
         return false;
     return checker.IsMatch (act.Sector + ':' + act.Namespace + '.' + act.Name);
 }
Example #5
0
        public ActionInfo(ActionName name, string flagstr, object handler = null)
        {
            if (name == null)
                throw new ArgumentNullException ("name");
            if (flagstr == null)
                flagstr = "";

            Name = name;
            Handler = handler;
            FlagString = flagstr;
            ParseFlags (FlagString, out Flags, out Timeout);
        }
Example #6
0
        public static void MakeJsonRequest(ActionName act, JObject header, JObject payload, Action<RPCException, JObject> cb)
        {
            header = header ?? new JObject ();
            byte[] body;
            try {
                body = Encoding.UTF8.GetBytes (JSON.Stringify (payload));
            } catch (Exception ex) {
                cb (new RPCException ("transport", "cannot encode payload: {0}", ex), null);
                return;
            }

            Message m = new Message (header);
            MakeRequest (new RequestLocalOptions (), act, header ["envelope"].AsString ("json"), m, (resp) => {
                resp.Consume (10485760, (rpyheader, data, dlen, error) => {
                    if (error != null) {
                        cb (new RPCException ("transport", error), null);
                        return;
                    }

                    if (rpyheader ["error_code"].AsString(null) != null) {
                        cb (new RPCException (rpyheader), null);
                        return;
                    }

                    JObject res = null;
                    try {
                        res = JSON.Parse (Encoding.UTF8.GetString (data, 0, dlen)).AsObject ();
                    } catch (Exception) {
                    }

                    if (res == null) {
                        cb (new RPCException ("transport", "failed to parse JSON response"), null);
                        return;
                    }

                    cb (null, res);
                });
            });
            m.StreamData (body);
        }
Example #7
0
        public ActionInfo LookupAction(ActionName name)
        {
            ActionInfo ai;

            return(actionLookup.TryGetValue(name, out ai) ? ai : null);
        }
Example #8
0
 public ActionInfo(ActionName name, RPCActionFlags flags, int timeout, object handler)
     : this(name, UnparseFlags (flags, timeout), handler)
 {
 }
Example #9
0
        protected virtual void ScanType(List<ActionInfo> ail, Type type, List<Attribute> typePriv, string sector, string nspace, uint version)
        {
            foreach (var m in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) {
                var action_meta = (RPCAttribute)Attribute.GetCustomAttribute (m, typeof(RPCAttribute));
                if (action_meta == null)
                    continue;
                var action_priv = new List<Attribute> (Attribute.GetCustomAttributes (m, typeof(RPCPrivilegeRequiredAttribute)));
                action_priv.AddRange (typePriv);

                List<string> privs = new List<string> ();
                foreach (var pra in action_priv)
                    privs.Add ((pra as RPCPrivilegeRequiredAttribute).Privilege);

                uint ver = action_meta.Version != 0 ? action_meta.Version : version;
                ActionName an = new ActionName (sector, nspace, action_meta.Name ?? m.Name, ver);

                ActionInvokeDetails d = new ActionInvokeDetails {
                    PermissionDemand = privs.Count == 0 ? null : privs.ToArray (),
                };

                var dg = (Func<RPCRequestInfo, JObject, JObject>)
                    Delegate.CreateDelegate (typeof(Func<RPCRequestInfo, JObject, JObject>), m, false);
                if (dg != null) {
                    d.Handler = dg;
                } else {
                    throw new Exception (string.Format ("Method {0}.{1} is marked as an RPC but does not have the correct signature", type, m));
                }

                ail.Add (new ActionInfo (an, action_meta.Flags, action_meta.Timeout != 0 ? action_meta.Timeout : ActionInfo.DEFAULT_TIMEOUT, d));
            }
        }
Example #10
0
 public ActionInfo LookupAction(ActionName name)
 {
     ActionInfo ai;
     return actionLookup.TryGetValue (name, out ai) ? ai : null;
 }