From 1b01b3a90e5474992e1272ebce5ad0b4cba13c98 Mon Sep 17 00:00:00 2001 From: Marie Hoeger Date: Tue, 26 May 2020 17:20:16 -0700 Subject: [PATCH 1/4] Ignore headers with empty value if capability is enabled --- .../RpcMessageConversionExtensions.cs | 10 ++++++ .../Workers/Rpc/RpcWorkerConstants.cs | 1 + .../RpcMessageConversionExtensionsTests.cs | 36 +++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/src/WebJobs.Script/Workers/Rpc/MessageExtensions/RpcMessageConversionExtensions.cs b/src/WebJobs.Script/Workers/Rpc/MessageExtensions/RpcMessageConversionExtensions.cs index 345ae063fa..0e75c24041 100644 --- a/src/WebJobs.Script/Workers/Rpc/MessageExtensions/RpcMessageConversionExtensions.cs +++ b/src/WebJobs.Script/Workers/Rpc/MessageExtensions/RpcMessageConversionExtensions.cs @@ -132,6 +132,11 @@ internal static TypedData ToRpcHttp(this HttpRequest request, ILogger logger, Ca foreach (var pair in request.Headers) { + if (ShouldIgnoreEmptyHeaderValues(capabilities) && !string.IsNullOrEmpty(pair.Value.ToString())) + { + continue; + } + http.Headers.Add(pair.Key.ToLowerInvariant(), pair.Value.ToString()); } @@ -346,6 +351,11 @@ private static bool IsTypedDataCollectionSupported(Capabilities capabilities) return !string.IsNullOrEmpty(capabilities.GetCapabilityState(RpcWorkerConstants.TypedDataCollection)); } + private static bool ShouldIgnoreEmptyHeaderValues(Capabilities capabilities) + { + return !string.IsNullOrEmpty(capabilities.GetCapabilityState(RpcWorkerConstants.IgnoreEmptyValuedRpcHttpHeaders)); + } + public static BindingInfo ToBindingInfo(this BindingMetadata bindingMetadata) { BindingInfo bindingInfo = new BindingInfo diff --git a/src/WebJobs.Script/Workers/Rpc/RpcWorkerConstants.cs b/src/WebJobs.Script/Workers/Rpc/RpcWorkerConstants.cs index 534f1a2aac..6f0e712ff4 100644 --- a/src/WebJobs.Script/Workers/Rpc/RpcWorkerConstants.cs +++ b/src/WebJobs.Script/Workers/Rpc/RpcWorkerConstants.cs @@ -35,6 +35,7 @@ public static class RpcWorkerConstants public const string TypedDataCollection = "TypedDataCollection"; public const string RpcHttpBodyOnly = "RpcHttpBodyOnly"; public const string RpcHttpTriggerMetadataRemoved = "RpcHttpTriggerMetadataRemoved"; + public const string IgnoreEmptyValuedRpcHttpHeaders = "IgnoreEmptyValuedRpcHttpHeaders"; // Host Capabilites public const string V2Compatable = "V2Compatable"; diff --git a/test/WebJobs.Script.Tests/Workers/Rpc/RpcMessageConversionExtensionsTests.cs b/test/WebJobs.Script.Tests/Workers/Rpc/RpcMessageConversionExtensionsTests.cs index 9fcfd6cf09..fa279e5952 100644 --- a/test/WebJobs.Script.Tests/Workers/Rpc/RpcMessageConversionExtensionsTests.cs +++ b/test/WebJobs.Script.Tests/Workers/Rpc/RpcMessageConversionExtensionsTests.cs @@ -160,6 +160,42 @@ public void HttpObjects_Query(string queryString, string[] expectedKeys, string[ } } + [Theory] + [InlineData(true, new string[] { "hello", "x-mx-key" }, new string[] { "world", "value" }, new string[] { "hello", "x-mx-key" }, new string[] { "world", "value" })] + [InlineData(true, new string[] { "hello", "empty", "x-mx-key" }, new string[] { "world", "", "value" }, new string[] { "hello", "x-mx-key" }, new string[] { "world", "value" })] // Removes empty value query params + [InlineData(false, new string[] { "hello", "x-mx-key" }, new string[] { "world", "value" }, new string[] { "hello", "x-mx-key" }, new string[] { "world", "value" })] + [InlineData(false, new string[] { "hello", "empty", "x-mx-key" }, new string[] { "world", "", "value" }, new string[] { "hello", "empty", "x-mx-key" }, new string[] { "world", "", "value" })] + + public void HttpObjects_Headers(bool ignoreEmptyValues, string[] headerKeys, string[] headerValues, string[] expectedKeys, string[] expectedValues) + { + var logger = MockNullLoggerFactory.CreateLogger(); + // Capability must be enabled + var capabilities = new Capabilities(logger); + + if (ignoreEmptyValues) { + capabilities.UpdateCapabilities(new MapField + { + { RpcWorkerConstants.IgnoreEmptyValuedRpcHttpHeaders, "true" } + }); + } + + var headerDictionary = new HeaderDictionary(); + for (int i = 0; i < headerValues.Length; i++) + { + headerDictionary.Add(headerKeys[i], headerValues[i]); + } + + HttpRequest request = HttpTestHelpers.CreateHttpRequest("GET", $"http://localhost/api/httptrigger-scenarios", headerDictionary); + + var rpcRequestObject = request.ToRpc(logger, capabilities); + // Same key and value strings for each pair + for (int i = 0; i < expectedKeys.Length; i++) + { + Assert.True(rpcRequestObject.Http.Headers.ContainsKey(expectedKeys[i])); + Assert.Equal(expectedValues[i], rpcRequestObject.Http.Headers.GetValueOrDefault(expectedKeys[i])); + } + } + [Theory] [InlineData(BindingDirection.In, "blob", DataType.String)] [InlineData(BindingDirection.Out, "blob", DataType.Binary)] From c18485848ad07a47325fc8a581358c7a8f48d80f Mon Sep 17 00:00:00 2001 From: Marie Hoeger Date: Tue, 26 May 2020 17:21:33 -0700 Subject: [PATCH 2/4] nit --- .../Workers/Rpc/RpcMessageConversionExtensionsTests.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/WebJobs.Script.Tests/Workers/Rpc/RpcMessageConversionExtensionsTests.cs b/test/WebJobs.Script.Tests/Workers/Rpc/RpcMessageConversionExtensionsTests.cs index fa279e5952..7941380b5f 100644 --- a/test/WebJobs.Script.Tests/Workers/Rpc/RpcMessageConversionExtensionsTests.cs +++ b/test/WebJobs.Script.Tests/Workers/Rpc/RpcMessageConversionExtensionsTests.cs @@ -176,9 +176,10 @@ public void HttpObjects_Headers(bool ignoreEmptyValues, string[] headerKeys, str capabilities.UpdateCapabilities(new MapField { { RpcWorkerConstants.IgnoreEmptyValuedRpcHttpHeaders, "true" } - }); + } + ); } - + var headerDictionary = new HeaderDictionary(); for (int i = 0; i < headerValues.Length; i++) { From 7bf6887ee3870bfabc4dafdc676192c01072608d Mon Sep 17 00:00:00 2001 From: Marie Hoeger Date: Tue, 26 May 2020 17:38:51 -0700 Subject: [PATCH 3/4] format fixes --- .../MessageExtensions/RpcMessageConversionExtensions.cs | 2 +- .../Workers/Rpc/RpcMessageConversionExtensionsTests.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/WebJobs.Script/Workers/Rpc/MessageExtensions/RpcMessageConversionExtensions.cs b/src/WebJobs.Script/Workers/Rpc/MessageExtensions/RpcMessageConversionExtensions.cs index 0e75c24041..9a320f153e 100644 --- a/src/WebJobs.Script/Workers/Rpc/MessageExtensions/RpcMessageConversionExtensions.cs +++ b/src/WebJobs.Script/Workers/Rpc/MessageExtensions/RpcMessageConversionExtensions.cs @@ -135,7 +135,7 @@ internal static TypedData ToRpcHttp(this HttpRequest request, ILogger logger, Ca if (ShouldIgnoreEmptyHeaderValues(capabilities) && !string.IsNullOrEmpty(pair.Value.ToString())) { continue; - } + } http.Headers.Add(pair.Key.ToLowerInvariant(), pair.Value.ToString()); } diff --git a/test/WebJobs.Script.Tests/Workers/Rpc/RpcMessageConversionExtensionsTests.cs b/test/WebJobs.Script.Tests/Workers/Rpc/RpcMessageConversionExtensionsTests.cs index 7941380b5f..f9b18a68d2 100644 --- a/test/WebJobs.Script.Tests/Workers/Rpc/RpcMessageConversionExtensionsTests.cs +++ b/test/WebJobs.Script.Tests/Workers/Rpc/RpcMessageConversionExtensionsTests.cs @@ -168,16 +168,16 @@ public void HttpObjects_Query(string queryString, string[] expectedKeys, string[ public void HttpObjects_Headers(bool ignoreEmptyValues, string[] headerKeys, string[] headerValues, string[] expectedKeys, string[] expectedValues) { - var logger = MockNullLoggerFactory.CreateLogger(); + var logger = MockNullLoggerFactory.CreateLogger(); // Capability must be enabled var capabilities = new Capabilities(logger); - if (ignoreEmptyValues) { + if (ignoreEmptyValues) + { capabilities.UpdateCapabilities(new MapField { { RpcWorkerConstants.IgnoreEmptyValuedRpcHttpHeaders, "true" } - } - ); + }); } var headerDictionary = new HeaderDictionary(); From 61ec0708b9d56c3f2fdf3085c20c2e9828bd6e77 Mon Sep 17 00:00:00 2001 From: Marie Hoeger Date: Tue, 26 May 2020 18:51:41 -0700 Subject: [PATCH 4/4] logic error --- .../Rpc/MessageExtensions/RpcMessageConversionExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebJobs.Script/Workers/Rpc/MessageExtensions/RpcMessageConversionExtensions.cs b/src/WebJobs.Script/Workers/Rpc/MessageExtensions/RpcMessageConversionExtensions.cs index 9a320f153e..58b3c82bb3 100644 --- a/src/WebJobs.Script/Workers/Rpc/MessageExtensions/RpcMessageConversionExtensions.cs +++ b/src/WebJobs.Script/Workers/Rpc/MessageExtensions/RpcMessageConversionExtensions.cs @@ -132,7 +132,7 @@ internal static TypedData ToRpcHttp(this HttpRequest request, ILogger logger, Ca foreach (var pair in request.Headers) { - if (ShouldIgnoreEmptyHeaderValues(capabilities) && !string.IsNullOrEmpty(pair.Value.ToString())) + if (ShouldIgnoreEmptyHeaderValues(capabilities) && string.IsNullOrEmpty(pair.Value.ToString())) { continue; }