Exemplo n.º 1
0
 private void CheckSessionAtPath(string sessionPath)
 {
     _session.SendAsyncRequest(HttpMethod.Get, sessionPath, null, (result, e) => {
         if (e != null)
         {
             // If not at /db/_session, try CouchDB location /_session
             var statusCode = Misc.GetStatusCode(e);
             if (statusCode.HasValue && statusCode.Value == HttpStatusCode.NotFound &&
                 sessionPath == "_session")
             {
                 CheckSessionAtPath("/_session");
                 return;
             }
             else if (statusCode == HttpStatusCode.Unauthorized)
             {
                 Login();
             }
             else
             {
                 Log.To.Sync.I(Tag, "{0} session check failed: {1}", this, e);
                 OnFinished(e);
             }
         }
         else
         {
             var userName = result?.AsDictionary <string, object>()?.Get("userCtx")?.AsDictionary <string, object>()?.GetCast <string>("name");
             if (userName != null)
             {
                 // Found a login session!
                 Log.To.Sync.I(Tag, "{0}: Active session, logged in as '{1}'", this, new SecureLogString(userName, LogMessageSensitivity.PotentiallyInsecure));
                 OnFinished(null);
             }
             else
             {
                 // No current login session, so continue to regular login:
                 Login();
             }
         }
     });
 }
        private Task ExecuteRequest(HttpRequestMessage request)
        {
            object              fullBody = null;
            Exception           error    = null;
            HttpResponseMessage response = null;

            if (_tokenSource.IsCancellationRequested)
            {
                RespondWithResult(fullBody, new Exception(string.Format("{0}: Request {1} has been aborted", this, request)), response);
                var tcs = new TaskCompletionSource <bool>();
                tcs.SetCanceled();
                return(tcs.Task);
            }

            request.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
            request.Headers.Add("X-Accept-Part-Encoding", "gzip");

            Log.To.Sync.V(Tag, "Sending request: {0}", request);
            var requestTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_tokenSource.Token);

            return(_session.SendAsyncRequest(request, HttpCompletionOption.ResponseContentRead, requestTokenSource.Token).ContinueWith(t =>
            {
                requestTokenSource.Dispose();
                try {
                    response = t.Result;
                } catch (Exception e) {
                    var err = Misc.Flatten(e).First();
                    Log.To.Sync.E(Tag, "Unhandled exception while getting bulk documents", err);
                    error = err;
                    RespondWithResult(fullBody, err, response);
                    return;
                }

                try {
                    if (response == null)
                    {
                        Log.To.Sync.I(Tag, "Didn't get response for {0}", request);

                        error = new HttpRequestException();
                        RespondWithResult(fullBody, error, response);
                    }
                    else if (!response.IsSuccessStatusCode)
                    {
                        HttpStatusCode status = response.StatusCode;

                        Log.To.Sync.I(Tag, "Got error status: {0} for {1}.  Reason: {2}", status.GetStatusCode(), request, response.ReasonPhrase);
                        error = new HttpResponseException(status);

                        RespondWithResult(fullBody, error, response);
                    }
                    else
                    {
                        Log.To.Sync.D(Tag, "Processing response: {0}", response);
                        var entity = response.Content;
                        var contentTypeHeader = entity.Headers.ContentType;
                        Stream inputStream = null;
                        if (contentTypeHeader != null && contentTypeHeader.ToString().Contains("multipart/"))
                        {
                            Log.To.Sync.D(Tag, "contentTypeHeader = {0}", contentTypeHeader.ToString());
                            try {
                                _topReader = new MultipartReader(contentTypeHeader.ToString(), this);
                                inputStream = entity.ReadAsStreamAsync().Result;
                                const int bufLen = 1024;
                                var buffer = new byte[bufLen];
                                var numBytesRead = 0;
                                while ((numBytesRead = inputStream.Read(buffer, 0, bufLen)) > 0)
                                {
                                    if (numBytesRead != bufLen)
                                    {
                                        var bufferToAppend = new Couchbase.Lite.Util.ArraySegment <byte>(buffer, 0, numBytesRead).ToArray();
                                        _topReader.AppendData(bufferToAppend);
                                    }
                                    else
                                    {
                                        _topReader.AppendData(buffer);
                                    }
                                }

                                RespondWithResult(fullBody, error, response);
                            } finally {
                                try {
                                    inputStream.Close();
                                } catch (IOException) { }
                            }
                        }
                        else
                        {
                            Log.To.Sync.D(Tag, "contentTypeHeader is not multipart = {0}", contentTypeHeader.ToString());
                            if (entity != null)
                            {
                                try {
                                    inputStream = entity.ReadAsStreamAsync().Result;
                                    fullBody = Manager.GetObjectMapper().ReadValue <object>(inputStream);
                                    RespondWithResult(fullBody, error, response);
                                } finally {
                                    try {
                                        inputStream.Close();
                                    } catch (IOException) {  }
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    var err = (e is AggregateException) ? e.InnerException : e;
                    Log.To.Sync.E(Tag, "Exception while processing bulk download response", err);
                    error = err;
                    RespondWithResult(fullBody, err, response);
                }
            }));
        }