コード例 #1
0
        internal async Task CreateDirectoryStructureForSwaggerEndpointAsync(IShellState shellState, HttpState programState, CancellationToken cancellationToken)
        {
            string swaggerRequeryBehaviorSetting = _preferences.GetValue(WellKnownPreference.SwaggerRequeryBehavior, "auto");

            if (swaggerRequeryBehaviorSetting.StartsWith("auto", StringComparison.OrdinalIgnoreCase))
            {
                await SetSwaggerCommand.CreateDirectoryStructureForSwaggerEndpointAsync(shellState, programState, programState.SwaggerEndpoint, cancellationToken).ConfigureAwait(false);
            }
        }
コード例 #2
0
        public IEnumerable <string> GetOpenApiSearchPaths()
        {
            string[] configSearchPaths = Split(_preferences.GetValue(WellKnownPreference.SwaggerSearchPaths));

            if (configSearchPaths.Length > 0)
            {
                return(configSearchPaths);
            }

            string[] addToSearchPaths      = Split(_preferences.GetValue(WellKnownPreference.SwaggerAddToSearchPaths));
            string[] removeFromSearchPaths = Split(_preferences.GetValue(WellKnownPreference.SwaggerRemoveFromSearchPaths));

            return(DefaultSearchPaths.Union(addToSearchPaths).Except(removeFromSearchPaths));
        }
コード例 #3
0
        internal async Task CreateDirectoryStructureForSwaggerEndpointAsync(HttpState programState, CancellationToken cancellationToken)
        {
            string swaggerRequeryBehaviorSetting = _preferences.GetValue(WellKnownPreference.SwaggerRequeryBehavior, "auto");

            if (swaggerRequeryBehaviorSetting.StartsWith("auto", StringComparison.OrdinalIgnoreCase))
            {
                ApiConnection apiConnection = new ApiConnection(_preferences)
                {
                    BaseUri    = programState.BaseAddress,
                    SwaggerUri = programState.SwaggerEndpoint,
                    AllowBaseOverrideBySwagger = false
                };
                await apiConnection.SetupHttpState(programState, performAutoDetect : false, cancellationToken).ConfigureAwait(false);
            }
        }
コード例 #4
0
ファイル: ApiConnection.cs プロジェクト: wilvk/HttpRepl
        private IEnumerable <string> GetSwaggerSearchPaths()
        {
            string rawValue = _preferences.GetValue(WellKnownPreference.SwaggerSearchPaths, SwaggerSearchPaths);

            string[] paths = rawValue?.Split('|', StringSplitOptions.RemoveEmptyEntries);

            return(paths);
        }
コード例 #5
0
ファイル: NuGetViewModel.cs プロジェクト: widistef/nuget
        private string LoadPrereleaseFilter()
        {
            if (_preferences != null && _preferences.ContainsValue(PrereleaseFilterKey))
            {
                return(_preferences.GetValue(PrereleaseFilterKey));
            }

            // Default Value
            return(Resources.Prerelease_Filter_StableOnly);
        }
コード例 #6
0
 public HttpState(IFileSystem fileSystem, IPreferences preferences, HttpClient httpClient)
 {
     _fileSystem  = fileSystem;
     _preferences = preferences;
     Client       = httpClient;
     PathSections = new Stack <string>();
     Headers      = new Dictionary <string, IEnumerable <string> >(StringComparer.OrdinalIgnoreCase)
     {
         { "User-Agent", new[] { _preferences.GetValue(WellKnownPreference.HttpClientUserAgent, "HTTP-REPL") } }
     };
 }
コード例 #7
0
ファイル: UICommand.cs プロジェクト: wilvk/HttpRepl
        public Task ExecuteAsync(IShellState shellState, HttpState programState, ICoreParseResult parseResult, CancellationToken cancellationToken)
        {
            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));

            programState = programState ?? throw new ArgumentNullException(nameof(programState));

            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));

            if (programState.BaseAddress == null)
            {
                shellState.ConsoleManager.Error.WriteLine(Strings.UICommand_NotConnectedToServerError.SetColor(programState.ErrorColor));
                return(Task.CompletedTask);
            }

            Uri uri = null;

            // Try to use the parameter first, if there was one.
            if (parseResult.Sections.Count > 1)
            {
                string parameter = parseResult.Sections[1];

                if (Uri.IsWellFormedUriString(parameter, UriKind.Absolute))
                {
                    uri = new Uri(parameter, UriKind.Absolute);
                }
                else if (!Uri.TryCreate(programState.BaseAddress, parameter, out uri))
                {
                    uri = null;
                }

                // If they specified a parameter and it failed, bail out
                if (uri is null)
                {
                    shellState.ConsoleManager.Error.WriteLine(string.Format(Strings.UICommand_InvalidParameter, parameter).SetColor(programState.ErrorColor));
                    return(Task.CompletedTask);
                }
            }

            // If no parameter specified, check the preferences or use the default
            if (uri is null)
            {
                string uiEndpoint = _preferences.GetValue(WellKnownPreference.SwaggerUIEndpoint, "swagger");
                if (Uri.IsWellFormedUriString(uiEndpoint, UriKind.Absolute))
                {
                    uri = new Uri(uiEndpoint, UriKind.Absolute);
                }
                else
                {
                    uri = new Uri(programState.BaseAddress, uiEndpoint);
                }
            }

            return(_uriLauncher.LaunchUriAsync(uri));
        }
コード例 #8
0
        public HttpState(IPreferences preferences, HttpClient httpClient)
        {
            preferences = preferences ?? throw new ArgumentNullException(nameof(preferences));

            _preferences = preferences;
            Client       = httpClient;
            PathSections = new Stack <string>();
            Headers      = new Dictionary <string, IEnumerable <string> >(StringComparer.OrdinalIgnoreCase)
            {
                { "User-Agent", new[] { _preferences.GetValue(WellKnownPreference.HttpClientUserAgent, "HTTP-REPL") } }
            };
        }
コード例 #9
0
ファイル: ApiConnection.cs プロジェクト: vijayraavi/HttpRepl
        private IEnumerable <string> GetSwaggerSearchPaths()
        {
            string rawValue = _preferences.GetValue(WellKnownPreference.SwaggerSearchPaths);

            if (rawValue is null)
            {
                return(OpenApiDescriptionSearchPaths);
            }
            else
            {
                string[] paths = rawValue?.Split('|', StringSplitOptions.RemoveEmptyEntries);
                return(paths);
            }
        }
コード例 #10
0
        /// <summary>
        /// Loads a sequence of strings from persistent storage.
        /// </summary>
        /// <returns>Sequence of strings.</returns>
        public IEnumerable <string> Load()
        {
            // Read the list of strings from the store
            string feedSequence = _preferences.GetValue(FeedsSequenceKey);
            IEnumerable <string> feedSources;

            if (!String.IsNullOrEmpty(feedSequence))
            {
                feedSources = feedSequence.Split(EnvironmentNewLine, StringSplitOptions.RemoveEmptyEntries);
            }
            else
            {
                feedSources = new List <String>();
            }

            return(feedSources);
        }
コード例 #11
0
ファイル: HelpCommand.cs プロジェクト: skeeler/HttpRepl
        public async Task ExecuteAsync(IShellState shellState, HttpState programState, ICoreParseResult parseResult, CancellationToken cancellationToken)
        {
            if (shellState.CommandDispatcher is ICommandDispatcher <HttpState, ICoreParseResult> dispatcher)
            {
                if (parseResult.Sections.Count == 1)
                {
                    CoreGetHelp(shellState, dispatcher, programState);
                }
                else
                {
                    bool anyHelp = false;
                    var  output  = new StringBuilder();

                    if (parseResult.Slice(1) is ICoreParseResult continuationParseResult)
                    {
                        foreach (ICommand <HttpState, ICoreParseResult> command in dispatcher.Commands)
                        {
                            string help = command.GetHelpDetails(shellState, programState, continuationParseResult);

                            if (!string.IsNullOrEmpty(help))
                            {
                                anyHelp = true;
                                output.AppendLine();
                                output.AppendLine(help);

                                var structuredCommand = command as CommandWithStructuredInputBase <HttpState, ICoreParseResult>;
                                if (structuredCommand != null && structuredCommand.InputSpec.Options.Any())
                                {
                                    output.AppendLine();
                                    output.AppendLine("Options:".Bold());
                                    foreach (var option in structuredCommand.InputSpec.Options)
                                    {
                                        var optionText = string.Empty;
                                        foreach (var form in option.Forms)
                                        {
                                            if (!string.IsNullOrEmpty(optionText))
                                            {
                                                optionText += "|";
                                            }
                                            optionText += form;
                                        }
                                        output.AppendLine($"    {optionText}");
                                    }
                                }

                                break;
                            }
                        }
                    }

                    if (!anyHelp)
                    {
                        //Maybe the input is an URL
                        if (parseResult.Sections.Count == 2)
                        {
                            if (programState.SwaggerEndpoint != null)
                            {
                                string swaggerRequeryBehaviorSetting = _preferences.GetValue(WellKnownPreference.SwaggerRequeryBehavior, "auto");

                                if (swaggerRequeryBehaviorSetting.StartsWith("auto", StringComparison.OrdinalIgnoreCase))
                                {
                                    await SetSwaggerCommand.CreateDirectoryStructureForSwaggerEndpointAsync(shellState, programState, programState.SwaggerEndpoint, cancellationToken).ConfigureAwait(false);
                                }
                            }

                            //Structure is null because, for example, SwaggerEndpoint exists but is not reachable.
                            if (programState.Structure != null)
                            {
                                IDirectoryStructure structure = programState.Structure.TraverseTo(parseResult.Sections[1]);
                                if (structure.DirectoryNames.Any())
                                {
                                    output.AppendLine("Child directories:");

                                    foreach (string name in structure.DirectoryNames)
                                    {
                                        output.AppendLine("  " + name + "/");
                                    }
                                    anyHelp = true;
                                }

                                if (structure.RequestInfo != null)
                                {
                                    if (structure.RequestInfo.Methods.Count > 0)
                                    {
                                        if (anyHelp)
                                        {
                                            output.AppendLine();
                                        }

                                        anyHelp = true;
                                        output.AppendLine("Available methods:");

                                        foreach (string method in structure.RequestInfo.Methods)
                                        {
                                            output.AppendLine("  " + method.ToUpperInvariant());
                                            IReadOnlyList <string> accepts = structure.RequestInfo.ContentTypesByMethod[method];
                                            string acceptsString           = string.Join(", ", accepts.Where(x => !string.IsNullOrEmpty(x)));
                                            if (!string.IsNullOrEmpty(acceptsString))
                                            {
                                                output.AppendLine("    Accepts: " + acceptsString);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (!anyHelp)
                        {
                            output.AppendLine("Unable to locate any help information for the specified command");
                        }
                    }

                    shellState.ConsoleManager.Write(output.ToString());
                }
            }
        }
コード例 #12
0
 private void AddDefaultHeaders()
 {
     Headers["User-Agent"] = new[] { _preferences.GetValue(WellKnownPreference.HttpClientUserAgent, "HTTP-REPL") };
 }
コード例 #13
0
ファイル: ListCommand.cs プロジェクト: scottaddie/HttpRepl
        protected override async Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput <ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)
        {
            programState = programState ?? throw new ArgumentNullException(nameof(programState));

            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));

            commandInput = commandInput ?? throw new ArgumentNullException(nameof(commandInput));

            if (programState.SwaggerEndpoint != null)
            {
                string swaggerRequeryBehaviorSetting = _preferences.GetValue(WellKnownPreference.SwaggerRequeryBehavior, "auto");

                if (swaggerRequeryBehaviorSetting.StartsWith("auto", StringComparison.OrdinalIgnoreCase))
                {
                    ApiConnection apiConnection = new ApiConnection(programState, _preferences, shellState.ConsoleManager, logVerboseMessages: false)
                    {
                        BaseUri    = programState.BaseAddress,
                        SwaggerUri = programState.SwaggerEndpoint,
                        AllowBaseOverrideBySwagger = false
                    };
                    await apiConnection.SetupHttpState(programState, performAutoDetect : false, cancellationToken).ConfigureAwait(false);
                }
            }

            if (programState.BaseAddress is null)
            {
                shellState.ConsoleManager.WriteLine(Resources.Strings.ListCommand_Error_NoBaseAddress.SetColor(programState.WarningColor));
                return;
            }

            if (programState.SwaggerEndpoint is null || programState.Structure is null)
            {
                shellState.ConsoleManager.WriteLine(Resources.Strings.ListCommand_Error_NoDirectoryStructure.SetColor(programState.WarningColor));
                return;
            }

            string path = commandInput.Arguments.Count > 0 ? commandInput.Arguments[0].Text : string.Empty;

            //If it's an absolute URI, nothing to suggest
            if (Uri.TryCreate(path, UriKind.Absolute, out Uri _))
            {
                return;
            }

            IDirectoryStructure s = programState.Structure.TraverseTo(programState.PathSections.Reverse()).TraverseTo(path);

            string thisDirMethod = s.RequestInfo.GetDirectoryMethodListing();

            List <TreeNode> roots     = new List <TreeNode>();
            Formatter       formatter = new Formatter();

            roots.Add(new TreeNode(formatter, ".", thisDirMethod));

            if (s.Parent != null)
            {
                string parentDirMethod = s.Parent.RequestInfo.GetDirectoryMethodListing();

                roots.Add(new TreeNode(formatter, "..", parentDirMethod));
            }

            int recursionDepth = 1;

            if (commandInput.Options[RecursiveOption].Count > 0)
            {
                if (string.IsNullOrEmpty(commandInput.Options[RecursiveOption][0]?.Text))
                {
                    recursionDepth = int.MaxValue;
                }
                else if (int.TryParse(commandInput.Options[RecursiveOption][0].Text, NumberStyles.Integer, CultureInfo.InvariantCulture, out int rd) && rd > 1)
                {
                    recursionDepth = rd;
                }
            }

            foreach (string child in s.DirectoryNames)
            {
                IDirectoryStructure dir = s.GetChildDirectory(child);

                string methods = dir.RequestInfo.GetDirectoryMethodListing();

                TreeNode dirNode = new TreeNode(formatter, child, methods);
                roots.Add(dirNode);
                Recurse(dirNode, dir, recursionDepth - 1);
            }

            foreach (TreeNode node in roots)
            {
                shellState.ConsoleManager.WriteLine(node.ToString());
            }

            bool hasVerboseOption  = commandInput.Options[VerboseOption].Count > 0;
            bool hasRequestMethods = s.RequestInfo?.Methods?.Count > 0;

            if (hasVerboseOption && hasRequestMethods)
            {
                shellState.ConsoleManager.WriteLine();
                shellState.ConsoleManager.WriteLine(Resources.Strings.ListCommand_AvailableMethods);

                foreach (string method in s.RequestInfo.Methods)
                {
                    shellState.ConsoleManager.WriteLine("  " + method.ToUpperInvariant());
                    IReadOnlyList <string> accepts = s.RequestInfo.ContentTypesByMethod[method];
                    string acceptsString           = string.Join(", ", accepts.Where(x => !string.IsNullOrEmpty(x)));
                    if (!string.IsNullOrEmpty(acceptsString))
                    {
                        shellState.ConsoleManager.WriteLine($"    {Resources.Strings.ListCommand_Accepts} " + acceptsString);
                    }
                }
            }
        }
コード例 #14
0
        protected override async Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput <ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)
        {
            if (programState.SwaggerEndpoint != null)
            {
                string swaggerRequeryBehaviorSetting = _preferences.GetValue(WellKnownPreference.SwaggerRequeryBehavior, "auto");

                if (swaggerRequeryBehaviorSetting.StartsWith("auto", StringComparison.OrdinalIgnoreCase))
                {
                    await SetSwaggerCommand.CreateApiDefinitionForSwaggerEndpointAsync(shellState, programState, programState.SwaggerEndpoint, cancellationToken).ConfigureAwait(false);
                }
            }

            if (programState.BaseAddress is null)
            {
                shellState.ConsoleManager.WriteLine(Resources.Strings.ListCommand_Error_NoBaseAddress.SetColor(programState.WarningColor));
                return;
            }

            if (programState.SwaggerEndpoint is null || programState.Structure is null)
            {
                shellState.ConsoleManager.WriteLine(Resources.Strings.ListCommand_Error_NoDirectoryStructure.SetColor(programState.WarningColor));
                return;
            }

            string path = commandInput.Arguments.Count > 0 ? commandInput.Arguments[0].Text : string.Empty;

            //If it's an absolute URI, nothing to suggest
            if (Uri.TryCreate(path, UriKind.Absolute, out Uri _))
            {
                return;
            }

            IDirectoryStructure s = programState.Structure.TraverseTo(programState.PathSections.Reverse()).TraverseTo(path);

            string thisDirMethod = s.RequestInfo != null && s.RequestInfo.Methods.Count > 0
                ? "[" + string.Join("|", s.RequestInfo.Methods) + "]"
                : "[]";

            List <TreeNode> roots     = new List <TreeNode>();
            Formatter       formatter = new Formatter();

            roots.Add(new TreeNode(formatter, ".", thisDirMethod));

            if (s.Parent != null)
            {
                string parentDirMethod = s.Parent.RequestInfo != null && s.Parent.RequestInfo.Methods.Count > 0
                    ? "[" + string.Join("|", s.Parent.RequestInfo.Methods) + "]"
                    : "[]";

                roots.Add(new TreeNode(formatter, "..", parentDirMethod));
            }

            int recursionDepth = 1;

            if (commandInput.Options[RecursiveOption].Count > 0)
            {
                if (string.IsNullOrEmpty(commandInput.Options[RecursiveOption][0]?.Text))
                {
                    recursionDepth = int.MaxValue;
                }
                else if (int.TryParse(commandInput.Options[RecursiveOption][0].Text, NumberStyles.Integer, CultureInfo.InvariantCulture, out int rd) && rd > 1)
                {
                    recursionDepth = rd;
                }
            }

            foreach (string child in s.DirectoryNames)
            {
                IDirectoryStructure dir = s.GetChildDirectory(child);

                string methods = dir.RequestInfo != null && dir.RequestInfo.Methods.Count > 0
                    ? "[" + string.Join("|", dir.RequestInfo.Methods) + "]"
                    : "[]";

                TreeNode dirNode = new TreeNode(formatter, child, methods);
                roots.Add(dirNode);
                Recurse(dirNode, dir, recursionDepth - 1);
            }

            foreach (TreeNode node in roots)
            {
                shellState.ConsoleManager.WriteLine(node.ToString());
            }
        }
コード例 #15
0
        protected override async Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput <ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)
        {
            if (programState.BaseAddress == null && (commandInput.Arguments.Count == 0 || !Uri.TryCreate(commandInput.Arguments[0].Text, UriKind.Absolute, out Uri _)))
            {
                shellState.ConsoleManager.Error.WriteLine(Resources.Strings.Error_NoBasePath.SetColor(programState.ErrorColor));
                return;
            }

            if (programState.SwaggerEndpoint != null)
            {
                string swaggerRequeryBehaviorSetting = _preferences.GetValue(WellKnownPreference.SwaggerRequeryBehavior, "auto");

                if (swaggerRequeryBehaviorSetting.StartsWith("auto", StringComparison.OrdinalIgnoreCase))
                {
                    await SetSwaggerCommand.CreateDirectoryStructureForSwaggerEndpointAsync(shellState, programState, programState.SwaggerEndpoint, cancellationToken).ConfigureAwait(false);
                }
            }

            Dictionary <string, string> thisRequestHeaders = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            foreach (InputElement header in commandInput.Options[HeaderOption])
            {
                int equalsIndex = header.Text.IndexOfAny(HeaderSeparatorChars);

                if (equalsIndex < 0)
                {
                    shellState.ConsoleManager.Error.WriteLine("Headers must be formatted as {header}={value} or {header}:{value}".SetColor(programState.ErrorColor));
                    return;
                }

                thisRequestHeaders[header.Text.Substring(0, equalsIndex)] = header.Text.Substring(equalsIndex + 1);
            }

            Uri effectivePath          = programState.GetEffectivePath(commandInput.Arguments.Count > 0 ? commandInput.Arguments[0].Text : string.Empty);
            HttpRequestMessage request = new HttpRequestMessage(new HttpMethod(Verb.ToUpperInvariant()), effectivePath);
            bool noBody = false;

            if (RequiresBody)
            {
                string filePath    = null;
                string bodyContent = null;
                bool   deleteFile  = false;
                noBody = commandInput.Options[NoBodyOption].Count > 0;

                if (!thisRequestHeaders.TryGetValue("content-type", out string contentType) && programState.Headers.TryGetValue("content-type", out IEnumerable <string> contentTypes))
                {
                    contentType = contentTypes.FirstOrDefault();
                }

                if (!noBody)
                {
                    if (string.IsNullOrEmpty(contentType))
                    {
                        contentType = "application/json";
                    }

                    if (commandInput.Options[BodyFileOption].Count > 0)
                    {
                        filePath = commandInput.Options[BodyFileOption][0].Text;

                        if (!_fileSystem.FileExists(filePath))
                        {
                            shellState.ConsoleManager.Error.WriteLine($"Content file {filePath} does not exist".SetColor(programState.ErrorColor));
                            return;
                        }
                    }
                    else if (commandInput.Options[BodyContentOption].Count > 0)
                    {
                        bodyContent = commandInput.Options[BodyContentOption][0].Text;
                    }
                    else
                    {
                        string defaultEditorCommand = _preferences.GetValue(WellKnownPreference.DefaultEditorCommand, null);
                        if (defaultEditorCommand == null)
                        {
                            shellState.ConsoleManager.Error.WriteLine($"The default editor must be configured using the command `pref set {WellKnownPreference.DefaultEditorCommand} \"{{commandline}}\"`".SetColor(programState.ErrorColor));
                            return;
                        }

                        deleteFile = true;
                        filePath   = _fileSystem.GetTempFileName();

                        string exampleBody = GetExampleBody(commandInput.Arguments.Count > 0 ? commandInput.Arguments[0].Text : string.Empty, ref contentType, Verb, programState);

                        if (!string.IsNullOrEmpty(exampleBody))
                        {
                            _fileSystem.WriteAllTextToFile(filePath, exampleBody);
                        }

                        string defaultEditorArguments = _preferences.GetValue(WellKnownPreference.DefaultEditorArguments, null) ?? "";
                        string original   = defaultEditorArguments;
                        string pathString = $"\"{filePath}\"";

                        defaultEditorArguments = defaultEditorArguments.Replace("{filename}", pathString);

                        if (string.Equals(defaultEditorArguments, original, StringComparison.Ordinal))
                        {
                            defaultEditorArguments = (defaultEditorArguments + " " + pathString).Trim();
                        }

                        ProcessStartInfo info = new ProcessStartInfo(defaultEditorCommand, defaultEditorArguments);

                        Process.Start(info)?.WaitForExit();
                    }
                }

                if (string.IsNullOrEmpty(contentType))
                {
                    contentType = "application/json";
                }

                byte[] data = noBody
                    ? new byte[0]
                    : string.IsNullOrEmpty(bodyContent)
                        ? _fileSystem.ReadAllBytesFromFile(filePath)
                        : Encoding.UTF8.GetBytes(bodyContent);

                HttpContent content = new ByteArrayContent(data);
                content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
                request.Content             = content;

                if (deleteFile)
                {
                    _fileSystem.DeleteFile(filePath);
                }

                foreach (KeyValuePair <string, IEnumerable <string> > header in programState.Headers)
                {
                    content.Headers.TryAddWithoutValidation(header.Key, header.Value);
                }

                foreach (KeyValuePair <string, string> header in thisRequestHeaders)
                {
                    content.Headers.TryAddWithoutValidation(header.Key, header.Value);
                }
            }

            foreach (KeyValuePair <string, IEnumerable <string> > header in programState.Headers)
            {
                request.Headers.TryAddWithoutValidation(header.Key, header.Value);
            }

            foreach (KeyValuePair <string, string> header in thisRequestHeaders)
            {
                request.Headers.TryAddWithoutValidation(header.Key, header.Value);
            }

            string headersTarget = commandInput.Options[ResponseHeadersFileOption].FirstOrDefault()?.Text ?? commandInput.Options[ResponseFileOption].FirstOrDefault()?.Text;
            string bodyTarget    = commandInput.Options[ResponseBodyFileOption].FirstOrDefault()?.Text ?? commandInput.Options[ResponseFileOption].FirstOrDefault()?.Text;

            HttpResponseMessage response = await programState.Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);

            await HandleResponseAsync(programState, commandInput, shellState.ConsoleManager, response, programState.EchoRequest, headersTarget, bodyTarget, cancellationToken).ConfigureAwait(false);
        }