Пример #1
0
        public async Task HandleRequest(HttpContext httpContext)
        {
            if (_type == null || _method == null || _constructor == null)
            {
                await httpContext.Response.WriteError("Cannot invoke an uninitialized action.");

                return;
            }

            try
            {
                string body = await new StreamReader(httpContext.Request.Body).ReadToEndAsync();

                JObject inputObject = string.IsNullOrEmpty(body) ? null : JObject.Parse(body);

                JObject valObject = null;

                if (inputObject != null)
                {
                    valObject = inputObject["value"] as JObject;
                    foreach (JToken token in inputObject.Children())
                    {
                        try
                        {
                            if (token.Path.Equals("value", StringComparison.InvariantCultureIgnoreCase))
                            {
                                continue;
                            }
                            string envKey = $"__OW_{token.Path.ToUpperInvariant()}";
                            string envVal = token.First.ToString();
                            Environment.SetEnvironmentVariable(envKey, envVal);
                            //Console.WriteLine($"Set environment variable \"{envKey}\" to \"{envVal}\".");
                        }
                        catch (Exception)
                        {
                            await Console.Error.WriteLineAsync(
                                $"Unable to set environment variable for the \"{token.Path}\" token.");
                        }
                    }
                }

                object owObject = _constructor.Invoke(new object[] { });

                try
                {
                    JObject output = (JObject)_method.Invoke(owObject, new object[] { valObject });

                    if (output == null)
                    {
                        await httpContext.Response.WriteError("The action returned null");

                        Console.Error.WriteLine("The action returned null");
                        return;
                    }

                    await httpContext.Response.WriteResponse(200, output.ToString());
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine(ex.StackTrace);
                    await httpContext.Response.WriteError(ex.Message
#if DEBUG
                                                          + ", " + ex.StackTrace
#endif
                                                          );
                }
            }
            finally
            {
                Startup.WriteLogMarkers();
            }
        }
Пример #2
0
        public async Task HandleRequest(HttpContext httpContext)
        {
            if (_methodAsync == null && _method == null)
            {
                await httpContext.Response.WriteError("Cannot invoke an uninitialized action.");

                return;
            }

            try
            {
                //string body = JsonSerializer.Serialize( new HttpResponseExtension.Response("test") );
                //httpContext.Response.StatusCode = 200;
                //httpContext.Response.ContentLength = Encoding.UTF8.GetByteCount( body );
                //await httpContext.Response.WriteAsync( body );
                //return;
                //string body = await new StreamReader(httpContext.Request.Body).ReadToEndAsync();

                //JObject inputObject = string.IsNullOrEmpty(body) ? null : JObject.Parse(body);

                //JObject valObject = null;

                //if (inputObject != null)
                //{
                //    valObject = inputObject["value"] as JObject;
                //    foreach (JToken token in inputObject.Children())
                //    {
                //        try
                //        {
                //            if (token.Path.Equals("value", StringComparison.InvariantCultureIgnoreCase))
                //                continue;
                //            string envKey = $"__OW_{token.Path.ToUpperInvariant()}";
                //            string envVal = token.First.ToString();
                //            Environment.SetEnvironmentVariable(envKey, envVal);
                //            //Console.WriteLine($"Set environment variable \"{envKey}\" to \"{envVal}\".");
                //        }
                //        catch (Exception)
                //        {
                //            await Console.Error.WriteLineAsync(
                //                $"Unable to set environment variable for the \"{token.Path}\" token.");
                //        }
                //    }
                //}

                try
                {
                    if (_awaitableMethod)
                    {
                        await _methodAsync(httpContext);
                    }
                    else
                    {
                        _method(httpContext);
                    }
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine(ex.StackTrace);
                    await httpContext.Response.WriteError(ex.Message
#if DEBUG
                                                          + ", " + ex.StackTrace
#endif
                                                          );
                }
            }
            finally
            {
                Startup.WriteLogMarkers();
            }
        }
Пример #3
0
        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 tempPath  = Path.Combine(Environment.CurrentDirectory, Guid.NewGuid().ToString());
                string base64Zip = message["code"].ToString();
                try
                {
                    using (MemoryStream stream = new MemoryStream(Convert.FromBase64String(base64Zip)))
                    {
                        using (ZipArchive archive = new ZipArchive(stream))
                        {
                            archive.ExtractToDirectory(tempPath);
                        }
                    }
                }
                catch (Exception)
                {
                    await httpContext.Response.WriteError("Unable to decompress package.");

                    return(null);
                }

                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
                {
                    // Export init arguments as environment variables
                    if (message["env"] != null && message["env"].HasValues)
                    {
                        Dictionary <string, string> dictEnv = message["env"].ToObject <Dictionary <string, string> >();
                        foreach (KeyValuePair <string, string> entry in dictEnv)
                        {
                            // See https://docs.microsoft.com/en-us/dotnet/api/system.environment.setenvironmentvariable
                            // If entry.Value is null or the empty string, the variable is not set
                            Environment.SetEnvironmentVariable(entry.Key, entry.Value);
                        }
                    }

                    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();
            }
        }
Пример #4
0
        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));
                }

                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 ex)
                {
                    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;

                await httpContext.Response.WriteResponse(200, "OK");

                return(new Run(Type, Method, Constructor));
            }
            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();
            }
        }
Пример #5
0
        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(Method, AwaitableMethod));
                }

                //string body = await new StreamReader(httpContext.Request.Body).ReadToEndAsync();
                //MethodToAdd.Value methodToAdd = JsonSerializer.Deserialize<MethodToAdd>(body).value;
                //MethodToAdd.Value methodToAdd = JsonConvert.DeserializeObject<MethodToAdd>(body).value;

                //fastest with much lower memory usage
                MethodToAdd.Value methodToAdd = (await System.Text.Json.JsonSerializer.DeserializeAsync <MethodToAdd>(httpContext.Request.Body)).value;


                if (string.IsNullOrEmpty(methodToAdd.main) ||
                    string.IsNullOrEmpty(methodToAdd.code))
                {
                    await httpContext.Response.WriteError("Missing main/no code to execute.");

                    return(null);
                }

                if (!methodToAdd.binary)
                {
                    await httpContext.Response.WriteError("code must be binary (zip file).");

                    return(null);
                }

                string[] mainParts = methodToAdd.main.Split("::");
                if (mainParts.Length != 3)
                {
                    await httpContext.Response.WriteError("main required format is \"Assembly::Type::Function\".");

                    return(null);
                }

                string tempPath = Path.Combine(Environment.CurrentDirectory, Guid.NewGuid().ToString());
                try
                {
                    using (var zipStream = new MemoryStream(Convert.FromBase64String(methodToAdd.code)))
                        using (var zip = new ZipArchive(zipStream))
                        {
                            zip.ExtractToDirectory(tempPath);
                        }
                }
                catch (Exception)
                {
                    await httpContext.Response.WriteError("Unable to decompress package.");

                    return(null);
                }

                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]);
                }
                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);
                }

                Initialized = true;

                AwaitableMethod = (Method.ReturnType.GetMethod(nameof(Task.GetAwaiter)) != null);
                //AwaitableMethod = Method.ReturnType == typeof(Task);

                return(new Run(Method, AwaitableMethod));
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.ToString());
                await httpContext.Response.WriteError(ex.ToString()
#if DEBUG
                                                      + ", " + ex.StackTrace
#endif
                                                      );

                Startup.WriteLogMarkers();
                return(null);
            }
            finally
            {
                _initSemaphoreSlim.Release();
            }
        }