internal async Task<SimpleHttpResponse> SendAsync(SimpleHttpClient client, int expectedReturnStatus) { var result = await client.SendAsync(); if (((int)result.StatusCode) != expectedReturnStatus) { // Check if we can deserialize the response CloudFoundryException cloudFoundryException; try { string response = await result.Content.ReadAsStringAsync(); var exceptionObject = Utilities.DeserializeJson<CloudFoundryExceptionObject>(response); cloudFoundryException = new CloudFoundryException(exceptionObject); cloudFoundryException.Response = result; throw cloudFoundryException; } catch (CloudFoundryException) { throw; } catch (Exception ex) { throw new CloudFoundryException(string.Format(CultureInfo.InvariantCulture, "An error occurred while talking to the server ({0})", result.StatusCode), ex); } } return result; }
/// <summary> /// Uploads a stream to CloudFoundry via HTTP /// </summary> /// <param name="uploadUri">Uri to upload to</param> /// <param name="zipStream">The compressed stream to upload</param> /// <param name="resources">The json payload describing the files of the app</param> /// <returns></returns> private async Task<SimpleHttpResponse> UploadZip(Uri uploadUri, Stream zipStream, string resources) { string boundary = DateTime.Now.Ticks.ToString("x"); using (SimpleHttpClient httpClient = new SimpleHttpClient(this.Client.CancellationToken, AppsEndpoint.DefaultUploadTimeout)) { // http://apidocs.cloudfoundry.org/210/apps/uploads_the_bits_for_an_app.html httpClient.HttpProxy = Client.HttpProxy; httpClient.SkipCertificateValidation = Client.SkipCertificateValidation; httpClient.Headers.Add("Authorization", string.Format("bearer {0}", this.Client.AuthorizationToken)); httpClient.Uri = uploadUri; httpClient.Method = HttpMethod.Put; List<HttpMultipartFormData> mpd = new List<HttpMultipartFormData>(); using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(resources))) { ms.Position = 0; mpd.Add(new HttpMultipartFormData("resources", string.Empty, string.Empty, ms)); mpd.Add(new HttpMultipartFormData("application", "application.zip", "application/zip", zipStream)); SimpleHttpResponse response = await httpClient.SendAsync(mpd); return response; } } }
/// <summary> /// Returns a LogMessage containing recent logs /// </summary> /// <param name="appGuid">The Cloud Foundry app unique identifier.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException">appGuid</exception> /// <returns></returns> public async Task<ApplicationLog[]> Recent(string appGuid, CancellationToken cancellationToken) { if (appGuid == null) { throw new ArgumentNullException("appGuid"); } UriBuilder appLogUri = new UriBuilder(this.LoggregatorEndpoint); if (appLogUri.Scheme == "ws") { appLogUri.Scheme = "http"; } else { appLogUri.Scheme = "https"; } appLogUri.Path = "recent"; appLogUri.Query = string.Format(CultureInfo.InvariantCulture, "app={0}", appGuid); SimpleHttpClient client = new SimpleHttpClient(cancellationToken); client.Uri = appLogUri.Uri; client.Method = HttpMethod.Get; client.Headers.Add("AUTHORIZATION", this.AuthenticationToken); client.HttpProxy = this.HttpProxy; client.SkipCertificateValidation = this.SkipCertificateValidation; SimpleHttpResponse response = await client.SendAsync(); if (response.StatusCode != System.Net.HttpStatusCode.OK) { string errorMessage = await response.ReadContentAsStringAsync(); throw new LoggregatorException(string.Format(CultureInfo.InvariantCulture, "Server returned error code {0} with message: '{1}'", response.StatusCode, errorMessage)); } MultipartMemoryStreamProvider multipart = null; try { multipart = await response.Content.ReadAsMultipartAsync(); } catch (IOException multipartException) { // There are no recent Logs. We need to investigate a better way for handling this if (multipartException.Message.Contains("MIME multipart message is not complete")) { return new ApplicationLog[] { new ApplicationLog() { Message = "(Server did not return any recent logs)" } }; } else { throw; } } List<ApplicationLog> messages = new List<ApplicationLog>(); foreach (var msg in multipart.Contents) { messages.Add(this.protobufSerializer.DeserializeApplicationLog(await msg.ReadAsByteArrayAsync())); } return messages.ToArray(); }