// Factors out the logic of opening the database and reading the document body from the HTTP request // and performs the specified logic on the body received in the request, barring any problems private static CouchbaseLiteResponse PerformLogicWithDocumentBody(ICouchbaseListenerContext context, Func<Database, Body, CouchbaseLiteResponse> callback) { return DatabaseMethods.PerformLogicWithDatabase(context, true, db => { MultipartDocumentReader reader = new MultipartDocumentReader(db); reader.SetContentType(context.RequestHeaders["Content-Type"]); reader.AppendData(context.BodyStream.ReadAllBytes()); try { reader.Finish(); } catch(InvalidOperationException) { return context.CreateResponse(StatusCode.BadRequest); } return callback(db, new Body(reader.GetDocumentProperties())); }); }
internal void SendAsyncMultipartDownloaderRequest(HttpMethod method, string relativePath, object body, Database db, RemoteRequestCompletionBlock onCompletion) { try { var urlStr = BuildRelativeURLString(relativePath); var url = new Uri(urlStr); var message = new HttpRequestMessage(method, url); message.Headers.Add("Accept", "*/*"); AddRequestHeaders(message); var client = clientFactory.GetHttpClient(false); var challengeResponseAuth = Authenticator as IChallengeResponseAuthenticator; if (challengeResponseAuth != null) { var authHandler = clientFactory.Handler as DefaultAuthHandler; if (authHandler != null) { authHandler.Authenticator = challengeResponseAuth; } challengeResponseAuth.PrepareWithRequest(message); } var authHeader = AuthUtils.GetAuthenticationHeaderValue(Authenticator, message.RequestUri); if (authHeader != null) { client.DefaultRequestHeaders.Authorization = authHeader; } client.SendAsync(message, CancellationTokenSource.Token).ContinueWith(new Action<Task<HttpResponseMessage>>(responseMessage => { object fullBody = null; Exception error = null; try { var response = responseMessage.Result; // add in cookies to global store //CouchbaseLiteHttpClientFactory.Instance.AddCookies(clientFactory.HttpHandler.CookieContainer.GetCookies(url)); var status = response.StatusCode; if ((Int32)status.GetStatusCode() >= 300) { Log.E(TAG, "Got error " + Sharpen.Extensions.ToString(status.GetStatusCode())); Log.E(TAG, "Request was for: " + message); Log.E(TAG, "Status reason: " + response.ReasonPhrase); error = new WebException(response.ReasonPhrase); } else { var entity = response.Content; var contentTypeHeader = response.Content.Headers.ContentType; InputStream inputStream = null; if (contentTypeHeader != null && contentTypeHeader.ToString().Contains("multipart/related")) { try { var reader = new MultipartDocumentReader(LocalDatabase); var contentType = contentTypeHeader.ToString(); reader.SetContentType(contentType); var inputStreamTask = entity.ReadAsStreamAsync(); //inputStreamTask.Wait(90000, CancellationTokenSource.Token); inputStream = inputStreamTask.Result; const int bufLen = 1024; var buffer = new byte[bufLen]; int numBytesRead = 0; while ((numBytesRead = inputStream.Read(buffer)) != -1) { if (numBytesRead != bufLen) { var bufferToAppend = new Couchbase.Lite.Util.ArraySegment<Byte>(buffer, 0, numBytesRead); reader.AppendData(bufferToAppend); } else { reader.AppendData(buffer); } } reader.Finish(); fullBody = reader.GetDocumentProperties(); if (onCompletion != null) { onCompletion(fullBody, error); } } catch (Exception ex) { Log.E(TAG, "SendAsyncMultipartDownloaderRequest has an error occurred.", ex); } finally { try { inputStream.Close(); } catch (Exception) { } } } else { if (entity != null) { try { var readTask = entity.ReadAsStreamAsync(); //readTask.Wait(); // TODO: This should be scaled based on content length. inputStream = readTask.Result; fullBody = Manager.GetObjectMapper().ReadValue<Object>(inputStream); if (onCompletion != null) onCompletion(fullBody, error); } catch (Exception ex) { Log.E(TAG, "SendAsyncMultipartDownloaderRequest has an error occurred.", ex); } finally { try { inputStream.Close(); } catch (Exception) { } } } } } } catch (System.Net.ProtocolViolationException e) { Log.E(TAG, "client protocol exception", e); error = e; } catch (IOException e) { Log.E(TAG, "IO Exception", e); error = e; } finally { client.Dispose(); } }), WorkExecutor.Scheduler); } catch (UriFormatException e) { Log.E(TAG, "Malformed URL for async request", e); } }
protected internal override void ExecuteRequest(HttpClient httpClient, HttpRequestMessage request) { object fullBody = null; Exception error = null; HttpResponse response = null; try { if (request.IsAborted()) { RespondWithResult(fullBody, new Exception(string.Format("%s: Request %s has been aborted" , this, request)), response); return; } response = httpClient.Execute(request); try { // add in cookies to global store if (httpClient is DefaultHttpClient) { DefaultHttpClient defaultHttpClient = (DefaultHttpClient)httpClient; this.clientFactory.AddCookies(defaultHttpClient.GetCookieStore().GetCookies()); } } catch (Exception e) { Log.E(Log.TagRemoteRequest, "Unable to add in cookies to global store", e); } StatusLine status = response.GetStatusLine(); if (status.GetStatusCode() >= 300) { Log.E(Log.TagRemoteRequest, "Got error status: %d for %s. Reason: %s", status.GetStatusCode (), request, status.GetReasonPhrase()); error = new HttpResponseException(status.GetStatusCode(), status.GetReasonPhrase( )); } else { HttpEntity entity = response.GetEntity(); Header contentTypeHeader = entity.GetContentType(); InputStream inputStream = null; if (contentTypeHeader != null && contentTypeHeader.GetValue().Contains("multipart/related" )) { try { MultipartDocumentReader reader = new MultipartDocumentReader(response, db); reader.SetContentType(contentTypeHeader.GetValue()); inputStream = entity.GetContent(); int bufLen = 1024; byte[] buffer = new byte[bufLen]; int numBytesRead = 0; while ((numBytesRead = inputStream.Read(buffer)) != -1) { if (numBytesRead != bufLen) { byte[] bufferToAppend = Arrays.CopyOfRange(buffer, 0, numBytesRead); reader.AppendData(bufferToAppend); } else { reader.AppendData(buffer); } } reader.Finish(); fullBody = reader.GetDocumentProperties(); RespondWithResult(fullBody, error, response); } finally { try { inputStream.Close(); } catch (IOException) { } } } else { if (entity != null) { try { inputStream = entity.GetContent(); fullBody = Manager.GetObjectMapper().ReadValue <object>(inputStream); RespondWithResult(fullBody, error, response); } finally { try { inputStream.Close(); } catch (IOException) { } } } } } } catch (IOException e) { Log.E(Log.TagRemoteRequest, "%s: io exception", e, this); error = e; RespondWithResult(fullBody, e, response); } catch (Exception e) { Log.E(Log.TagRemoteRequest, "%s: executeRequest() Exception: ", e, this); error = e; RespondWithResult(fullBody, e, response); } finally { Log.E(Log.TagRemoteRequest, "%s: executeRequest() finally", this); } }
protected internal override void ExecuteRequest(HttpClient httpClient, HttpRequestMessage request) { object fullBody = null; Exception error = null; try { HttpResponse response = httpClient.Execute(request); try { // add in cookies to global store if (httpClient is DefaultHttpClient) { DefaultHttpClient defaultHttpClient = (DefaultHttpClient)httpClient; CouchbaseLiteHttpClientFactory.Instance.AddCookies(defaultHttpClient.GetCookieStore ().GetCookies()); } } catch (Exception e) { Log.E(Database.Tag, "Unable to add in cookies to global store", e); } StatusLine status = response.GetStatusLine(); if (status.GetStatusCode() >= 300) { Log.E(Database.Tag, "Got error " + Sharpen.Extensions.ToString(status.GetStatusCode ())); Log.E(Database.Tag, "Request was for: " + request.ToString()); Log.E(Database.Tag, "Status reason: " + status.GetReasonPhrase()); error = new HttpResponseException(status.GetStatusCode(), status.GetReasonPhrase( )); } else { HttpEntity entity = response.GetEntity(); Header contentTypeHeader = entity.GetContentType(); InputStream inputStream = null; if (contentTypeHeader != null && contentTypeHeader.GetValue().Contains("multipart/related" )) { try { MultipartDocumentReader reader = new MultipartDocumentReader(response, db); reader.SetContentType(contentTypeHeader.GetValue()); inputStream = entity.GetContent(); int bufLen = 1024; byte[] buffer = new byte[bufLen]; int numBytesRead = 0; while ((numBytesRead = inputStream.Read(buffer)) != -1) { if (numBytesRead != bufLen) { byte[] bufferToAppend = Arrays.CopyOfRange(buffer, 0, numBytesRead); reader.AppendData(bufferToAppend); } else { reader.AppendData(buffer); } } reader.Finish(); fullBody = reader.GetDocumentProperties(); RespondWithResult(fullBody, error); } finally { try { inputStream.Close(); } catch (IOException) { } } } else { if (entity != null) { try { inputStream = entity.GetContent(); fullBody = Manager.GetObjectMapper().ReadValue <object>(inputStream); RespondWithResult(fullBody, error); } finally { try { inputStream.Close(); } catch (IOException) { } } } } } } catch (ClientProtocolException e) { Log.E(Database.Tag, "client protocol exception", e); error = e; } catch (IOException e) { Log.E(Database.Tag, "io exception", e); error = e; } }
internal void SendAsyncMultipartDownloaderRequest(HttpMethod method, string relativePath, object body, Database db, RemoteRequestCompletionBlock onCompletion) { try { var url = _baseUrl.Append(relativePath); var message = new HttpRequestMessage(method, url); message.Headers.Add("Accept", "*/*"); AddRequestHeaders(message); var client = default(CouchbaseLiteHttpClient); if(!_client.AcquireFor(TimeSpan.FromSeconds(1), out client)) { Log.To.Sync.I(Tag, "Client is disposed, aborting request to {0}", new SecureLogString(relativePath, LogMessageSensitivity.PotentiallyInsecure)); return; } client.Authenticator = Authenticator; var request = client.SendAsync(message, _cancellationTokenSource.Token).ContinueWith(new Action<Task<HttpResponseMessage>>(responseMessage => { object fullBody = null; Exception error = null; try { if(responseMessage.IsFaulted) { error = responseMessage.Exception.InnerException; if(onCompletion != null) { onCompletion(null, error); } return; } var response = responseMessage.Result; // add in cookies to global store //CouchbaseLiteHttpClientFactory.Instance.AddCoIokies(clientFactory.HttpHandler.CookieContainer.GetCookies(url)); var status = response.StatusCode; if((Int32)status.GetStatusCode() >= 300) { Log.To.Sync.W(Tag, "Got error {0}", status.GetStatusCode()); Log.To.Sync.W(Tag, "Request was for: " + message); Log.To.Sync.W(Tag, "Status reason: " + response.ReasonPhrase); Log.To.Sync.W(Tag, "Passing error onto callback..."); error = new HttpResponseException(status); if(onCompletion != null) { onCompletion(null, error); } } else { var entity = response.Content; var contentTypeHeader = response.Content.Headers.ContentType; Stream inputStream = null; if(contentTypeHeader != null && contentTypeHeader.ToString().Contains("multipart/related")) { try { var reader = new MultipartDocumentReader(db); var contentType = contentTypeHeader.ToString(); reader.SetContentType(contentType); var inputStreamTask = entity.ReadAsStreamAsync(); //inputStreamTask.Wait(90000, CancellationTokenSource.Token); inputStream = inputStreamTask.Result; const int bufLen = 1024; var buffer = new byte[bufLen]; int numBytesRead = 0; while((numBytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0) { if(numBytesRead != bufLen) { var bufferToAppend = new Couchbase.Lite.Util.ArraySegment<Byte>(buffer, 0, numBytesRead); reader.AppendData(bufferToAppend); } else { reader.AppendData(buffer); } } reader.Finish(); fullBody = reader.GetDocumentProperties(); if(onCompletion != null) { onCompletion(fullBody, error); } } catch(Exception ex) { Log.To.Sync.W(Tag, "SendAsyncMultipartDownloaderRequest got an exception, aborting...", ex); } finally { try { inputStream.Close(); } catch(Exception) { } } } else { if(entity != null) { try { var readTask = entity.ReadAsStreamAsync(); //readTask.Wait(); // TODO: This should be scaled based on content length. inputStream = readTask.Result; fullBody = Manager.GetObjectMapper().ReadValue<Object>(inputStream); if(onCompletion != null) onCompletion(fullBody, error); } catch(Exception ex) { Log.To.Sync.W(Tag, "SendAsyncMultipartDownloaderRequest got an exception, aborting...", ex); } finally { try { inputStream.Close(); } catch(Exception) { } } } } } } catch(Exception e) { Log.To.Sync.W(Tag, "Got exception during SendAsyncMultipartDownload, aborting..."); error = e; } finally { Task dummy; _requests.TryRemove(message, out dummy); responseMessage.Result.Dispose(); } }), _workExecutor.Scheduler); _requests.TryAdd(message, request); } catch(UriFormatException e) { Log.To.Sync.W(Tag, "Malformed URL for async request, aborting...", e); } }
protected internal override void ExecuteRequest(HttpClient httpClient, HttpRequestMessage request) { object fullBody = null; Exception error = null; HttpResponse response = null; try { if (request.IsAborted()) { RespondWithResult(fullBody, new Exception(string.Format("%s: Request %s has been aborted" , this, request)), response); return; } response = httpClient.Execute(request); try { // add in cookies to global store if (httpClient is DefaultHttpClient) { DefaultHttpClient defaultHttpClient = (DefaultHttpClient)httpClient; this.clientFactory.AddCookies(defaultHttpClient.GetCookieStore().GetCookies()); } } catch (Exception e) { Log.E(Log.TagRemoteRequest, "Unable to add in cookies to global store", e); } StatusLine status = response.GetStatusLine(); if (status.GetStatusCode() >= 300) { Log.E(Log.TagRemoteRequest, "Got error status: %d for %s. Reason: %s", status.GetStatusCode (), request, status.GetReasonPhrase()); error = new HttpResponseException(status.GetStatusCode(), status.GetReasonPhrase( )); } else { HttpEntity entity = response.GetEntity(); Header contentTypeHeader = entity.GetContentType(); InputStream inputStream = null; if (contentTypeHeader != null && contentTypeHeader.GetValue().Contains("multipart/related" )) { try { MultipartDocumentReader reader = new MultipartDocumentReader(response, db); reader.SetContentType(contentTypeHeader.GetValue()); inputStream = entity.GetContent(); int bufLen = 1024; byte[] buffer = new byte[bufLen]; int numBytesRead = 0; while ((numBytesRead = inputStream.Read(buffer)) != -1) { if (numBytesRead != bufLen) { byte[] bufferToAppend = Arrays.CopyOfRange(buffer, 0, numBytesRead); reader.AppendData(bufferToAppend); } else { reader.AppendData(buffer); } } reader.Finish(); fullBody = reader.GetDocumentProperties(); RespondWithResult(fullBody, error, response); } finally { try { inputStream.Close(); } catch (IOException) { } } } else { if (entity != null) { try { inputStream = entity.GetContent(); fullBody = Manager.GetObjectMapper().ReadValue<object>(inputStream); RespondWithResult(fullBody, error, response); } finally { try { inputStream.Close(); } catch (IOException) { } } } } } } catch (IOException e) { Log.E(Log.TagRemoteRequest, "%s: io exception", e, this); error = e; RespondWithResult(fullBody, e, response); } catch (Exception e) { Log.E(Log.TagRemoteRequest, "%s: executeRequest() Exception: ", e, this); error = e; RespondWithResult(fullBody, e, response); } finally { Log.E(Log.TagRemoteRequest, "%s: executeRequest() finally", this); } }
internal void SendAsyncMultipartDownloaderRequest(HttpMethod method, string relativePath, object body, Database db, RemoteRequestCompletionBlock onCompletion) { try { var urlStr = BuildRelativeURLString(relativePath); var url = new Uri(urlStr); var message = new HttpRequestMessage(method, url); message.Headers.Add("Accept", "*/*"); AddRequestHeaders(message); var httpClient = clientFactory.GetHttpClient(); httpClient.SendAsync(message, HttpCompletionOption.ResponseHeadersRead, CancellationTokenSource.Token) .ContinueWith(new Action<Task<HttpResponseMessage>>(responseMessage=> { object fullBody = null; Exception error = null; try { var response = responseMessage.Result; // add in cookies to global store CouchbaseLiteHttpClientFactory.Instance.AddCookies(clientFactory.HttpHandler.CookieContainer.GetCookies(url), url); var status = response.StatusCode; if ((Int32)status.GetStatusCode() >= 300) { Log.E(Database.Tag, "Got error " + Sharpen.Extensions.ToString(status.GetStatusCode ())); Log.E(Database.Tag, "Request was for: " + message); Log.E(Database.Tag, "Status reason: " + response.ReasonPhrase); error = new HttpResponseException(status); //, response.ReasonPhrase); } else { var entity = response.Content; var contentTypeHeader = response.Content.Headers.ContentType; InputStream inputStream = null; if (contentTypeHeader != null && contentTypeHeader.ToString().Contains("multipart/related")) { try { var reader = new MultipartDocumentReader(responseMessage.Result, LocalDatabase); reader.SetContentType(contentTypeHeader.MediaType); var inputStreamTask = entity.ReadAsStreamAsync(); inputStreamTask.Wait(90000, CancellationTokenSource.Token); const int bufLen = 1024; var buffer = new byte[bufLen]; int numBytesRead = 0; while ((numBytesRead = inputStream.Read(buffer)) != -1) { if (numBytesRead != bufLen) { var bufferToAppend = new ArraySegment<Byte>(buffer, 0, numBytesRead).Array; reader.AppendData(bufferToAppend); } else { reader.AppendData(buffer); } } reader.Finish(); fullBody = reader.GetDocumentProperties(); if (onCompletion != null) onCompletion(fullBody, error); } finally { try { inputStream.Close(); } catch (IOException) { // NOTE: swallow? } } } else { if (entity != null) { try { var readTask = entity.ReadAsStreamAsync(); readTask.Wait(); // TODO: This should be scaled based on content length. inputStream = readTask.Result; fullBody = Manager.GetObjectMapper().ReadValue<Object>(inputStream); if (onCompletion != null) onCompletion(fullBody, error); } catch (Exception ex) { Log.E(Tag, ex.Message); } finally { try { inputStream.Close(); } catch (IOException) { } } } } } } catch (ProtocolViolationException e) { Log.E(Database.Tag, "client protocol exception", e); error = e; } catch (IOException e) { Log.E(Database.Tag, "io exception", e); error = e; } })); } #if PORTABLE catch (FormatException e) #else catch (UriFormatException e) #endif { Log.E(Database.Tag, "Malformed URL for async request", e); } }
// Factors out the logic of opening the database and reading the document body from the HTTP request // and performs the specified logic on the body received in the request, barring any problems private static CouchbaseLiteResponse PerformLogicWithDocumentBody(ICouchbaseListenerContext context, Func<Database, Body, CouchbaseLiteResponse> callback) { return DatabaseMethods.PerformLogicWithDatabase(context, true, db => { MultipartDocumentReader reader = new MultipartDocumentReader(db); reader.SetContentType(context.RequestHeaders["Content-Type"]); try { reader.AppendData(context.BodyStream.ReadAllBytes()); reader.Finish(); } catch(InvalidOperationException e) { Log.To.Router.E(TAG, "Exception trying to read data from multipart upload", e); return context.CreateResponse(StatusCode.BadRequest); } catch(IOException e) { Log.To.Router.E(TAG, "IOException while reading context body", e); return context.CreateResponse(StatusCode.RequestTimeout); } return callback(db, new Body(reader.GetDocumentProperties())); }); }
protected internal override void ExecuteRequest(HttpClient httpClient, HttpRequestMessage request) { object fullBody = null; Exception error = null; try { HttpResponse response = httpClient.Execute(request); try { // add in cookies to global store if (httpClient is DefaultHttpClient) { DefaultHttpClient defaultHttpClient = (DefaultHttpClient)httpClient; CouchbaseLiteHttpClientFactory.Instance.AddCookies(defaultHttpClient.GetCookieStore ().GetCookies()); } } catch (Exception e) { Log.E(Database.Tag, "Unable to add in cookies to global store", e); } StatusLine status = response.GetStatusLine(); if (status.GetStatusCode() >= 300) { Log.E(Database.Tag, "Got error " + Sharpen.Extensions.ToString(status.GetStatusCode ())); Log.E(Database.Tag, "Request was for: " + request.ToString()); Log.E(Database.Tag, "Status reason: " + status.GetReasonPhrase()); error = new HttpResponseException(status.GetStatusCode(), status.GetReasonPhrase( )); } else { HttpEntity entity = response.GetEntity(); Header contentTypeHeader = entity.GetContentType(); InputStream inputStream = null; if (contentTypeHeader != null && contentTypeHeader.GetValue().Contains("multipart/related" )) { try { MultipartDocumentReader reader = new MultipartDocumentReader(response, db); reader.SetContentType(contentTypeHeader.GetValue()); inputStream = entity.GetContent(); int bufLen = 1024; byte[] buffer = new byte[bufLen]; int numBytesRead = 0; while ((numBytesRead = inputStream.Read(buffer)) != -1) { if (numBytesRead != bufLen) { byte[] bufferToAppend = Arrays.CopyOfRange(buffer, 0, numBytesRead); reader.AppendData(bufferToAppend); } else { reader.AppendData(buffer); } } reader.Finish(); fullBody = reader.GetDocumentProperties(); RespondWithResult(fullBody, error); } finally { try { inputStream.Close(); } catch (IOException) { } } } else { if (entity != null) { try { inputStream = entity.GetContent(); fullBody = Manager.GetObjectMapper().ReadValue<object>(inputStream); RespondWithResult(fullBody, error); } finally { try { inputStream.Close(); } catch (IOException) { } } } } } } catch (ClientProtocolException e) { Log.E(Database.Tag, "client protocol exception", e); error = e; } catch (IOException e) { Log.E(Database.Tag, "io exception", e); error = e; } }