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}.");
                }
            }
        }
Exemplo n.º 2
0
        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
                    {
                    }
                }
            }
        }