Example #1
0
        /// <summary>
        /// Determine the access appropriate for an incoming request.
        /// </summary>
        /// <param name="context">Request context.</param>
        /// <param name="request">Request message.</param>
        /// <returns>Access level for request.</returns>
        public virtual DreamAccess DetermineAccess(DreamContext context, DreamMessage request)
        {
            DreamMessage message = request;

            // check if request has a service or api key
            string key = DreamContext.Current.Uri.GetParam("apikey", null);

            if (key == null)
            {
                DreamCookie cookie = DreamCookie.GetCookie(message.Cookies, "service-key");
                if (cookie != null)
                {
                    key = cookie.Value;
                }
            }
            return(DetermineAccess(context, key));
        }
Example #2
0
        //--- Methods ---

        /// <summary>
        /// Invoke the stage method.
        /// </summary>
        /// <param name="context"><see cref="DreamContext"/> for invocation.</param>
        /// <param name="request"><see cref="DreamMessage"/> for invocation.</param>
        /// <param name="response"><see cref="Result{DreamMessage}"/> for invocations.</param>
        public void Invoke(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            if (_handler != null)
            {
                Coroutine.Invoke(_handler, context, request, response);
            }
            else
            {
                try {
                    // build parameter list
                    var arguments = new object[_plan.Count];
                    for (var i = 0; i < _plan.Count; ++i)
                    {
                        try {
                            arguments[i] = _plan[i].Invoke(context, request, response);
                        } catch (DreamException) {
                            throw;
                        } catch (Exception e) {
                            throw new FeatureArgumentParseException(_plan[i].ArgumentName, e);
                        }
                    }

                    // invoke method
                    if (_method.ReturnType == typeof(Yield))
                    {
                        // invoke method as coroutine
                        new Coroutine(_method, response).Invoke(() => (Yield)_method.InvokeWithRethrow(_service, arguments));
                    }
                    else if (_method.ReturnType == typeof(XDoc))
                    {
                        // invoke method to get XDoc response (always an Ok)
                        var doc = _method.InvokeWithRethrow(_service, arguments) as XDoc;
                        response.Return(DreamMessage.Ok(doc));
                    }
                    else
                    {
                        response.Return((DreamMessage)_method.InvokeWithRethrow(_service, arguments));
                    }
                } catch (Exception e) {
                    response.Throw(e);
                }
            }
        }
Example #3
0
        protected virtual Yield PutConfig(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            XDoc config = request.ToDocument();

            if (config.Name != "config")
            {
                throw new DreamBadRequestException("bad document type");
            }
            if (IsStarted)
            {
                throw new DreamBadRequestException("service must be stopped first");
            }
            _timerFactory = TaskTimerFactory.Create(this);

            // configure service container
            var components       = config["components"];
            var servicecontainer = _env.CreateServiceContainer(this);
            var builder          = new ContainerBuilder();

            builder.Register(_timerFactory).ExternallyOwned();
            if (!components.IsEmpty)
            {
                _log.Debug("registering service level module");
                builder.RegisterModule(new XDocAutofacContainerConfigurator(components, DreamContainerScope.Service));
            }
            builder.Build(servicecontainer);

            // call container-less start (which contains shared start logic)
            yield return(Coroutine.Invoke(Start, request.ToDocument(), new Result()));

            // call start with container for sub-classes that want to resolve instances at service start
            yield return(Coroutine.Invoke(Start, config, servicecontainer, new Result()));

            response.Return(DreamMessage.Ok(new XDoc("service-info")
                                            .Start("private-key")
                                            .Add(DreamCookie.NewSetCookie("service-key", PrivateAccessKey, Self.Uri).AsSetCookieDocument)
                                            .End()
                                            .Start("internal-key")
                                            .Add(DreamCookie.NewSetCookie("service-key", InternalAccessKey, Self.Uri).AsSetCookieDocument)
                                            .End()
                                            ));
        }
Example #4
0
 /// <summary>
 /// Provides a hook for overriding what access level the current request should be granted.
 /// </summary>
 /// <param name="context">Request context.</param>
 /// <param name="key">Authorization key of request.</param>
 /// <returns>Access level granted to the request.</returns>
 protected virtual DreamAccess DetermineAccess(DreamContext context, string key)
 {
     if (_env.IsDebugEnv)
     {
         return(DreamAccess.Private);
     }
     if (!string.IsNullOrEmpty(key) && (key.EqualsInvariant(_apikey)))
     {
         return(DreamAccess.Private);
     }
     if (key == InternalAccessKey)
     {
         return(DreamAccess.Internal);
     }
     if (key == PrivateAccessKey)
     {
         return(DreamAccess.Private);
     }
     return(DreamAccess.Public);
 }
Example #5
0
 public object Invoke(DreamContext context, DreamMessage message, Result <DreamMessage> response)
 {
     return(_invocation(context, message, response));
 }
Example #6
0
 private static object GetMessageResponse(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     return(response);
 }
Example #7
0
 private static object GetContextFeatureSubpathSegments(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     return(context.Uri.GetRelativePathTo(context.Feature.ServiceUri).Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries));
 }
Example #8
0
 private static object GetContextFeatureSubpath(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     return(context.Uri.GetRelativePathTo(context.Feature.ServiceUri));
 }
Example #9
0
 private static object GetContextUri(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     return(context.Uri);
 }
Example #10
0
 private static object GetRequestAsBytes(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     return(request.ToBytes());
 }
Example #11
0
        protected virtual Yield DeleteService(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            yield return(Env.At("stop").Post(new XDoc("service").Elem("uri", Self), new Result <DreamMessage>(TimeSpan.MaxValue)).CatchAndLog(_log));

            response.Return(DreamMessage.Ok());
        }
Example #12
0
        public virtual Yield GetServiceInfo(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            XDoc   blueprint = Blueprint;
            string title     = blueprint["name"].AsText ?? "Service Blueprint";
            XDoc   result    = new XDoc("html").Attr("xmlns", "http://www.w3.org/1999/xhtml")
                               .Start("head")
                               .Elem("title", title)
                               .Start("meta").Attr("http-equiv", "content-type").Attr("content", "text/html;charset=utf-8").End()
                               .Start("meta").Attr("http-equiv", "Content-Style-Type").Attr("content", "text/css").End()
                               .End();

            if (blueprint.IsEmpty)
            {
                result.Elem("body", "Missing service blueprint");
            }
            else
            {
                result.Start("body")
                .Elem("h1", title)
                .Start("p")
                .Value(blueprint["copyright"].Contents)
                .Value(" ")
                .Start("a").Attr("href", blueprint["info"].Contents).Value("(more)").End()
                .Value(" ")
                .Start("a").Attr("href", Self.Uri.At("@blueprint").Path).Value("(blueprint)").End()
                .End();

                // show configuration information
                XDoc config = blueprint["configuration"];
                if (!config.IsEmpty)
                {
                    result.Elem("h2", "Configuration");
                    result.Start("ul");
                    foreach (XDoc entry in config["entry"])
                    {
                        result.Start("li");
                        if (entry["valuetype"].Contents != string.Empty)
                        {
                            result.Value(string.Format("{0} = {1} : {2}", entry["name"].Contents, entry["valuetype"].Contents, entry["description"].Contents));
                        }
                        else
                        {
                            result.Value(string.Format("{0} : {1}", entry["name"].Contents, entry["description"].Contents));
                        }
                        result.End();
                    }
                    result.End();
                }

                // sort features by signature then verb
                blueprint["features"].Sort(delegate(XDoc first, XDoc second) {
                    string[] firstPattern  = first["pattern"].Contents.Split(new[] { ':' }, 2);
                    string[] secondPattern = second["pattern"].Contents.Split(new[] { ':' }, 2);
                    int cmp = firstPattern[1].CompareInvariantIgnoreCase(secondPattern[1]);
                    if (cmp != 0)
                    {
                        return(cmp);
                    }
                    return(firstPattern[0].CompareInvariant(secondPattern[0]));
                });

                // display features
                XDoc features = blueprint["features/feature"];
                if (!features.IsEmpty)
                {
                    result.Elem("h2", "Features");
                    List <string> modifiers = new List <string>();
                    foreach (XDoc feature in features)
                    {
                        modifiers.Clear();

                        // add modifiers
                        string modifier = feature["access"].AsText;
                        if (modifier != null)
                        {
                            modifiers.Add(modifier);
                        }
                        modifier = feature["obsolete"].AsText;
                        if (modifier != null)
                        {
                            modifiers.Add("OBSOLETE => " + modifier);
                        }
                        if (modifiers.Count > 0)
                        {
                            modifier = " (" + string.Join(", ", modifiers.ToArray()) + ")";
                        }
                        else
                        {
                            modifier = string.Empty;
                        }

                        // check if feature has GET verb and no path parameters
                        string pattern = feature["pattern"].Contents;
                        if (pattern.StartsWithInvariantIgnoreCase(Verb.GET + ":") && (pattern.IndexOfAny(new[] { '{', '*', '?' }) == -1))
                        {
                            string[] parts = pattern.Split(new[] { ':' }, 2);
                            result.Start("h3")
                            .Start("a").Attr("href", context.AsPublicUri(Self.Uri.AtPath(parts[1])))
                            .Value(feature["pattern"].Contents)
                            .End()
                            .Value(modifier)
                            .End();
                        }
                        else
                        {
                            result.Elem("h3", feature["pattern"].Contents + modifier);
                        }
                        result.Start("p")
                        .Value(feature["description"].Contents)
                        .Value(" ")
                        .Start("a").Attr("href", feature["info"].Contents).Value("(more)").End();
                        XDoc paramlist = feature["param"];
                        if (!paramlist.IsEmpty)
                        {
                            result.Start("ul");
                            foreach (XDoc param in paramlist)
                            {
                                result.Start("li");
                                if (param["valuetype"].Contents != string.Empty)
                                {
                                    result.Value(string.Format("{0} = {1} : {2}", param["name"].Contents, param["valuetype"].Contents, param["description"].Contents));
                                }
                                else
                                {
                                    result.Value(string.Format("{0} : {1}", param["name"].Contents, param["description"].Contents));
                                }
                                result.End();
                            }
                            result.End();
                        }
                        result.End();
                    }
                }
            }
            response.Return(DreamMessage.Ok(MimeType.HTML, result.ToString()));
            yield break;
        }
Example #13
0
 public virtual Yield GetServiceBlueprint(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     response.Return(DreamMessage.Ok(Blueprint));
     yield break;
 }
Example #14
0
 private Yield InServiceInvokeHandler(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     throw new InvalidOperationException("this feature should never be invoked");
 }