public void TestSaveCookieStore()
        {
            var cookieStore = new CookieStore(GetCookiesDirectory().FullName);
            Assert.AreEqual(0, cookieStore.Count);

            var name = "foo";
            var value = "bar";
            var uri = new Uri("http://foo.com/baz");
            var domain = uri.Host;
            var path = uri.PathAndQuery;
            var httpOnly = false;
            var isSecure = false;
            var expires = DateTime.Now.Add(TimeSpan.FromDays(1));

            var cookie = new Cookie(name, value);
            cookie.Path = path;
            cookie.Domain = domain;
            cookie.HttpOnly = httpOnly;
            cookie.Secure = isSecure;
            cookie.Expires = expires;

            cookieStore.Add(cookie);
            cookieStore.Save();

            cookieStore = new CookieStore(GetCookiesDirectory().FullName);
            Assert.AreEqual(1, cookieStore.Count);

            var cookies = cookieStore.GetCookies(uri);
            Assert.AreEqual(1, cookies.Count);
            Assert.AreEqual(name, cookies[0].Name);
            Assert.AreEqual(value, cookies[0].Value);
            Assert.AreEqual(path, cookies[0].Path);
            Assert.AreEqual(domain, cookies[0].Domain);
            Assert.AreEqual(expires, cookies[0].Expires);
        }
 public DefaultAuthHandler(HttpClientHandler context, CookieStore cookieStore, bool chunkedMode)
 {
     _chunkedMode = chunkedMode;
     _context = context;
     _cookieStore = cookieStore;
     InnerHandler = _context;
 }
 public DefaultAuthHandler(HttpClientHandler context, CookieStore cookieStore, bool chunkedMode) : base()
 {
     _chunkedMode = chunkedMode;
     this.context = context;
     this.cookieStore = cookieStore;
     InnerHandler = this.context;
 }
        public CouchbaseLiteHttpClientFactory(CookieStore cookieStore)
        {
            this.cookieStore = cookieStore;
            Headers = new ConcurrentDictionary<string,string>();

            // Disable SSL 3 fallback to mitigate POODLE vulnerability.
            ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls;

            //
            // Source: http://msdn.microsoft.com/en-us/library/office/dd633677(v=exchg.80).aspx
            // ServerCertificateValidationCallback returns true if either of the following criteria are met:
            // The certificate is valid and signed with a valid root certificate.
            // The certificate is self-signed by the server that returned the certificate.
            //
            ServicePointManager.ServerCertificateValidationCallback = 
            (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) =>
            {
                // If the certificate is a valid, signed certificate, return true.
                if (sslPolicyErrors == SslPolicyErrors.None)
                {
                    return true;
                }

                // If there are errors in the certificate chain, look at each error to determine the cause.
                if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0)
                {
                    if (chain != null && chain.ChainStatus != null)
                    {
                        foreach (X509ChainStatus status in chain.ChainStatus)
                        {
                            if ((certificate.Subject == certificate.Issuer) &&
                                (status.Status == X509ChainStatusFlags.UntrustedRoot))
                            {
                                // Self-signed certificates with an untrusted root are valid. 
                                continue;
                            }
                            else
                            {
                                if (status.Status != X509ChainStatusFlags.NoError)
                                {
                                    // If there are any other errors in the certificate chain, the certificate is invalid,
                                    // so the method returns false.
                                    return false;
                                }
                            }
                        }
                    }

                    // When processing reaches this line, the only errors in the certificate chain are 
                    // untrusted root errors for self-signed certificates. These certificates are valid
                    // for default Exchange server installations, so return true.
                    return true;
                }
                else
                {
                    // In all other cases, return false.
                    return false;
                }
            };
        }
        public MockHttpClientFactory(DirectoryInfo cookieStoreDirectory, bool defaultFail = true)
        {
            cookieStore = new CookieStore(cookieStoreDirectory != null 
                ? cookieStoreDirectory.FullName
                : null);
            HttpHandler = new MockHttpRequestHandler(defaultFail);
            HttpHandler.CookieContainer = cookieStore;
            HttpHandler.UseCookies = true;

            Headers = new Dictionary<string,string>();
        }
        public MockHttpClientFactory(DirectoryInfo cookieStoreDirectory, bool defaultFail = true)
        {
            cookieStore = new CookieStore(cookieStoreDirectory != null 
                ? cookieStoreDirectory.FullName
                : null);
            HttpHandler = new MockHttpRequestHandler(defaultFail);
            HttpHandler.CookieContainer = cookieStore;
            HttpHandler.UseCookies = true;
            HttpHandler.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;

            Headers = new Dictionary<string,string>();
        }
        public void TestSetCookiePersistent()
        {
            var cookieStore = new CookieStore(database, "cookie_store_unit_test");
            Assert.AreEqual(0, cookieStore.Count);

            var cookie1 = new Cookie("whitechoco", "sweet", "/", "mycookie.com") {
                Comment = "yummy",
                CommentUri = new Uri("http://www.mycookie.com"),
                Expires = DateTime.Now.AddSeconds(60),
            };
            cookieStore.Add(cookie1);

            var cookie2 = new Cookie("darkchoco", "sweet", "/", "mycookie.com") {
                Comment = "yummy",
                CommentUri = new Uri("http://www.mycookie.com"),
                Expires = DateTime.Now.AddSeconds(60)
            };
            cookieStore.Add(cookie2);

            var cookies = cookieStore.GetCookies(new Uri("http://mycookie.com"));
            Assert.AreEqual(2, cookieStore.Count);
            Assert.AreEqual(cookie1, cookies[0]);
            Assert.AreEqual(cookie2, cookies[1]);

            // Set cookie with same name, domain, and path
            // with one of the previously set cookies:
            var cookie3 = new Cookie("darkchoco", "bitter sweet", "/", "mycookie.com") {
                Comment = "yummy",
                CommentUri = new Uri("http://www.mycookie.com"),
                Expires = DateTime.Now.AddSeconds(60)
            };
            cookieStore.Add(cookie3);
            Assert.AreEqual(2, cookieStore.Count);
            cookies = cookieStore.GetCookies(new Uri("http://mycookie.com"));
            Assert.AreEqual(cookie1, cookies[0]);
            Assert.AreEqual(cookie3, cookies[1]);

            cookieStore = new CookieStore(database, "cookie_store_unit_test");
            cookies = cookieStore.GetCookies(new Uri("http://mycookie.com"));
            Assert.AreEqual(2, cookieStore.Count);
            Assert.AreEqual(cookie1, cookies[0]);
            Assert.AreEqual(cookie3, cookies[1]);
        }
        /// <summary>
        /// Build a pipeline of HttpMessageHandlers.
        /// </summary>
        internal HttpMessageHandler BuildHandlerPipeline (CookieStore store, IRetryStrategy retryStrategy)
        {
            var handler = new WebRequestHandler {
                CookieContainer = store,
                UseCookies = true,
                ReadWriteTimeout = (int)SocketTimeout.TotalMilliseconds
            };

            // For now, we are not using the client cert for identity verification, just to
            // satisfy Mono so it doesn't matter if the user doesn't choose it.
            //handler.ClientCertificates.Add(SSLGenerator.GetOrCreateClientCert());

            if(handler.SupportsAutomaticDecompression) {
                handler.AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate;
            }

            var authHandler = new DefaultAuthHandler (handler, store, SocketTimeout);
            if (retryStrategy == null) {
                return authHandler;
            }

            var retryHandler = new TransientErrorRetryHandler(authHandler, retryStrategy);
            return retryHandler;
        }
        public CouchbaseLiteHttpClient GetHttpClient(CookieStore cookieStore, IRetryStrategy retryStrategy)
        {
            var authHandler = BuildHandlerPipeline(cookieStore, retryStrategy);

            // As the handler will not be shared, client.Dispose() needs to be 
            // called once the operation is done to release the unmanaged resources 
            // and disposes of the managed resources.
            var client =  new HttpClient(authHandler, true) 
            {
                Timeout = ReplicationOptions.DefaultRequestTimeout
            };

            client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", String.Format("CouchbaseLite/{0} ({1})", Replication.SyncProtocolVersion, Manager.VersionString));
            client.DefaultRequestHeaders.Connection.Add("keep-alive");

            foreach(var header in Headers)
            {
                var success = client.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value);
                if (!success)
                    Log.To.Sync.W(Tag, String.Format("Unabled to add header to request: {0}: {1}", header.Key, header.Value));
            }

            var transientHandler = authHandler as TransientErrorRetryHandler;
            var defaultAuthHandler = default(DefaultAuthHandler);
            if (transientHandler != null) {
                defaultAuthHandler = transientHandler.InnerHandler as DefaultAuthHandler;
            } else {
                defaultAuthHandler = authHandler as DefaultAuthHandler;
            }

            return new CouchbaseLiteHttpClient(client, defaultAuthHandler);
        }
 public CouchbaseLiteHttpClient GetHttpClient(CookieStore cookieStore, IRetryStrategy strategy)
 {
     var mockHttpClient = new HttpClient(HttpHandler);
     return new CouchbaseLiteHttpClient(mockHttpClient, null);
 }
        protected void SetClientFactory(IHttpClientFactory clientFactory)
        {
            if (clientFactory != null)
            {
                this.clientFactory = clientFactory;
            }
            else
            {
                Manager manager = null;
                if (LocalDatabase != null)
                {
                    manager = LocalDatabase.Manager;
                }

                IHttpClientFactory managerClientFactory = null;
                if (manager != null)
                {
                    managerClientFactory = manager.DefaultHttpClientFactory;
                }

                if (managerClientFactory != null)
                {
                    this.clientFactory = managerClientFactory;
                }
                else
                {
                    CookieStore cookieStore = null;
                    if (manager != null)
                    {
                        cookieStore = manager.SharedCookieStore;
                    }

                    if (cookieStore == null)
                    {
                        cookieStore = new CookieStore();
                    }

                    this.clientFactory = new CouchbaseLiteHttpClientFactory(cookieStore);
                }
            }
        }
        /// <summary>
        /// Build a pipeline of HttpMessageHandlers.
        /// </summary>
        internal HttpMessageHandler BuildHandlerPipeline (CookieStore store)
        {
            var handler = new HttpClientHandler {
                CookieContainer = store,
                UseCookies = true
            };

            // For now, we are not using the client cert for identity verification, just to
            // satisfy Mono so it doesn't matter if the user doesn't choose it.
            //handler.ClientCertificates.Add(SSLGenerator.GetOrCreateClientCert());

            if(handler.SupportsAutomaticDecompression) {
                handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
            }

            Handler = new DefaultAuthHandler (handler, store);

            var retryHandler = new TransientErrorRetryHandler(Handler);

            return retryHandler;
        }
        public HttpClient GetHttpClient(CookieStore cookieStore)
        {
            var authHandler = BuildHandlerPipeline(cookieStore);

            // As the handler will not be shared, client.Dispose() needs to be 
            // called once the operation is done to release the unmanaged resources 
            // and disposes of the managed resources.
            var client =  new HttpClient(authHandler, true) 
            {
                Timeout = ManagerOptions.Default.RequestTimeout
            };

            client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", String.Format("CouchbaseLite/{0} ({1})", Replication.SYNC_PROTOCOL_VERSION, Manager.VersionString));

            foreach(var header in Headers)
            {
                var success = client.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value);
                if (!success)
                    Log.W(Tag, "Unabled to add header to request: {0}: {1}".Fmt(header.Key, header.Value));
            }

            return client;
        }
        public void TestSaveEmptyCookieStore()
        {
            var cookieStore = new CookieStore(GetCookiesDirectory().FullName);
            Assert.AreEqual(0, cookieStore.Count);
            cookieStore.Save();

            cookieStore = new CookieStore(GetCookiesDirectory().FullName);
            Assert.AreEqual(0, cookieStore.Count);
        }
 public DefaultAuthHandler(HttpClientHandler context, CookieStore cookieStore)
 {
     _cookieStore = cookieStore;
     InnerHandler = context;
 }
 public HttpClient GetHttpClient(CookieStore cookieStore)
 {
     var mockHttpClient = new HttpClient(HttpHandler);
     return mockHttpClient;
 }
        public void TestFacebookAuth()
        {
            var doneEvent = new ManualResetEvent(false);

            var accountStore = new ACAccountStore();
            var accountType = accountStore.FindAccountType(ACAccountType.Facebook);

            var options = new AccountStoreOptions();
            options.FacebookAppId = FacebookAppId;
            options.SetPermissions(ACFacebookAudience.Friends, new [] { "email" });

            var success = true;
            ACAccount account = null;
            accountStore.RequestAccess(accountType, options, (result, error) => 
            {
                success = result;
                if (success)
                {
                    var accounts = accountStore.FindAccounts(accountType);
                    account = accounts != null && accounts.Length > 0 ? accounts[0] : null;
                }
                else
                {
                    Log.W(Tag, "Facebook Login needed. Go to Settings > Facebook and login.");
                    Log.E(Tag, "Facebook Request Access Error : " + error);
                }
                doneEvent.Set();
            });

            doneEvent.WaitOne(TimeSpan.FromSeconds(30));

            Assert.IsTrue(success);
            Assert.IsNotNull(account);

            var token = account.Credential.OAuthToken;
            Assert.IsNotNull(token);
            Assert.IsTrue(token.Length > 0);

            var url = GetReplicationURLWithoutCredentials();

            var cookieStore = new CookieStore();
            var httpClientFactory = new CouchbaseLiteHttpClientFactory(cookieStore);
            manager.DefaultHttpClientFactory = httpClientFactory;
            Replication replicator = database.CreatePushReplication(url);
            replicator.Authenticator = AuthenticatorFactory.CreateFacebookAuthenticator(token);

            Assert.IsNotNull(replicator);
            Assert.IsNotNull(replicator.Authenticator);
            Assert.IsTrue(replicator.Authenticator is TokenAuthenticator);

            replicator.Start();

            doneEvent.Reset();
            Task.Factory.StartNew(()=>
            {
                var timeout = DateTime.UtcNow + TimeSpan.FromSeconds(30);
                while (DateTime.UtcNow < timeout)
                {
                    if (!replicator.active)
                    {
                        break;
                    }
                    System.Threading.Thread.Sleep(TimeSpan.FromMilliseconds(10));
                }
                doneEvent.Set();
            });
            doneEvent.WaitOne(TimeSpan.FromSeconds(35));

            var urlStr = url.ToString();
            urlStr = urlStr.EndsWith("/") ? urlStr : urlStr + "/";
            var cookies = httpClientFactory.GetCookieContainer().GetCookies(new Uri(urlStr));
            Assert.IsTrue(cookies.Count == 1);
            Assert.AreEqual("SyncGatewaySession", cookies[0].Name);
        }
        public void TestSetCookieNameDomainPath()
        {
            var cookieStore = new CookieStore(database, "cookie_store_unit_test");
            Assert.AreEqual(0, cookieStore.Count);
            var cookie1 = new Cookie("cookie1", "sweet", "/", "mycookie.com");
            cookieStore.Add(cookie1);
            var cookie2 = new Cookie("cookie1", "sweet", "", "mycookie.com");
            cookieStore.Add(cookie2);
            var cookie3 = new Cookie("cookie1", "sweet", "/path", "mycookie.com");
            cookieStore.Add(cookie3);
            var cookie4 = new Cookie("cookie1", "sweet", "/path/", "mycookie.com");
            cookieStore.Add(cookie4);
            var cookie5 = new Cookie("cookie1", "sweet", "/", "www.mycookie.com");
            cookieStore.Add(cookie5);
            var cookie6 = new Cookie("cookie7", "sweet", "/", "www.mycookie.com");
            cookieStore.Add(cookie6);

            Assert.AreEqual(6, cookieStore.Count);
            var cookies = cookieStore.GetCookies(new Uri("http://www.mycookie.com/path/"));
            Assert.AreEqual(6, cookies.Count);
            CollectionAssert.Contains(cookies, cookie1);
            CollectionAssert.Contains(cookies, cookie2);
            CollectionAssert.Contains(cookies, cookie3);
            CollectionAssert.Contains(cookies, cookie4);
            CollectionAssert.Contains(cookies, cookie5);
            CollectionAssert.Contains(cookies, cookie6);

            var cookie8 = new Cookie("cookie1", "bitter. sweet", "/", "mycookie.com");
            cookieStore.Add(cookie8);

            Assert.AreEqual(6, cookieStore.Count);
            cookies = cookieStore.GetCookies(new Uri("http://www.mycookie.com/path/"));
            Assert.AreEqual(6, cookies.Count);
            CollectionAssert.DoesNotContain(cookies, cookie1);
            CollectionAssert.Contains(cookies, cookie8);
        }
        public void TestSaveEmptyCookieStore()
        {
            var cookieStore = new CookieStore(database, "cookie_store_unit_test");
            Assert.AreEqual(0, cookieStore.Count);
            cookieStore.Save();

            cookieStore = new CookieStore(database, "cookie_store_unit_test");
            Assert.AreEqual(0, cookieStore.Count);
        }
        public void TestCookieExpires()
        {
            var cookieStore = new CookieStore(database, "cookie_store_unit_test");
            Assert.AreEqual(0, cookieStore.Count);

            var cookie1 = new Cookie("whitechoco", "sweet", "/", ".mycookie.com") {
                Expires = DateTime.Now.AddSeconds(1),
                Version = 1
            };
            cookieStore.Add(cookie1);

            Assert.AreEqual(1, cookieStore.Count);
            var cookies = cookieStore.GetCookies(new Uri("http://mycookie.com"));
            Assert.AreEqual(1, cookies.Count);
            Assert.AreEqual(cookie1, cookies[0]);

            Sleep(1500);

            Assert.AreEqual(0, cookieStore.Count);
        }
        public void TestDeleteCookie()
        {
            var cookieStore = new CookieStore(database, "cookie_store_unit_test");
            Assert.AreEqual(0, cookieStore.Count);

            var cookie1 = new Cookie("whitechoco", "sweet", "/", "mycookie.com") {
                Expires = DateTime.Now.AddSeconds(3600),
            };
            cookieStore.Add(cookie1);

            var cookie2 = new Cookie("oatmeal_raisin", "sweet", "/", "mycookie.com") {
                Expires = DateTime.Now.AddSeconds(3600),
            };
            cookieStore.Add(cookie2);

            var cookie3 = new Cookie("darkchoco", "sweet", "/", "mycookie.com") {
                Expires = DateTime.Now.AddSeconds(3600),
            };
            cookieStore.Add(cookie3);

            Assert.AreEqual(3, cookieStore.Count);
            var cookies = cookieStore.GetCookies(new Uri("http://mycookie.com"));
            CollectionAssert.Contains(cookies, cookie1);
            CollectionAssert.Contains(cookies, cookie2);
            CollectionAssert.Contains(cookies, cookie3);

            cookieStore.Delete(new Uri("http://mycookie.com"), cookie2.Name);
            Assert.AreEqual(2, cookieStore.Count);
            cookies = cookieStore.GetCookies(new Uri("http://mycookie.com"));
            CollectionAssert.Contains(cookies, cookie1);
            CollectionAssert.Contains(cookies, cookie3);

            cookieStore = new CookieStore(database, "cookie_store_unit_test");
            Assert.AreEqual(2, cookieStore.Count);
            cookies = cookieStore.GetCookies(new Uri("http://mycookie.com"));
            CollectionAssert.Contains(cookies, cookie1);
            CollectionAssert.Contains(cookies, cookie3);

            cookieStore.Delete(new Uri("http://mycookie.com"), cookie1.Name);
            cookieStore.Delete(new Uri("http://mycookie.com"), cookie3.Name);
            Assert.AreEqual(0, cookieStore.Count);

            cookieStore = new CookieStore(database, "cookie_store_unit_test");
            Assert.AreEqual(0, cookieStore.Count);
        }
        public void TestSetCookieSessionOnly()
        {
            var cookieStore = new CookieStore(database, "cookie_store_unit_test");
            Assert.AreEqual(0, cookieStore.Count);

            // No expires date specified for a cookie v0:
            var cookie1 = new Cookie("whitechoco", "sweet", "/", "mycookie.com");
            Assert.AreEqual(DateTime.MinValue, cookie1.Expires);
            cookieStore.Add(cookie1);

            // No max age specified for a cookie v1:
            var cookie2 = new Cookie("oatmeal_raisin", "sweet", "/", ".mycookie.com") { Version = 1 };
            Assert.AreEqual(DateTime.MinValue, cookie2.Expires);
            cookieStore.Add(cookie2);

            Assert.AreEqual(2, cookieStore.Count);
            var cookies = cookieStore.GetCookies(new Uri("http://mycookie.com"));
            Assert.AreEqual(cookie1, cookies[0]);
            Assert.AreEqual(cookie2, cookies[1]);

            cookieStore = new CookieStore(database, "cookie_store_unit_test");
            Assert.AreEqual(0, cookieStore.Count);
        }
 public DefaultAuthHandler(HttpClientHandler context, CookieStore cookieStore) : base()
 {
     this.context = context;
     this.cookieStore = cookieStore;
     InnerHandler = this.context;
 }
        public HttpClient GetHttpClient(CookieStore cookieStore)
        {
            var client = new HttpClient(HttpHandler, false);
            foreach (var header in Headers) {
                var success = client.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value);
                if (!success) {
                    Log.W(Tag, "Unabled to add header to request: {0}: {1}".Fmt(header.Key, header.Value));
                }
            }

            return client;
        }
        public void TestFacebookAuth()
        {
            var sg = new SyncGateway("http", GetReplicationServer());
            using (var remoteDb = sg.CreateDatabase("facebook")) {
                remoteDb.DisableGuestAccess();
                var doneEvent = new ManualResetEvent(false);

                var accountStore = new ACAccountStore();
                var accountType = accountStore.FindAccountType(ACAccountType.Facebook);

                var options = new AccountStoreOptions();
                options.FacebookAppId = FacebookAppId;
                options.SetPermissions(ACFacebookAudience.Friends, new [] { "email" });

                var success = true;
                ACAccount account = null;
                accountStore.RequestAccess(accountType, options, (result, error) =>
                {
                    success = result;
                    if (success) {
                        var accounts = accountStore.FindAccounts(accountType);
                        account = accounts != null && accounts.Length > 0 ? accounts[0] : null;
                    }
                    else {
                        Log.W(Tag, "Facebook Login needed. Go to Settings > Facebook and login.");
                        Log.E(Tag, "Facebook Request Access Error : " + error);
                    }
                    doneEvent.Set();
                });

                doneEvent.WaitOne(TimeSpan.FromSeconds(30));

                Assert.IsTrue(success);
                Assert.IsNotNull(account);

                var token = account.Credential.OAuthToken;
                Assert.IsNotNull(token);
                Assert.IsTrue(token.Length > 0);

                var url = remoteDb.RemoteUri;

                var cookieStore = new CookieStore(manager.Directory);
                var httpClientFactory = new CouchbaseLiteHttpClientFactory(cookieStore);
                manager.DefaultHttpClientFactory = httpClientFactory;
                Replication replicator = database.CreatePushReplication(url);
                replicator.Authenticator = AuthenticatorFactory.CreateFacebookAuthenticator(token);

                Assert.IsNotNull(replicator);
                Assert.IsNotNull(replicator.Authenticator);
                Assert.IsTrue(replicator.Authenticator is TokenAuthenticator);

                CreateDocuments(database, 20);

                RunReplication(replicator);

                var urlStr = url.ToString();
                urlStr = urlStr.EndsWith("/") ? urlStr : urlStr + "/";
                //var cookies = httpClientFactory.GetCookieContainer().GetCookies(new Uri(urlStr));
                //Assert.IsTrue(cookies.Count == 1);
                //Assert.AreEqual("SyncGatewaySession", cookies[0].Name);
            }
        }
        internal void SetupHttpClientFactory(IHttpClientFactory newValue, Database db)
        {
            if(newValue != null) {
                ClientFactory = newValue;
            } else {
                var manager = db?.Manager;
                var managerClientFactory = manager?.DefaultHttpClientFactory;
                ClientFactory = managerClientFactory ?? new CouchbaseLiteHttpClientFactory();
            }

            CookieStore = new CookieStore(db, null);
        }
        public CouchbaseLiteHttpClient GetHttpClient(CookieStore cookieStore, IRetryStrategy strategy)
        {
            var handler = strategy != null ? (HttpMessageHandler)new TransientErrorRetryHandler(HttpHandler, strategy) : HttpHandler;
            var client = new HttpClient(handler, false);
            foreach (var header in Headers) {
                var success = client.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value);
                if (!success) {
                    Console.WriteLine("Unable to add header to request: {0}: {1}", header.Key, header.Value);
                }
            }

            return new CouchbaseLiteHttpClient(client, null);
        }
        public void TestMigration()
        {
            var cookie1 = new Cookie {
                Name = "whitechoco",
                Domain = ".mycookie.com",
                Path = "/",
                Value = "sweet",
                Expires = DateTime.Now.AddSeconds(3600)
            };

            var cookie2 = new Cookie {
                Name = "oatmeal_raisin",
                Domain = ".mycookie.com",
                Path = "/",
                Value = "sweet",
                Expires = DateTime.Now.AddSeconds(3600),
                Version = 1
            };

            const string LocalCheckpointCookiesKey = "cbl_cookie_storage_xxxxx";
            database.PutLocalCheckpointDoc(LocalCheckpointCookiesKey, new[] { cookie1, cookie2 });
            var cookies = database.GetLocalCheckpointDocValue(LocalCheckpointCookiesKey).AsList<Cookie>();
            Assert.AreEqual(2, cookies.Count);

            var cookieStore = new CookieStore(database, null);

            var newCookies = cookieStore.GetCookies(new Uri("http://mycookie.com"));
            Assert.AreEqual(2, cookieStore.Count);
            Assert.AreEqual(cookie1, newCookies[0]);
            Assert.AreEqual(cookie2, newCookies[1]);
            Assert.IsNull(database.GetLocalCheckpointDocValue(LocalCheckpointCookiesKey));
        }