From 0dd8c6d64d8d1414ab6cfed4c4587cdbdc3ad950 Mon Sep 17 00:00:00 2001 From: sjuarezgx Date: Wed, 30 Nov 2022 17:41:51 -0300 Subject: [PATCH 1/4] Fix GAM Ext Authentication Serverless --- .../dotnetcore/GxClasses.Web/Middleware/HandlerFactory.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dotnet/src/dotnetcore/GxClasses.Web/Middleware/HandlerFactory.cs b/dotnet/src/dotnetcore/GxClasses.Web/Middleware/HandlerFactory.cs index db6be89fa..549b6ba9e 100644 --- a/dotnet/src/dotnetcore/GxClasses.Web/Middleware/HandlerFactory.cs +++ b/dotnet/src/dotnetcore/GxClasses.Web/Middleware/HandlerFactory.cs @@ -222,11 +222,12 @@ internal static List GetGxNamespaces(HttpContext context, string mainNam try { string binPath = GxContext.StaticPhysicalPath(); - if (context != null && !binPath.EndsWith("bin")){ + GXLogging.Debug(log, $"binPath at GetGXNamespaces {binPath}"); + if (context != null && !binPath.EndsWith("bin") && !GxContext.IsAzureContext){ binPath = Path.Combine(binPath, "bin"); } string[] files = Directory.GetFiles(binPath, "*.Common.dll", SearchOption.TopDirectoryOnly); - if (files == null || files.Length == 0) + if ((files == null || files.Length == 0) && (!GxContext.IsAzureContext)) { binPath = Path.Combine(binPath, "bin"); files = Directory.GetFiles(binPath, "*.Common.dll", SearchOption.TopDirectoryOnly); From 996a15259e38247c2d9a69de108e4b62e82ad2ef Mon Sep 17 00:00:00 2001 From: sjuarezgx Date: Thu, 8 Dec 2022 15:45:27 -0300 Subject: [PATCH 2/4] make method public --- dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs b/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs index ac8b0af58..35db29f06 100644 --- a/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs +++ b/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs @@ -2928,7 +2928,7 @@ public static bool IsRestService } #if NETCORE static bool _isHttpContext; - internal static bool IsAzureContext + public static bool IsAzureContext { get; set; } #endif public static bool IsHttpContext From 46abd286717f0183a2bf2372c34283953beb219c Mon Sep 17 00:00:00 2001 From: sjuarezgx Date: Thu, 8 Dec 2022 16:13:11 -0300 Subject: [PATCH 3/4] Set GxContext.IsHttpContext when is AzureContext --- dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs | 2 +- dotnet/src/extensions/Azure/Handlers/Program.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs b/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs index 35db29f06..ac8b0af58 100644 --- a/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs +++ b/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs @@ -2928,7 +2928,7 @@ public static bool IsRestService } #if NETCORE static bool _isHttpContext; - public static bool IsAzureContext + internal static bool IsAzureContext { get; set; } #endif public static bool IsHttpContext diff --git a/dotnet/src/extensions/Azure/Handlers/Program.cs b/dotnet/src/extensions/Azure/Handlers/Program.cs index 2a5079852..2f085c0cb 100644 --- a/dotnet/src/extensions/Azure/Handlers/Program.cs +++ b/dotnet/src/extensions/Azure/Handlers/Program.cs @@ -45,6 +45,7 @@ static async Task Main() }) .Build(); GxContext.IsAzureContext = true; + GxContext.IsHttpContext = true; await host.RunAsync(); } private static string GetRoutePrefix(string ContentRootPath) From ccc592f377a037e80efcae35787ed3c4a87debe8 Mon Sep 17 00:00:00 2001 From: sjuarezgx Date: Tue, 13 Dec 2022 18:36:47 -0300 Subject: [PATCH 4/4] custom http headers were not being set in the azure response --- .../HttpHandler/GXHttpAzureContextAccessor.cs | 117 ++++++++++++++++-- 1 file changed, 106 insertions(+), 11 deletions(-) diff --git a/dotnet/src/extensions/Azure/Handlers/HttpHandler/GXHttpAzureContextAccessor.cs b/dotnet/src/extensions/Azure/Handlers/HttpHandler/GXHttpAzureContextAccessor.cs index 14172f9b5..bc58ac9d3 100644 --- a/dotnet/src/extensions/Azure/Handlers/HttpHandler/GXHttpAzureContextAccessor.cs +++ b/dotnet/src/extensions/Azure/Handlers/HttpHandler/GXHttpAzureContextAccessor.cs @@ -1,5 +1,7 @@ using System; +using System.Collections; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.IO.Pipelines; using System.Linq; @@ -14,6 +16,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.Azure.Functions.Worker.Http; +using Microsoft.Extensions.Primitives; namespace GeneXus.Deploy.AzureFunctions.HttpHandler { @@ -45,7 +48,7 @@ public GXHttpAzureContextAccessor(HttpRequestData requestData, HttpResponseData isSecure = GetSecureConnection(header.Key, defaultHttpContext.Request.Headers[header.Key]); } - if (requestData.FunctionContext.BindingContext!=null) + if (requestData.FunctionContext.BindingContext != null) { IReadOnlyDictionary keyValuePairs = requestData.FunctionContext.BindingContext.BindingData; object queryparamsJson = requestData.FunctionContext.BindingContext.BindingData.GetValueOrDefault("Query"); @@ -83,7 +86,7 @@ public GXHttpAzureContextAccessor(HttpRequestData requestData, HttpResponseData RedisHttpSession redisHttpSession = (RedisHttpSession)Session; //Check if session is in cache if (redisHttpSession.SessionKeyExists(sessionId)) - { + { bool success = redisHttpSession.RefreshSession(sessionId); if (!success) GXLogging.Debug(log, $"Azure Serverless: Session could not be refreshed :{sessionId}"); @@ -97,7 +100,7 @@ private bool GetSecureConnection(string headerKey, string headerValue) { if ((headerKey == "Front-End-Https") & (headerValue == "on")) return true; - + if ((headerKey == "X-Forwarded-Proto") & (headerValue == "https")) return true; @@ -126,7 +129,7 @@ private string CookieValue(string header, string name) { string[] words = header.Split(';'); - foreach (var word in words) + foreach (string word in words) { string[] parts = word.Split('='); if (parts[0].Trim() == name) @@ -164,6 +167,104 @@ public override void Abort() //throw new NotImplementedException(); } } + internal class GxAzureResponseHeaders : IHeaderDictionary + { + HeaderDictionary m_headers; + HttpResponseData m_httpResponseData; + internal GxAzureResponseHeaders(HttpResponseData httpResponseData) + { + m_headers = new HeaderDictionary(); + foreach (var header in httpResponseData.Headers) + { + string[] values = new Microsoft.Extensions.Primitives.StringValues(header.Value.Select(val => val).ToArray()); + m_headers.Add(header.Key, values); + } + m_httpResponseData = httpResponseData; + } + + public StringValues this[string key] + { + get + { + return m_headers[key]; + } + set + { + m_httpResponseData.Headers.Add(key, value.AsEnumerable()); + m_headers[key] = value; + } + } + + public long? ContentLength { get { return m_headers.ContentLength; } set {; } } + + public ICollection Keys { get { return m_headers.Keys; } } + public ICollection Values { get { return m_headers.Values; } } + + public int Count { get { return m_headers.Count; } } + + public bool IsReadOnly { get { return m_headers.IsReadOnly; } } + + public void Add(string key, StringValues value) + { + m_httpResponseData.Headers.Add(key, value.AsEnumerable()); + m_headers.Add(key, value); + } + + public void Add(KeyValuePair item) + { + m_httpResponseData.Headers.Add(item.Key, item.Value.AsEnumerable()); + m_headers.Add(item.Key, item.Value); + } + + public void Clear() + { + m_httpResponseData.Headers.Clear(); + m_headers.Clear(); + } + + public bool Contains(KeyValuePair item) + { + return m_headers.Contains(item); + } + + public bool ContainsKey(string key) + { + return m_headers.ContainsKey(key); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + m_headers.CopyTo(array, arrayIndex); + } + + public IEnumerator> GetEnumerator() + { + return m_headers.GetEnumerator(); + } + + public bool Remove(string key) + { + m_httpResponseData.Headers.Remove(key); + return m_headers.Remove(key); + } + + public bool Remove(KeyValuePair item) + { + m_httpResponseData.Headers.Remove(item.Key); + return m_headers.Remove(item); + } + + public bool TryGetValue(string key, [MaybeNullWhen(false)] out StringValues value) + { + return m_headers.TryGetValue(key, out value); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return m_headers.GetEnumerator(); + } + } + public class GxHttpAzureResponse : HttpResponse { HttpResponseData httpResponseData; @@ -212,13 +313,7 @@ public override IHeaderDictionary Headers { get { - IHeaderDictionary headers = new HeaderDictionary(); - foreach (var header in httpResponseData.Headers) - { - string[] values = new Microsoft.Extensions.Primitives.StringValues(header.Value.Select(val => val).ToArray()); - headers.Add(header.Key, values); - } - return headers; + return new GxAzureResponseHeaders(httpResponseData); } } public override Stream Body { get => httpResponseData.Body; set => httpResponseData.Body = value; }