예제 #1
0
 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));
 }
예제 #2
0
 public void Can_roundtrip_DispatchItem_with_complex_event()
 {
     var body = new XDoc("msg").Elem("foo", "bar");
     var channel = new XUri("channel://foo.com/bar");
     var resource = new XUri("http://foo.com/baz/0");
     var origin1 = new XUri("http://foo.com/baz/1");
     var origin2 = new XUri("http://foo.com/baz/2");
     var recipient1 = new DispatcherRecipient(new XUri("http://recipient1"));
     var recipient2 = new DispatcherRecipient(new XUri("http://recipient2"));
     var via1 = new XUri("http://via1");
     var via2 = new XUri("http://via2");
     var ev = new DispatcherEvent(body, channel, resource, origin1, origin2);
     ev = ev.WithRecipient(false, recipient1, recipient2).WithVia(via1).WithVia(via2);
     var item = new DispatchItem(
         new XUri("http://foo"),
         ev,
         "abc"
     );
     var serializer = new DispatchItemSerializer();
     var stream = serializer.ToStream(item);
     var item2 = serializer.FromStream(stream);
     Assert.AreEqual(item.Uri, item2.Uri, "uri mismatch");
     Assert.AreEqual(item.Location, item2.Location, "location mismatch");
     Assert.AreEqual(item.Event.Id, item2.Event.Id, "id mismatch");
     Assert.AreEqual(body.ToCompactString(), item2.Event.AsDocument().ToCompactString(), "body mismatch");
     Assert.AreEqual(channel, item2.Event.Channel, "channel mismatch");
     Assert.AreEqual(resource, item2.Event.Resource, "resource mismatch");
     Assert.AreEqual(origin1, item2.Event.Origins[0], "first origin mismatch");
     Assert.AreEqual(origin2, item2.Event.Origins[1], "second origin mismatch");
     Assert.AreEqual(recipient1.Uri, item2.Event.Recipients[0].Uri, "first recipient mismatch");
     Assert.AreEqual(recipient2.Uri, item2.Event.Recipients[1].Uri, "second recipient mismatch");
     Assert.AreEqual(via1, item2.Event.Via[0], "first via mismatch");
     Assert.AreEqual(via2, item2.Event.Via[1], "second via mismatch");
 }
예제 #3
0
 public void Deregister(XUri uri)
 {
     lock(_registry) {
         if(!_registry.ContainsKey(uri)) {
             return;
         }
         _registry.Remove(uri);
         _map.Remove(uri);
     }
 }
예제 #4
0
 public void Exact_Match()
 {
     XUriMap<string> map = new XUriMap<string>();
     string key = "foo/bar";
     map[new XUri("test://foo/bar")] = key;
     string match;
     int similarity;
     XUri test = new XUri("test://foo/bar");
     map.TryGetValue(test, out match, out similarity);
     Assert.AreEqual(key, match);
     Assert.AreEqual(test.MaxSimilarity, similarity);
 }
예제 #5
0
 //--- Constructors ---
 public HttpTransport(IDreamEnvironment env, XUri uri, AuthenticationSchemes authenticationSheme)
 {
     if(env == null) {
         throw new ArgumentNullException("env");
     }
     if(uri == null) {
         throw new ArgumentNullException("uri");
     }
     _env = env;
     _uri = uri.WithoutCredentialsPathQueryFragment();
     _minSimilarity = _uri.MaxSimilarity;
     _sourceInternal = _uri + " (internal)";
     _sourceExternal = _uri.ToString();
     _authenticationSheme = authenticationSheme;
 }
예제 #6
0
 //--- Constructors ---
 public HttpTransport(IDreamEnvironment env, XUri uri, AuthenticationSchemes authenticationSheme, string dreamInParamAuthtoken)
 {
     if(env == null) {
         throw new ArgumentNullException("env");
     }
     if(uri == null) {
         throw new ArgumentNullException("uri");
     }
     _env = env;
     _uri = uri.WithoutCredentialsPathQueryFragment();
     _minSimilarity = _uri.MaxSimilarity;
     _sourceInternal = _uri + " (internal)";
     _sourceExternal = _uri.ToString();
     _authenticationSheme = authenticationSheme;
     _dreamInParamAuthtoken = dreamInParamAuthtoken;
     this.ServerSignature = "Dream-HTTPAPI/" + DreamUtil.DreamVersion;
 }
예제 #7
0
 //--- Methods ---
 public int GetScoreWithNormalizedUri(XUri uri, out XUri normalized)
 {
     normalized = uri;
     switch(uri.Scheme.ToLowerInvariant()) {
     case "http":
     case "https":
         return 1;
     case "ext-http":
         normalized = normalized.WithScheme("http");
         return int.MaxValue;
     case "ext-https":
         normalized = normalized.WithScheme("https");
         return int.MaxValue;
     default:
         return 0;
     }
 }
예제 #8
0
 public void Can_roundtrip_DispatchItem()
 {
     var msg = new XDoc("msg");
     var channel = new XUri("channel://foo.com/bar");
     var origin = new XUri("http://foo.com/baz");
     var ev = new DispatcherEvent(msg, channel, origin);
     var item = new DispatchItem(
         new XUri("http://foo"),
         ev,
         "abc"
     );
     var serializer = new DispatchItemSerializer();
     var stream = serializer.ToStream(item);
     var item2 = serializer.FromStream(stream);
     Assert.AreEqual(item.Uri, item2.Uri, "uri mismatch");
     Assert.AreEqual(item.Location, item2.Location, "location mismatch");
     Assert.AreEqual(item.Event.Id, item2.Event.Id, "id mismatch");
 }
예제 #9
0
파일: EventTests.cs 프로젝트: sdether/DReAM
 public void Add_via_to_event()
 {
     XDoc msg = new XDoc("msg");
     XUri via1 = new XUri("http://foo.com/route1");
     XUri via2 = new XUri("http://foo.com/route2");
     DispatcherEvent ev1 = new DispatcherEvent(msg, new XUri("channel://foo.com/bar"), new XUri("http://foo.com/baz"));
     DispatcherEvent ev2 = ev1.WithVia(via1);
     Assert.AreEqual(0, ev1.Via.Length);
     Assert.AreEqual(1, ev2.Via.Length);
     Assert.AreEqual(via1, ev2.Via[0]);
     DispatcherEvent ev3 = ev2.WithVia(via2);
     Assert.AreEqual(2, ev3.Via.Length);
     Assert.AreEqual(via1, ev3.Via[0]);
     Assert.AreEqual(via2, ev3.Via[1]);
     DreamMessage ev3msg = ev3.AsMessage();
     Assert.AreEqual(msg, ev3msg.ToDocument());
     Assert.AreEqual(ev1.Id, ev3.Id);
     Assert.AreEqual("channel://foo.com/bar", ev3msg.Headers.DreamEventChannel);
     Assert.AreEqual("http://foo.com/baz", ev3msg.Headers.DreamEventOrigin[0]);
     Assert.AreEqual(via1.ToString(), ev3msg.Headers.DreamEventVia[0]);
 }
예제 #10
0
        public void Adding_new_sub_will_push_combined_set_to_upstream_subscriber()
        {
            var downstream = CreatePubSubService().WithInternalKey().AtLocalHost;
            var upstreamUri = new XUri("http://upstream/");
            var upstreamMock = MockPlug.Register(upstreamUri);
            XDoc downstreamSet = null;
            upstreamMock.Expect().Verb("POST").RequestDocument(_ => {
                downstreamSet = _;
                return true;
            }).Response(DreamMessage.Ok());
            var subscribeToDownstream = new XDoc("subscription-set")
                .Elem("uri.owner", upstreamUri)
                .Start("subscription")
                    .Attr("id", "1")
                    .Elem("channel", "pubsub://*/*")
                    .Start("recipient").Elem("uri", upstreamUri).End()
                .End();

            // subscribe to set updates from downstream, expect most recent version to be pushed
            var downstreamResponse = downstream.At("subscribers").PostAsync(subscribeToDownstream).Wait();
            Assert.IsTrue(downstreamResponse.IsSuccessful, downstreamResponse.ToText());
            Assert.IsTrue(upstreamMock.WaitAndVerify(TimeSpan.FromSeconds(10)), upstreamMock.VerificationFailure);

            // someone else posts a subscription, expect a new push including that sub
            upstreamMock.Expect().Verb("POST").RequestDocument(_ => {
                downstreamSet = _;
                return true;
            }).Response(DreamMessage.Ok());
            var subscription = new XDoc("subscription-set")
                .Elem("uri.owner", "http://foo/")
                .Start("subscription")
                    .Attr("id", "1")
                    .Elem("channel", "foo://bar/baz")
                    .Start("recipient").Elem("uri", "http://foo/bar").End()
                .End();
            var subResponse = downstream.At("subscribers").PostAsync(subscription).Wait();
            Assert.IsTrue(subResponse.IsSuccessful, subResponse.ToText());
            Assert.IsTrue(upstreamMock.WaitAndVerify(TimeSpan.FromSeconds(10)), upstreamMock.VerificationFailure);
            Assert.AreEqual(1, downstreamSet["subscription[channel='foo://bar/baz']"].ListLength);
        }
예제 #11
0
        public Yield convert(DreamContext context, DreamMessage request, Result<DreamMessage> response)
        {
            string methodStr = context.GetParam("method", string.Empty);
            string aliasStr = context.GetParam("id", string.Empty);

            XUri secPage = new XUri( context.ServerUri ).At( "deki", "pages", "=Convert:" + methodStr );
            Plug _dekiSec = Plug.New( secPage );
            XDoc secDoc = _dekiSec.Get().ToDocument();

            string userURL = secDoc["user.author/@href"].AsInnerText;
            Plug _dekiUser = Plug.New( userURL );
            XDoc userDoc = _dekiUser.Get().ToDocument();
            string perms = userDoc["permissions.user"]["operations"].AsInnerText;
            if ( !perms.Contains("UNSAFECONTENT") ) {
                response.Return( DreamMessage.Forbidden("UNSAFECONTENT not enabled") );
                yield break;
            }

            XUri codePage = new XUri( context.ServerUri ).At( "deki","pages", "=Convert:" + methodStr,"contents");
            Plug _deki = Plug.New( codePage, new TimeSpan(0,0,15) );
            string bodyText = _deki.With("format", "xhtml").Get().ToDocument()["body"]["pre"].Contents;

            for ( int i = 0; i < toHTML.GetLength(0); i++ ) {
                bodyText = Regex.Replace( bodyText, toHTML[i,0], toHTML[i,1] );
            }
            //string codeStr = HttpUtility.HtmlDecode( bodyText );
            //XDoc doc = XDocFactory.From( codeStr, MimeType.ANY );
            //response.Return( DreamMessage.Ok( MimeType.TEXT, bodyText ) );

            Assembly scriptCode = CompileCode( bodyText, response );
            if ( scriptCode != null ) {
                XmlDocument outDoc = runScript( scriptCode, aliasStr );
                response.Return( DreamMessage.Ok( MimeType.XML, new XDoc(outDoc) ) );
            }
            yield break;
        }
예제 #12
0
 public IEnumerator<IYield> Invoke(Plug plug, string verb, XUri uri, DreamMessage request, Result<DreamMessage> response)
 {
     var match = GetBestMatch(uri);
     yield return AsyncUtil.Fork(() => match.Invoke(plug, verb, uri,  MemorizeAndClone(request), response), new Result(TimeSpan.MaxValue));
 }
예제 #13
0
 public void EncodeFragment()
 {
     Assert.AreEqual("a^b|c#d", XUri.EncodeFragment("a^b|c#d"));
 }
예제 #14
0
 public void TestGethashcodeWithNullQueryParam()
 {
     XUri uri      = new XUri("http://foobar").With("abc", null);
     int  hashcode = uri.GetHashCode();
 }
예제 #15
0
 public void TestTryParse()
 {
     Assert.IsFalse(XUri.TryParse("htt;//") != null);
 }
예제 #16
0
 public void EncodeQuery()
 {
     Assert.AreEqual("a^b|c", XUri.EncodeQuery("a^b|c"));
 }
예제 #17
0
        public void Windows_drive_file_path_uri_with_backslashes()
        {
            XUri uri = new XUri(@"file:///c:\temp\foo.txt");

            Assert.AreEqual(@"file:///c:/temp/foo.txt", uri.ToString());
        }
예제 #18
0
        //--- Constructors ---

        /// <summary>
        /// Create new handler instance
        /// </summary>
        public HttpHandler()
        {
            if (_env == null)
            {
                lock (SyncRoot) {
                    if (_env == null)
                    {
                        _log.InfoMethodCall("Startup");
                        try {
                            _log.InfoMethodCall("ctor: initializing HttpHandler");
                            NameValueCollection settings = System.Configuration.ConfigurationManager.AppSettings;

                            // determine storage locations
                            string basePath    = HttpContext.Current.ApplicationInstance.Server.MapPath("~");
                            string storagePath = settings["storage-dir"] ?? settings["service-dir"];
                            if (string.IsNullOrEmpty(storagePath))
                            {
                                storagePath = Path.Combine(basePath, "storage");
                            }
                            else if (!Path.IsPathRooted(storagePath))
                            {
                                storagePath = Path.Combine(basePath, storagePath);
                            }

                            // read configuration
                            string apikey = settings["apikey"];
                            _uri           = new XUri(settings["public-uri"] ?? settings["root-uri"] ?? "http://localhost/@api");
                            _minSimilarity = _uri.MaxSimilarity;

                            // start dreamhost
                            XDoc config = new XDoc("config")
                                          .Elem("guid", settings["guid"])
                                          .Elem("uri.public", _uri.ToString())
                                          .Elem("storage-dir", storagePath)
                                          .Elem("host-path", settings["host-path"])
                                          .Elem("connect-limit", settings["connect-limit"])
                                          .Elem("apikey", apikey);
                            IDreamEnvironment env = new DreamHostService();
                            env.Initialize(config);

                            // load assemblies in 'services' folder
                            string servicesFolder = settings["service-dir"] ?? Path.Combine("bin", "services");
                            if (!Path.IsPathRooted(servicesFolder))
                            {
                                servicesFolder = Path.Combine(basePath, servicesFolder);
                            }
                            _log.DebugFormat("examining services directory '{0}'", servicesFolder);
                            if (Directory.Exists(servicesFolder))
                            {
                                Plug host = env.Self.With("apikey", apikey);
                                foreach (string file in Directory.GetFiles(servicesFolder, "*.dll"))
                                {
                                    string assembly = Path.GetFileNameWithoutExtension(file);
                                    _log.DebugFormat("attempting to load '{0}'", assembly);

                                    // register assembly blueprints
                                    DreamMessage response = host.At("load").With("name", assembly).Post(new Result <DreamMessage>(TimeSpan.MaxValue)).Wait();
                                    if (!response.IsSuccessful)
                                    {
                                        _log.WarnFormat("DreamHost: ERROR: assembly '{0}' failed to load", file);
                                    }
                                }
                            }
                            else
                            {
                                _log.WarnFormat("DreamHost: WARN: no services directory '{0}'", servicesFolder);
                            }


                            // execute script
                            string scriptFilename = settings["script"];
                            if (!string.IsNullOrEmpty(scriptFilename))
                            {
                                string filename = scriptFilename;
                                if (!Path.IsPathRooted(filename))
                                {
                                    filename = Path.Combine(basePath, filename);
                                }

                                // execute xml script file
                                XDoc script = XDocFactory.LoadFrom(filename, MimeType.XML);
                                Plug host   = env.Self.With("apikey", apikey);
                                host.At("execute").Post(script);
                            }

                            // register plug factory for this uri
                            Plug.AddEndpoint(this);

                            // set _env variable so other constructors don't initialize it anymore
                            _env = env;
                        } catch (Exception e) {
                            _log.ErrorExceptionMethodCall(e, "ctor");
                            throw;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Perform startup configuration of a service instance.
        /// </summary>
        /// <remarks>
        /// Should not be manually invoked and should only be overridden if <see cref="Start(MindTouch.Xml.XDoc,Autofac.IContainer,MindTouch.Tasking.Result)"/> isn't already overriden.
        /// </remarks>
        /// <param name="config">Service configuration.</param>
        /// <param name="result">Synchronization handle for coroutine invocation.</param>
        /// <returns>Iterator used by <see cref="Coroutine"/> execution environment.</returns>
        protected virtual Yield Start(XDoc config, Result result)
        {
            Result <DreamMessage> res;

            // store configuration and uri
            _config = config;
            _self   = Plug.New(config["uri.self"].AsUri);
            if (_self == null)
            {
                throw new ArgumentNullException("uri.self");
            }
            _owner = Plug.New(config["uri.owner"].AsUri);

            // check for api-key settings
            _apikey = config["apikey"].AsText;

            // process 'set-cookie' entries
            List <DreamCookie> setCookies = DreamCookie.ParseAllSetCookieNodes(config["set-cookie"]);

            if (setCookies.Count > 0)
            {
                Cookies.Update(setCookies, null);
            }

            // grant private access key to self, host, and owner
            //string privateAcccessCookie = HttpUtil.RenderSetCookieHeader(HttpUtil.SetCookie("service-key", PrivateAccessKey, Self.Uri.Path, Self.Uri.Host, DateTime.MaxValue));
            //Cookies.Update(HttpUtil.ParseSetCookieHeader(privateAcccessCookie), null);
            DreamCookie privateAcccessCookie = DreamCookie.NewSetCookie("service-key", PrivateAccessKey, Self.Uri);

            Cookies.Update(privateAcccessCookie, null);
            yield return(Env.At("@grants").Post(DreamMessage.Ok(privateAcccessCookie.AsSetCookieDocument), new Result <DreamMessage>(TimeSpan.MaxValue)));

            if (Owner != null)
            {
                yield return(res = Owner.At("@grants").Post(DreamMessage.Ok(privateAcccessCookie.AsSetCookieDocument), new Result <DreamMessage>(TimeSpan.MaxValue)));

                if (!res.Value.IsSuccessful)
                {
                    throw new ArgumentException("unexpected failure setting grants on owner service");
                }
            }

            // check if this service requires a service-license to work
            if (this is IDreamServiceLicense)
            {
                string service_license = config["service-license"].AsText;
                if (string.IsNullOrEmpty(service_license))
                {
                    throw new DreamAbortException(DreamMessage.LicenseRequired("service-license missing"));
                }

                // extract public RSA key for validation
                RSACryptoServiceProvider public_key = RSAUtil.ProviderFrom(GetType().Assembly);
                if (public_key == null)
                {
                    throw new DreamAbortException(DreamMessage.InternalError("service assembly invalid"));
                }

                // validate the service-license
                _license = null;
                Dictionary <string, string> values;
                try {
                    // parse service-license
                    values = HttpUtil.ParseNameValuePairs(service_license);
                    if (!Encoding.UTF8.GetBytes(service_license.Substring(0, service_license.LastIndexOf(','))).VerifySignature(values["dsig"], public_key))
                    {
                        throw new DreamAbortException(DreamMessage.InternalError("invalid service-license (1)"));
                    }

                    // check if the SID matches
                    string sid;
                    if (!values.TryGetValue("sid", out sid) || !SID.HasPrefix(XUri.TryParse(sid), true))
                    {
                        throw new DreamAbortException(DreamMessage.InternalError("invalid service-license (2)"));
                    }
                    _license = service_license;
                } catch (Exception e) {
                    // unexpected error, blame it on the license
                    if (e is DreamAbortException)
                    {
                        throw;
                    }
                    throw new DreamAbortException(DreamMessage.InternalError("corrupt service-license (1)"));
                }

                // validate expiration date
                string expirationtext;
                if (values.TryGetValue("expire", out expirationtext))
                {
                    try {
                        DateTime expiration = DateTime.Parse(expirationtext);
                        if (expiration < DateTime.UtcNow)
                        {
                            _license = null;
                        }
                    } catch (Exception e) {
                        _license = null;

                        // unexpected error, blame it on the license
                        if (e is DreamAbortException)
                        {
                            throw;
                        }
                        throw new DreamAbortException(DreamMessage.InternalError("corrupt service-license (2)"));
                    }
                }

                // check if a license was assigned
                if (_license == null)
                {
                    throw new DreamAbortException(DreamMessage.LicenseRequired("service-license has expired"));
                }
            }
            else
            {
                config["service-license"].RemoveAll();
            }

            // create built-in services
            _storage = Plug.New(config["uri.storage"].AsUri);
            _pubsub  = Plug.New(config["uri.pubsub"].AsUri);

            // done
            _log.Debug("Start");
            result.Return();
        }
        //--- Class Methods ---

        /// <summary>
        /// Merge two subscriptions on matchine channel and resource.
        /// </summary>
        /// <param name="channel">Common channel.</param>
        /// <param name="resource">Common resource.</param>
        /// <param name="owner">Common owner.</param>
        /// <param name="cookie">Subscription set cookie.</param>
        /// <param name="first">First subscription to merge.</param>
        /// <param name="second">Second subscription to merge.</param>
        /// <returns></returns>
        public static PubSubSubscription MergeForChannelAndResource(XUri channel, XUri resource, PubSubSubscriptionSet owner, DreamCookie cookie, PubSubSubscription first, PubSubSubscription second)
        {
            return(new PubSubSubscription(channel, resource, owner, cookie, first, second));
        }
예제 #21
0
        //--- Methods ---
        void IHttpHandler.ProcessRequest(HttpContext httpContext)
        {
            var          key     = new object();
            DreamMessage request = null;

            try {
                string verb       = httpContext.Request.HttpMethod;
                XUri   requestUri = HttpUtil.FromHttpContext(httpContext);
                _env.AddActivityDescription(key, string.Format("Incoming: {0} {1}", verb, requestUri.ToString()));
                _log.DebugMethodCall("ProcessRequest", verb, requestUri);

                // create request message
                request = new DreamMessage(DreamStatus.Ok, new DreamHeaders(httpContext.Request.Headers), MimeType.New(httpContext.Request.ContentType), httpContext.Request.ContentLength, httpContext.Request.InputStream);
                DreamUtil.PrepareIncomingMessage(request, httpContext.Request.ContentEncoding, string.Format("{0}://{1}{2}", httpContext.Request.Url.Scheme, httpContext.Request.Url.Authority, httpContext.Request.ApplicationPath), httpContext.Request.UserHostAddress, httpContext.Request.UserAgent);

                // process message
                Result <DreamMessage> response = _env.SubmitRequestAsync(verb, requestUri, httpContext.User, request, new Result <DreamMessage>(TimeSpan.MaxValue)).Block();
                request.Close();
                DreamMessage item = response.HasException ? DreamMessage.InternalError(response.Exception) : response.Value;

                // set status
                if (_log.IsDebugEnabled)
                {
                    _log.DebugMethodCall("ProcessRequest[Status]", item.Status, String.Format("{0}{1}", httpContext.Request.Url.GetLeftPart(UriPartial.Authority), httpContext.Request.RawUrl).Replace("/index.aspx", "/"));
                }
                httpContext.Response.StatusCode = (int)item.Status;

                // remove internal headers
                item.Headers.DreamTransport = null;
                item.Headers.DreamPublicUri = null;

                // create stream for response (this will force the creation of the 'Content-Length' header as well)
                Stream stream = item.ToStream();

                // copy headers
                foreach (KeyValuePair <string, string> pair in item.Headers)
                {
                    _log.TraceMethodCall("ProcessRequest[Header]", pair.Key, pair.Value);
                    httpContext.Response.AppendHeader(pair.Key, pair.Value);
                }

                // add set-cookie headers to response
                if (item.HasCookies)
                {
                    foreach (DreamCookie cookie in item.Cookies)
                    {
                        httpContext.Response.AppendHeader(DreamHeaders.SET_COOKIE, cookie.ToSetCookieHeader());
                    }
                }

                // send message stream
                long size = item.ContentLength;
                if (((size == -1) || (size > 0)) && (stream != Stream.Null))
                {
                    stream.CopyTo(httpContext.Response.OutputStream, size, new Result <long>(TimeSpan.MaxValue)).Wait();
                }
                item.Close();
            } catch (Exception ex) {
                _log.ErrorExceptionMethodCall(ex, "CommonRequestHandler");
                if (request != null)
                {
                    request.Close();
                }
                if (httpContext != null)
                {
                    httpContext.Response.Close();
                }
            } finally {
                _env.RemoveActivityDescription(key);
            }
        }
        /// <summary>
        /// Create a subscription from a subscription document.
        /// </summary>
        /// <param name="sub">Subscription document.</param>
        /// <param name="owner">Owning set.</param>
        public PubSubSubscription(XDoc sub, PubSubSubscriptionSet owner)
        {
            Owner = owner;
            // sanity check the input
            XDoc channels = sub["channel"];

            if (channels.IsEmpty)
            {
                throw new ArgumentException("<subscription> must have at least one <channel>");
            }
            XDoc filter = sub["filter"];

            if (filter.ListLength > 1)
            {
                throw new ArgumentException("<subscription> must have zero or one <filter>");
            }
            XDoc proxy = sub["uri.proxy"];

            if (proxy.ListLength > 1)
            {
                throw new ArgumentException("<subscription> must have zero or one <uri.proxy>");
            }
            XDoc recipients = sub["recipient"];

            if (recipients.IsEmpty)
            {
                throw new ArgumentException("<subscription> must have at least one valid <recipient>");
            }
            if (recipients.ListLength > 1 && proxy.ListLength == 0)
            {
                throw new ArgumentException("<subscription> must include <uri.proxy> if there is more than one <recipient>");
            }

            // create our internal representation
            try {
                Id = sub["@id"].Contents;
                if (string.IsNullOrEmpty(Id))
                {
                    Id = Guid.NewGuid().ToString();
                }
                XDoc cookie = sub["set-cookie"];
                if (!cookie.IsEmpty)
                {
                    Cookie = DreamCookie.ParseSetCookie(cookie);
                }
                List <XUri> channelList = new List <XUri>();
                foreach (XDoc c in channels)
                {
                    channelList.Add(c.AsUri);
                }
                Channels = channelList.ToArray();
                List <XUri> resourceList = new List <XUri>();
                foreach (XDoc r in sub["uri.resource"])
                {
                    resourceList.Add(r.AsUri);
                }
                Resources = resourceList.ToArray();
                if (proxy.IsEmpty)
                {
                    Destination = new DispatcherRecipient(recipients).Uri;
                }
                else
                {
                    Destination = proxy.AsUri;
                    _isProxy    = true;
                }
                List <DispatcherRecipient> recipientList = new List <DispatcherRecipient>();
                foreach (XDoc recipient in recipients)
                {
                    recipientList.Add(new DispatcherRecipient(recipient));
                }
                Recipients = recipientList.ToArray();
            } catch (Exception e) {
                throw new ArgumentException("Unable to parse subscription: " + e.Message, e);
            }
        }
예제 #23
0
 private string GetUriTitle(string title)
 {
     return(XUri.EncodeSegment(title.ReplaceAll("-", "_", " ", "_")));
 }
        public DekiScriptLiteral Visit(DekiScriptBinary expr, DekiScriptEnv env)
        {
            DekiScriptExpression Left  = expr.Left;
            DekiScriptExpression Right = expr.Right;

            switch (expr.OpCode)
            {
            case DekiScriptBinary.Op.LeftValue:
                return(Left.VisitWith(this, env));

            case DekiScriptBinary.Op.IdentityEqual: {
                DekiScriptLiteral left  = Left.VisitWith(this, env);
                DekiScriptLiteral right = Right.VisitWith(this, env);
                return(DekiScriptBinary.IdentityEqual(left, right));
            }

            case DekiScriptBinary.Op.IdentityNotEqual: {
                DekiScriptLiteral left  = Left.VisitWith(this, env);
                DekiScriptLiteral right = Right.VisitWith(this, env);
                return(DekiScriptBinary.IdentityNotEqual(left, right));
            }

            case DekiScriptBinary.Op.IsType: {
                DekiScriptLiteral left = Left.VisitWith(this, env);
                string            type = ((DekiScriptString)Right).Value;
                return(DekiScriptBool.New(StringUtil.EqualsInvariantIgnoreCase(type, "any") || StringUtil.EqualsInvariantIgnoreCase(left.ScriptTypeName, type)));
            }

            case DekiScriptBinary.Op.Equal: {
                DekiScriptLiteral left  = Left.VisitWith(this, env);
                DekiScriptLiteral right = Right.VisitWith(this, env);
                return(DekiScriptBinary.Equal(left, right));
            }

            case DekiScriptBinary.Op.NotEqual: {
                DekiScriptLiteral left  = Left.VisitWith(this, env);
                DekiScriptLiteral right = Right.VisitWith(this, env);
                return(DekiScriptBinary.NotEqual(left, right));
            }

            case DekiScriptBinary.Op.GreaterOrEqual: {
                DekiScriptLiteral left  = Left.VisitWith(this, env);
                DekiScriptLiteral right = Right.VisitWith(this, env);
                if (DekiScriptLiteral.CoerceValuesToSameType(ref left, ref right))
                {
                    switch (left.ScriptType)
                    {
                    case DekiScriptType.BOOL:
                    case DekiScriptType.NUM:
                        return(DekiScriptBool.New(left.AsNumber() >= right.AsNumber()));

                    case DekiScriptType.STR:
                        return(DekiScriptBool.New(StringUtil.CompareInvariant(left.AsString(), right.AsString()) >= 0));

                    default:
                        return(DekiScriptNil.Value);
                    }
                }
                else
                {
                    return(DekiScriptNil.Value);
                }
            }

            case DekiScriptBinary.Op.GreaterThan: {
                DekiScriptLiteral left  = Left.VisitWith(this, env);
                DekiScriptLiteral right = Right.VisitWith(this, env);
                if (DekiScriptLiteral.CoerceValuesToSameType(ref left, ref right))
                {
                    switch (left.ScriptType)
                    {
                    case DekiScriptType.BOOL:
                    case DekiScriptType.NUM:
                        return(DekiScriptBool.New(left.AsNumber() > right.AsNumber()));

                    case DekiScriptType.STR:
                        return(DekiScriptBool.New(StringUtil.CompareInvariant(left.AsString(), right.AsString()) > 0));

                    default:
                        return(DekiScriptNil.Value);
                    }
                }
                else
                {
                    return(DekiScriptNil.Value);
                }
            }

            case DekiScriptBinary.Op.LessOrEqual: {
                DekiScriptLiteral left  = Left.VisitWith(this, env);
                DekiScriptLiteral right = Right.VisitWith(this, env);
                if (DekiScriptLiteral.CoerceValuesToSameType(ref left, ref right))
                {
                    switch (left.ScriptType)
                    {
                    case DekiScriptType.BOOL:
                    case DekiScriptType.NUM:
                        return(DekiScriptBool.New(left.AsNumber() <= right.AsNumber()));

                    case DekiScriptType.STR:
                        return(DekiScriptBool.New(StringUtil.CompareInvariant(left.AsString(), right.AsString()) <= 0));

                    default:
                        return(DekiScriptNil.Value);
                    }
                }
                else
                {
                    return(DekiScriptNil.Value);
                }
            }

            case DekiScriptBinary.Op.LessThan: {
                DekiScriptLiteral left  = Left.VisitWith(this, env);
                DekiScriptLiteral right = Right.VisitWith(this, env);
                if (DekiScriptLiteral.CoerceValuesToSameType(ref left, ref right))
                {
                    switch (left.ScriptType)
                    {
                    case DekiScriptType.BOOL:
                    case DekiScriptType.NUM:
                        return(DekiScriptBool.New(left.AsNumber() < right.AsNumber()));

                    case DekiScriptType.STR:
                        return(DekiScriptBool.New(StringUtil.CompareInvariant(left.AsString(), right.AsString()) < 0));

                    default:
                        return(DekiScriptNil.Value);
                    }
                }
                else
                {
                    return(DekiScriptNil.Value);
                }
            }

            case DekiScriptBinary.Op.LogicalAnd: {
                DekiScriptLiteral result = Left.VisitWith(this, env);
                if (!result.IsNilFalseZero)
                {
                    result = Right.VisitWith(this, env);
                }
                return(result);
            }

            case DekiScriptBinary.Op.LogicalOr: {
                DekiScriptLiteral result = Left.VisitWith(this, env);
                if (result.IsNilFalseZero)
                {
                    result = Right.VisitWith(this, env);
                }
                return(result);
            }

            case DekiScriptBinary.Op.Addition:
                return(DekiScriptNumber.New(Left.VisitWith(this, env).AsNumber() + Right.VisitWith(this, env).AsNumber()));

            case DekiScriptBinary.Op.Division:
                return(DekiScriptNumber.New(Left.VisitWith(this, env).AsNumber() / Right.VisitWith(this, env).AsNumber()));

            case DekiScriptBinary.Op.Modulo: {
                DekiScriptLiteral left  = Left.VisitWith(this, env);
                DekiScriptLiteral right = Right.VisitWith(this, env);
                if ((left is DekiScriptString) && ((right is DekiScriptMap) || (right is DekiScriptList)))
                {
                    // NOTE (steveb): string.format shorthand notation: "abc = $abc" % { abc: 123 } -OR- "0 = $0" % [ 123 ]
                    return(DekiScriptLiteral.FromNativeValue(DekiScriptLibrary.StringFormat(((DekiScriptString)left).Value, right.NativeValue)));
                }
                else
                {
                    return(DekiScriptNumber.New(left.AsNumber() % right.AsNumber()));
                }
            }

            case DekiScriptBinary.Op.Multiplication:
                return(DekiScriptNumber.New(Left.VisitWith(this, env).AsNumber() * Right.VisitWith(this, env).AsNumber()));

            case DekiScriptBinary.Op.Subtraction:
                return(DekiScriptNumber.New(Left.VisitWith(this, env).AsNumber() - Right.VisitWith(this, env).AsNumber()));

            case DekiScriptBinary.Op.NullCoalesce: {
                DekiScriptLiteral result = Left.VisitWith(this, env);
                if (result.IsNil)
                {
                    result = Right.VisitWith(this, env);
                }
                return(result);
            }

            case DekiScriptBinary.Op.Concat: {
                DekiScriptLiteral left  = Left.VisitWith(this, env);
                DekiScriptLiteral right = Right.VisitWith(this, env);
                if (left is DekiScriptNil)
                {
                    return(right);
                }
                else if (right is DekiScriptNil)
                {
                    return(left);
                }
                else if ((left is DekiScriptMap) && (right is DekiScriptMap))
                {
                    // left and right expressions are maps, merge them
                    DekiScriptMap result = new DekiScriptMap();
                    result.AddRange((DekiScriptMap)left);
                    result.AddRange((DekiScriptMap)right);
                    return(result);
                }
                else if ((left is DekiScriptList) && (right is DekiScriptList))
                {
                    // left and right expressions are lists, concatenate them
                    DekiScriptList result = new DekiScriptList();
                    result.AddRange((DekiScriptList)left);
                    result.AddRange((DekiScriptList)right);
                    return(result);
                }
                else
                {
                    // treat left and right expressions as strings
                    string leftText  = left.AsString();
                    string rightText = right.AsString();
                    if ((leftText != null) && (rightText != null))
                    {
                        return(DekiScriptString.New(leftText + rightText));
                    }
                    else if (leftText != null)
                    {
                        return(DekiScriptString.New(leftText));
                    }
                    else if (rightText != null)
                    {
                        return(DekiScriptString.New(rightText));
                    }
                    else
                    {
                        return(DekiScriptNil.Value);
                    }
                }
            }

            case DekiScriptBinary.Op.UriAppend: {
                // TODO (steveb): we should throw an exception when the LHS is not a valid string or uri

                XUri   left   = XUri.TryParse(Left.VisitWith(this, env).AsString());
                string result = null;
                if (left != null)
                {
                    DekiScriptLiteral right = Right.VisitWith(this, env);
                    if (right is DekiScriptString)
                    {
                        result = DekiScriptLibrary.UriBuild(left, right.AsString(), null);
                    }
                    else if (right is DekiScriptMap)
                    {
                        result = DekiScriptLibrary.UriBuild(left, null, (Hashtable)right.NativeValue);
                    }
                    else
                    {
                        result = left.ToString();
                    }
                }
                return(DekiScriptLiteral.FromNativeValue(result));
            }

            case DekiScriptBinary.Op.InCollection: {
                DekiScriptLiteral left  = Left.VisitWith(this, env);
                DekiScriptLiteral right = Right.VisitWith(this, env);
                if (right is DekiScriptList)
                {
                    foreach (DekiScriptLiteral item in ((DekiScriptList)right).Value)
                    {
                        if (!DekiScriptBinary.Equal(left, item).IsNilFalseZero)
                        {
                            return(DekiScriptBool.True);
                        }
                    }
                    return(DekiScriptBool.False);
                }
                else if (right is DekiScriptMap)
                {
                    foreach (DekiScriptLiteral item in ((DekiScriptMap)right).Value.Values)
                    {
                        if (!DekiScriptBinary.Equal(left, item).IsNilFalseZero)
                        {
                            return(DekiScriptBool.True);
                        }
                    }
                    return(DekiScriptBool.False);
                }
                else
                {
                    return(DekiScriptBool.False);
                }
            }
            }
            throw new InvalidOperationException("invalid op code:" + expr.OpCode);
        }
예제 #25
0
파일: Program.cs 프로젝트: pauldx/csv2cb
        //--- Class Methods ---
        public static void Main(string[] args)
        {
            var console = Console.Error;

            console.WriteLine("MindTouch CSV2CB - Import CSV files into Couchbase");
            console.WriteLine();

            // parse command line options
            string password = null;
            XUri   host     = null;
            string doctype  = null;
            bool   help     = false;
            string select   = null;
            var    options  = new OptionSet {
                { "host=", "Couchbase hostname with bucket name.\nExample: http://example.com:8091/bucket", v => host = XUri.TryParse(v) },
                { "password="******"(optional) Password for Couchbase bucket.", v => password = v },
                { "doctype=", "(optional) Document type identifier (doctype) to add to each converted JSON document.", v => doctype = v },
                { "select=", "(optional) List of CSV columns to import. By default, all columns are imported.", v => select = v },
                { "h|?|help", "This help text", v => help = (v != null) }
            };
            var filenames = options.Parse(args);

            // show help if requested
            if (help)
            {
                WriteOptions(Console.Out, options);
                return;
            }

            // validate arguments
            if (host == null)
            {
                console.WriteLine("ERROR: missing couchbase hostname");
                console.WriteLine();
                WriteOptions(Console.Out, options);
                return;
            }
            HashSet <string> columns = null;

            if (select != null)
            {
                try {
                    CsvTable schema = null;
                    using (var reader = new StringReader(select)) {
                        schema = CsvTable.NewFromStream(reader);
                    }
                    columns = new HashSet <string>();
                    foreach (var column in schema.Headers)
                    {
                        columns.Add(column);
                    }
                } catch (Exception e) {
                    console.WriteLine("ERROR: {0}", e.Message);
                    return;
                }
            }

            // create client and verify connection
            try {
                _client = CreateClient(host, password);
                var key = "test:" + StringUtil.CreateAlphaNumericKey(16);
                if (!_client.Store(StoreMode.Set, key, "succcess!"))
                {
                    throw new ApplicationException("unable to connect to couchbase server");
                }
                _client.Remove(key);
            } catch (Exception e) {
                console.WriteLine("ERROR: {0}", e.Message);
                return;
            }

            // process all files
            var loadStopwatch     = new Stopwatch();
            var convertStopwatch  = new Stopwatch();
            var importStopwatch   = new Stopwatch();
            var documentTotal     = 0;
            var importFailedTotal = 0;

            try {
                foreach (var filename in filenames)
                {
                    if (!File.Exists(filename))
                    {
                        console.WriteLine("ERROR: unable to find '{0}'", filename);
                        return;
                    }
                    try {
                        // load CSV file
                        console.Write("Loading file '{0}'...", filename);
                        loadStopwatch.Start();
                        var table = CsvTable.NewFromPath(filename, Encoding.UTF8);
                        loadStopwatch.Stop();
                        console.WriteLine("done ({0:#,##0} rows)", table.RowCount);

                        // converting from CSV to JSON documents
                        console.Write("Converting rows...");
                        var documents = new List <KeyValuePair <string, string> >();
                        convertStopwatch.Start();
                        foreach (var row in table)
                        {
                            var value = RowToJson(columns, row, doctype);
                            if (value == null)
                            {
                                continue;
                            }
                            var key = StringUtil.CreateAlphaNumericKey(16);
                            if (!string.IsNullOrEmpty(doctype))
                            {
                                key = doctype + ":" + key;
                            }
                            documents.Add(new KeyValuePair <string, string>(key, value));
                        }
                        convertStopwatch.Stop();
                        documentTotal += documents.Count;
                        console.WriteLine("done ({0:#,##0} documents)", documents.Count);

                        // importing JSON documents
                        if (documents.Any())
                        {
                            console.Write("Importing documents...");
                            int importFailed;
                            importStopwatch.Start();
                            Send(documents, out importFailed);
                            importStopwatch.Stop();
                            importFailedTotal += importFailed;
                            console.WriteLine("done ({0:#,##0} documents)", documents.Count - importFailed);
                        }
                    } catch (Exception e) {
                        console.WriteLine("ERROR: error loading file '{0}': {1}", filename, e.Message);
                        return;
                    }
                }
            } finally {
                loadStopwatch.Stop();
                convertStopwatch.Stop();
                importStopwatch.Stop();
                var loadTime    = loadStopwatch.Elapsed.TotalSeconds;
                var convertTime = convertStopwatch.Elapsed.TotalSeconds;
                var importTime  = importStopwatch.Elapsed.TotalSeconds;
                console.WriteLine();
                console.WriteLine("{0:#,##0.000} seconds elapsed (loading: {1:#,##0.000}s, converting: {2:#,##0.000}s, importing: {3:#,##0.000}s)", loadTime + convertTime + importTime, loadTime, convertTime, importTime);
                console.WriteLine("{0:#,##0} records loaded ({1:#,##0.000} records/second)", documentTotal, documentTotal / loadTime);
                console.WriteLine("{0:#,##0} records converted ({1:#,##0.000} records/second)", documentTotal, documentTotal / convertTime);
                console.WriteLine("{0:#,##0} records imported ({1:#,##0.000} records/second)", documentTotal - importFailedTotal, (documentTotal - importFailedTotal) / importTime);
                if (importFailedTotal > 0)
                {
                    console.WriteLine("WARNING: {0:#,##0} records failed to import!", importFailedTotal);
                }
            }
        }
예제 #26
0
 public DreamMessage SyncUri(XUri uri)
 {
     return(Response(new XDoc("r").Elem("uri", uri.WithoutQuery())));
 }
예제 #27
0
        public void Subscribing_to_pubsub_channel_results_in_combined_set_being_pushed()
        {
            var downstream = CreatePubSubService().WithInternalKey().AtLocalHost;
            var upstreamUri = new XUri("http://upstream/");
            var upstreamMock = MockPlug.Register(upstreamUri);
            XDoc downstreamSet = null;
            upstreamMock.Expect().Verb("POST").RequestDocument(_ => {
                downstreamSet = _;
                return true;
            }).Response(DreamMessage.Ok());
            var subscribeToDownstream = new XDoc("subscription-set")
                .Elem("uri.owner", upstreamUri)
                .Start("subscription")
                    .Attr("id", "1")
                    .Elem("channel", "foo://bar/baz/*")
                    .Start("recipient").Elem("uri", upstreamUri).End()
                .End()
                .Start("subscription")
                    .Attr("id", "1")
                    .Elem("channel", "pubsub://*/*")
                    .Start("recipient").Elem("uri", upstreamUri).End()
                .End();

            // subscribe to set updates from downstream, expect most recent version to be pushed
            var downstreamResponse = downstream.At("subscribers").PostAsync(subscribeToDownstream).Wait();
            var location = downstreamResponse.Headers.Location;
            Assert.IsTrue(downstreamResponse.IsSuccessful, downstreamResponse.ToText());
            Assert.IsTrue(upstreamMock.WaitAndVerify(TimeSpan.FromSeconds(10)), upstreamMock.VerificationFailure);
            Assert.AreEqual(1, downstreamSet["subscription[channel='foo://bar/baz/*']"].ListLength);

            subscribeToDownstream
                .Start("subscription")
                    .Attr("id", "3")
                    .Elem("channel", "foo://bar/bob")
                    .Start("recipient").Elem("uri", upstreamUri).End()
                .End();

            // change subscription, expect most recent version to be pushed
            upstreamMock.Expect().Verb("POST").RequestDocument(_ => {
                downstreamSet = _;
                return true;
            }).Response(DreamMessage.Ok());
            downstreamResponse = Plug.New(location).PutAsync(subscribeToDownstream).Wait();
            Assert.IsTrue(downstreamResponse.IsSuccessful, downstreamResponse.ToText());
            Assert.IsTrue(upstreamMock.WaitAndVerify(TimeSpan.FromSeconds(10)), upstreamMock.VerificationFailure);
            Assert.AreEqual(1, downstreamSet["subscription[channel='foo://bar/baz/*']"].ListLength);
            Assert.AreEqual(1, downstreamSet["subscription[channel='foo://bar/bob']"].ListLength);
        }
예제 #28
0
        private Yield HandleInvoke(Action <string> activity, Plug plug, string verb, XUri uri, DreamMessage request, Result <DreamMessage> response)
        {
            Result <IAsyncResult> async;

            // remove internal headers
            request.Headers.DreamTransport = null;

            // set request headers
            request.Headers.Host = uri.Host;
            if (request.Headers.UserAgent == null)
            {
                request.Headers.UserAgent = "Dream/" + DreamUtil.DreamVersion;
            }

            // add cookies to request
            if (request.HasCookies)
            {
                request.Headers[DreamHeaders.COOKIE] = DreamCookie.RenderCookieHeader(request.Cookies);
            }

            // check if we can pool the request with an existing one
            if ((plug.Credentials == null) && StringUtil.ContainsInvariantIgnoreCase(verb, "GET"))
            {
                // create the request hashcode
                StringBuilder buffer = new StringBuilder();
                buffer.AppendLine(uri.ToString());
                foreach (KeyValuePair <string, string> header in request.Headers)
                {
                    buffer.Append(header.Key).Append(": ").Append(header.Value).AppendLine();
                }
                Guid hash = new Guid(StringUtil.ComputeHash(buffer.ToString()));

                // check if an active connection exists
                Result <DreamMessage> relay = null;
                lock (_requests) {
                    List <Result <DreamMessage> > pending;
                    if (_requests.TryGetValue(hash, out pending))
                    {
                        relay = new Result <DreamMessage>(response.Timeout);
                        pending.Add(relay);
                    }
                    else
                    {
                        pending = new List <Result <DreamMessage> >();
                        pending.Add(response);
                        _requests[hash] = pending;
                    }
                }

                // check if we're pooling a request
                if (relay != null)
                {
                    // wait for the relayed response
                    yield return(relay);

                    response.Return(relay);
                    yield break;
                }
                else
                {
                    // NOTE (steveb): we use TaskEnv.Instantaneous so that we don't exit the current stack frame before we've executed the continuation;
                    //                otherwise, we'll trigger an exception because our result object may not be set.

                    // create new handler to multicast the response to the relays
                    response = new Result <DreamMessage>(response.Timeout, TaskEnv.Instantaneous);
                    response.WhenDone(_ => {
                        List <Result <DreamMessage> > pending;
                        lock (_requests) {
                            _requests.TryGetValue(hash, out pending);
                            _requests.Remove(hash);
                        }

                        // this check should never fail!
                        if (response.HasException)
                        {
                            // send the exception to all relays
                            foreach (Result <DreamMessage> result in pending)
                            {
                                result.Throw(response.Exception);
                            }
                        }
                        else
                        {
                            DreamMessage original = response.Value;

                            // only memorize the message if it needs to be cloned
                            if (pending.Count > 1)
                            {
                                // clone the message to all relays
                                foreach (Result <DreamMessage> result in pending)
                                {
                                    result.Return(original.Clone());
                                }
                            }
                            else
                            {
                                // relay the original message
                                pending[0].Return(original);
                            }
                        }
                    });
                }
            }

            // initialize request
            activity("pre WebRequest.Create");
            var httpRequest = (HttpWebRequest)WebRequest.Create(uri.ToUri());

            activity("post WebRequest.Create");
            httpRequest.Method           = verb;
            httpRequest.Timeout          = System.Threading.Timeout.Infinite;
            httpRequest.ReadWriteTimeout = System.Threading.Timeout.Infinite;

            // Note (arnec): httpRequest AutoRedirect is disabled because Plug is responsible for it (this allows redirects to follow
            // the appropriate handler instead staying stuck in http end point land
            httpRequest.AllowAutoRedirect = false;

            // Note from http://support.microsoft.com/kb/904262
            // The HTTP request is made up of the following parts:
            // 1.   Sending the request is covered by using the HttpWebRequest.Timeout method.
            // 2.   Getting the response header is covered by using the HttpWebRequest.Timeout method.
            // 3.   Reading the body of the response is not covered by using the HttpWebResponse.Timeout method. In ASP.NET 1.1 and in later versions, reading the body of the response
            //      is covered by using the HttpWebRequest.ReadWriteTimeout method. The HttpWebRequest.ReadWriteTimeout method is used to handle cases where the response headers are
            //      retrieved in a timely manner but where the reading of the response body times out.

            httpRequest.KeepAlive       = false;
            httpRequest.ProtocolVersion = System.Net.HttpVersion.Version10;

            // TODO (steveb): set default proxy
            //httpRequest.Proxy = WebProxy.GetDefaultProxy();
            //httpRequest.Proxy.Credentials = CredentialCache.DefaultCredentials;

            // set credentials
            if (plug.Credentials != null)
            {
                httpRequest.Credentials     = plug.Credentials;
                httpRequest.PreAuthenticate = true;
            }
            else if (!string.IsNullOrEmpty(uri.User) || !string.IsNullOrEmpty(uri.Password))
            {
                httpRequest.Credentials     = new NetworkCredential(uri.User ?? string.Empty, uri.Password ?? string.Empty);
                httpRequest.PreAuthenticate = true;

                // Note (arnec): this manually adds the basic auth header, so it can authorize
                // in a single request without requiring challenge
                var authbytes = Encoding.ASCII.GetBytes(string.Concat(uri.User ?? string.Empty, ":", uri.Password ?? string.Empty));
                var base64    = Convert.ToBase64String(authbytes);
                httpRequest.Headers.Add(DreamHeaders.AUTHORIZATION, "Basic " + base64);
            }

            // add request headres
            foreach (KeyValuePair <string, string> header in request.Headers)
            {
                HttpUtil.AddHeader(httpRequest, header.Key, header.Value);
            }

            // send message stream
            if ((request.ContentLength != 0) || (verb == Verb.POST))
            {
                async = new Result <IAsyncResult>();
                try {
                    activity("pre BeginGetRequestStream");
                    httpRequest.BeginGetRequestStream(async.Return, null);
                    activity("post BeginGetRequestStream");
                } catch (Exception e) {
                    activity("pre HandleResponse 1");
                    if (!HandleResponse(activity, e, null, response))
                    {
                        _log.ErrorExceptionMethodCall(e, "HandleInvoke@BeginGetRequestStream", verb, uri);
                        try {
                            httpRequest.Abort();
                        } catch { }
                    }
                    yield break;
                }
                activity("pre yield BeginGetRequestStream");
                yield return(async.Catch());

                activity("post yield BeginGetRequestStream");

                // send request
                Stream outStream;
                try {
                    activity("pre EndGetRequestStream");
                    outStream = httpRequest.EndGetRequestStream(async.Value);
                    activity("pre EndGetRequestStream");
                } catch (Exception e) {
                    activity("pre HandleResponse 2");
                    if (!HandleResponse(activity, e, null, response))
                    {
                        _log.ErrorExceptionMethodCall(e, "HandleInvoke@EndGetRequestStream", verb, uri);
                        try {
                            httpRequest.Abort();
                        } catch { }
                    }
                    yield break;
                }

                // copy data
                using (outStream) {
                    Result <long> res;
                    activity("pre yield CopyStream");
                    yield return(res = request.ToStream().CopyTo(outStream, request.ContentLength, new Result <long>(TimeSpan.MaxValue)).Catch());

                    activity("post yield CopyStream");
                    if (res.HasException)
                    {
                        activity("pre HandleResponse 3");
                        if (!HandleResponse(activity, res.Exception, null, response))
                        {
                            _log.ErrorExceptionMethodCall(res.Exception, "*****@*****.**", verb, uri);
                            try {
                                httpRequest.Abort();
                            } catch { }
                        }
                        yield break;
                    }
                }
            }
            request = null;

            // wait for response
            async = new Result <IAsyncResult>(response.Timeout);
            try {
                activity("pre BeginGetResponse");
                httpRequest.BeginGetResponse(async.Return, null);
                activity("post BeginGetResponse");
            } catch (Exception e) {
                activity("pre HandleResponse 4");
                if (!HandleResponse(activity, e, null, response))
                {
                    _log.ErrorExceptionMethodCall(e, "HandleInvoke@BeginGetResponse", verb, uri);
                    try {
                        httpRequest.Abort();
                    } catch { }
                }
                yield break;
            }
            activity("pre yield BeginGetResponse");
            yield return(async.Catch());

            activity("post yield BeginGetResponse");

            // check if an error occurred
            if (async.HasException)
            {
                activity("pre HandleResponse 5");
                if (!HandleResponse(activity, async.Exception, null, response))
                {
                    _log.ErrorExceptionMethodCall(async.Exception, "HandleInvoke@BeginGetResponse", verb, uri);
                    try {
                        httpRequest.Abort();
                    } catch { }
                }
                yield break;
            }
            else
            {
                // handle response
                try {
                    HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.EndGetResponse(async.Value);
                    activity("pre HandleResponse 6");
                    if (!HandleResponse(activity, null, httpResponse, response))
                    {
                        try {
                            httpRequest.Abort();
                        } catch { }
                    }
                } catch (Exception e) {
                    activity("pre HandleResponse 7");
                    if (!HandleResponse(activity, e, null, response))
                    {
                        _log.ErrorExceptionMethodCall(e, "HandleInvoke@EndGetResponse", verb, uri);
                        try {
                            httpRequest.Abort();
                        } catch { }
                    }
                    yield break;
                }
            }
        }
예제 #29
0
        public void PubSub_downstream_chaining_and_subscription_propagation()
        {
            XUri downstreamUri = new XUri("http://localhost/downstream");
            var mock = MockPlug.Register(downstreamUri);
            XDoc downstreamDoc = null;
            mock.Expect().Verb("GET").Uri(downstreamUri).Response(DreamMessage.Ok(new XDoc("subscription-set")
                .Elem("uri.owner", downstreamUri)
                .Start("subscription")
                   .Attr("id", "1")
                   .Elem("channel", "channel:///foo/*")
                   .Elem("uri.proxy", downstreamUri.At("publish"))
                   .Start("recipient").Elem("uri", "http:///foo/sub1").End()
                .End()));
            mock.Expect().Verb("POST").Uri(downstreamUri).RequestDocument(doc => {
                downstreamDoc = doc;
                return true;
            });

            // create service, which should subscribe to the upstream one
            Plug upstreamPubSub = CreatePubSubService(new XDoc("config").Start("downstream").Elem("uri", downstreamUri).End()).WithInternalKey().AtLocalHost;
            Assert.IsTrue(mock.WaitAndVerify(TimeSpan.FromSeconds(10)), mock.VerificationFailure);
            var subUri = downstreamDoc["subscription/recipient/uri"].AsUri.AsPublicUri();
            Plug.GlobalCookies.Update(DreamCookie.ParseAllSetCookieNodes(downstreamDoc["subscription/set-cookie"]), subUri);
            Assert.AreEqual("pubsub://*/*", downstreamDoc["subscription/channel"].AsText);
            Assert.AreEqual(upstreamPubSub.Uri.WithoutQuery(), downstreamDoc["uri.owner"].AsUri);
            Assert.AreEqual(upstreamPubSub.Uri.At("subscribers").WithoutQuery(), subUri.WithoutLastSegment());

            // check that our set is properly represented by the upstream service
            DreamMessage upstreamSet = upstreamPubSub.At("subscribers").GetAsync().Wait();
            Assert.IsTrue(upstreamSet.IsSuccessful);
            XDoc upstreamDoc = upstreamSet.ToDocument();
            Assert.AreEqual(1, upstreamDoc["subscription"].ListLength);
            Assert.AreEqual("channel:///foo/*", upstreamDoc["subscription/channel"].AsText);

            // update the subscription set on the upstream service
            XDoc set2 = new XDoc("subscription-set")
               .Elem("uri.owner", downstreamUri)
               .Start("subscription")
                   .Attr("id", "1")
                   .Elem("channel", "channel:///bar/*")
                   .Elem("uri.proxy", downstreamUri.At("publish"))
                   .Start("recipient").Elem("uri", "http:///foo/sub1").End()
               .End();
            DreamMessage subPush = Plug.New(subUri).PostAsync(set2).Wait();
            Assert.IsTrue(subPush.IsSuccessful);
            upstreamSet = upstreamPubSub.At("subscribers").GetAsync().Wait();
            Assert.IsTrue(upstreamSet.IsSuccessful);
            upstreamDoc = upstreamSet.ToDocument();
            Assert.AreEqual(1, upstreamDoc["subscription"].ListLength);
            Assert.AreEqual("channel:///bar/*", upstreamDoc["subscription/channel"].AsText);
        }
예제 #30
0
 //--- Interface Methods ---
 int IPlugEndpoint.GetScoreWithNormalizedUri(XUri uri, out XUri normalized)
 {
     normalized = uri;
     int similarity = uri.Similarity(_uri);
     return (similarity >= _minSimilarity) ? similarity : 0;
 }
예제 #31
0
        /// <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);
                }
            }
            // 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;
            }
        }
예제 #32
0
        public void Shutdown()
        {
            _log.InfoMethodCall("Shutdown", _uri);
            Plug.RemoveEndpoint(this);
            _uri = null;

            // BUGBUGBUG (arnec): the following line may throw an exception on shutdown and
            // there is no way of differentiating it from other failures, so we log just in case.
            try {
                _listener.Stop();
            } catch(Exception e) {
                _log.Debug("Shutdown", e);
            }
        }
예제 #33
0
        public void Windows_network_file_path_uri_with_backslashes()
        {
            XUri uri = new XUri(@"file:///\\deki-hayes\drive");

            Assert.AreEqual("file://///deki-hayes/drive", uri.ToString());
        }
예제 #34
0
 /// <summary>
 /// Create a new subscription set from a subscription set document.
 /// </summary>
 /// <param name="setDoc">Set Xml document.</param>
 /// <param name="location">location id.</param>
 /// <param name="accessKey">secret key for accessing the set.</param>
 public PubSubSubscriptionSet(XDoc setDoc, string location, string accessKey)
 {
     try {
         // Note: not using AsUri to avoid automatic local:// translation
         Owner = new XUri(setDoc["uri.owner"].AsText);
         MaxFailureDuration = (setDoc["@max-failure-duration"].AsDouble ?? 0).Seconds();
         var subscriptions = new List<PubSubSubscription>();
         foreach(XDoc sub in setDoc["subscription"]) {
             subscriptions.Add(new PubSubSubscription(sub, this));
         }
         Version = setDoc["@version"].AsLong;
         Subscriptions = subscriptions.ToArray();
         Location = location;
         AccessKey = accessKey;
         MaxFailures = UsesFailureDuration ? int.MaxValue : setDoc["@max-failures"].AsInt ?? MAX_FAILURES;
     } catch(Exception e) {
         throw new ArgumentException("Unable to parse subscription set: " + e.Message, e);
     }
 }
예제 #35
0
        public void TestToStringFalse()
        {
            XUri uri = new XUri("http://*****:*****@hostname/path");

            Assert.AreEqual("http://*****:*****@hostname/path", uri.ToString(false), "ToString(false)");
        }
예제 #36
0
 //--- Constructors ---
 internal MockPlugInvocation(string verb, XUri uri, DreamMessage request, DreamHeaders responseHeaders) {
     Verb = verb;
     Uri = uri;
     Request = request;
     ResponseHeaders = responseHeaders;
 }
예제 #37
0
        public void TestAppendPath5()
        {
            XUri uri = new XUri("http://www.dummy.com:8081/first/second?query=arg");

            uri = uri.At("foo/bar");
        }
예제 #38
0
 public void Can_mock_a_request_with_a_stream_body()
 {
     var tmp = Path.GetTempFileName();
     var payload = "blahblah";
     File.WriteAllText(tmp, payload);
     var message = DreamMessage.FromFile(tmp);
     var uri = new XUri("http://mock/post/stream");
     MockPlug.Setup(uri).Verb("POST")
         .WithMessage(m => m.ToText() == payload)
         .ExpectAtLeastOneCall();
     var response = Plug.New(uri).Post(message, new Result<DreamMessage>()).Wait();
     response.AssertSuccess();
     MockPlug.VerifyAll(1.Seconds());
 }
예제 #39
0
        private MockPlug.IMockInvokee GetBestMatch(XUri uri)
        {
            MockPlug.IMockInvokee invokee;

            // using _registry as our guard for both _map and _registry, since they are always modified in sync
            lock(_registry) {
                int result;
                _map.TryGetValue(uri, out invokee, out result);
            }
            if(invokee != null) {
                return invokee;
            }
            return uri.SchemeHostPort.EqualsInvariant(DEFAULT) ? DefaultInvokee : null;
        }
예제 #40
0
 public void Register_twice_throws()
 {
     XUri uri = new XUri("http://www.mindtouch.com/foo");
     MockPlug.Register(uri, delegate(Plug p, string v, XUri u, DreamMessage r, Result<DreamMessage> r2) {
         r2.Return(DreamMessage.Ok());
     });
     try {
         MockPlug.Register(uri, delegate(Plug p, string v, XUri u, DreamMessage r, Result<DreamMessage> r2) {
             r2.Return(DreamMessage.Ok());
         });
     } catch(ArgumentException) {
         return;
     } catch(Exception e) {
         Assert.Fail("wrong exception: " + e);
     }
     Assert.Fail("no exception`");
 }
예제 #41
0
        private void ExecuteRequest(String operation, String url)
        {
            DreamMessage msg = null;
            XUri         uri = null;

            try {
                uri = new XUri(url);

                // exectue the specified request and display the results
                switch (operation.ToUpper())
                {
                case "DELETE": {
                    Plug p = Plug.New(url).WithCredentials(loginTextBox.Text, passwordTextBox.Text);
                    msg = p.DeleteAsync(GetDreamMessage(uri)).Wait();
                    SetRequestResult(msg, uri);
                    break;
                }

                case "GET": {
                    Plug p = Plug.New(url).WithCredentials(loginTextBox.Text, passwordTextBox.Text);
                    msg = DreamMessage.Ok();
                    msg.Cookies.AddRange(_cookies.Fetch(uri));
                    msg = p.GetAsync(msg).Wait();
                    SetRequestResult(msg, uri);
                    break;
                }

                case "HEAD": {
                    Plug p = Plug.New(url).WithCredentials(loginTextBox.Text, passwordTextBox.Text);
                    msg = p.InvokeAsync("HEAD", DreamMessage.Ok()).Wait();
                    if (DreamStatus.Ok == msg.Status)
                    {
                        StringBuilder result = new StringBuilder();
                        foreach (KeyValuePair <string, string> header in msg.Headers)
                        {
                            result.Append(header.Key);
                            result.Append("=");
                            result.Append(header.Value);
                            result.Append(Environment.NewLine);
                        }
                        msg = DreamMessage.Ok(MimeType.TEXT, result.ToString());
                    }
                    SetRequestResult(msg, uri);
                    break;
                }

                case "POST": {
                    Plug p = Plug.New(url).WithCredentials(loginTextBox.Text, passwordTextBox.Text);
                    msg = p.PostAsync(GetDreamMessage(uri)).Wait();
                    SetRequestResult(msg, uri);
                    break;
                }

                case "PUT": {
                    Plug p = Plug.New(url).WithCredentials(loginTextBox.Text, passwordTextBox.Text);
                    msg = p.PutAsync(GetDreamMessage(uri)).Wait();
                    SetRequestResult(msg, uri);
                    break;
                }

                case "OPTIONS": {
                    Plug p = Plug.New(url).WithCredentials(loginTextBox.Text, passwordTextBox.Text);
                    msg = p.OptionsAsync().Wait();
                    SetRequestResult(msg, uri);
                    break;
                }
                }
            } catch (DreamResponseException error) {
                SetRequestResult(error.Response, uri);
            } catch (Exception error) {
                SetRequestResult(DreamMessage.Ok(MimeType.TEXT, error.ToString()), uri);
            }
        }
 /// <summary>
 /// No-op hook for retrieving a service license string from its Service Identifier uri.
 /// </summary>
 /// <param name="sid">Service Identifier.</param>
 /// <returns>Service license.</returns>
 protected virtual string TryGetServiceLicense(XUri sid)
 {
     return(null);
 }
예제 #43
0
 Yield IPlugEndpoint.Invoke(Plug plug, string verb, XUri uri, DreamMessage request, Result<DreamMessage> response)
 {
     _env.UpdateInfoMessage(_sourceInternal, null);
     Result<DreamMessage> res = new Result<DreamMessage>(response.Timeout);
     _env.SubmitRequestAsync(verb, uri, null, request, res);
     yield return res;
     response.Return(res);
 }
예제 #44
0
        public IEnumerator <IYield> Invoke(Plug plug, string verb, XUri uri, DreamMessage request, Result <DreamMessage> response)
        {
            var match = GetBestMatch(uri);

            yield return(Async.Fork(() => match.Invoke(plug, verb, uri, MemorizeAndClone(request), response), new Result(TimeSpan.MaxValue)));
        }
예제 #45
0
파일: PlugTests.cs 프로젝트: heran/DReAM
 public void Get_via_internal_routing_and_AutoRedirect_off_shows_302()
 {
     using(var hostInfo = DreamTestHelper.CreateRandomPortHost()) {
         var mock = MockService.CreateMockService(hostInfo);
         var redirectCalled = 0;
         var redirectUri = new XUri("mock://foo/bar");
         mock.Service.CatchAllCallback = delegate(DreamContext context, DreamMessage request, Result<DreamMessage> response) {
             var msg = "nothing here";
             if(context.Uri.LastSegment == "redirect") {
                 _log.Debug("called redirect");
                 redirectCalled++;
                 response.Return(DreamMessage.Redirect(redirectUri));
                 return;
             }
             _log.DebugFormat("called uri: {0} => {1}", context.Uri, msg);
             response.Return(DreamMessage.NotFound(msg));
         };
         var uri = mock.AtLocalMachine.At("redirect");
         _log.DebugFormat("calling redirect service at {0}", uri);
         var r = Plug.New(uri).WithHeader("h", "y").WithoutAutoRedirects().GetAsync().Wait();
         Assert.AreEqual(DreamStatus.Found, r.Status, r.HasDocument ? r.ToDocument()["message"].AsText : "request failed: " + r.Status);
         Assert.AreEqual(1, redirectCalled, "redirect called incorrectly");
         Assert.AreEqual(redirectUri.ToString(), r.Headers.Location.ToString());
     }
 }
예제 #46
0
        public void Title_Case02_WithNamespacePrefix_CorrectPathTitle()
        {
            // Case 02
            // Old path:  Namespace:aaa
            // Old title: Namespace:aaa
            //            move?title=bbb
            // New path:  Namespace:bbb
            // New title: bbb

            // Log in as ADMIN
            Plug p = Utils.BuildPlugForAdmin();

            // Run this test for each namespace
            for (int i = 0; i < name_space.Length; i++)
            {
                string path = name_space[i] + Utils.GenerateUniqueName();
                PageUtils.SavePage(p, path, name_space[i] + "test");

                // Rename page from Namespace:aaa -> bbb using "title"
                string       title    = Utils.GenerateUniqueName();
                string       newtitle = title;
                string       newpath  = name_space[i] + title;
                DreamMessage msg      = PageUtils.MovePage(Utils.BuildPlugForAdmin().At("pages", "=" + XUri.DoubleEncode(path), "move").With("title", newtitle));
                Assert.IsTrue(msg.IsSuccessful, "move page failed");
                Assert.AreEqual(1, msg.ToDocument()["@count"].AsInt, "unexpected number of pages moved");
                if (msg.ToDocument()["page/path/@type"].AsText == "fixed")
                {
                    // fixed path page are not moved, just the title is changed
                    newpath = msg.ToDocument()["page/path"].AsText;
                }

                // Retrieve the page and verify correct path/title
                msg = PageUtils.GetPage(p, newpath);
                string metapath  = msg.ToDocument()["path"].AsText ?? String.Empty;
                string metatitle = msg.ToDocument()["title"].AsText ?? String.Empty;

                // path should be Namespace:bbb, title should be bbb, page should be linked
                Assert.AreEqual(newpath, metapath, "Unexpected path");
                Assert.AreEqual(newtitle, metatitle, "Unexpected title");
                PageUtils.IsLinked(msg);

                // Delete page as to not contaminate the namespace
                PageUtils.DeletePageByName(p, newpath, true);
            }
        }
예제 #47
0
        //--- Constructors ---
        /// <summary>
        /// Create a new subscription set.
        /// </summary>
        /// <param name="owner">Owner uri.</param>
        /// <param name="version">Version serial number.</param>
        /// <param name="cookie">Pub sub location access cookie.</param>
        /// <param name="childSubscriptions">Subscriptions.</param>
        public PubSubSubscriptionSet(XUri owner, long version, DreamCookie cookie, params PubSubSubscription[] childSubscriptions)
        {
            Owner = owner;
            Version = version;
            Dictionary<string, PubSubSubscription> subs = new Dictionary<string, PubSubSubscription>();
            foreach(var sub in childSubscriptions) {
                foreach(var channel in sub.Channels) {
                    if(channel.Scheme == "pubsub") {

                        // pubsub scheme is for PubSubService internal use only, so it should never be aggregated
                        continue;
                    }
                    XUri[] resources = (sub.Resources == null || sub.Resources.Length == 0) ? new XUri[] { null } : sub.Resources;
                    foreach(XUri resource in resources) {
                        PubSubSubscription combo;
                        string key = channel + ":" + resource;
                        subs.TryGetValue(key, out combo);
                        subs[key] = PubSubSubscription.MergeForChannelAndResource(channel, resource, this, cookie, sub, combo);
                    }
                }
            }
            Subscriptions = new PubSubSubscription[subs.Count];
            subs.Values.CopyTo(Subscriptions, 0);
            MaxFailures = MAX_FAILURES;
        }
예제 #48
0
 public static string DoubleUrlEncode(string url)
 {
     return(XUri.DoubleEncodeSegment(url));
 }
예제 #49
0
 public DreamMessage SyncUri(XUri uri)
 {
     return Response(new XDoc("r").Elem("uri", uri.WithoutQuery()));
 }
예제 #50
0
 public static string DoubleUrlDecode(string url)
 {
     return(XUri.DoubleDecode(url));
 }
예제 #51
0
 public void Deregister_allows_reregister_of_uri()
 {
     XUri uri = new XUri("http://www.mindtouch.com/foo");
     int firstCalled = 0;
     MockPlug.Register(uri, delegate(Plug p, string v, XUri u, DreamMessage r, Result<DreamMessage> r2) {
         firstCalled++;
         r2.Return(DreamMessage.Ok());
     });
     Assert.IsTrue(Plug.New(uri).GetAsync().Wait().IsSuccessful);
     Assert.AreEqual(1, firstCalled);
     MockPlug.Deregister(uri);
     int secondCalled = 0;
     MockPlug.Register(uri, delegate(Plug p, string v, XUri u, DreamMessage r, Result<DreamMessage> r2) {
         secondCalled++;
         r2.Return(DreamMessage.Ok());
     });
     Assert.IsTrue(Plug.New(uri).GetAsync().Wait().IsSuccessful);
     Assert.AreEqual(1, firstCalled);
     Assert.AreEqual(1, secondCalled);
 }
예제 #52
0
        /// <summary>
        /// Try to get the best matching parent uri.
        /// </summary>
        /// <param name="key">Uri to match.</param>
        /// <param name="value">When the method returns <see langword="True"/>, this variable contains the reference object for matched parent Uri.</param>
        /// <returns><see langword="True"/> if a match was found.</returns>
        public bool TryGetValue(XUri key, out T value)
        {
            int similarity;

            return(TryGetValue(key, out value, out similarity));
        }
예제 #53
0
 public void Returns_callback_gets_request_data()
 {
     var doc = new XDoc("doc").Elem("foo", StringUtil.CreateAlphaNumericKey(6));
     var success = new XDoc("yay");
     var uri = new XUri("http://mock/foo/").With("foo", "baz");
     MockPlug.Setup(new XUri("http://mock/foo")).Returns(invocation => {
         if(invocation.Verb != "POST") {
             return DreamMessage.BadRequest("wrong verb: " + invocation.Verb);
         }
         if(invocation.Uri != uri) {
             return DreamMessage.BadRequest("wrong uri: " + invocation.Uri);
         }
         if(invocation.Request.Headers["header"] != "value") {
             return DreamMessage.BadRequest("wrong header value");
         }
         if(invocation.Request.ToDocument() != doc) {
             return DreamMessage.BadRequest("wrong body");
         }
         return DreamMessage.Ok(success);
     });
     var msg = Plug.New(uri).WithHeader("header", "value").Post(doc, new Result<DreamMessage>()).Wait();
     Assert.IsTrue(msg.IsSuccessful, msg.ToDocument().ToPrettyString());
     Assert.AreEqual(success, msg.ToDocument());
 }
예제 #54
0
 /// <summary>
 /// Add a new entry to the map.
 /// </summary>
 /// <param name="key">Key Uri.</param>
 /// <param name="value">Reference object.</param>
 public void Add(XUri key, T value)
 {
     Add(key, value, true);
 }
예제 #55
0
        public void CombinedSet_of_service_combines_all_registered_subs()
        {
            XUri c1 = new XUri("channel:///c1");
            XUri c2 = new XUri("channel:///c2");
            XUri c3 = new XUri("channel:///c3");
            XUri r1 = new XUri("http:///r1");
            XUri r2 = new XUri("http:///r2");
            XDoc set1 = new XDoc("subscription-set")
                .Attr("max-failures", 1)
                .Elem("uri.owner", "http:///owner1")
                .Start("subscription")
                    .Attr("id", "123")
                    .Elem("channel", c1)
                    .Elem("channel", c2)
                    .Elem("uri.proxy", "http:///proxy")
                    .Start("recipient").Attr("auth-token", "abc").Elem("uri", r1).End()
                .EndAll();
            XDoc set2 = new XDoc("subscription-set")
                .Attr("max-failures", 1)
                .Elem("uri.owner", "http:///owner2")
                .Start("subscription")
                    .Attr("id", "123")
                    .Elem("channel", c1)
                    .Elem("channel", c3)
                    .Elem("uri.proxy", "http:///proxy")
                    .Start("recipient").Attr("auth-token", "abc").Elem("uri", r2).End()
                .EndAll();

            Plug pubsub = CreatePubSubService().WithInternalKey().AtLocalHost;
            DreamMessage response = pubsub.At("subscribers").PostAsync(set1).Wait();
            Assert.IsTrue(response.IsSuccessful);
            Assert.AreEqual(DreamStatus.Created, response.Status);
            response = pubsub.At("subscribers").PostAsync(set2).Wait();
            Assert.IsTrue(response.IsSuccessful);
            Assert.AreEqual(DreamStatus.Created, response.Status);
            Thread.Sleep(1000);
            response = pubsub.At("subscribers").GetAsync().Wait();
            Assert.IsTrue(response.IsSuccessful);
            Assert.AreEqual(DreamStatus.Ok, response.Status);
            PubSubSubscriptionSet combinedSet = new PubSubSubscriptionSet(response.ToDocument(), "abc", "def");
            Assert.AreEqual(3, combinedSet.Subscriptions.Length);
            XUri owner = pubsub.Uri.WithoutQuery();
            foreach(PubSubSubscription subx in combinedSet.Subscriptions) {
                switch(subx.Channels[0].ToString()) {
                case "channel:///c1":
                    Assert.AreEqual(owner.At("publish"), subx.Destination);
                    Assert.AreEqual(1, subx.Channels.Length);
                    Assert.AreEqual(c1, subx.Channels[0]);
                    Assert.AreEqual(2, subx.Recipients.Length);
                    bool foundR1 = false;
                    bool foundR2 = false;
                    foreach(DispatcherRecipient r in subx.Recipients) {
                        if(r.Uri == r1) {
                            foundR1 = true;
                        } else if(r.Uri == r2) {
                            foundR2 = true;
                        }
                    }
                    Assert.IsTrue(foundR1 && foundR2);
                    break;
                case "channel:///c2":
                    Assert.AreEqual(owner.At("publish"), subx.Destination);
                    Assert.AreEqual(1, subx.Channels.Length);
                    Assert.AreEqual(c2, subx.Channels[0]);
                    Assert.AreEqual(1, subx.Recipients.Length);
                    Assert.AreEqual(r1, subx.Recipients[0].Uri);
                    break;
                case "channel:///c3":
                    Assert.AreEqual(owner.At("publish"), subx.Destination);
                    Assert.AreEqual(1, subx.Channels.Length);
                    Assert.AreEqual(c3, subx.Channels[0]);
                    Assert.AreEqual(1, subx.Recipients.Length);
                    Assert.AreEqual(r2, subx.Recipients[0].Uri);
                    break;
                default:
                    Assert.Fail();
                    break;
                }
            }
        }
예제 #56
0
 public XUri Blend(
     [DekiExtParam("image uri")] XUri image
     )
 {
     return(Process(image, "-size 500x500 - -matte -virtual-pixel transparent -channel A -blur 0x8 -evaluate subtract 50% -evaluate multiply 2.001"));
 }
예제 #57
0
        public void Parallel_chaining_subscription_and_message_propagation()
        {
            var rootPubsub = Plug.New(_hostInfo.Host.LocalMachineUri.At("host", "$pubsub", "subscribers"));
            var goTrigger = new ManualResetEvent(false);
            var pubsubResults = new List<Result<Plug>>();
            for(var i = 0; i < 10; i++) {
                pubsubResults.Add(Async.ForkThread(() => {
                    goTrigger.WaitOne();
                    return CreatePubSubService("upstream", new XDoc("config").Start("downstream").Elem("uri", rootPubsub).End()).WithInternalKey().AtLocalHost;
                }, new Result<Plug>()));
            }
            var subscriberResults = new List<Result<Tuplet<XUri, AutoMockPlug>>>();
            for(var i = 0; i < 20; i++) {
                var mockUri = new XUri("http://mock/" + i);
                subscriberResults.Add(Async.ForkThread(() => {
                    goTrigger.WaitOne();
                    rootPubsub.With("apikey", _hostInfo.ApiKey).Post(new XDoc("subscription-set")
                        .Elem("uri.owner", mockUri)
                        .Start("subscription")
                            .Attr("id", "1")
                            .Elem("channel", "channel://foo/bar")
                            .Start("recipient").Elem("uri", mockUri).End()
                        .End());
                    var mock = MockPlug.Register(mockUri);
                    return new Tuplet<XUri, AutoMockPlug>(mockUri, mock);
                }, new Result<Tuplet<XUri, AutoMockPlug>>()));
            }
            goTrigger.Set();
            var pubsubs = new List<Plug>();
            foreach(var r in pubsubResults) {
                pubsubs.Add(r.Wait());
            }
            var endpoints = new List<XUri>();
            var mocks = new List<AutoMockPlug>();
            foreach(var r in subscriberResults) {
                var v = r.Wait();
                endpoints.Add(v.Item1);
                mocks.Add(v.Item2);
            }
            foreach(var pubsub in pubsubs) {
                Plug plug = pubsub;
                Wait.For(() => {
                    var set = plug.At("subscribers").Get();
                    return set.ToDocument()["subscription/recipient"].ListLength == endpoints.Count;
                }, TimeSpan.FromSeconds(10));
            }
            var ev = new DispatcherEvent(new XDoc("blah"), new XUri("channel://foo/bar"), new XUri("http://foobar.com/some/page"));

            foreach(var mock in mocks) {
                mock.Expect().Verb("POST").RequestDocument(ev.AsDocument()).Response(DreamMessage.Ok());
            }
            pubsubs[0].At("publish").Post(ev.AsMessage());
            foreach(var mock in mocks) {
                Assert.IsTrue(mock.WaitAndVerify(TimeSpan.FromSeconds(10)), mock.VerificationFailure);
            }
        }
예제 #58
0
 public XUri Flip(
     [DekiExtParam("image uri")] XUri image
     )
 {
     return(Process(image, "-size 500x500 - -flip"));
 }
예제 #59
0
        public void Can_aggregate_from_multiple_dream_hosts()
        {
            // set up hosts
            _log.DebugFormat("---- creating upstream hosts");
            var sourceHost1 = DreamTestHelper.CreateRandomPortHost();
            var source1PubSub = Plug.New(sourceHost1.LocalHost.At("host", "$pubsub").With("apikey", sourceHost1.ApiKey));
            var sourceHost2 = DreamTestHelper.CreateRandomPortHost();
            var source2PubSub = Plug.New(sourceHost2.LocalHost.At("host", "$pubsub").With("apikey", sourceHost2.ApiKey));

            // create aggregator
            _log.DebugFormat("---- creating downstream host");
            var aggregatorPath = "pubsubaggregator";
            var aggregatorHost = DreamTestHelper.CreateRandomPortHost();
            aggregatorHost.Host.RunScripts(new XDoc("config")
                .Start("script").Start("action")
                    .Attr("verb", "POST")
                    .Attr("path", "/host/services")
                    .Start("config")
                        .Elem("path", aggregatorPath)
                        .Elem("sid", "sid://mindtouch.com/dream/2008/10/pubsub")
                        .Elem("apikey", "abc")
                        .Start("upstream")
                            .Elem("uri", source1PubSub.At("subscribers"))
                            .Elem("uri", source2PubSub.At("subscribers"))
                    .End()
                .End().End(), null);
            var aggregatorPubSub = aggregatorHost.LocalHost.At(aggregatorPath).With("apikey", "abc");

            // create subscription
            _log.DebugFormat("---- create downstream subscription");
            var testUri = new XUri("http://mock/aggregator");
            var serviceKey = "1234";
            var accessCookie = DreamCookie.NewSetCookie("service-key", serviceKey, testUri);
            var subscriberApiKey = "xyz";
            var set = new XDoc("subscription-set")
                .Elem("uri.owner", "http:///owner1")
                .Start("subscription")
                    .Attr("id", "1")
                    .Add(accessCookie.AsSetCookieDocument)
                    .Elem("channel", "channel:///foo/*")
                    .Start("recipient")
                        .Attr("authtoken", subscriberApiKey)
                        .Elem("uri", testUri)
                    .End()
                .End();
            var r = aggregatorPubSub.At("subscribers").PostAsync(set).Wait();
            Assert.IsTrue(r.IsSuccessful, r.Status.ToString());
            Assert.AreEqual(DreamStatus.Created, r.Status);

            // Verify that upstream host pubsub services have the subscription
            Func<DreamMessage, bool> waitFunc = response => {
                var sub = response.ToDocument()["subscription-set/subscription[channel='channel:///foo/*']"];
                return (!sub.IsEmpty
                        && sub["recipient/uri"].AsText.EqualsInvariantIgnoreCase(testUri.ToString())
                        && sub["recipient/@authtoken"].AsText.EqualsInvariant(subscriberApiKey));
            };
            Assert.IsTrue(WaitFor(source1PubSub.At("diagnostics", "subscriptions"), waitFunc, TimeSpan.FromSeconds(5)), "source 1 didn't get the subscription");
            Assert.IsTrue(WaitFor(source2PubSub.At("diagnostics", "subscriptions"), waitFunc, TimeSpan.FromSeconds(5)), "source 2 didn't get the subscription");

            // set up destination mock
            DispatcherEvent aggregatorEvent = new DispatcherEvent(
                new XDoc("aggregator"),
                new XUri("channel:///foo/bar"),
                new XUri("http://foobar.com/some/page"));
            DispatcherEvent source1Event = new DispatcherEvent(
                new XDoc("source1"),
                new XUri("channel:///foo/bar"),
                new XUri("http://foobar.com/some/page"));
            DispatcherEvent source2Event = new DispatcherEvent(
                new XDoc("source2"),
                new XUri("channel:///foo/bar"),
                new XUri("http://foobar.com/some/page"));
            var mock = MockPlug.Register(testUri);

            // Publish event into aggregator
            mock.Expect().Verb("POST").RequestDocument(aggregatorEvent.AsDocument());
            r = aggregatorPubSub.At("publish").PostAsync(aggregatorEvent.AsMessage()).Wait();
            Assert.IsTrue(r.IsSuccessful, r.Status.ToString());
            Assert.IsTrue(mock.WaitAndVerify(TimeSpan.FromSeconds(10)), mock.VerificationFailure);

            // Publish event into source1
            mock.Reset();
            mock.Expect().Verb("POST").RequestDocument(source1Event.AsDocument());
            r = source1PubSub.At("publish").PostAsync(source1Event.AsMessage()).Wait();
            Assert.IsTrue(r.IsSuccessful, r.Status.ToString());
            Assert.IsTrue(mock.WaitAndVerify(TimeSpan.FromSeconds(10)), mock.VerificationFailure);

            // Publish event into source2
            mock.Reset();
            mock.Expect().Verb("POST").RequestDocument(source2Event.AsDocument());
            r = source2PubSub.At("publish").PostAsync(source2Event.AsMessage()).Wait();
            Assert.IsTrue(r.IsSuccessful, r.Status.ToString());
            Assert.IsTrue(mock.WaitAndVerify(TimeSpan.FromSeconds(10)), mock.VerificationFailure);
        }
예제 #60
0
 public void EncodeSegment()
 {
     Assert.AreEqual("a^b", XUri.EncodeSegment("a^b"));
 }