public void Can_roundtrip_AtPath_via_GetRelativePathTo_with_trailing_slash_on_base() { var relative = "b/c"; var baseUri = new XUri("http://foo/a/"); var combined = baseUri.AtPath(relative); Assert.AreEqual(relative, combined.GetRelativePathTo(baseUri)); }
public void Can_roundtrip_GetRelativePathTo_via_AtPath_with_trailing_slash_on_uri() { var uri = new XUri("http://foo/a/b/c/"); var baseUri = new XUri("http://foo/a"); var relative = uri.GetRelativePathTo(baseUri); var roundtrip = baseUri.AtPath(relative); Assert.AreEqual(uri.ToString(), roundtrip.ToString()); }
public static string UriBuild( [DekiScriptParam("base uri")] XUri uri, [DekiScriptParam("path segments to append (must a string or list of strings)", true)] object path, [DekiScriptParam("query parameters to append", true)] Hashtable args ) { if (path is string) { uri = uri.AtPath((string)path); } else if (path is ArrayList) { foreach (string segment in (ArrayList)path) { uri = uri.At(XUri.EncodeSegment(segment)); } } if (args != null) { foreach (DictionaryEntry entry in args) { string key = (string)entry.Key; // remove existing parameter uri = uri.WithoutParams(key); // check if entry is a list of values if (entry.Value is ArrayList) { foreach (var value in (ArrayList)entry.Value) { uri = uri.With(key, SysUtil.ChangeType <string>(value)); } } else if (entry.Value != null) { uri = uri.With(key, SysUtil.ChangeType <string>(entry.Value)); } } } return(uri.ToString()); }
public void TestAppendPath4() { XUri uri = new XUri("http://www.dummy.com:8081/first/second?query=arg"); uri = uri.AtPath("foo/bar?q=a"); Assert.AreEqual("http://www.dummy.com:8081/first/second/foo/bar?query=arg&q=a", uri.ToString()); }
public void TestAppendPath2() { XUri uri = new XUri("http://www.dummy.com:8081/first/second"); uri = uri.AtPath("/foo/bar"); Assert.AreEqual("http://www.dummy.com:8081/first/second//foo/bar", uri.ToString()); }
private DekiScriptInvocationTargetDescriptor ConvertFunction(XDoc function) { string functionName = function["name"].AsText; if (string.IsNullOrEmpty(functionName)) { _log.WarnFormat("function without name in script {0}; skipping function definition", _manifestUri); return(null); } // determine function access level DreamAccess access; switch (function["access"].AsText ?? "public") { case "private": access = DreamAccess.Private; break; case "internal": access = DreamAccess.Internal; break; case "public": access = DreamAccess.Public; break; default: _log.WarnFormat("unrecognized access level '{0}' for function {1} in script {2}; defaulting to public", function["access"].AsText, functionName, _manifestUri); access = DreamAccess.Public; break; } // convert parameters List <DekiScriptParameter> parameters = new List <DekiScriptParameter>(); foreach (XDoc param in function["param"]) { string paramName = param["@name"].AsText; // determine if parameter has a default value string paramDefault = param["@default"].AsText; DekiScriptLiteral paramDefaultExpression = DekiScriptNil.Value; bool paramOptional = false; if (paramDefault != null) { paramOptional = true; try { paramDefaultExpression = ScriptRuntime.Evaluate(DekiScriptParser.Parse(Location.Start, paramDefault), DekiScriptEvalMode.Evaluate, ScriptRuntime.CreateEnv()); } catch (Exception e) { _log.ErrorExceptionFormat(e, "invalid default value for parameter {0} in function {1} in script {2}; skipping function definition", paramName, functionName, _manifestUri); return(null); } } else { paramOptional = (param["@optional"].AsText == "true"); } // determine parameter type string paramType = param["@type"].AsText ?? "any"; DekiScriptType paramScriptType; if (!SysUtil.TryParseEnum(paramType, out paramScriptType)) { _log.WarnFormat("unrecognized param type '{0}' for parameter {1} in function {2} in script {3}; defaulting to any", paramType, paramName, functionName, _manifestUri); paramScriptType = DekiScriptType.ANY; } // add parameter parameters.Add(new DekiScriptParameter(paramName, paramScriptType, paramOptional, param.Contents, typeof(object), paramDefaultExpression)); } var parameterArray = parameters.ToArray(); // determine function body XDoc ret = function["return"]; string src = ret["@src"].AsText; string type = ret["@type"].AsText; DekiScriptExpression expression; if (!string.IsNullOrEmpty(src)) { // 'src' attribute is set, load the script from it XDoc script; if (_manifestUri != null) { // check if uri is relative XUri scriptUri = XUri.TryParse(src) ?? _manifestUri.AtPath(src); script = Plug.New(scriptUri).Get().ToDocument(); } else { // check if filename is relative if (!Path.IsPathRooted(src)) { src = Path.Combine(_resourcesPath, src); } script = XDocFactory.LoadFrom(src, MimeType.XML); } expression = DekiScriptParser.Parse(script); type = type ?? "xml"; } else if (!ret["html"].IsEmpty) { // <return> element contains a <html> node; parse it as a script expression = DekiScriptParser.Parse(ret["html"]); type = type ?? "xml"; } else if (!ret.IsEmpty) { // <return> element contains something else; use the text contents as deki-script expression var location = new Location(string.Format("/function[name={0}]/return", functionName)); expression = DekiScriptParser.Parse(location, function["return"].AsText ?? string.Empty); expression = DekiScriptExpression.ReturnScope(location, expression); type = type ?? "any"; } else { _log.WarnFormat("function {0} has no body in script {1}; skipping function definition", functionName, _manifestUri); return(null); } // determine return type DekiScriptType returnScriptType; if (!SysUtil.TryParseEnum(type, out returnScriptType)) { _log.WarnFormat("unrecognized return type '{0}' for function {1} in script {2}; defaulting to any", type, functionName, _manifestUri); returnScriptType = DekiScriptType.ANY; } // create function descriptor var target = new DekiScriptScriptFunctionInvocationTarget(access, parameterArray, expression, _commonEnv, returnScriptType); string description = function["description"].AsText; string transform = function["@transform"].AsText; return(new DekiScriptInvocationTargetDescriptor(access, false, false, functionName, parameterArray, returnScriptType, description, transform, target)); }
/// <summary> /// Create a new host with provided configuration and an Inversion of Control container. /// </summary> /// <remarks> /// The IoC container is also injected into default activator, so that <see cref="IDreamService"/> instances /// can be resolved from the container. The host configuration is provided to the container as a typed parameter. /// </remarks> /// <param name="config">Host configuration.</param> /// <param name="container">IoC Container.</param> public DreamHost(XDoc config, IContainer container) { if (config == null) { throw new ArgumentNullException("config"); } // read host settings string appDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName); int limit = config["connect-limit"].AsInt ?? 0; int httpPort = config["http-port"].AsInt ?? DEFAULT_PORT; AuthenticationSchemes authenticationScheme = AuthenticationSchemes.Anonymous; string authShemes = config["authentication-shemes"].AsText; if (!String.IsNullOrEmpty(authShemes)) { try { authenticationScheme = (AuthenticationSchemes)Enum.Parse(typeof(AuthenticationSchemes), authShemes, true); } catch (Exception e) { _log.Warn(String.Format("invalid authetication scheme specified :{0}", authShemes), e); } } // get the authtoken for whitelisting dream.in.* query args _dreamInParamAuthtoken = config["dream.in.authtoken"].AsText; if (!string.IsNullOrEmpty(_dreamInParamAuthtoken)) { _log.Debug("Host is configured in dream.in param authorizing mode"); } // read ip-addresses var addresses = new List <string>(); foreach (XDoc ip in config["host|ip"]) { addresses.Add(ip.AsText); } if (addresses.Count == 0) { // if no addresses were supplied listen to all addresses.Add("*:" + httpPort); } // use default servername XUri publicUri = config["uri.public"].AsUri; if (publicUri == null) { // backwards compatibility publicUri = config["server-name"].AsUri; if (publicUri == null) { foreach (IPAddress addr in Dns.GetHostAddresses(Dns.GetHostName())) { if (addr.AddressFamily == AddressFamily.InterNetwork) { XUri.TryParse("http://" + addr, out publicUri); } } if (publicUri == null) { // failed to get an address out of dns, fall back to localhost XUri.TryParse("http://localhost", out publicUri); } } publicUri = publicUri.AtPath(config["server-path"].AsText ?? config["path-prefix"].AsText ?? string.Empty); } // create environment and initialize it _env = new DreamHostService(container); try { // initialize environment string apikey = config["apikey"].AsText ?? StringUtil.CreateAlphaNumericKey(32); XDoc serviceConfig = new XDoc("config"); var storageType = config["storage/@type"].AsText ?? "local"; if ("s3".EqualsInvariant(storageType)) { serviceConfig.Add(config["storage"]); } else { serviceConfig.Elem("storage-dir", config["storage-dir"].AsText ?? config["service-dir"].AsText ?? appDirectory); } serviceConfig.Elem("apikey", apikey); serviceConfig.Elem("uri.public", publicUri); serviceConfig.Elem("connect-limit", limit); serviceConfig.Elem("guid", config["guid"].AsText); serviceConfig.AddAll(config["components"]); var memorize = config["memorize-aliases"]; if (!memorize.IsEmpty) { serviceConfig.Elem("memorize-aliases", memorize.AsBool); } _env.Initialize(serviceConfig); // initialize host plug _host = _env.Self.With("apikey", apikey); // load assemblies in 'services' folder string servicesFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "services"); if (Directory.Exists(servicesFolder)) { // Note (arnec): Deprecated, but the suggested alternative really doesn't apply since we don't want to // load services into a separate appdomain. #pragma warning disable 618,612 AppDomain.CurrentDomain.AppendPrivatePath("services"); #pragma warning restore 618,612 foreach (string file in Directory.GetFiles(servicesFolder, "*.dll")) { // register assembly blueprints DreamMessage response = _host.At("load").With("name", Path.GetFileNameWithoutExtension(file)).Post(new Result <DreamMessage>(TimeSpan.MaxValue)).Wait(); if (!response.IsSuccessful) { _log.WarnFormat("DreamHost: ERROR: assembly '{0}' failed to load", file); } } } // add acccess-points AddListener(new XUri(String.Format("http://{0}:{1}/", "localhost", httpPort)), authenticationScheme); // check if user prescribed a set of IP addresses to use if (addresses != null) { // listen to custom addresses (don't use the supplied port info, we expect that to be part of the address) foreach (string address in addresses) { if (!StringUtil.EqualsInvariantIgnoreCase(address, "localhost")) { AddListener(new XUri(String.Format("http://{0}/", address)), authenticationScheme); } } } else { // add listeners for all known IP addresses foreach (IPAddress address in Dns.GetHostAddresses(Dns.GetHostName())) { XUri uri = MakeUri(address, httpPort); if (uri != null) { AddListener(uri, authenticationScheme); try { foreach (string alias in Dns.GetHostEntry(address).Aliases) { AddListener(new XUri(String.Format("http://{0}:{1}/", alias, httpPort)), authenticationScheme); } } catch { } } } } } catch (Exception e) { if ((e is HttpListenerException) && e.Message.EqualsInvariant("Access is denied")) { _log.ErrorExceptionMethodCall(e, "ctor", "insufficient privileges to create HttpListener, make sure the application runs with Administrator rights"); } else { _log.ErrorExceptionMethodCall(e, "ctor"); } try { _env.Deinitialize(); } catch { } throw; } }