// The DELETE Http verb means release all resources allocated // and return to an initial state public HttpResponseMessage Delete(HttpRequestMessage request) { Trace.WriteLine(String.Format("{0:T} - received DELETE request", DateTime.Now), typeof(ResourceController).Name); // A resource change can have wide impact, so we don't allow concurrent use lock (ConfigController.ConfigLock) { try { BridgeController.ReleaseAllResources(force: false); HttpResponseMessage response = request.CreateResponse(HttpStatusCode.OK); response.Content = new StringContent("\"Bridge resources have been released.\""); response.Content.Headers.ContentType = new MediaTypeHeaderValue(JsonSerializer.JsonMediaType); return(response); } catch (Exception ex) { var exceptionResponse = ex.Message; Trace.WriteLine(String.Format("{0:T} - DELETE config exception:{1}{2}", DateTime.Now, Environment.NewLine, ex), typeof(ResourceController).Name); return(request.CreateResponse(HttpStatusCode.BadRequest, exceptionResponse)); } } }
// Asks the Bridge to release all its resources but continue running private static void ResetBridge(CommandLineArguments commandLineArgs) { string errorMessage = null; if (!PingBridge(commandLineArgs.BridgeConfiguration.BridgeHost, commandLineArgs.BridgeConfiguration.BridgePort, out errorMessage)) { Console.WriteLine("The Bridge is not running: {0}", errorMessage); Environment.Exit(0); } string bridgeUrl = String.Format("http://{0}:{1}/Resource", commandLineArgs.BridgeConfiguration.BridgeHost, commandLineArgs.BridgeConfiguration.BridgePort); string problem = null; Console.WriteLine("Resetting the Bridge by sending DELETE request to {0}", bridgeUrl); // We reset the Bridge using a DELETE request to the /resource endpoint. using (HttpClient httpClient = new HttpClient()) { try { var response = httpClient.DeleteAsync(bridgeUrl).GetAwaiter().GetResult(); if (!response.IsSuccessStatusCode) { problem = String.Format("{0}Bridge returned unexpected status code='{1}', reason='{2}'", Environment.NewLine, response.StatusCode, response.ReasonPhrase); if (response.Content != null) { string contentAsString = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); if (contentAsString.Length > 1000) { contentAsString = contentAsString.Substring(0, 999) + "..."; } problem = String.Format("{0}, content:{1}{2}", problem, Environment.NewLine, contentAsString); } } } catch (Exception ex) { problem = ex.ToString(); } } if (problem != null) { Console.WriteLine("A problem was encountered resetting the Bridge:{0}{1}", Environment.NewLine, problem); Console.WriteLine("Forcing local resource cleanup..."); } // A successfull DELETE will have cleaned up all firewall rules, // certificates, etc. So when using localhost, this cleanup will // be redundant and harmless. When the Bridge is running remotely, // this cleanup will remove all firewall rules and certificates we // installed on the current machine to talk with that Bridge. BridgeController.ReleaseAllResources(force: false); }
private IdleTimeoutHandler(TimeSpan idleTimeout) { s_timeoutManager.IdleTimeout = idleTimeout; s_timeoutManager.Restart(); s_timeoutManager.OnTimeOut += (s, e) => { Trace.WriteLine(String.Format("{0:T} - Timed out as there were no messages to the bridge for {1} seconds", DateTime.Now, (int)e.TotalSeconds), this.GetType().Name); BridgeController.StopBridgeProcess(0); }; }
// Starts the Bridge locally if it is not already running. private static void StartBridge(CommandLineArguments commandLineArgs) { string errorMessage = null; if (PingBridge(commandLineArgs.BridgeConfiguration.BridgeHost, commandLineArgs.BridgeConfiguration.BridgePort, out errorMessage)) { Console.WriteLine("The Bridge is already running."); Environment.Exit(0); } // The host is not local so we cannot start the Bridge if (!IsBridgeHostLocal(commandLineArgs.BridgeConfiguration)) { Console.WriteLine("The Bridge cannot be started from this machine on {0}", commandLineArgs.BridgeConfiguration.BridgeHost); Environment.Exit(1); } string resourceFolder = commandLineArgs.BridgeConfiguration.BridgeResourceFolder; if (String.IsNullOrWhiteSpace(resourceFolder)) { Console.WriteLine("Starting the Bridge requires the BridgeResourceFolder to be specified."); Console.WriteLine("Use either -BridgeResourceFolder:folderName or set it as an environment variable."); Environment.Exit(1); } resourceFolder = Path.GetFullPath(resourceFolder); if (!Directory.Exists(resourceFolder)) { Console.WriteLine("The specified BridgeResourceFolder '{0}' does not exist."); Environment.Exit(1); } commandLineArgs.BridgeConfiguration.BridgeResourceFolder = resourceFolder; int port = commandLineArgs.BridgeConfiguration.BridgePort; string hostFormatString = "http://{0}:{1}"; string owinAddress = String.Format(hostFormatString, commandLineArgs.AllowRemote ? "+" : "localhost", port); string visibleHost = (commandLineArgs.AllowRemote) ? Environment.MachineName : "localhost"; string visibleAddress = String.Format(hostFormatString, visibleHost, port); // Configure the remote addresses the firewall rules will accept. // If remote access is not allowed, specifically disallow remote addresses PortManager.RemoteAddresses = commandLineArgs.AllowRemote ? commandLineArgs.RemoteAddresses : String.Empty; // Initialize the BridgeConfiguration from command line. ConfigController.BridgeConfiguration = commandLineArgs.BridgeConfiguration; ConfigController.BridgeConfiguration.BridgeHost = visibleHost; // Remove any pre-existing firewall rules or certificates the Bridge // may have added in past runs. We normally clean them up on exit but // it is possible a prior Bridge process was terminated prematurely. BridgeController.ReleaseAllResources(force: false); Console.WriteLine("Starting the Bridge at {0}", visibleAddress); OwinSelfhostStartup.Startup(owinAddress); // Now test whether the Bridge is running. Failure cleans up // all resources and terminates the process. if (!PingBridge(visibleHost, port, out errorMessage)) { Console.WriteLine("The Bridge failed to start or is not responding: {0}", errorMessage); BridgeController.StopBridgeProcess(1); } while (true) { Console.WriteLine(); Console.WriteLine("The Bridge is running"); Console.WriteLine(" Listening at {0}/{1}", visibleAddress, BridgeControllerEndpoint); if (commandLineArgs.AllowRemote) { Console.WriteLine(" Remote access is allowed from '{0}'", commandLineArgs.RemoteAddresses); } else { Console.WriteLine(" Remote access is disabled."); } Console.WriteLine(" Commands:"); Console.WriteLine(" \"cls\" to clear the screen"); Console.WriteLine(" \"exit\" to stop the Bridge"); Console.WriteLine(); Console.Write("Bridge> "); string answer = Console.ReadLine(); if (string.Equals(answer, "exit", StringComparison.OrdinalIgnoreCase)) { break; } else if (string.Equals(answer, "cls", StringComparison.OrdinalIgnoreCase)) { Console.Clear(); } } BridgeController.StopBridgeProcess(0); }
// Starts the Bridge locally if it is not already running. private static void StartBridge(CommandLineArguments commandLineArgs) { string errorMessage = null; if (PingBridge(commandLineArgs.BridgeConfiguration.BridgeHost, commandLineArgs.BridgeConfiguration.BridgePort, out errorMessage)) { Console.WriteLine("The Bridge is already running."); Environment.Exit(0); } // The host is not local so we cannot start the Bridge if (!IsBridgeHostLocal(commandLineArgs.BridgeConfiguration)) { Console.WriteLine("The Bridge cannot be started from this machine on {0}", commandLineArgs.BridgeConfiguration.BridgeHost); Environment.Exit(1); } int port = commandLineArgs.BridgeConfiguration.BridgePort; string hostFormatString = "http://{0}:{1}"; string owinAddress = String.Format(hostFormatString, commandLineArgs.AllowRemote ? "+" : "localhost", port); string visibleHost = (commandLineArgs.AllowRemote) ? Environment.MachineName : "localhost"; string visibleAddress = String.Format(hostFormatString, visibleHost, port); // Configure the remote addresses the firewall rules will accept. // If remote access is not allowed, specifically disallow remote addresses PortManager.RemoteAddresses = commandLineArgs.AllowRemote ? commandLineArgs.RemoteAddresses : String.Empty; // Initialize the BridgeConfiguration from command line. // The first POST to the ConfigController will supply the rest. ConfigController.BridgeConfiguration = commandLineArgs.BridgeConfiguration; ConfigController.BridgeConfiguration.BridgeHost = visibleHost; // Remove any pre-existing firewall rules or certificates the Bridge // may have added in past runs. We normally clean them up on exit but // it is possible a prior Bridge process was terminated prematurely. BridgeController.ReleaseAllResources(); // Open the port used to communicate with the Bridge itself PortManager.OpenPortInFirewall(port); Console.WriteLine("Starting the Bridge at {0}", visibleAddress); OwinSelfhostStartup.Startup(owinAddress); // Now test whether the Bridge is running. Failure cleans up // all resources and terminates the process. if (!PingBridge(visibleHost, port, out errorMessage)) { Console.WriteLine("The Bridge failed to start or is not responding: {0}", errorMessage); BridgeController.StopBridgeProcess(1); } while (true) { Console.WriteLine("The Bridge is running and listening at {0}", visibleAddress); if (commandLineArgs.AllowRemote) { Console.WriteLine("Remote access is allowed from '{0}'", commandLineArgs.RemoteAddresses); } else { Console.WriteLine("Remote access is disabled."); } Console.WriteLine("Type \"exit\" to stop the Bridge."); string answer = Console.ReadLine(); if (String.Equals(answer, "exit", StringComparison.OrdinalIgnoreCase)) { break; } } BridgeController.StopBridgeProcess(0); }
private static int StopBridge(CommandLineArguments commandLineArgs) { string errorMessage = null; Dictionary <string, string> properties; if (!PingBridge(commandLineArgs.BridgeConfiguration.BridgeHost, commandLineArgs.BridgeConfiguration.BridgePort, out errorMessage, out properties)) { Console.WriteLine("The Bridge is not running: {0}", errorMessage); return(Bridge_ExitCode_Success); } string bridgeUrl = String.Format("http://{0}:{1}/{2}", commandLineArgs.BridgeConfiguration.BridgeHost, commandLineArgs.BridgeConfiguration.BridgePort, BridgeControllerEndpoint); string problem = null; // We stop the Bridge using a DELETE request. // If the Bridge is running on localhost, it will be running // in a different process on this machine. using (HttpClient httpClient = new HttpClient()) { Console.WriteLine("Stopping the Bridge by issuing DELETE request to {0}", bridgeUrl); try { var response = httpClient.DeleteAsync(bridgeUrl).GetAwaiter().GetResult(); if (!response.IsSuccessStatusCode) { problem = String.Format("{0}Bridge returned unexpected status code='{1}', reason='{2}'", Environment.NewLine, response.StatusCode, response.ReasonPhrase); if (response.Content != null) { string contentAsString = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); if (contentAsString.Length > 1000) { contentAsString = contentAsString.Substring(0, 999) + "..."; } problem = String.Format("{0}, content:{1}{2}", problem, Environment.NewLine, contentAsString); } } } catch (Exception ex) { problem = ex.ToString(); } } if (problem != null) { Console.WriteLine("A problem was encountered stopping the Bridge:{0}{1}", Environment.NewLine, problem); Console.WriteLine("Forcing local resource cleanup..."); BridgeController.StopBridgeProcess(Bridge_ExitCode_Success); } // A successfull DELETE will have cleaned up all firewall rules, // certificates, etc. So when using localhost, this cleanup will // be redundant and harmless. When the Bridge is running remotely, // this cleanup will remove all firewall rules and certificates we // installed on the current machine to talk with that Bridge. BridgeController.StopBridgeProcess(Bridge_ExitCode_Success); // The process will be torn down before executing this return return(Bridge_ExitCode_Success); }