Index: binary-improvements2/MapRendering/Web/Handlers/ApiHandler.cs
===================================================================
--- binary-improvements2/MapRendering/Web/Handlers/ApiHandler.cs	(revision 384)
+++ binary-improvements2/MapRendering/Web/Handlers/ApiHandler.cs	(revision 387)
@@ -4,10 +4,8 @@
 using System.Reflection;
 using AllocsFixes.NetConnections.Servers.Web.API;
-using HttpListenerRequest = SpaceWizards.HttpListener.HttpListenerRequest;
-using HttpListenerResponse = SpaceWizards.HttpListener.HttpListenerResponse;
 
 namespace AllocsFixes.NetConnections.Servers.Web.Handlers {
 	public class ApiHandler : AbsHandler {
-		private readonly Dictionary<string, WebAPI> apis = new CaseInsensitiveStringDictionary<WebAPI> ();
+		private readonly Dictionary<string, AbsWebAPI> apis = new CaseInsensitiveStringDictionary<AbsWebAPI> ();
 
 		public ApiHandler () : base (null) {
@@ -25,8 +23,8 @@
 			
 			foreach (Type t in Assembly.GetExecutingAssembly ().GetTypes ()) {
-				if (!t.IsAbstract && t.IsSubclassOf (typeof (WebAPI))) {
+				if (!t.IsAbstract && t.IsSubclassOf (typeof (AbsWebAPI))) {
 					ConstructorInfo ctor = t.GetConstructor (apiWithParentCtorTypes);
 					if (ctor != null) {
-						WebAPI apiInstance = (WebAPI) ctor.Invoke (apiWithParentCtorArgs);
+						AbsWebAPI apiInstance = (AbsWebAPI) ctor.Invoke (apiWithParentCtorArgs);
 						addApi (apiInstance);
 						continue;
@@ -35,5 +33,5 @@
 					ctor = t.GetConstructor (apiEmptyCtorTypes);
 					if (ctor != null) {
-						WebAPI apiInstance = (WebAPI) ctor.Invoke (apiEmptyCtorArgs);
+						AbsWebAPI apiInstance = (AbsWebAPI) ctor.Invoke (apiEmptyCtorArgs);
 						addApi (apiInstance);
 					}
@@ -46,5 +44,5 @@
 		}
 
-		private void addApi (WebAPI _api) {
+		private void addApi (AbsWebAPI _api) {
 			apis.Add (_api.Name, _api);
 			WebPermissions.Instance.AddKnownModule ("webapi." + _api.Name, _api.DefaultPermissionLevel ());
@@ -55,17 +53,26 @@
 #endif
 
-		public override void HandleRequest (string _requestPath, HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _con,
-			int _permissionLevel) {
-			string apiName = _requestPath.Remove (0, urlBasePath.Length);
+		public override void HandleRequest (RequestContext _context) {
 
-			if (!apis.TryGetValue (apiName, out WebAPI api)) {
+			string apiName;
+			string subPath = null;
+
+			int pathSeparatorIndex = _context.RequestPath.IndexOf ('/', urlBasePath.Length);
+			if (pathSeparatorIndex >= 0) {
+				apiName = _context.RequestPath.Substring (urlBasePath.Length, pathSeparatorIndex - urlBasePath.Length);
+				subPath = _context.RequestPath.Substring (pathSeparatorIndex + 1);
+			} else {
+				apiName = _context.RequestPath.Substring (urlBasePath.Length);
+			}
+			
+			if (!apis.TryGetValue (apiName, out AbsWebAPI api)) {
 				Log.Out ($"Error in {nameof(ApiHandler)}.HandleRequest(): No handler found for API \"{apiName}\"");
-				_resp.StatusCode = (int) HttpStatusCode.NotFound;
+				_context.Response.StatusCode = (int) HttpStatusCode.NotFound;
 				return;
 			}
 
-			if (!AuthorizeForApi (apiName, _permissionLevel)) {
-				_resp.StatusCode = (int) HttpStatusCode.Forbidden;
-				if (_con != null) {
+			if (!AuthorizeForApi (apiName, _context.PermissionLevel)) {
+				_context.Response.StatusCode = (int) HttpStatusCode.Forbidden;
+				if (_context.Connection != null) {
 					//Log.Out ($"{nameof(ApiHandler)}: user '{user.SteamID}' not allowed to execute '{apiName}'");
 				}
@@ -74,9 +81,11 @@
 			}
 
+			_context.RequestPath = subPath;
+
 			try {
 #if ENABLE_PROFILER
 				apiHandlerSampler.Begin ();
 #endif
-				api.HandleRequest (_req, _resp, _con, _permissionLevel);
+				api.HandleRequest (_context);
 #if ENABLE_PROFILER
 				apiHandlerSampler.End ();
@@ -85,5 +94,5 @@
 				Log.Error ($"Error in {nameof(ApiHandler)}.HandleRequest(): Handler {api.Name} threw an exception:");
 				Log.Exception (e);
-				_resp.StatusCode = (int) HttpStatusCode.InternalServerError;
+				_context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
 			}
 		}
