public async Task <Run> HandleRequest(HttpContext httpContext) { await _initSemaphoreSlim.WaitAsync(); try { if (Initialized) { await httpContext.Response.WriteError("Cannot initialize the action more than once."); Console.Error.WriteLine("Cannot initialize the action more than once."); return(new Run(Type, Method, Constructor, AwaitableMethod)); } string body = await new StreamReader(httpContext.Request.Body).ReadToEndAsync(); JObject inputObject = JObject.Parse(body); if (!inputObject.ContainsKey("value")) { await httpContext.Response.WriteError("Missing main/no code to execute."); return(null); } JToken message = inputObject["value"]; if (message["main"] == null || message["binary"] == null || message["code"] == null) { await httpContext.Response.WriteError("Missing main/no code to execute."); return(null); } string main = message["main"].ToString(); bool binary = message["binary"].ToObject <bool>(); if (!binary) { await httpContext.Response.WriteError("code must be binary (zip file)."); return(null); } string[] mainParts = main.Split("::"); if (mainParts.Length != 3) { await httpContext.Response.WriteError("main required format is \"Assembly::Type::Function\"."); return(null); } string base64Zip = message["code"].ToString(); string tempPath = Path.Combine(Environment.CurrentDirectory, Guid.NewGuid().ToString()); string tempFile = Path.GetTempFileName(); await File.WriteAllBytesAsync(tempFile, Convert.FromBase64String(base64Zip)); try { System.IO.Compression.ZipFile.ExtractToDirectory(tempFile, tempPath); } catch (Exception) { await httpContext.Response.WriteError("Unable to decompress package."); return(null); } finally { File.Delete(tempFile); } Environment.CurrentDirectory = tempPath; string assemblyFile = $"{mainParts[0]}.dll"; string assemblyPath = Path.Combine(tempPath, assemblyFile); if (!File.Exists(assemblyPath)) { await httpContext.Response.WriteError($"Unable to locate requested assembly (\"{assemblyFile}\")."); return(null); } try { Assembly assembly = Assembly.LoadFrom(assemblyPath); Type = assembly.GetType(mainParts[1]); if (Type == null) { await httpContext.Response.WriteError($"Unable to locate requested type (\"{mainParts[1]}\")."); return(null); } Method = Type.GetMethod(mainParts[2]); Constructor = Type.GetConstructor(Type.EmptyTypes); } catch (Exception ex) { Console.Error.WriteLine(ex.ToString()); await httpContext.Response.WriteError(ex.Message #if DEBUG + ", " + ex.StackTrace #endif ); return(null); } if (Method == null) { await httpContext.Response.WriteError($"Unable to locate requested method (\"{mainParts[2]}\")."); return(null); } if (Constructor == null) { await httpContext.Response.WriteError($"Unable to locate appropriate constructor for (\"{mainParts[1]}\")."); return(null); } Initialized = true; AwaitableMethod = (Method.ReturnType.GetMethod(nameof(Task.GetAwaiter)) != null); return(new Run(Type, Method, Constructor, AwaitableMethod)); } catch (Exception ex) { Console.Error.WriteLine(ex.StackTrace); await httpContext.Response.WriteError(ex.Message #if DEBUG + ", " + ex.StackTrace #endif ); Startup.WriteLogMarkers(); return(null); } finally { _initSemaphoreSlim.Release(); } }