Index: binary-improvements2/WebServer/src/Commands/CreateWebUser.cs
===================================================================
--- binary-improvements2/WebServer/src/Commands/CreateWebUser.cs	(revision 419)
+++ 	(revision )
@@ -1,72 +1,0 @@
-using System.Collections.Generic;
-using System.Text.RegularExpressions;
-using JetBrains.Annotations;
-using Platform.EOS;
-using Platform.Steam;
-using Webserver.Permissions;
-
-namespace Webserver.Commands {
-	[UsedImplicitly]
-	public class CreateWebUser : ConsoleCmdAbstract {
-		private static readonly Regex validNameTokenMatcher = new Regex (@"^\w+$");
-
-		protected override string[] getCommands () {
-			return new[] {"createwebusermanual"};
-		}
-
-		protected override string getDescription () {
-			return "Create a web dashboard user account - manual for testing";
-		}
-
-		protected override string getHelp () {
-			return ""; // TODO
-		}
-
-		public override bool IsExecuteOnClient => true;
-
-		public override void Execute (List<string> _params, CommandSenderInfo _senderInfo) {
-			// if (GameManager.IsDedicatedServer) {
-			// 	SdtdConsole.Instance.Output ("Command can only be executed on game clients or listen servers.");
-			// 	return;
-			// }
-			
-			// TODO
-			
-			if (_params.Count < 2) {
-				SdtdConsole.Instance.Output ($"Wrong number of arguments");
-				return;
-			}
-
-			string name = _params [0];
-			string pass = _params [1];
-			
-			if (string.IsNullOrEmpty (name)) {
-				SdtdConsole.Instance.Output ("Argument 'name' is empty.");
-				return;
-			}
-
-			if (!validNameTokenMatcher.IsMatch (name)) {
-				SdtdConsole.Instance.Output (
-					"Argument 'name' may only contain characters (A-Z, a-z), digits (0-9) and underscores (_).");
-				return;
-			}
-
-			if (string.IsNullOrEmpty (pass)) {
-				SdtdConsole.Instance.Output ("Argument 'password' is empty.");
-				return;
-			}
-
-			if (!validNameTokenMatcher.IsMatch (pass)) {
-				SdtdConsole.Instance.Output (
-					"Argument 'password' may only contain characters (A-Z, a-z), digits (0-9) and underscores (_).");
-				return;
-			}
-
-			AdminWebUsers.Instance.AddUser (name, pass, new UserIdentifierSteam (76561198066968172ul),
-				new UserIdentifierEos ("0002bc29a5624774b4b0dc27e60b974f"));
-
-			SdtdConsole.Instance.Output ($"User added");
-		}
-
-	}
-}
Index: binary-improvements2/WebServer/src/UrlHandlers/SessionHandler.cs
===================================================================
--- binary-improvements2/WebServer/src/UrlHandlers/SessionHandler.cs	(revision 419)
+++ binary-improvements2/WebServer/src/UrlHandlers/SessionHandler.cs	(revision 422)
@@ -61,5 +61,5 @@
 		private void HandleUserPassLogin (RequestContext _context, string _remoteEndpointString) {
 			if (!_context.Request.HasEntityBody) {
-				_context.Response.Redirect (pageErrorPath + "NoLoginData");
+				WebUtils.WriteText (_context.Response, "NoLoginData", HttpStatusCode.BadRequest);
 				return;
 			}
@@ -76,15 +76,15 @@
 				Log.Error ("Error deserializing JSON from user/password login:");
 				Log.Exception (e);
-				_context.Response.Redirect (pageErrorPath + "InvalidLoginJson");
+				WebUtils.WriteText (_context.Response, "InvalidLoginJson", HttpStatusCode.BadRequest);
 				return;
 			}
 
 			if (!inputJson.TryGetValue ("username", out object fieldNode) || fieldNode is not string username) {
-				_context.Response.Redirect (pageErrorPath + "InvalidLoginJson");
+				WebUtils.WriteText (_context.Response, "InvalidLoginJson", HttpStatusCode.BadRequest);
 				return;
 			}
 
 			if (!inputJson.TryGetValue ("password", out fieldNode) || fieldNode is not string password) {
-				_context.Response.Redirect (pageErrorPath + "InvalidLoginJson");
+				WebUtils.WriteText (_context.Response, "InvalidLoginJson", HttpStatusCode.BadRequest);
 				return;
 			}
@@ -94,5 +94,5 @@
 			if (!webUser.HasValue) {
 				Log.Out ($"[Web] User/pass login failed from {_remoteEndpointString}");
-				_context.Response.Redirect (pageErrorPath + "UserPassInvalid");
+				WebUtils.WriteText (_context.Response, "UserPassInvalid", HttpStatusCode.Unauthorized);
 				return;
 			}
@@ -144,5 +144,5 @@
 
 		public static void HandleUserIdLogin (ConnectionHandler _connectionHandler, RequestContext _context, string _remoteEndpointString,
-			string _loginName, string _errorPage, string _username, PlatformUserIdentifierAbs _userId, PlatformUserIdentifierAbs _crossUserId = null, bool _redirect = true) {
+			string _loginName, string _errorPage, string _username, PlatformUserIdentifierAbs _userId, PlatformUserIdentifierAbs _crossUserId = null, bool _sendResponse = true) {
 			try {
 				WebConnection con = _connectionHandler.LogIn (_context.Request.RemoteEndPoint!.Address, _username, _userId, _crossUserId);
@@ -165,12 +165,12 @@
 				_context.Response.AppendCookie (cookie);
 
-				if (_redirect) {
-					_context.Response.Redirect (pageBasePath);
+				if (_sendResponse) {
+					WebUtils.WriteText (_context.Response, "");
 				}
 			} catch (Exception e) {
 				Log.Error ($"[Web] Error during {_loginName} login:");
 				Log.Exception (e);
-				if (_redirect) {
-					_context.Response.Redirect (pageErrorPath + _errorPage);
+				if (_sendResponse) {
+					WebUtils.WriteText (_context.Response, "LoginError", HttpStatusCode.InternalServerError);
 				}
 			}
Index: binary-improvements2/WebServer/src/WebUtils.cs
===================================================================
--- binary-improvements2/WebServer/src/WebUtils.cs	(revision 419)
+++ binary-improvements2/WebServer/src/WebUtils.cs	(revision 422)
@@ -24,7 +24,11 @@
 			_resp.ContentEncoding = Encoding.UTF8;
 
-			byte[] buf = Encoding.UTF8.GetBytes (_text);
-			_resp.ContentLength64 = buf.Length;
-			_resp.OutputStream.Write (buf, 0, buf.Length);
+			if (string.IsNullOrEmpty (_text)) {
+				_resp.ContentLength64 = 0;
+			} else {
+				byte[] buf = Encoding.UTF8.GetBytes (_text);
+				_resp.ContentLength64 = buf.Length;
+				_resp.OutputStream.Write (buf, 0, buf.Length);
+			}
 		}
 
