Пример #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 async Task ExecuteAsync(IShellState shellState, HttpState state, ICoreParseResult parseResult, CancellationToken cancellationToken)
        {
            if (parseResult.Sections.Count == 2)
            {
                state.BaseAddress = null;
            }
            else if (parseResult.Sections.Count != 3 || string.IsNullOrEmpty(parseResult.Sections[2]) || !Uri.TryCreate(EnsureTrailingSlash(parseResult.Sections[2]), UriKind.Absolute, out Uri serverUri))
            {
                shellState.ConsoleManager.Error.WriteLine("Must specify a server".SetColor(state.ErrorColor));
            }
            else
            {
                state.BaseAddress = serverUri;
                try
                {
                    await state.Client.SendAsync(new HttpRequestMessage(HttpMethod.Head, serverUri)).ConfigureAwait(false);
                }
                catch (Exception ex) when(ex.InnerException is SocketException se)
                {
                    shellState.ConsoleManager.Error.WriteLine($"Warning: HEAD request to the specified address was unsuccessful ({se.Message})".SetColor(state.WarningColor));
                }
                catch { }
            }

            if (state.BaseAddress == null || !Uri.TryCreate(state.BaseAddress, "swagger.json", out Uri result))
            {
                state.SwaggerStructure = null;
            }
            else
            {
                await SetSwaggerCommand.CreateDirectoryStructureForSwaggerEndpointAsync(shellState, state, result, cancellationToken).ConfigureAwait(false);

                if (state.SwaggerStructure != null)
                {
                    shellState.ConsoleManager.WriteLine("Using swagger metadata from " + result);
                }
                else
                {
                    if (state.BaseAddress == null || !Uri.TryCreate(state.BaseAddress, "swagger/v1/swagger.json", out result))
                    {
                        state.SwaggerStructure = null;
                    }
                    else
                    {
                        await SetSwaggerCommand.CreateDirectoryStructureForSwaggerEndpointAsync(shellState, state, result, cancellationToken).ConfigureAwait(false);

                        if (state.SwaggerStructure != null)
                        {
                            shellState.ConsoleManager.WriteLine("Using swagger metadata from " + result);
                        }
                    }
                }
            }
        }
Пример #3
0
        public async Task ExecuteAsync(IShellState shellState, HttpState state, ICoreParseResult parseResult, CancellationToken cancellationToken)
        {
            if (parseResult.Sections.Count == 2)
            {
                state.BaseAddress = null;
            }
            else if (parseResult.Sections.Count != 3 || string.IsNullOrEmpty(parseResult.Sections[2]) || !Uri.TryCreate(parseResult.Sections[2].EnsureTrailingSlash(), UriKind.Absolute, out Uri serverUri))
            {
                shellState.ConsoleManager.Error.WriteLine(Strings.SetBaseCommand_MustSpecifyServerError.SetColor(state.ErrorColor));
            }
            else
            {
                state.BaseAddress = serverUri;
                try
                {
                    await state.Client.SendAsync(new HttpRequestMessage(HttpMethod.Head, serverUri)).ConfigureAwait(false);
                }
                catch (Exception ex) when(ex.InnerException is SocketException se)
                {
                    shellState.ConsoleManager.Error.WriteLine(String.Format(Strings.SetBaseCommand_HEADRequestUnSuccessful, se.Message).SetColor(state.WarningColor));
                }
                catch { }
            }

            if (state.BaseAddress == null)
            {
                state.ApiDefinition = null;
            }
            else
            {
                foreach (string swaggerSearchPath in SwaggerSearchPaths)
                {
                    if (Uri.TryCreate(state.BaseAddress, swaggerSearchPath, out Uri result))
                    {
                        await SetSwaggerCommand.CreateApiDefinitionForSwaggerEndpointAsync(shellState, state, result, cancellationToken).ConfigureAwait(false);

                        if (state.ApiDefinition != null)
                        {
                            shellState.ConsoleManager.WriteLine(Strings.SetBaseCommand_SwaggerMetadataUriLocation + result);
                            break;
                        }
                    }
                }
            }
        }
Пример #4
0
        protected override async Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput <ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)
        {
            if (programState.SwaggerEndpoint != null)
            {
                string swaggerRequeryBehaviorSetting = programState.GetStringPreference(WellKnownPreference.SwaggerRequeryBehavior, "auto");

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

            if (programState.Structure == null || programState.BaseAddress == null)
            {
                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());
            }
        }
Пример #5
0
        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());
                }
            }
        }
Пример #6
0
        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;

                    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;
                                shellState.ConsoleManager.WriteLine(help);
                            }
                        }
                    }

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

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

                            IDirectoryStructure structure = programState.Structure.TraverseTo(parseResult.Sections[1]);
                            if (structure.DirectoryNames.Any())
                            {
                                shellState.ConsoleManager.WriteLine("Child directories:");

                                foreach (string name in structure.DirectoryNames)
                                {
                                    shellState.ConsoleManager.WriteLine("  " + name + "/");
                                }

                                anyHelp = true;
                            }

                            if (structure.RequestInfo != null)
                            {
                                if (structure.RequestInfo.Methods.Count > 0)
                                {
                                    if (anyHelp)
                                    {
                                        shellState.ConsoleManager.WriteLine();
                                    }

                                    anyHelp = true;
                                    shellState.ConsoleManager.WriteLine("Available methods:");

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

                        if (!anyHelp)
                        {
                            shellState.ConsoleManager.WriteLine("Unable to locate any help information for the specified command");
                        }
                    }
                }
            }
        }
Пример #7
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("'set base {url}' must be called before issuing requests to a relative path".SetColor(programState.ErrorColor));
                return;
            }

            if (programState.SwaggerEndpoint != null)
            {
                string swaggerRequeryBehaviorSetting = programState.GetStringPreference(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>();

            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 (!noBody)
                {
                    if (commandInput.Options[BodyFileOption].Count > 0)
                    {
                        filePath = commandInput.Options[BodyFileOption][0].Text;

                        if (!File.Exists(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 = programState.GetStringPreference(WellKnownPreference.DefaultEditorCommand);
                        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   = Path.GetTempFileName();

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

                        if (contentType == null)
                        {
                            contentType = "application/json";
                        }

                        string exampleBody = programState.GetExampleBody(commandInput.Arguments.Count > 0 ? commandInput.Arguments[0].Text : string.Empty, contentType, Verb);
                        request.Headers.TryAddWithoutValidation("Content-Type", contentType);

                        if (!string.IsNullOrEmpty(exampleBody))
                        {
                            File.WriteAllText(filePath, exampleBody);
                        }

                        string defaultEditorArguments = programState.GetStringPreference(WellKnownPreference.DefaultEditorArguments) ?? "";
                        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();
                    }
                }

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

                HttpContent content = new ByteArrayContent(data);
                request.Content = content;

                if (deleteFile)
                {
                    File.Delete(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);
        }