protected virtual async Task <OctopusResponse <TResponseResource> > DispatchRequest <TResponseResource>(OctopusRequest request, bool readResponse) { using (var message = new HttpRequestMessage()) { message.RequestUri = request.Uri; message.Method = new HttpMethod(request.Method); if (request.Method == "PUT" || request.Method == "DELETE") { message.Method = HttpMethod.Post; message.Headers.Add("X-HTTP-Method-Override", request.Method); } if (RootDocument != null) { var expectedCookieName = $"{ApiConstants.AntiforgeryTokenCookiePrefix}_{RootDocument.InstallationId}"; var antiforgeryCookie = cookieContainer.GetCookies(cookieOriginUri) .Cast <Cookie>() .SingleOrDefault(c => string.Equals(c.Name, expectedCookieName)); if (antiforgeryCookie != null) { message.Headers.Add(ApiConstants.AntiforgeryTokenHttpHeaderName, antiforgeryCookie.Value); } } SendingOctopusRequest?.Invoke(request); BeforeSendingHttpRequest?.Invoke(message); if (request.RequestResource != null) { message.Content = GetContent(request); } var completionOption = readResponse ? HttpCompletionOption.ResponseContentRead : HttpCompletionOption.ResponseHeadersRead; try { using (var response = await client.SendAsync(message, completionOption).ConfigureAwait(false)) { AfterReceivedHttpResponse?.Invoke(response); if (!response.IsSuccessStatusCode) { throw await OctopusExceptionFactory.CreateException(response).ConfigureAwait(false); } var resource = readResponse ? await ReadResponse <TResponseResource>(response).ConfigureAwait(false) : default(TResponseResource); var locationHeader = response.Headers.Location?.OriginalString; var octopusResponse = new OctopusResponse <TResponseResource>(request, response.StatusCode, locationHeader, resource); ReceivedOctopusResponse?.Invoke(octopusResponse); return(octopusResponse); } } catch (TaskCanceledException) { throw new TimeoutException($"Timeout getting response, client timeout is set to {client.Timeout}."); } } }
protected virtual OctopusResponse <TResponseResource> DispatchRequest <TResponseResource>(OctopusRequest request, bool readResponse) { var webRequest = (HttpWebRequest)WebRequest.Create(request.Uri); if (serverEndpoint.Proxy != null) { webRequest.Proxy = serverEndpoint.Proxy; } webRequest.CookieContainer = cookieContainer; webRequest.Accept = "application/json"; webRequest.ContentType = "application/json"; webRequest.ReadWriteTimeout = ApiConstants.DefaultClientRequestTimeout; webRequest.Timeout = ApiConstants.DefaultClientRequestTimeout; webRequest.Credentials = serverEndpoint.Credentials ?? CredentialCache.DefaultNetworkCredentials; webRequest.Method = request.Method; webRequest.Headers[ApiConstants.ApiKeyHttpHeaderName] = serverEndpoint.ApiKey; webRequest.UserAgent = octopusCustomHeaders.UserAgent; if (webRequest.Method == "PUT") { webRequest.Headers["X-HTTP-Method-Override"] = "PUT"; webRequest.Method = "POST"; } if (webRequest.Method == "DELETE") { webRequest.Headers["X-HTTP-Method-Override"] = "DELETE"; webRequest.Method = "POST"; } if (!string.IsNullOrEmpty(antiforgeryCookieName)) { var antiforgeryCookie = cookieContainer.GetCookies(cookieOriginUri) .Cast <Cookie>() .SingleOrDefault(c => string.Equals(c.Name, antiforgeryCookieName)); if (antiforgeryCookie != null) { webRequest.Headers[ApiConstants.AntiforgeryTokenHttpHeaderName] = antiforgeryCookie.Value; } } SendingOctopusRequest?.Invoke(request); BeforeSendingHttpRequest?.Invoke(webRequest); HttpWebResponse webResponse = null; try { if (request.RequestResource == null) { webRequest.ContentLength = 0; } else { var requestStreamContent = request.RequestResource as Stream; if (requestStreamContent != null) { webRequest.Accept = null; webRequest.ContentType = "application/octet-stream"; webRequest.ContentLength = requestStreamContent.Length; requestStreamContent.CopyTo(webRequest.GetRequestStream()); // Caller owns stream. } else { var fileUploadContent = request.RequestResource as FileUpload; if (fileUploadContent != null) { webRequest.AllowWriteStreamBuffering = false; webRequest.SendChunked = true; var boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x"); var boundarybytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); webRequest.ContentType = "multipart/form-data; boundary=" + boundary; var requestStream = webRequest.GetRequestStream(); requestStream.Write(boundarybytes, 0, boundarybytes.Length); var headerTemplate = "Content-Disposition: form-data; filename=\"{0}\"\r\nContent-Type: application/octet-stream\r\n\r\n"; var header = string.Format(headerTemplate, fileUploadContent.FileName); var headerbytes = Encoding.UTF8.GetBytes(header); requestStream.Write(headerbytes, 0, headerbytes.Length); fileUploadContent.Contents.CopyTo(requestStream); requestStream.Write(boundarybytes, 0, boundarybytes.Length); requestStream.Flush(); requestStream.Close(); } else { var text = JsonConvert.SerializeObject(request.RequestResource, defaultJsonSerializerSettings); webRequest.ContentLength = Encoding.UTF8.GetByteCount(text); var requestStream = new StreamWriter(webRequest.GetRequestStream()); requestStream.Write(text); requestStream.Flush(); } } } Logger.Trace($"DispatchRequest: {webRequest.Method} {webRequest.RequestUri}"); webResponse = (HttpWebResponse)webRequest.GetResponse(); AfterReceivingHttpResponse?.Invoke(webResponse); var resource = default(TResponseResource); if (readResponse) { var responseStream = webResponse.GetResponseStream(); if (responseStream != null) { if (typeof(TResponseResource) == typeof(Stream)) { var stream = new MemoryStream(); responseStream.CopyTo(stream); stream.Seek(0, SeekOrigin.Begin); resource = (TResponseResource)(object)stream; } else if (typeof(TResponseResource) == typeof(byte[])) { var stream = new MemoryStream(); responseStream.CopyTo(stream); resource = (TResponseResource)(object)stream.ToArray(); } else if (typeof(TResponseResource) == typeof(string)) { using (var reader = new StreamReader(responseStream)) { resource = (TResponseResource)(object)reader.ReadToEnd(); } } else { using (var reader = new StreamReader(responseStream)) { var content = reader.ReadToEnd(); try { resource = JsonConvert.DeserializeObject <TResponseResource>(content, defaultJsonSerializerSettings); } catch (Exception ex) { throw new OctopusDeserializationException((int)webResponse.StatusCode, "Unable to process response from server: " + ex.Message + ". Response content: " + (content.Length > 100 ? content.Substring(0, 100) : content), ex); } } } } } var locationHeader = webResponse.Headers.Get("Location"); var octopusResponse = new OctopusResponse <TResponseResource>(request, webResponse.StatusCode, locationHeader, resource); ReceivedOctopusResponse?.Invoke(octopusResponse); return(octopusResponse); } catch (WebException wex) { if (wex.Response != null) { throw OctopusExceptionFactory.CreateException(wex, (HttpWebResponse)wex.Response); } throw; } finally { if (webResponse != null) { try { webResponse.Close(); } // ReSharper disable once EmptyGeneralCatchClause catch { } } } }