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); } }
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); } } } } }
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; } } } } }
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()); } }
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()); } } }
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"); } } } } }
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); }