Beispiel #1
0
        public string GetURL(OneNetContext context)
        {
            var url      = URIUtils.fmtURI(URI, context);
            var webUtils = new WebUtils();

            return(webUtils.BuildGetUrl(url, otherParameters));
        }
 protected internal virtual void PreemptivelySetAuthCredentials(HttpClient httpClient
                                                                )
 {
     // if the URL contains user info AND if this a DefaultHttpClient
     // then preemptively set the auth credentials
     if (url.GetUserInfo() != null)
     {
         if (url.GetUserInfo().Contains(":") && !url.GetUserInfo().Trim().Equals(":"))
         {
             string[]    userInfoSplit = url.GetUserInfo().Split(":");
             Credentials creds         = new UsernamePasswordCredentials(URIUtils.Decode(userInfoSplit
                                                                                         [0]), URIUtils.Decode(userInfoSplit[1]));
             if (httpClient is DefaultHttpClient)
             {
                 DefaultHttpClient        dhc            = (DefaultHttpClient)httpClient;
                 MessageProcessingHandler preemptiveAuth = new _MessageProcessingHandler_185(creds
                                                                                             );
                 dhc.AddRequestInterceptor(preemptiveAuth, 0);
             }
         }
         else
         {
             Log.W(Database.Tag, "RemoteRequest Unable to parse user info, not setting credentials"
                   );
         }
     }
 }
        protected internal void PreemptivelySetAuthCredentials(HttpClient httpClient)
        {
            var isUrlBasedUserInfo = false;
            var userInfo           = url.UserInfo;

            if (userInfo != null)
            {
                isUrlBasedUserInfo = true;
            }
            else
            {
                if (Authenticator != null)
                {
                    var auth = Authenticator;
                    userInfo = auth.UserInfo;
                }
            }
            if (userInfo != null)
            {
                if (userInfo.Contains(":") && !userInfo.Trim().Equals(":"))
                {
                    var userInfoElements = userInfo.Split(':');
                    var username         = isUrlBasedUserInfo ? URIUtils.Decode(userInfoElements[0]) : userInfoElements[0];
                    var password         = isUrlBasedUserInfo ? URIUtils.Decode(userInfoElements[1]) : userInfoElements[1];
                    var authHandler      = clientFactory.Handler.InnerHandler as HttpClientHandler;
                    authHandler.Credentials = new NetworkCredential(username, password);
                }
                else
                {
                    Log.W(Tag, "RemoteRequest Unable to parse user info, not setting credentials");
                }
            }
        }
Beispiel #4
0
        public String GetURL(OneNetContext context)
        {
            context.setContext(CMD_UUID, CmdUuid);
            var url      = URIUtils.fmtURI(URI, context);
            var webUtils = new WebUtils();

            return(webUtils.BuildGetUrl(url, otherParameters));
        }
Beispiel #5
0
        public String GetURL(OneNetContext context)
        {
            context.setContext(DEVICE_ID, DeviceID);
            var url      = URIUtils.fmtURI(URI, context);
            var webUtils = new WebUtils();

            return(webUtils.BuildGetUrl(url, otherParameters));
        }
 public static int Digit(char character, int radix)
 {
     if (radix != 16)
     {
         throw new ArgumentException("Only hex/base16 is supported.", "radix");
     }
     return(URIUtils.HexToInt(character));
 }
        public String GetURL(OneNetContext context)
        {
            otherParameters.Add(Register_Code, RegisterCode);
            var url      = URIUtils.fmtURI(URI, context);
            var webUtils = new WebUtils();

            return(webUtils.BuildGetUrl(url, otherParameters));
        }
        public string GetURL(OneNetContext context)
        {
            otherParameters.Add("title", Title);
            otherParameters.Add("page", Page.ToString());
            otherParameters.Add("per_page", Per_Page.ToString());
            var url      = URIUtils.fmtURI(URI, context);
            var webUtils = new WebUtils();

            return(webUtils.BuildGetUrl(url, otherParameters));
        }
Beispiel #9
0
        public void ComposeURLQueryString_SpecSymbols()
        {
            var pars = new Dictionary <string, object> {
                { "name", "Petrov" }, { "age", 19 }, { "spec", @" -y~!@#$%^&*()_?><|';:\/=+" }
            };

            var result = URIUtils.ComposeURLQueryString(pars);

            Aver.AreEqual("name=Petrov&age=19&spec=%20-y%7E%21%40%23%24%25%5E%26%2A%28%29_%3F%3E%3C%7C%27%3B%3A%5C%2F%3D%2B", result);
        }
Beispiel #10
0
        public string GetURL(OneNetContext context)
        {
            otherParameters.Add(DEVICE_ID, DeviceID.ToString());
            otherParameters.Add(DATASTREAM_ID, DatastreamId);

            var url      = URIUtils.fmtURI(URI, context);
            var webUtils = new WebUtils();

            return(webUtils.BuildGetUrl(url, otherParameters));
        }
Beispiel #11
0
        public void ComposeURLQueryString_Empty()
        {
            Dictionary <string, object> pars = null;
            var result = URIUtils.ComposeURLQueryString(pars);

            Aver.AreEqual(string.Empty, result);

            pars   = new Dictionary <string, object>();
            result = URIUtils.ComposeURLQueryString(pars);
            Aver.AreEqual(string.Empty, result);
        }
Beispiel #12
0
 public void URI_Join()
 {
     Aver.AreEqual("static/site/content", URIUtils.JoinPathSegs("static", "site", "content"));
     Aver.AreEqual("static/site/content", URIUtils.JoinPathSegs(" static", "  site  ", " content"));
     Aver.AreEqual("static/site/content", URIUtils.JoinPathSegs(" static", " \\ site  ", " // content"));
     Aver.AreEqual("static/site/content", URIUtils.JoinPathSegs(" static/", "//site  ", " // content"));
     Aver.AreEqual("static/site/content", URIUtils.JoinPathSegs(" static/", "/", "/site", "// content"));
     Aver.AreEqual("/static/site/content", URIUtils.JoinPathSegs("/static/", "/", "/site", "// content"));
     Aver.AreEqual("/static/site/content", URIUtils.JoinPathSegs("      /static/", "site", "\\content"));
     Aver.AreEqual("/static/site/content", URIUtils.JoinPathSegs(" ", null, "      /static/", "site", "\\content"));
     Aver.AreEqual("static/site/content", URIUtils.JoinPathSegs("static", null, "site", "", "", "\\content"));
 }
Beispiel #13
0
        public void ComposeURLQueryString_PlusAndSpaces()
        {
            var pars = new Dictionary <string, object>
            {
                { "eng", "Hello Lenin!" },
                { "rus", "Привет Ленин!" }
            };

            var result = URIUtils.ComposeURLQueryString(pars);

            Aver.AreEqual("eng=Hello%20Lenin%21&rus=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%9B%D0%B5%D0%BD%D0%B8%D0%BD%21", result);
        }
Beispiel #14
0
        public string GetURL(OneNetContext context)
        {
            var url = URIUtils.fmtURI(URI, context);

            otherParameters.Add("page", Page.ToString());
            otherParameters.Add("per_page", PerPage.ToString());
            otherParameters.Add("dev_id", DeviceId);
            otherParameters.Add("key", Key);

            var webUtils = new WebUtils();

            return(webUtils.BuildGetUrl(url, otherParameters));
        }
        public static PersonaAuthorizer FromUri(Uri uri)
        {
            var personaAssertion = URIUtils.GetQueryParameter(uri, QueryParameter);

            if (personaAssertion != null && !StringEx.IsNullOrWhiteSpace(personaAssertion))
            {
                var email      = RegisterAssertion(personaAssertion);
                var authorizer = new PersonaAuthorizer(email);
                return(authorizer);
            }

            return(null);
        }
Beispiel #16
0
        public void ComposeURLQueryString_Types()
        {
            var pars = new Dictionary <string, object>
            {
                { "int", -257 },
                { "bool", true },
                { "double", 1.9D },
                { "string", "data&data" },
                { "dec", 23.45M },
                { "float", -12.34F }
            };

            var result = URIUtils.ComposeURLQueryString(pars);

            Aver.AreEqual("int=-257&bool=True&double=1.9&string=data%26data&dec=23.45&float=-12.34", result);
        }
Beispiel #17
0
        public void ComposeURLQueryString_Mixed()
        {
            var pars = new Dictionary <string, object>
            {
                { "eng", "Hello!" },
                { "jap", null },
                { "chi", "久有归天愿" },
                { "chi2", 12 },
                { "", -123456 },
                { "привет", string.Empty },
                { "नमस्कार", null }
            };

            var result = URIUtils.ComposeURLQueryString(pars);

            Aver.AreEqual("eng=Hello%21&jap&chi=%E4%B9%85%E6%9C%89%E5%BD%92%E5%A4%A9%E6%84%BF&chi2=12&%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82=&%E0%A4%A8%E0%A4%AE%E0%A4%B8%E0%A5%8D%E0%A4%95%E0%A4%BE%E0%A4%B0", result);
        }
Beispiel #18
0
        public void ComposeURLQueryString_UTF8()
        {
            var pars = new Dictionary <string, object>
            {
                { "eng", "Hello!" },
                { "jap", "こんにちは" },
                { "chi", "久有归天愿" },
                { "chi2", "你好" },
                { "fra", "Allô" },
                { "привет", "rus" },
                { "नमस्कार", "hind" }
            };

            var result = URIUtils.ComposeURLQueryString(pars);

            Aver.AreEqual("eng=Hello%21&jap=%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF&chi=%E4%B9%85%E6%9C%89%E5%BD%92%E5%A4%A9%E6%84%BF&chi2=%E4%BD%A0%E5%A5%BD&fra=All%C3%B4&%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82=rus&%E0%A4%A8%E0%A4%AE%E0%A4%B8%E0%A5%8D%E0%A4%95%E0%A4%BE%E0%A4%B0=hind", result);
        }
Beispiel #19
0
        public String GetURL(OneNetContext context)
        {
            context.setContext(DEVICE_ID, DeviceID);
            otherParameters.Add(DatastreamID, DataStreamId);
            otherParameters.Add(START, StartTimeTxt);
            otherParameters.Add(END, EndTimeTxt);
            otherParameters.Add(LIMIT, Limit);
            otherParameters.Add(CURSOR, Cursor);
            otherParameters.Add(INTERVAL, Interval);
            otherParameters.Add(METHOD, Method);
            otherParameters.Add(FIRST, First);

            var url      = URIUtils.fmtURI(URI, context);
            var webUtils = new WebUtils();

            return(webUtils.BuildGetUrl(url, otherParameters));
        }
Beispiel #20
0
        // Fallback to upload a revision if uploadMultipartRevision failed due to the server's rejecting
        // multipart format.
        private void UploadJsonRevision(RevisionInternal rev)
        {
            // Get the revision's properties:
            if (!db.InlineFollowingAttachmentsIn(rev))
            {
                error = new CouchbaseLiteException(Status.BadAttachment);
                RevisionFailed();
                return;
            }
            Log.V(Log.TagSync, "%s | %s: uploadJsonRevision() calling asyncTaskStarted()", this
                  , Sharpen.Thread.CurrentThread());
            AsyncTaskStarted();
            string path = string.Format("/%s?new_edits=false", URIUtils.Encode(rev.GetDocId()
                                                                               ));

            SendAsyncRequest("PUT", path, rev.GetProperties(), new _RemoteRequestCompletionBlock_594
                                 (this, rev));
        }
        /// <exception cref="Apache.Http.Client.ClientProtocolException"></exception>
        private static HttpHost DetermineTarget(IHttpUriRequest request)
        {
            // A null target may be acceptable if there is a default target.
            // Otherwise, the null target is detected in the director.
            HttpHost target     = null;
            URI      requestURI = request.GetURI();

            if (requestURI.IsAbsolute())
            {
                target = URIUtils.ExtractHost(requestURI);
                if (target == null)
                {
                    throw new ClientProtocolException("URI does not specify a valid host name: " + requestURI
                                                      );
                }
            }
            return(target);
        }
Beispiel #22
0
        public void ComposeURLQueryString_NullOrEmptyQueryParts()
        {
            var pars = new Dictionary <string, object>
            {
                { "name", null }
            };
            var result = URIUtils.ComposeURLQueryString(pars);

            Aver.AreEqual("name", result);

            pars = new Dictionary <string, object>
            {
                { "name", string.Empty },
            };
            result = URIUtils.ComposeURLQueryString(pars);
            Aver.AreEqual("name=", result);

            pars = new Dictionary <string, object>
            {
                { string.Empty, "ABBA" }
            };
            result = URIUtils.ComposeURLQueryString(pars);
            Aver.AreEqual(string.Empty, result);

            pars = new Dictionary <string, object>
            {
                { "name1", null },
                { "name2", string.Empty },
                { string.Empty, "ABBA" }
            };
            result = URIUtils.ComposeURLQueryString(pars);
            Aver.AreEqual("name1&name2=", result);

            pars = new Dictionary <string, object>
            {
                { "name1", string.Empty },
                { "name2", null },
                { string.Empty, "ABBA" },
                { "name3", "John" }
            };
            result = URIUtils.ComposeURLQueryString(pars);
            Aver.AreEqual("name1=&name2&name3=John", result);
        }
        protected internal virtual void PreemptivelySetAuthCredentials(HttpClient httpClient
                                                                       )
        {
            bool   isUrlBasedUserInfo = false;
            string userInfo           = url.GetUserInfo();

            if (userInfo != null)
            {
                isUrlBasedUserInfo = true;
            }
            else
            {
                if (authenticator != null)
                {
                    AuthenticatorImpl auth = (AuthenticatorImpl)authenticator;
                    userInfo = auth.AuthUserInfo();
                }
            }
            if (userInfo != null)
            {
                if (userInfo.Contains(":") && !userInfo.Trim().Equals(":"))
                {
                    string[] userInfoElements = userInfo.Split(":");
                    string   username         = isUrlBasedUserInfo ? URIUtils.Decode(userInfoElements[0]) : userInfoElements
                                                [0];
                    string password = isUrlBasedUserInfo ? URIUtils.Decode(userInfoElements[1]) : userInfoElements
                                      [1];
                    Credentials credentials = new UsernamePasswordCredentials(username, password);
                    if (httpClient is DefaultHttpClient)
                    {
                        DefaultHttpClient        dhc            = (DefaultHttpClient)httpClient;
                        MessageProcessingHandler preemptiveAuth = new _MessageProcessingHandler_286(credentials
                                                                                                    );
                        dhc.AddRequestInterceptor(preemptiveAuth, 0);
                    }
                }
                else
                {
                    Log.W(Log.TagRemoteRequest, "RemoteRequest Unable to parse user info, not setting credentials"
                          );
                }
            }
        }
Beispiel #24
0
 /// <exception cref="Apache.Http.ProtocolException"></exception>
 internal virtual void RewriteRequestURI(HttpRequestWrapper request, HttpRoute route
                                         )
 {
     try
     {
         URI uri = request.GetURI();
         if (uri != null)
         {
             if (route.GetProxyHost() != null && !route.IsTunnelled())
             {
                 // Make sure the request URI is absolute
                 if (!uri.IsAbsolute())
                 {
                     HttpHost target = route.GetTargetHost();
                     uri = URIUtils.RewriteURI(uri, target, true);
                 }
                 else
                 {
                     uri = URIUtils.RewriteURI(uri);
                 }
             }
             else
             {
                 // Make sure the request URI is relative
                 if (uri.IsAbsolute())
                 {
                     uri = URIUtils.RewriteURI(uri, null, true);
                 }
                 else
                 {
                     uri = URIUtils.RewriteURI(uri);
                 }
             }
             request.SetURI(uri);
         }
     }
     catch (URISyntaxException ex)
     {
         throw new ProtocolException("Invalid URI: " + request.GetRequestLine().GetUri(),
                                     ex);
     }
 }
Beispiel #25
0
        public String GetURL(OneNetContext context)
        {
            otherParameters.Add(Key_WORDS, Keywords);
            if (OnLine.HasValue)
            {
                otherParameters.Add(ONLINE, OnLine.ToString());
            }
            if (Private.HasValue)
            {
                otherParameters.Add(PRIVATE, Private.ToString());
            }
            otherParameters.Add(PAGE, Page.ToString());
            otherParameters.Add(PER_PAGE, PageSize.ToString());
            otherParameters.Add(TAG, Tag);

            context.setContext(DEVICE_ID, DeviceIds);

            var url      = URIUtils.fmtURI(URI, context);
            var webUtils = new WebUtils();

            return(webUtils.BuildGetUrl(url, otherParameters));
        }
        public String GetURL(OneNetContext context)
        {
            otherParameters.Add("start", Start.ToString("s"));
            otherParameters.Add("device_id", DeviceID);
            otherParameters.Add("datastream_id", DataStreamId);
            if (End.HasValue)
            {
                otherParameters.Add("end", End.Value.ToString("s"));
            }
            otherParameters.Add("limit", Limit.ToString());
            otherParameters.Add("cursor", Cursor);
            if (Duration.HasValue)
            {
                otherParameters.Add("duration", Duration.ToString());
            }
            otherParameters.Add("page", Page.ToString());

            var url      = URIUtils.fmtURI(URI, context);
            var webUtils = new WebUtils();

            return(webUtils.BuildGetUrl(url, otherParameters));
        }
Beispiel #27
0
        public static FacebookAuthorizer FromUri(Uri uri)
        {
            var facebookAccessToken = URIUtils.GetQueryParameter(uri, QueryParameter);

            if (facebookAccessToken != null && !StringEx.IsNullOrWhiteSpace(facebookAccessToken))
            {
                var email                  = URIUtils.GetQueryParameter(uri, QueryParameterEmail);
                var authorizer             = new FacebookAuthorizer(email);
                Uri remoteWithQueryRemoved = null;

                try {
                    remoteWithQueryRemoved = new UriBuilder(uri.Scheme, uri.Host, uri.Port, uri.AbsolutePath).Uri;
                } catch (UriFormatException e) {
                    throw Misc.CreateExceptionAndLog(Log.To.Sync, e, Tag,
                                                     "Invalid URI format for remote endpoint");
                }

                RegisterAccessToken(facebookAccessToken, email, remoteWithQueryRemoved);
                return(authorizer);
            }

            return(null);
        }
        public virtual void Run()
        {
            running = true;
            HttpClient httpClient;

            if (client == null)
            {
                // This is a race condition that can be reproduced by calling cbpuller.start() and cbpuller.stop()
                // directly afterwards.  What happens is that by the time the Changetracker thread fires up,
                // the cbpuller has already set this.client to null.  See issue #109
                Log.W(Database.Tag, "ChangeTracker run() loop aborting because client == null");
                return;
            }
            if (mode == ChangeTracker.ChangeTrackerMode.Continuous)
            {
                // there is a failing unit test for this, and from looking at the code the Replication
                // object will never use Continuous mode anyway.  Explicitly prevent its use until
                // it is demonstrated to actually work.
                throw new RuntimeException("ChangeTracker does not correctly support continuous mode"
                                           );
            }
            httpClient = client.GetHttpClient();
            ChangeTrackerBackoff backoff = new ChangeTrackerBackoff();

            while (running)
            {
                Uri url = GetChangesFeedURL();
                request = new HttpGet(url.ToString());
                AddRequestHeaders(request);
                // if the URL contains user info AND if this a DefaultHttpClient
                // then preemptively set the auth credentials
                if (url.GetUserInfo() != null)
                {
                    Log.V(Database.Tag, "url.getUserInfo(): " + url.GetUserInfo());
                    if (url.GetUserInfo().Contains(":") && !url.GetUserInfo().Trim().Equals(":"))
                    {
                        string[]    userInfoSplit = url.GetUserInfo().Split(":");
                        Credentials creds         = new UsernamePasswordCredentials(URIUtils.Decode(userInfoSplit
                                                                                                    [0]), URIUtils.Decode(userInfoSplit[1]));
                        if (httpClient is DefaultHttpClient)
                        {
                            DefaultHttpClient        dhc            = (DefaultHttpClient)httpClient;
                            MessageProcessingHandler preemptiveAuth = new _MessageProcessingHandler_212(creds
                                                                                                        );
                            dhc.AddRequestInterceptor(preemptiveAuth, 0);
                        }
                    }
                    else
                    {
                        Log.W(Database.Tag, "ChangeTracker Unable to parse user info, not setting credentials"
                              );
                    }
                }
                try
                {
                    string maskedRemoteWithoutCredentials = GetChangesFeedURL().ToString();
                    maskedRemoteWithoutCredentials = maskedRemoteWithoutCredentials.ReplaceAll("://.*:.*@"
                                                                                               , "://---:---@");
                    Log.V(Database.Tag, "Making request to " + maskedRemoteWithoutCredentials);
                    HttpResponse response = httpClient.Execute(request);
                    StatusLine   status   = response.GetStatusLine();
                    if (status.GetStatusCode() >= 300)
                    {
                        Log.E(Database.Tag, "Change tracker got error " + Sharpen.Extensions.ToString(status
                                                                                                      .GetStatusCode()));
                        string msg = string.Format(status.ToString());
                        this.error = new CouchbaseLiteException(msg, new Status(status.GetStatusCode()));
                        Stop();
                    }
                    HttpEntity  entity = response.GetEntity();
                    InputStream input  = null;
                    if (entity != null)
                    {
                        input = entity.GetContent();
                        if (mode == ChangeTracker.ChangeTrackerMode.LongPoll)
                        {
                            IDictionary <string, object> fullBody = Manager.GetObjectMapper().ReadValue <IDictionary
                                                                                                         >(input);
                            bool responseOK = ReceivedPollResponse(fullBody);
                            if (mode == ChangeTracker.ChangeTrackerMode.LongPoll && responseOK)
                            {
                                Log.V(Database.Tag, "Starting new longpoll");
                                continue;
                            }
                            else
                            {
                                Log.W(Database.Tag, "Change tracker calling stop");
                                Stop();
                            }
                        }
                        else
                        {
                            JsonFactory jsonFactory = Manager.GetObjectMapper().GetJsonFactory();
                            JsonParser  jp          = jsonFactory.CreateJsonParser(input);
                            while (jp.NextToken() != JsonToken.StartArray)
                            {
                            }
                            // ignore these tokens
                            while (jp.NextToken() == JsonToken.StartObject)
                            {
                                IDictionary <string, object> change = (IDictionary)Manager.GetObjectMapper().ReadValue
                                                                      <IDictionary>(jp);
                                if (!ReceivedChange(change))
                                {
                                    Log.W(Database.Tag, string.Format("Received unparseable change line from server: %s"
                                                                      , change));
                                }
                            }
                            Stop();
                            break;
                        }
                        backoff.ResetBackoff();
                    }
                }
                catch (Exception e)
                {
                    if (!running && e is IOException)
                    {
                    }
                    else
                    {
                        // in this case, just silently absorb the exception because it
                        // frequently happens when we're shutting down and have to
                        // close the socket underneath our read.
                        Log.E(Database.Tag, "Exception in change tracker", e);
                    }
                    backoff.SleepAppropriateAmountOfTime();
                }
            }
            Log.V(Database.Tag, "Change tracker run loop exiting");
        }
Beispiel #29
0
        /// <summary>Private Constructor</summary>
        protected Replication(Database db, Uri remote, bool continuous, IHttpClientFactory clientFactory, TaskFactory workExecutor, CancellationTokenSource tokenSource = null)
        {
            LocalDatabase           = db;
            Continuous              = continuous;
            WorkExecutor            = workExecutor;
            CancellationTokenSource = tokenSource ?? new CancellationTokenSource();
            RemoteUrl      = remote;
            Status         = ReplicationStatus.Stopped;
            online         = true;
            RequestHeaders = new Dictionary <String, Object>();

            if (RemoteUrl.GetQuery() != null && !RemoteUrl.GetQuery().IsEmpty())
            {
                var uri = new Uri(remote.ToString());
                var personaAssertion = URIUtils.GetQueryParameter(uri, PersonaAuthorizer.QueryParameter);

                if (personaAssertion != null && !personaAssertion.IsEmpty())
                {
                    var email      = PersonaAuthorizer.RegisterAssertion(personaAssertion);
                    var authorizer = new PersonaAuthorizer(email);
                    Authorizer = authorizer;
                }

                var facebookAccessToken = URIUtils.GetQueryParameter(uri, FacebookAuthorizer.QueryParameter);

                if (facebookAccessToken != null && !facebookAccessToken.IsEmpty())
                {
                    var email                  = URIUtils.GetQueryParameter(uri, FacebookAuthorizer.QueryParameterEmail);
                    var authorizer             = new FacebookAuthorizer(email);
                    Uri remoteWithQueryRemoved = null;

                    try
                    {
                        remoteWithQueryRemoved = new UriBuilder(remote.Scheme, remote.GetHost(), remote.Port, remote.AbsolutePath).Uri;
                    }
                    catch (UriFormatException e)
                    {
                        throw new ArgumentException("Invalid URI format.", "remote", e);
                    }

                    FacebookAuthorizer.RegisterAccessToken(facebookAccessToken, email, remoteWithQueryRemoved.ToString());

                    Authorizer = authorizer;
                }
                // we need to remove the query from the URL, since it will cause problems when
                // communicating with sync gw / couchdb
                try
                {
                    RemoteUrl = new UriBuilder(remote.Scheme, remote.GetHost(), remote.Port, remote.AbsolutePath).Uri;
                }
                catch (UriFormatException e)
                {
                    throw new ArgumentException("Invalid URI format.", "remote", e);
                }
            }

            Batcher = new Batcher <RevisionInternal>(workExecutor, InboxCapacity, ProcessorDelay,
                                                     inbox =>
            {
                Log.V(Database.Tag, "*** " + this + ": BEGIN processInbox (" + inbox.Count + " sequences)");
                ProcessInbox(new RevisionList(inbox));
                Log.V(Database.Tag, "*** " + this.ToString() + ": END processInbox (lastSequence=" + LastSequence);
                UpdateActive();
            }, CancellationTokenSource);

            this.clientFactory = clientFactory ?? CouchbaseLiteHttpClientFactory.Instance;
        }
        public virtual void Run()
        {
            running = true;
            HttpClient httpClient;

            if (client == null)
            {
                // This is a race condition that can be reproduced by calling cbpuller.start() and cbpuller.stop()
                // directly afterwards.  What happens is that by the time the Changetracker thread fires up,
                // the cbpuller has already set this.client to null.  See issue #109
                Log.W(Log.TagChangeTracker, "%s: ChangeTracker run() loop aborting because client == null"
                      , this);
                return;
            }
            if (mode == ChangeTracker.ChangeTrackerMode.Continuous)
            {
                // there is a failing unit test for this, and from looking at the code the Replication
                // object will never use Continuous mode anyway.  Explicitly prevent its use until
                // it is demonstrated to actually work.
                throw new RuntimeException("ChangeTracker does not correctly support continuous mode"
                                           );
            }
            httpClient = client.GetHttpClient();
            backoff    = new ChangeTrackerBackoff();
            while (running)
            {
                Uri url = GetChangesFeedURL();
                if (usePOST)
                {
                    HttpPost postRequest = new HttpPost(url.ToString());
                    postRequest.SetHeader("Content-Type", "application/json");
                    StringEntity entity;
                    try
                    {
                        entity = new StringEntity(ChangesFeedPOSTBody());
                    }
                    catch (UnsupportedEncodingException e)
                    {
                        throw new RuntimeException(e);
                    }
                    postRequest.SetEntity(entity);
                    request = postRequest;
                }
                else
                {
                    request = new HttpGet(url.ToString());
                }
                AddRequestHeaders(request);
                // Perform BASIC Authentication if needed
                bool isUrlBasedUserInfo = false;
                // If the URL contains user info AND if this a DefaultHttpClient then preemptively set the auth credentials
                string userInfo = url.GetUserInfo();
                if (userInfo != null)
                {
                    isUrlBasedUserInfo = true;
                }
                else
                {
                    if (authenticator != null)
                    {
                        AuthenticatorImpl auth = (AuthenticatorImpl)authenticator;
                        userInfo = auth.AuthUserInfo();
                    }
                }
                if (userInfo != null)
                {
                    if (userInfo.Contains(":") && !userInfo.Trim().Equals(":"))
                    {
                        string[] userInfoElements = userInfo.Split(":");
                        string   username         = isUrlBasedUserInfo ? URIUtils.Decode(userInfoElements[0]) : userInfoElements
                                                    [0];
                        string password = isUrlBasedUserInfo ? URIUtils.Decode(userInfoElements[1]) : userInfoElements
                                          [1];
                        Credentials credentials = new UsernamePasswordCredentials(username, password);
                        if (httpClient is DefaultHttpClient)
                        {
                            DefaultHttpClient        dhc            = (DefaultHttpClient)httpClient;
                            MessageProcessingHandler preemptiveAuth = new _MessageProcessingHandler_285(credentials
                                                                                                        );
                            dhc.AddRequestInterceptor(preemptiveAuth, 0);
                        }
                    }
                    else
                    {
                        Log.W(Log.TagChangeTracker, "RemoteRequest Unable to parse user info, not setting credentials"
                              );
                    }
                }
                try
                {
                    string maskedRemoteWithoutCredentials = GetChangesFeedURL().ToString();
                    maskedRemoteWithoutCredentials = maskedRemoteWithoutCredentials.ReplaceAll("://.*:.*@"
                                                                                               , "://---:---@");
                    Log.V(Log.TagChangeTracker, "%s: Making request to %s", this, maskedRemoteWithoutCredentials
                          );
                    HttpResponse response = httpClient.Execute(request);
                    StatusLine   status   = response.GetStatusLine();
                    if (status.GetStatusCode() >= 300 && !Utils.IsTransientError(status))
                    {
                        Log.E(Log.TagChangeTracker, "%s: Change tracker got error %d", this, status.GetStatusCode
                                  ());
                        this.error = new HttpResponseException(status.GetStatusCode(), status.GetReasonPhrase
                                                                   ());
                        Stop();
                    }
                    HttpEntity  entity = response.GetEntity();
                    InputStream input  = null;
                    if (entity != null)
                    {
                        try
                        {
                            input = entity.GetContent();
                            if (mode == ChangeTracker.ChangeTrackerMode.LongPoll)
                            {
                                // continuous replications
                                IDictionary <string, object> fullBody = Manager.GetObjectMapper().ReadValue <IDictionary
                                                                                                             >(input);
                                bool responseOK = ReceivedPollResponse(fullBody);
                                if (mode == ChangeTracker.ChangeTrackerMode.LongPoll && responseOK)
                                {
                                    Log.V(Log.TagChangeTracker, "%s: Starting new longpoll", this);
                                    backoff.ResetBackoff();
                                    continue;
                                }
                                else
                                {
                                    Log.W(Log.TagChangeTracker, "%s: Change tracker calling stop (LongPoll)", this);
                                    Stop();
                                }
                            }
                            else
                            {
                                // one-shot replications
                                JsonFactory jsonFactory = Manager.GetObjectMapper().GetJsonFactory();
                                JsonParser  jp          = jsonFactory.CreateJsonParser(input);
                                while (jp.NextToken() != JsonToken.StartArray)
                                {
                                }
                                // ignore these tokens
                                while (jp.NextToken() == JsonToken.StartObject)
                                {
                                    IDictionary <string, object> change = (IDictionary)Manager.GetObjectMapper().ReadValue
                                                                          <IDictionary>(jp);
                                    if (!ReceivedChange(change))
                                    {
                                        Log.W(Log.TagChangeTracker, "Received unparseable change line from server: %s", change
                                              );
                                    }
                                }
                                Log.W(Log.TagChangeTracker, "%s: Change tracker calling stop (OneShot)", this);
                                Stop();
                                break;
                            }
                            backoff.ResetBackoff();
                        }
                        finally
                        {
                            try
                            {
                                entity.ConsumeContent();
                            }
                            catch (IOException)
                            {
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    if (!running && e is IOException)
                    {
                    }
                    else
                    {
                        // in this case, just silently absorb the exception because it
                        // frequently happens when we're shutting down and have to
                        // close the socket underneath our read.
                        Log.E(Log.TagChangeTracker, this + ": Exception in change tracker", e);
                    }
                    backoff.SleepAppropriateAmountOfTime();
                }
            }
            Log.V(Log.TagChangeTracker, "%s: Change tracker run loop exiting", this);
        }