summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsr55 <[email protected]>2021-03-24 22:21:49 +0000
committersr55 <[email protected]>2021-03-24 22:22:02 +0000
commit2b18fe2d65b2146b96a9da0e599b1fb372087497 (patch)
tree762e74f65528d079f8b678e3073f30302bb9dc30
parent126013c87d2069b36dce86a5a11996f92a6593a8 (diff)
WinGui: Refactor the Worker HttpServer class and fix some issues caused by the Caliburn Micro upgrade.
-rw-r--r--win/CS/HandBrake.Worker/HttpServer.cs141
-rw-r--r--win/CS/HandBrake.Worker/Logging/ConsoleOutput.cs40
-rw-r--r--win/CS/HandBrake.Worker/Program.cs13
-rw-r--r--win/CS/HandBrakeWPF/App.xaml.cs36
-rw-r--r--win/CS/HandBrakeWPF/Instance/RemoteInstance.cs15
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/LogViewModel.cs6
-rw-r--r--win/CS/HandBrakeWPF/Views/LogView.xaml.cs2
7 files changed, 159 insertions, 94 deletions
diff --git a/win/CS/HandBrake.Worker/HttpServer.cs b/win/CS/HandBrake.Worker/HttpServer.cs
index b7da9c7aa..d4efcbba2 100644
--- a/win/CS/HandBrake.Worker/HttpServer.cs
+++ b/win/CS/HandBrake.Worker/HttpServer.cs
@@ -16,7 +16,9 @@ namespace HandBrake.Worker
using System.Net;
using System.Text;
using System.Threading;
+ using System.Threading.Tasks;
+ using HandBrake.Worker.Logging;
using HandBrake.Worker.Services.Interfaces;
public class HttpServer
@@ -42,10 +44,9 @@ namespace HandBrake.Worker
if (!tokenService.IsTokenSet())
{
- Console.WriteLine("Worker: No Token Set.");
-
- Console.WriteLine();
- Console.WriteLine("API Information: ");
+ ConsoleOutput.WriteLine("Worker: Token has not been initialised. API Access is limited!", ConsoleColor.Red);
+ Console.WriteLine(Environment.NewLine);
+ ConsoleOutput.WriteLine("API Information: ", ConsoleColor.Cyan);
Console.WriteLine("All calls require a 'token' in the HTTP header ");
}
@@ -56,7 +57,7 @@ namespace HandBrake.Worker
if (!tokenService.IsTokenSet())
{
- Console.WriteLine(url);
+ Console.WriteLine(" - " + url);
}
}
@@ -78,81 +79,33 @@ namespace HandBrake.Worker
}
}
- public bool Run()
+ public async Task<bool> Run()
{
if (this.failedStart)
{
return false;
}
- ThreadPool.QueueUserWorkItem(o =>
+
+ while (this.httpListener.IsListening)
{
try
{
- while (this.httpListener.IsListening)
+ var context = await this.httpListener.GetContextAsync();
+ lock (this.httpListener)
{
- ThreadPool.QueueUserWorkItem(
- (c) =>
- {
- var context = c as HttpListenerContext;
- if (context == null)
- {
- return;
- }
-
- try
- {
- string path = context.Request.RawUrl.TrimStart('/').TrimEnd('/');
- string token = context.Request.Headers.Get("token");
-
- if (!path.Equals("Version") && !tokenService.IsAuthenticated(token))
- {
- string rstr = "Worker: Access Denied. The token provided in the HTTP header was not valid.";
- Console.WriteLine(rstr);
- byte[] buf = Encoding.UTF8.GetBytes(rstr);
- context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
- context.Response.ContentLength64 = buf.Length;
- context.Response.OutputStream.Write(buf, 0, buf.Length);
- return;
- }
-
- Debug.WriteLine("Handling call to: " + path);
-
- if (this.apiHandlers.TryGetValue(path, out var actionToPerform))
- {
- string rstr = actionToPerform(context.Request);
- if (!string.IsNullOrEmpty(rstr))
- {
- byte[] buf = Encoding.UTF8.GetBytes(rstr);
- context.Response.ContentLength64 = buf.Length;
- context.Response.OutputStream.Write(buf, 0, buf.Length);
- }
- }
- else
- {
- string rstr = "Error, There is a missing API handler.";
- byte[] buf = Encoding.UTF8.GetBytes(rstr);
- context.Response.ContentLength64 = buf.Length;
- context.Response.OutputStream.Write(buf, 0, buf.Length);
- }
- }
- catch (Exception exc)
- {
- Console.WriteLine("Worker: Listener Thread: " + exc);
- }
- finally
- {
- context?.Response.OutputStream.Close();
- }
- },
- this.httpListener.GetContext());
+ this.HandleRequest(context);
}
}
- catch (Exception exc)
+ catch (Exception e)
{
- Console.WriteLine("Worker: " + exc);
+ if (e is HttpListenerException)
+ {
+ Debug.WriteLine("Worker: " + e);
+ return false;
+ }
}
- });
+ }
return true;
}
@@ -162,5 +115,61 @@ namespace HandBrake.Worker
this.httpListener.Stop();
this.httpListener.Close();
}
+
+ private void HandleRequest(HttpListenerContext context)
+ {
+ try
+ {
+ if (context == null)
+ {
+ return;
+ }
+
+ Stopwatch watch = Stopwatch.StartNew();
+
+ string path = context.Request.RawUrl.TrimStart('/').TrimEnd('/');
+ string token = context.Request.Headers.Get("token");
+
+ if (!path.Equals("Version") && !tokenService.IsAuthenticated(token))
+ {
+ string rstr = string.Format("Worker: Access Denied to '/{0}'. The token provided in the HTTP header was not valid.", path);
+ ConsoleOutput.WriteLine(rstr, ConsoleColor.Red, true);
+ byte[] buf = Encoding.UTF8.GetBytes(rstr);
+ context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
+ context.Response.ContentLength64 = buf.Length;
+ context.Response.OutputStream.Write(buf, 0, buf.Length);
+ return;
+ }
+
+ if (this.apiHandlers.TryGetValue(path, out var actionToPerform))
+ {
+ string rstr = actionToPerform(context.Request);
+ if (!string.IsNullOrEmpty(rstr))
+ {
+ byte[] buf = Encoding.UTF8.GetBytes(rstr);
+ context.Response.ContentLength64 = buf.Length;
+ context.Response.OutputStream.Write(buf, 0, buf.Length);
+ }
+ }
+ else
+ {
+ string rstr = "Error, There is a missing API handler.";
+ byte[] buf = Encoding.UTF8.GetBytes(rstr);
+ context.Response.ContentLength64 = buf.Length;
+ context.Response.OutputStream.Write(buf, 0, buf.Length);
+ }
+
+ watch.Stop();
+ Debug.WriteLine(string.Format(" - Processed call to: '/{0}', Took {1}ms", path, watch.ElapsedMilliseconds), ConsoleColor.White, true);
+ }
+ catch (Exception exc)
+ {
+ Debug.WriteLine("Worker: Listener Thread: " + exc);
+ }
+ finally
+ {
+ context?.Response.OutputStream.Close();
+ }
+ }
}
} \ No newline at end of file
diff --git a/win/CS/HandBrake.Worker/Logging/ConsoleOutput.cs b/win/CS/HandBrake.Worker/Logging/ConsoleOutput.cs
new file mode 100644
index 000000000..8931d9712
--- /dev/null
+++ b/win/CS/HandBrake.Worker/Logging/ConsoleOutput.cs
@@ -0,0 +1,40 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="ConsoleOutput.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Defines the ConsoleOutput type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrake.Worker.Logging
+{
+ using System;
+
+ public class ConsoleOutput
+ {
+ public static void WriteLine(string text, ConsoleColor colour = ConsoleColor.White, bool enableTimecode = false)
+ {
+ Console.ForegroundColor = colour;
+ if (enableTimecode)
+ {
+ string time = DateTime.Now.ToString("HH:mm:ss", System.Globalization.DateTimeFormatInfo.InvariantInfo);
+ Console.WriteLine("[{0}] {1}", time, text);
+ }
+ else
+ {
+ Console.WriteLine(text);
+ }
+
+ Console.ResetColor();
+ }
+
+ public static void ClearLine()
+ {
+ int currentLineCursor = Console.CursorTop;
+ Console.SetCursorPosition(0, Console.CursorTop);
+ Console.Write(new string(' ', Console.WindowWidth));
+ Console.SetCursorPosition(0, currentLineCursor);
+ }
+ }
+}
diff --git a/win/CS/HandBrake.Worker/Program.cs b/win/CS/HandBrake.Worker/Program.cs
index 937546232..3eba94182 100644
--- a/win/CS/HandBrake.Worker/Program.cs
+++ b/win/CS/HandBrake.Worker/Program.cs
@@ -15,6 +15,7 @@ namespace HandBrake.Worker
using System.Threading;
using HandBrake.Interop.Interop;
+ using HandBrake.Worker.Logging;
using HandBrake.Worker.Routing;
using HandBrake.Worker.Services;
using HandBrake.Worker.Services.Interfaces;
@@ -64,15 +65,23 @@ namespace HandBrake.Worker
}
}
}
+
+ if (!TokenService.IsTokenSet())
+ {
+ ConsoleOutput.WriteLine("# HandBrake Worker", ConsoleColor.DarkYellow);
+ ConsoleOutput.WriteLine("*** Please note, this application should not be run standalone. To run the GUI, please use 'HandBrake.exe' *** ", ConsoleColor.Red);
+ Console.WriteLine();
+ }
Console.WriteLine("Worker: Starting HandBrake Engine ...");
router = new ApiRouter();
router.TerminationEvent += Router_TerminationEvent;
Console.WriteLine("Worker: Starting Web Server on port {0} ...", port);
+
Dictionary<string, Func<HttpListenerRequest, string>> apiHandlers = RegisterApiHandlers();
HttpServer webServer = new HttpServer(apiHandlers, port, TokenService);
- if (webServer.Run())
+ if (webServer.Run().Result)
{
Console.WriteLine("Worker: Server Started");
manualResetEvent.WaitOne();
@@ -80,7 +89,7 @@ namespace HandBrake.Worker
}
else
{
- Console.WriteLine("Worker: Failed to start. Exiting ...");
+ Console.WriteLine("Worker is exiting ...");
}
}
diff --git a/win/CS/HandBrakeWPF/App.xaml.cs b/win/CS/HandBrakeWPF/App.xaml.cs
index e9dad8a0e..bf9f33933 100644
--- a/win/CS/HandBrakeWPF/App.xaml.cs
+++ b/win/CS/HandBrakeWPF/App.xaml.cs
@@ -211,23 +211,22 @@ namespace HandBrakeWPF
/// </param>
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
- Task t = new Task(
- () =>
+ Execute.BeginOnUIThread(
+ () =>
+ {
+ if (e.ExceptionObject.GetType() == typeof(FileNotFoundException))
{
- if (e.ExceptionObject.GetType() == typeof(FileNotFoundException))
- {
- GeneralApplicationException exception = new GeneralApplicationException(
- "A file appears to be missing.",
- "Try re-installing Microsoft .NET Framework 4.8",
- (Exception)e.ExceptionObject);
- this.ShowError(exception);
- }
- else
- {
- this.ShowError(e.ExceptionObject);
- }
- });
- Execute.OnUIThreadAsync(() => t);
+ GeneralApplicationException exception = new GeneralApplicationException(
+ "A file appears to be missing.",
+ "Try re-installing Microsoft .NET 5 Desktop Runtime",
+ (Exception)e.ExceptionObject);
+ this.ShowError(exception);
+ }
+ else
+ {
+ this.ShowError(e.ExceptionObject);
+ }
+ });
}
/// <summary>
@@ -244,7 +243,7 @@ namespace HandBrakeWPF
{
if (e.Exception.GetType() == typeof(FileNotFoundException))
{
- GeneralApplicationException exception = new GeneralApplicationException("A file appears to be missing.", "Try re-installing Microsoft .NET Framework 4.7.1", e.Exception);
+ GeneralApplicationException exception = new GeneralApplicationException("A file appears to be missing.", "Try re-installing Microsoft .NET 5 Desktop Runtime", e.Exception);
this.ShowError(exception);
}
else if (e.Exception.GetType() == typeof(GeneralApplicationException))
@@ -317,8 +316,7 @@ namespace HandBrakeWPF
}
catch (Exception)
{
- MessageBox.Show("An Unknown Error has occurred. \n\n Exception:" + exception, "Unhandled Exception",
- MessageBoxButton.OK, MessageBoxImage.Error);
+ MessageBox.Show("An Unknown Error has occurred. \n\n Exception:" + exception, "Unhandled Exception", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
diff --git a/win/CS/HandBrakeWPF/Instance/RemoteInstance.cs b/win/CS/HandBrakeWPF/Instance/RemoteInstance.cs
index e52360ba5..c2c5d290e 100644
--- a/win/CS/HandBrakeWPF/Instance/RemoteInstance.cs
+++ b/win/CS/HandBrakeWPF/Instance/RemoteInstance.cs
@@ -224,7 +224,7 @@ namespace HandBrakeWPF.Instance
private void WorkerProcess_Exited(object sender, EventArgs e)
{
- this.logService.LogMessage("Worker Process Exited!");
+ this.logService.LogMessage("Worker process exited!");
}
private void StopServer()
@@ -252,7 +252,18 @@ namespace HandBrakeWPF.Instance
encodeCompleteFired = true;
this.encodePollTimer?.Stop();
- this.EncodeCompleted?.Invoke(sender: this, e: new EncodeCompletedEventArgs(-11));
+ int exitcode = -11;
+ if (this.workerProcess != null && this.workerProcess.HasExited)
+ {
+ this.logService.LogMessage("Worker process exit was not expected.");
+ exitcode = -12;
+ }
+ else
+ {
+ this.logService.LogMessage("Worker process appears to be unresponsive. Terminating .... ");
+ }
+
+ this.EncodeCompleted?.Invoke(sender: this, e: new EncodeCompletedEventArgs(exitcode));
if (this.workerProcess != null && !this.workerProcess.HasExited)
{
diff --git a/win/CS/HandBrakeWPF/ViewModels/LogViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/LogViewModel.cs
index 62c43adf5..96ea56f05 100644
--- a/win/CS/HandBrakeWPF/ViewModels/LogViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/LogViewModel.cs
@@ -223,15 +223,13 @@ namespace HandBrakeWPF.ViewModels
{
if (this.lastReadIndex < e.Log.MessageIndex)
{
- Execute.OnUIThreadAsync(
- () => new Task(
- () =>
+ Execute.BeginOnUIThread(() =>
{
this.lastReadIndex = e.Log.MessageIndex;
this.log.AppendLine(e.Log.Content);
this.OnLogMessageReceived(e);
this.NotifyOfPropertyChange(() => this.ActivityLog);
- }));
+ });
}
}
diff --git a/win/CS/HandBrakeWPF/Views/LogView.xaml.cs b/win/CS/HandBrakeWPF/Views/LogView.xaml.cs
index 2861c5b62..4c57ebcda 100644
--- a/win/CS/HandBrakeWPF/Views/LogView.xaml.cs
+++ b/win/CS/HandBrakeWPF/Views/LogView.xaml.cs
@@ -93,7 +93,7 @@ namespace HandBrakeWPF.Views
if (this.AutoScroll.IsChecked)
{
- delayProcessor.PerformTask(() => Execute.OnUIThreadAsync(() => new Task(() => this.logText.ScrollToEnd())), 100);
+ delayProcessor.PerformTask(() => Execute.BeginOnUIThread(() => this.logText.ScrollToEnd()), 100);
}
}
}