Exemplo n.º 1
0
        internal async Task HandleAsync(string rsc, WebContext wc)
        {
            wc.Work = this;

            if (!DoAuthorize(wc, false))
            {
                throw new WebException("authorize failed: " + Name)
                      {
                          Code = wc.Principal == null ? 401 : 403
                      };
            }

            int slash = rsc.IndexOf('/');

            if (slash == -1) // this work is the target work
            {
                if (Before != null)
                {
                    if (Before.IsAsync && !await Before.DoAsync(wc) || !Before.IsAsync && Before.Do(wc))
                    {
                        return;
                    }
                }

                //
                // resolve the resource
                string name    = rsc;
                int    subscpt = 0;
                int    dash    = rsc.LastIndexOf('-');
                if (dash != -1)
                {
                    name         = rsc.Substring(0, dash);
                    wc.Subscript = subscpt = rsc.Substring(dash + 1).ToInt();
                }

                var act = this[name];
                if (act == null)
                {
                    wc.Give(404, "action not found", true, 30);
                    return;
                }

                wc.Action = act;

                if (!act.DoAuthorize(wc, false))
                {
                    throw new WebException("Do authorize failure: " + act.Name)
                          {
                              Code = wc.Principal == null ? 401 : 403
                          };
                }

                // try in the cache first
                if (!Service.TryGiveFromCache(wc))
                {
                    // invoke action method
                    if (act.IsAsync)
                    {
                        await act.DoAsync(wc, subscpt);
                    }
                    else
                    {
                        act.Do(wc, subscpt);
                    }

                    Service.TryAddForCache(wc);
                }

                wc.Action = null;

                if (After != null)
                {
                    if (After.IsAsync && !await After.DoAsync(wc) || !After.IsAsync && After.Do(wc))
                    {
                        return;
                    }
                }
            }
            else // sub works
            {
                string key = rsc.Substring(0, slash);
                var    wrk = GetSubWork(wc, key);
                if (wrk != null) // if child
                {
                    // do necessary authentication before entering
                    if (wc.Principal == null && !await wrk.DoAuthenticate(wc))
                    {
                        return;
                    }

                    wc.AppendSeg(wrk, key);
                    await wrk.HandleAsync(rsc.Substring(slash + 1), wc);
                }
                else if (varwork != null) // if variable-key subwork
                {
                    // do necessary authentication before entering
                    if (wc.Principal == null && !await varwork.DoAuthenticate(wc))
                    {
                        return;
                    }

                    var    prin = wc.Principal;
                    object accessor;
                    if (key.Length == 0)
                    {
                        if (prin == null)
                        {
                            throw AuthReq;
                        }
                        accessor = varwork.GetAccessor(prin, null);
                        if (accessor == null)
                        {
                            throw AccessorReq;
                        }
                    }
                    else
                    {
                        accessor = varwork.GetAccessor(prin, key);
                    }
                    // append the segment
                    wc.AppendSeg(varwork, key, accessor);
                    await varwork.HandleAsync(rsc.Substring(slash + 1), wc);
                }
            }
        }