internal static void LogResponseDetails(FullResponse fullResponse)
 {
     Log.Debug("Response status code: {StatusCode}", fullResponse.StatusCode);
     Log.Debug("  Response headers: {ResponseHeaders}",
               fullResponse.Headers?.Select(kv => $"{kv.Key}: {kv.Value}")
               .Aggregate("", (str, header) => $"{str}{header}, ").TrimEnd(',', ' '));
     Log.Debug("  Body size: {ResponseBodySize}",
               fullResponse.Body == null ? "None" : $"{fullResponse.Body.Length}");
 }
Пример #2
0
        public static void LogResponseDetails(this FullResponse fullResponse)
        {
            if (fullResponse is null)
            {
                Log.Debug("LogResponseDetails: fullResponse is null!");
                return;
            }

            Log.Debug($"Response status code: {fullResponse.StatusCode}");

            Log.Debug("  Response headers: {ResponseHeaders}",
                      fullResponse.Headers?.Select(kv => $"{kv.Key}: {kv.Value}")
                      .Aggregate("", (str, header) => $"{str}{header}, ").TrimEnd(',', ' '));

            Log.Debug("  Body size: {ResponseBodySize}", fullResponse.Body == null ? "None" : $"{fullResponse.Body.Length}");
        }
Пример #3
0
        public static void LogResponseDetails(this IRestResponse restResponse)
        {
            if (restResponse is null)
            {
                Log.Debug("LogResponseDetails: restResponse is null!");
                return;
            }

            var fullResponse = new FullResponse
            {
                StatusCode = restResponse.StatusCode,
                Headers    = new Dictionary <string, string>(),
                Body       = restResponse.Content
            };

            fullResponse.LogResponseDetails();
        }
Пример #4
0
        private async Task <string> ValidatePostResponse(HttpResponseMessage response)
        {
            var fullResponse = new FullResponse
            {
                Body       = await response.Content.ReadAsStringAsync(),
                Headers    = response.Headers.ToDictionary(key => key.Key, value => value.Value.FirstOrDefault()),
                StatusCode = response.StatusCode
            };

            if (!response.IsSuccessStatusCode)
            {
                throw new SafeguardDotNetException(
                          $"Error returned from Safeguard API, Error: {fullResponse.StatusCode} {fullResponse.Body}",
                          fullResponse.StatusCode, fullResponse.Body);
            }

            fullResponse.LogResponseDetails();

            return(fullResponse.Body);
        }
Пример #5
0
        private void ValidateGetResponse(HttpResponseMessage response)
        {
            var fullResponse = new FullResponse
            {
                Headers    = response.Headers.ToDictionary(key => key.Key, value => value.Value.FirstOrDefault()),
                StatusCode = response.StatusCode
            };

            // Check for 200 OK here because 204 Accepted doesn't return a stream,
            // better to fail in that case.
            if (response.StatusCode != System.Net.HttpStatusCode.OK)
            {
                fullResponse.Body = response.Content.ReadAsStringAsync().Result;
                throw new SafeguardDotNetException(
                          $"Response does not indicate OK status. Error: {fullResponse.StatusCode} {fullResponse.Body}",
                          fullResponse.StatusCode, fullResponse.Body);
            }

            fullResponse.LogResponseDetails();
        }
        public FullResponse InvokeMethodFull(Service service, Method method, string relativeUrl,
                                             string body = null, IDictionary <string, string> parameters             = null,
                                             IDictionary <string, string> additionalHeaders = null, TimeSpan?timeout = null)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException("SafeguardConnection");
            }
            if (string.IsNullOrEmpty(relativeUrl))
            {
                throw new ArgumentException("Parameter may not be null or empty", nameof(relativeUrl));
            }

            var request = new RestRequest(relativeUrl, method.ConvertToRestSharpMethod());

            if (!_authenticationMechanism.IsAnonymous)
            {
                if (!_authenticationMechanism.HasAccessToken())
                {
                    throw new SafeguardDotNetException("Access token is missing due to log out, you must refresh the access token to invoke a method");
                }
                // SecureString handling here basically negates the use of a secure string anyway, but when calling a Web API
                // I'm not sure there is anything you can do about it.
                request.AddHeader("Authorization",
                                  $"Bearer {_authenticationMechanism.GetAccessToken().ToInsecureString()}");
            }
            if (additionalHeaders != null && !additionalHeaders.ContainsKey("Accept"))
            {
                request.AddHeader("Accept", "application/json"); // Assume JSON unless specified
            }
            if (additionalHeaders != null)
            {
                foreach (var header in additionalHeaders)
                {
                    request.AddHeader(header.Key, header.Value);
                }
            }
            if ((method == Method.Post || method == Method.Put) && body != null)
            {
                request.AddParameter("application/json", body, ParameterType.RequestBody);
            }
            else if (method == Method.Post || method == Method.Put) // have to set the Content-type header even if empty body or Safeguard chokes
            {
                request.AddHeader("Content-type", "application/json");
            }
            if (parameters != null)
            {
                foreach (var param in parameters)
                {
                    request.AddParameter(param.Key, param.Value, ParameterType.QueryString);
                }
            }
            if (timeout.HasValue)
            {
                request.Timeout = (timeout.Value.TotalMilliseconds > int.MaxValue)
                    ? int.MaxValue : (int)timeout.Value.TotalMilliseconds;
            }

            var client = GetClientForService(service);

            client.LogRequestDetails(request, parameters, additionalHeaders);

            var response = client.Execute(request);

            Log.Debug("  Body size: {RequestBodySize}", body == null ? "None" : $"{body.Length}");
            if (response.ResponseStatus != ResponseStatus.Completed)
            {
                throw new SafeguardDotNetException($"Unable to connect to web service {client.BaseUrl}, Error: " +
                                                   response.ErrorMessage);
            }
            if (!response.IsSuccessful)
            {
                throw new SafeguardDotNetException(
                          "Error returned from Safeguard API, Error: " + $"{response.StatusCode} {response.Content}",
                          response.StatusCode, response.Content);
            }
            var fullResponse = new FullResponse
            {
                StatusCode = response.StatusCode,
                Headers    = new Dictionary <string, string>(),
                Body       = response.Content
            };

            foreach (var header in response.Headers)
            {
                if (header.Name != null)
                {
                    fullResponse.Headers.Add(header.Name, header.Value?.ToString());
                }
            }

            fullResponse.LogResponseDetails();

            return(fullResponse);
        }
        public FullResponse InvokeMethodFull(Service service, Method method, string relativeUrl,
                                             string body = null, IDictionary <string, string> parameters = null,
                                             IDictionary <string, string> additionalHeaders = null)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException("SafeguardConnection");
            }
            if (string.IsNullOrEmpty(relativeUrl))
            {
                throw new ArgumentException("Parameter may not be null or empty", nameof(relativeUrl));
            }

            var request = new RestRequest(relativeUrl, method.ConvertToRestSharpMethod());

            if (!_authenticationMechanism.IsAnonymous)
            {
                if (!_authenticationMechanism.HasAccessToken())
                {
                    throw new SafeguardDotNetException("Access token is missing due to log out, you must refresh the access token to invoke a method");
                }
                // SecureString handling here basically negates the use of a secure string anyway, but when calling a Web API
                // I'm not sure there is anything you can do about it.
                request.AddHeader("Authorization",
                                  $"Bearer {_authenticationMechanism.GetAccessToken().ToInsecureString()}");
            }
            if (additionalHeaders != null && !additionalHeaders.ContainsKey("Accept"))
            {
                request.AddHeader("Accept", "application/json"); // Assume JSON unless specified
            }
            if (additionalHeaders != null)
            {
                foreach (var header in additionalHeaders)
                {
                    request.AddHeader(header.Key, header.Value);
                }
            }
            if (method == Method.Post || method == Method.Put)
            {
                request.AddParameter("application/json", body, ParameterType.RequestBody);
            }
            if (parameters != null)
            {
                foreach (var param in parameters)
                {
                    request.AddParameter(param.Key, param.Value, ParameterType.QueryString);
                }
            }

            var client = GetClientForService(service);

            Log.Debug("Invoking method: {Method} {Endpoint}", method.ToString().ToUpper(),
                      client.BaseUrl + $"/{relativeUrl}");
            Log.Debug("  Query parameters: {QueryParameters}",
                      parameters?.Select(kv => $"{kv.Key}={kv.Value}").Aggregate("", (str, param) => $"{str}{param}&")
                      .TrimEnd('&') ?? "None");
            Log.Debug("  Additional headers: {AdditionalHeaders}",
                      additionalHeaders?.Select(kv => $"{kv.Key}: {kv.Value}")
                      .Aggregate("", (str, header) => $"{str}{header}, ").TrimEnd(',', ' ') ?? "None");
            var response = client.Execute(request);

            Log.Debug("  Body size: {RequestBodySize}", body == null ? "None" : $"{body.Length}");
            if (response.ResponseStatus != ResponseStatus.Completed)
            {
                throw new SafeguardDotNetException($"Unable to connect to web service {client.BaseUrl}, Error: " +
                                                   response.ErrorMessage);
            }
            if (!response.IsSuccessful)
            {
                throw new SafeguardDotNetException(
                          "Error returned from Safeguard API, Error: " + $"{response.StatusCode} {response.Content}",
                          response.StatusCode, response.Content);
            }
            var fullResponse = new FullResponse
            {
                StatusCode = response.StatusCode,
                Headers    = new Dictionary <string, string>(),
                Body       = response.Content
            };

            if (response.Headers != null)
            {
                foreach (var header in response.Headers)
                {
                    fullResponse.Headers.Add(header.Name, header.Value?.ToString());
                }
            }
            Log.Debug("Response status code: {StatusCode}", fullResponse.StatusCode);
            Log.Debug("  Response headers: {ResponseHeaders}",
                      fullResponse.Headers?.Select(kv => $"{kv.Key}: {kv.Value}")
                      .Aggregate("", (str, header) => $"{str}{header}, ").TrimEnd(',', ' '));
            Log.Debug("  Body size: {ResponseBodySize}",
                      fullResponse.Body == null ? "None" : $"{fullResponse.Body.Length}");
            return(fullResponse);
        }
Пример #8
0
        public async Task <string> UploadAsync(Service service, string relativeUrl, Stream stream, IProgress <TransferProgress> progress = null, IDictionary <string, string> parameters = null, IDictionary <string, string> additionalHeaders = null, CancellationToken?cancellationToken = null)
        {
            if (_isDisposed())
            {
                throw new ObjectDisposedException("SafeguardConnection");
            }
            if (string.IsNullOrEmpty(relativeUrl))
            {
                throw new ArgumentException("Parameter may not be null or empty", nameof(relativeUrl));
            }

            var token = cancellationToken ?? CancellationToken.None;
            var uri   = $"https://{_authenticationMechanism.NetworkAddress}/service/{service}/v{_authenticationMechanism.ApiVersion}/{relativeUrl}";

            if (parameters != null)
            {
                uri = QueryHelpers.AddQueryString(uri, parameters);
            }

            using (var request = new HttpRequestMessage(HttpMethod.Post, uri))
            {
                if (!_authenticationMechanism.IsAnonymous)
                {
                    if (!_authenticationMechanism.HasAccessToken())
                    {
                        throw new SafeguardDotNetException("Access token is missing due to log out, you must refresh the access token to invoke a method");
                    }
                    // SecureString handling here basically negates the use of a secure string anyway, but when calling a Web API
                    // I'm not sure there is anything you can do about it.
                    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _authenticationMechanism.GetAccessToken().ToInsecureString());
                }

                if (additionalHeaders != null && !additionalHeaders.ContainsKey("Accept"))
                {
                    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                }

                if (additionalHeaders != null)
                {
                    foreach (var header in additionalHeaders)
                    {
                        request.Headers.Add(header.Key, header.Value);
                    }
                }

                SafeguardConnection.LogRequestDetails(Method.Post, new Uri(uri), parameters, additionalHeaders);

                EventHandler <HttpProgressEventArgs> progressHandlerFunc = null;

                using (var content = new StreamContent(stream, DefaultBufferSize))
                {
                    request.Content = content;
                    request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

                    if (progress != null)
                    {
                        progressHandlerFunc = (sender, args) =>
                        {
                            var uploadProgress = new TransferProgress
                            {
                                BytesTotal       = args.TotalBytes.GetValueOrDefault(0),
                                BytesTransferred = args.BytesTransferred
                            };
                            progress.Report(uploadProgress);
                        };
                        _progressMessageHandler.HttpSendProgress += progressHandlerFunc;
                    }
                    try
                    {
                        var response = await Client.SendAsync(request, completionOption : HttpCompletionOption.ResponseHeadersRead, token);

                        var fullResponse = new FullResponse
                        {
                            Body       = await response.Content.ReadAsStringAsync(),
                            Headers    = response.Headers.ToDictionary(key => key.Key, value => value.Value.FirstOrDefault()),
                            StatusCode = response.StatusCode
                        };

                        if (!response.IsSuccessStatusCode)
                        {
                            throw new SafeguardDotNetException(
                                      $"Error returned from Safeguard API, Error: {fullResponse.StatusCode} {fullResponse.Body}",
                                      fullResponse.StatusCode, fullResponse.Body);
                        }

                        SafeguardConnection.LogResponseDetails(fullResponse);

                        return(fullResponse.Body);
                    }
                    finally
                    {
                        if (progressHandlerFunc != null)
                        {
                            _progressMessageHandler.HttpSendProgress -= progressHandlerFunc;
                        }
                    }
                }
            }
        }