Added WebRequest node

This commit is contained in:
John Andrews
2022-03-12 19:45:29 +13:00
parent 3375cdec40
commit b0b0067f6c
7 changed files with 216 additions and 1 deletions

Binary file not shown.

View File

@@ -243,6 +243,27 @@
"CsvFile-Help": "Will append to this file the original name and the renamed file. Useful when using ''Log Only'' to test the renamer before changing files."
}
},
"WebRequest": {
"Description": "Allows you to send a web request",
"Outputs": {
"1": "Successfully sent",
"2": "Request returned a non-successful status code"
},
"Fields": {
"Url": "URL",
"Url-Help": "The URL of the request",
"Method": "Method",
"Method-Help": "The web method to use when sending this request",
"ContentType": "Content Type",
"ContentType-Help": "The Content-Type of the message to send.",
"Headers": "Headers",
"Headers-Help": "Optional headers to send with the request",
"HeadersKey": "Key",
"HeadersValue": "Value",
"Body": "Body",
"Body-Help": "The body of the request being sent. Variables can be used in this field."
}
},
"Zip": {
"Description": "Allows you to zip the input",
"Outputs": {

View File

@@ -0,0 +1,10 @@
namespace BasicNodes
{
internal static class ExtensionMethods
{
public static string? EmptyAsNull(this string str)
{
return str == string.Empty ? null : str;
}
}
}

View File

@@ -4,6 +4,7 @@ namespace BasicNodes.Tests
{
using FileFlows.BasicNodes.File;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Text.RegularExpressions;
[TestClass]
public class ExecutorTests
@@ -24,6 +25,11 @@ namespace BasicNodes.Tests
string output = args.Variables["ExecOutput"] as string;
Assert.IsNotNull(output);
}
[TestMethod]
public void Executor_VariablePattern_Tests()
{
Assert.IsFalse(Regex.IsMatch(string.Empty, Executor.VariablePattern));
}
}
}

View File

@@ -0,0 +1,38 @@
#if(DEBUG)
namespace BasicNodes.Tests
{
using BasicNodes.Tools;
using FileFlows.BasicNodes.File;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class WebRequestTests
{
[TestMethod]
public void WebRequest_PostJson()
{
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(@"c:\test\testfile.mkv", logger, false, string.Empty);
WebRequest node = new();
node.Method = "POST";
node.Url = "http://localhost:7096/Users/New";
node.ContentType = "application/json";
node.Headers = new List<KeyValuePair<string, string>>();
node.Headers.Add(new KeyValuePair<string, string> ("X-MediaBrowser-Token", ""));
node.Body = @$"{{
""Name"": ""{Guid.NewGuid()}""
}}";
var result = node.Execute(args);
string body = node.Variables["web.Body"] as string;
Assert.IsFalse(string.IsNullOrWhiteSpace(body));
Assert.AreEqual(1, result);
}
}
}
#endif

View File

@@ -0,0 +1,141 @@
namespace BasicNodes.Tools
{
using FileFlows.Plugin;
using FileFlows.Plugin.Attributes;
using System;
using System.Text;
public class WebRequest : Node
{
public override int Inputs => 1;
public override int Outputs => 2;
public override FlowElementType Type => FlowElementType.Process;
public override string Icon => "fas fa-globe";
[TextVariable(1)]
public string Url { get; set; }
[Select(nameof(MethodOptions), 2)]
public string Method { get; set; }
private static List<ListOption> _MethodOptions;
public static List<ListOption> MethodOptions
{
get
{
if (_MethodOptions == null)
{
_MethodOptions = new List<ListOption>
{
new ListOption { Label = "GET", Value = "GET"},
new ListOption { Label = "POST", Value = "POST"},
new ListOption { Label = "PUT", Value = "PUT"},
new ListOption { Label = "DELETE", Value = "DELETE"},
};
}
return _MethodOptions;
}
}
[Select(nameof(ContentTypeOptions), 3)]
public string ContentType { get; set; }
private static List<ListOption> _ContentTypeOptions;
public static List<ListOption> ContentTypeOptions
{
get
{
if (_ContentTypeOptions == null)
{
_ContentTypeOptions = new List<ListOption>
{
new ListOption { Label = "None", Value = ""},
new ListOption { Label = "JSON", Value = "application/json"},
new ListOption { Label = "Form Data", Value = "application/x-www-form-urlencoded"},
};
}
return _ContentTypeOptions;
}
}
[KeyValue(4)]
public List<KeyValuePair<string, string>> Headers { get; set; }
[TextArea(5)]
public string Body { get; set; }
private Dictionary<string, object> _Variables;
public override Dictionary<string, object> Variables => _Variables;
public WebRequest()
{
_Variables = new Dictionary<string, object>()
{
{ "web.StatusCode", 200 },
{ "web.Body", "this is a sample body" }
};
}
public override int Execute(NodeParameters args)
{
try
{
using var client = new HttpClient();
string url = args.ReplaceVariables(this.Url, stripMissing: true);
HttpMethod method = this.Method switch
{
"POST" => HttpMethod.Post,
"PUT" => HttpMethod.Put,
"DELETE" => HttpMethod.Delete,
_ => HttpMethod.Get
};
args.Logger.ILog("Requesting: [" + method + "] " + url);
HttpRequestMessage message = new HttpRequestMessage(method, url);
if(this.Headers?.Any() == true)
{
foreach(var header in this.Headers)
{
if (string.IsNullOrEmpty(header.Key) || string.IsNullOrEmpty(header.Value))
continue;
message.Headers.Add(header.Key, header.Value);
}
}
if (string.IsNullOrEmpty(this.ContentType) == false && method != HttpMethod.Get && string.IsNullOrWhiteSpace(this.Body) == false)
{
string body = args.ReplaceVariables(this.Body, stripMissing: false);
message.Content = new StringContent(body, Encoding.UTF8, this.ContentType?.EmptyAsNull() ?? "application/json");
}
var result = client.Send(message);
string stringBody = result.Content.ReadAsStringAsync().Result ?? string.Empty;
args.UpdateVariables(new Dictionary<string, object>{
{ "web.StatusCode", (int)result.StatusCode },
{ "web.Body", stringBody }
});
if (result.IsSuccessStatusCode == false)
{
args.Logger.WLog("Non successfully status code returned: " + result.StatusCode);
return 2;
}
args.Logger?.ILog("Successful status code returned: " + result.StatusCode);
return 1;
}
catch (Exception ex)
{
args.Logger?.ELog("Failed sending web request: " + ex.Message + Environment.NewLine + ex.StackTrace);
return -1;
}
}
}
}

View File

@@ -3,7 +3,6 @@
using FileFlows.Plugin;
using FileFlows.Plugin.Attributes;
using System;
using System.ComponentModel.DataAnnotations;
using System.IO.Compression;