Exemplo n.º 1
0
        /// <summary>
        /// To hndle a request/response context. authorize, before/after filters
        /// </summary>
        /// <param name="rsc">the resource path</param>
        /// <param name="ac">ActionContext</param>
        /// <exception cref="AuthorizeException">Thrown when authorization is required and false is returned by checking</exception>
        /// <seealso cref="AuthorizeAttribute.Check"/>
        internal async Task HandleAsync(string rsc, ActionContext ac)
        {
            ac.Work = this;

            // authorize and filters
            if (!DoAuthorize(ac))
            {
                throw AuthorizeEx;
            }
            Before?.Do(ac);
            if (BeforeAsync != null)
            {
                await BeforeAsync.DoAsync(ac);
            }

            int dot = rsc.LastIndexOf('.');

            if (dot != -1) // file
            {
                // try in cache
                if (!Service.TryGiveFromCache(ac))
                {
                    DoFile(rsc, rsc.Substring(dot), ac);
                    Service.Cache(ac); // try cache it
                }
            }
            else // action
            {
                string name    = rsc;
                int    subscpt = 0;
                int    dash    = rsc.LastIndexOf('-');
                if (dash != -1)
                {
                    name         = rsc.Substring(0, dash);
                    ac.Subscript = subscpt = rsc.Substring(dash + 1).ToInt();
                }
                ActionInfo ai = string.IsNullOrEmpty(name) ? @default : GetAction(name);
                if (ai == null)
                {
                    ac.Give(404); // not found
                    return;
                }

                ac.Doer = ai;

                // action's authorization check
                if (!ai.DoAuthorize(ac))
                {
                    throw AuthorizeEx;
                }

                // action's before filtering
                ai.Before?.Do(ac);
                if (ai.BeforeAsync != null)
                {
                    await ai.BeforeAsync.DoAsync(ac);
                }

                // try in cache
                if (!Service.TryGiveFromCache(ac))
                {
                    // method invocation
                    if (ai.IsAsync)
                    {
                        await ai.DoAsync(ac, subscpt); // invoke action method
                    }
                    else
                    {
                        ai.Do(ac, subscpt);
                    }
                    Service.Cache(ac); // try cache it
                }

                // action's after filtering
                ai.After?.Do(ac);
                if (ai.AfterAsync != null)
                {
                    await ai.AfterAsync.DoAsync(ac);
                }

                ac.Doer = null;
            }

            After?.Do(ac);
            if (AfterAsync != null)
            {
                await AfterAsync.DoAsync(ac);
            }

            ac.Work = null;
        }
Exemplo n.º 2
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);
                }
            }
        }