/// <summary> /// Entry point /// </summary> /// <param name="args">Command-line arguments</param> /// <returns>Asynchronous task</returns> public static async Task Main(string[] args) { // Parse the command line arguments string lastArg = null, socketPath = Defaults.FullSocketPath, ns = "custom-http-endpoint", path = "demo"; foreach (string arg in args) { if (lastArg == "-s" || lastArg == "--socket") { socketPath = arg; } else if (lastArg == "-m" || lastArg == "--method") { if (!Enum.TryParse(arg, true, out _method)) { Console.WriteLine("Error: Invalid HTTP method"); return; } } else if (lastArg == "-n" || lastArg == "--namespace") { ns = arg; } else if (lastArg == "-p" || lastArg == "--path") { path = arg; } else if (lastArg == "-e" || lastArg == "--exec") { _cmd = arg; } else if (lastArg == "-a" || lastArg == "--args") { _args = arg; } else if (arg == "-q" || lastArg == "--quiet") { _quiet = true; } else if (arg == "-h" || arg == "--help") { Console.WriteLine("Create a custom HTTP endpoint in the format /machine/{namespace}/{path}"); Console.WriteLine("Available command line options:"); Console.WriteLine("-s, --socket <socket>: UNIX socket to connect to"); Console.WriteLine("-m, --method [GET, POST, PUT, PATCH, TRACE, DELETE, OPTIONS, WebSocket]: HTTP method to use (defaults to GET)"); Console.WriteLine("-n, --namespace <namespace>: Namespace to use (defaults to custom-http-endpoint)"); Console.WriteLine("-p, --path <path>: HTTP query path (defaults to demo)"); Console.WriteLine("-e, --exec <executable>: Command to execute when an HTTP query is received, stdout and stderr are returned as the response body"); Console.WriteLine("-a, --args <arguments>: Arguments for the executable command. Query values in % chars are replaced with query options (e.g. %myvalue%). Not applicable for WebSockets"); Console.WriteLine("-q, --quiet: Do not display info text"); Console.WriteLine("-h, --help: Displays this text"); return; } lastArg = arg; } if (_method == HttpEndpointType.WebSocket && (!string.IsNullOrWhiteSpace(_cmd) || !string.IsNullOrWhiteSpace(_args))) { Console.WriteLine("Error: Cannot use --exec parameter if method equals WebSocket"); } // Create a new Command connection CommandConnection connection = new CommandConnection(); await connection.Connect(socketPath); // Create a new HTTP GET endpoint and keep listening for new requests try { using HttpEndpointUnixSocket socket = await connection.AddHttpEndpoint(_method, ns, path); socket.OnEndpointRequestReceived += OnHttpRequestReceived; // Display a message if (!_quiet) { Console.WriteLine("{0} endpoint has been created and is now accessible via /machine/{1}/{2}", _method, ns, path); if (_method == HttpEndpointType.WebSocket) { Console.WriteLine("IO from the first WebSocket connection will be redirected to stdio. Additional connections will be automatically closed."); } else if (string.IsNullOrWhiteSpace(_cmd)) { Console.WriteLine("Press RETURN to close this program again"); } } // Wait forever (or for Ctrl+C) in WebSocket mode or for the user to press RETURN in interactive REST mode. // If the connection is terminated while waiting, continue as well if (_method == HttpEndpointType.WebSocket || string.IsNullOrWhiteSpace(_cmd)) { Task primaryTask = (_method == HttpEndpointType.WebSocket) ? Task.Delay(-1) : Task.Run(() => Console.ReadLine()); await Task.WhenAny(primaryTask, PollConnection(connection)); } } catch (SocketException) { // You may want to try to unregister your endpoint here and try again... Console.WriteLine("Failed to create new HTTP socket. Perhaps another instance of this program is already running?"); } finally { if (connection.IsConnected) { // Remove the endpoint again when the plugin is being unloaded await connection.RemoveHttpEndpoint(_method, ns, path); } } }