// 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);
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); }