Esempio n. 1
0
        // Must be called from within the ThreadSafety
        private void StartInternal()
        {
            _desc = ToString(); // Cache this; it may be called a lot when logging

            // Target:
            var      addr      = new C4Address();
            var      scheme    = new C4String();
            var      host      = new C4String();
            var      path      = new C4String();
            Database otherDB   = null;
            var      remoteUrl = Config.RemoteUrl;
            string   dbNameStr = null;

            if (remoteUrl != null)
            {
                var pathStr = String.Concat(remoteUrl.Segments.Take(remoteUrl.Segments.Length - 1));
                dbNameStr     = remoteUrl.Segments.Last().TrimEnd('/');
                scheme        = new C4String(remoteUrl.Scheme);
                host          = new C4String(remoteUrl.Host);
                path          = new C4String(pathStr);
                addr.scheme   = scheme.AsC4Slice();
                addr.hostname = host.AsC4Slice();
                addr.port     = (ushort)remoteUrl.Port;
                addr.path     = path.AsC4Slice();
            }
            else
            {
                otherDB = Config.OtherDB;
            }

            var options  = Config.Options;
            var userInfo = remoteUrl?.UserInfo?.Split(':');

            if (userInfo?.Length == 2)
            {
                throw new ArgumentException(
                          "Embedded credentials in a URL (username:password@url) are not allowed; use the BasicAuthenticator class instead");
            }

            Config.Authenticator?.Authenticate(options);

            options.Build();
            var push       = Config.ReplicatorType.HasFlag(ReplicatorType.Push);
            var pull       = Config.ReplicatorType.HasFlag(ReplicatorType.Pull);
            var continuous = Config.Continuous;

            // Clear the reset flag, it is a one-time thing
            Config.Options.Reset = false;

            var socketFactory = Config.SocketFactory;

            socketFactory.context = GCHandle.ToIntPtr(GCHandle.Alloc(this)).ToPointer();
            _nativeParams         = new ReplicatorParameters(options)
            {
                Push            = Mkmode(push, continuous),
                Pull            = Mkmode(pull, continuous),
                Context         = this,
                OnDocumentError = OnDocError,
                OnStatusChanged = StatusChangedCallback,
                SocketFactory   = &socketFactory
            };

            var err    = new C4Error();
            var status = default(C4ReplicatorStatus);

            _stopping = false;
            _databaseThreadSafety.DoLocked(() =>
            {
                C4Error localErr;
                _repl = Native.c4repl_new(Config.Database.c4db, addr, dbNameStr, otherDB != null ? otherDB.c4db : null,
                                          _nativeParams.C4Params, &localErr);
                err = localErr;
                if (_repl != null)
                {
                    status = Native.c4repl_getStatus(_repl);
                    Config.Database.ActiveReplications.Add(this);
                }
                else
                {
                    status = new C4ReplicatorStatus {
                        error    = err,
                        level    = C4ReplicatorActivityLevel.Stopped,
                        progress = new C4Progress()
                    };
                }
            });

            scheme.Dispose();
            path.Dispose();
            host.Dispose();

            UpdateStateProperties(status);
            DispatchQueue.DispatchSync(() => StatusChangedCallback(status));
        }
 public static C4Replicator *c4repl_new(C4Database *db, C4Address remoteAddress, FLSlice remoteDatabaseName, C4Database *otherLocalDB, C4ReplicatorParameters @params, C4Error *outError) => Impl.c4repl_new(db, remoteAddress, remoteDatabaseName, otherLocalDB, @params, outError);
 public static C4SliceResult c4db_getCookies(C4Database *db, C4Address request, C4Error *error) => Impl.c4db_getCookies(db, request, error);
 public static C4SliceResult c4address_toURL(C4Address address) => Impl.c4address_toURL(address);
 public static string c4address_toURL(C4Address address) => Impl.c4address_toURL(address);
Esempio n. 6
0
        private C4Error SetupC4Replicator()
        {
            Config.Database.CheckOpenLocked();
            C4Error err = new C4Error();

            if (_repl != null)
            {
                Native.c4repl_setOptions(_repl, ((FLSlice)Config.Options.FLEncode()).ToArrayFast());
                return(err);
            }

            _desc = ToString(); // Cache this; it may be called a lot when logging

            // Target:
            var      addr      = new C4Address();
            var      scheme    = new C4String();
            var      host      = new C4String();
            var      path      = new C4String();
            Database otherDB   = null;
            var      remoteUrl = Config.RemoteUrl;
            string   dbNameStr = null;

            if (remoteUrl != null)
            {
                var pathStr = String.Concat(remoteUrl.Segments.Take(remoteUrl.Segments.Length - 1));
                dbNameStr     = remoteUrl.Segments.Last().TrimEnd('/');
                scheme        = new C4String(remoteUrl.Scheme);
                host          = new C4String(remoteUrl.Host);
                path          = new C4String(pathStr);
                addr.scheme   = scheme.AsFLSlice();
                addr.hostname = host.AsFLSlice();
                addr.port     = (ushort)remoteUrl.Port;
                addr.path     = path.AsFLSlice();

                //get cookies from url and add to replicator options
                var cookiestring = Config.Database.GetCookies(remoteUrl);
                if (!String.IsNullOrEmpty(cookiestring))
                {
                    var split = cookiestring.Split(';') ?? Enumerable.Empty <string>();
                    foreach (var entry in split)
                    {
                        var pieces = entry?.Split('=');
                        if (pieces?.Length != 2)
                        {
                            WriteLog.To.Sync.W(Tag, "Garbage cookie value, ignoring");
                            continue;
                        }

                        Config.Options.Cookies.Add(new Cookie(pieces[0]?.Trim(), pieces[1]?.Trim()));
                    }
                }
            }
            else
            {
                Config.OtherDB?.CheckOpenLocked();
                otherDB = Config.OtherDB;
            }

            var options = Config.Options;

            Config.Authenticator?.Authenticate(options);

            options.Build();
            var push       = Config.ReplicatorType.HasFlag(ReplicatorType.Push);
            var pull       = Config.ReplicatorType.HasFlag(ReplicatorType.Pull);
            var continuous = Config.Continuous;

            var socketFactory = Config.SocketFactory;

            socketFactory.context = GCHandle.ToIntPtr(GCHandle.Alloc(this)).ToPointer();
            _nativeParams         = new ReplicatorParameters(options)
            {
                Push            = Mkmode(push, continuous),
                Pull            = Mkmode(pull, continuous),
                Context         = this,
                OnDocumentEnded = OnDocEnded,
                OnStatusChanged = StatusChangedCallback,
                SocketFactory   = &socketFactory
            };

            // Clear the reset flag, it is a one-time thing
            options.Reset = false;

            if (Config.PushFilter != null)
            {
                _nativeParams.PushFilter = PushFilterCallback;
            }
            if (Config.PullFilter != null)
            {
                _nativeParams.PullFilter = PullValidateCallback;
            }

            DispatchQueue.DispatchSync(() =>
            {
                C4Error localErr = new C4Error();
            #if COUCHBASE_ENTERPRISE
                if (otherDB != null)
                {
                    _repl = Native.c4repl_newLocal(Config.Database.c4db, otherDB.c4db, _nativeParams.C4Params,
                                                   &localErr);
                }
                else
            #endif
                _repl = Native.c4repl_new(Config.Database.c4db, addr, dbNameStr, _nativeParams.C4Params, &localErr);
                err   = localErr;
            });

            scheme.Dispose();
            path.Dispose();
            host.Dispose();

            return(err);
        }