/// <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)); }
//--- 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); } } }
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() )); }
/// <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); }
public object Invoke(DreamContext context, DreamMessage message, Result <DreamMessage> response) { return(_invocation(context, message, response)); }
private static object GetMessageResponse(DreamContext context, DreamMessage request, Result <DreamMessage> response) { return(response); }
private static object GetContextFeatureSubpathSegments(DreamContext context, DreamMessage request, Result <DreamMessage> response) { return(context.Uri.GetRelativePathTo(context.Feature.ServiceUri).Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries)); }
private static object GetContextFeatureSubpath(DreamContext context, DreamMessage request, Result <DreamMessage> response) { return(context.Uri.GetRelativePathTo(context.Feature.ServiceUri)); }
private static object GetContextUri(DreamContext context, DreamMessage request, Result <DreamMessage> response) { return(context.Uri); }
private static object GetRequestAsBytes(DreamContext context, DreamMessage request, Result <DreamMessage> response) { return(request.ToBytes()); }
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()); }
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; }
public virtual Yield GetServiceBlueprint(DreamContext context, DreamMessage request, Result <DreamMessage> response) { response.Return(DreamMessage.Ok(Blueprint)); yield break; }
private Yield InServiceInvokeHandler(DreamContext context, DreamMessage request, Result <DreamMessage> response) { throw new InvalidOperationException("this feature should never be invoked"); }