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