From 73cda750646cb6f1314efb4abc80ba8e4bdbb3c0 Mon Sep 17 00:00:00 2001 From: aspyankov Date: Thu, 24 Jul 2025 15:16:28 +0300 Subject: [PATCH 1/2] Added client certificate and request body encoding support --- .../bin/Debug/ClrHttpRequest.dacpac | Bin 13721 -> 16642 bytes ClrHttpRequest/bin/Debug/ClrHttpRequest.dll | Bin 13312 -> 15872 bytes ClrHttpRequest/bin/Debug/ClrHttpRequest.pdb | Bin 15872 -> 22016 bytes ClrHttpRequest/clr_http_request.cs | 106 +++++++++++++++--- README.md | 12 ++ 5 files changed, 104 insertions(+), 14 deletions(-) diff --git a/ClrHttpRequest/bin/Debug/ClrHttpRequest.dacpac b/ClrHttpRequest/bin/Debug/ClrHttpRequest.dacpac index d4991c8d4e5ca51fac0ee53c3ba112ae6d773287..725a12cf430cd1302f31c5e56239a07a29182803 100644 GIT binary patch delta 16125 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 delta 13191 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 A1^@s6 delta 5249 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 F{{f`43is@GRcI=1c;A1 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 - /// Generates an XML element with a standard format for debug steps - /// - /// Name for this step in the process - /// XElement representing a debug step - private static XElement GetDebugStepXElement(string stepName) + /// + /// Tries to get encoding from options + /// + private static Encoding GetEncoding(Dictionary options, XElement debugXml) + { + var encodingKey = "encoding"; + Encoding result = Encoding.ASCII; + try + { + if (options.ContainsKey(encodingKey)) + { + result = Encoding.GetEncoding(options[encodingKey]); + } + } + catch (Exception ex) + { + debugXml.Add(GetDebugStepXElement($"Error while parse specified encoding value {options[encodingKey]}")); + + debugXml.Add(GetXElementFromException(ex)); + } + + debugXml.Add(GetDebugStepXElement($"Set encoding to {result}")); + + return result; + } + + /// + /// Tries to read certificate by its name from certificates store + /// + /// CN or Subject Distinguished name + /// Client certificate + private static X509Certificate2 ReadClientCertificate(string clientCertName, XElement debugXml) + { + var storeLocations = new StoreLocation[] { StoreLocation.LocalMachine, StoreLocation.CurrentUser }; + var storeNames = new StoreName[] { StoreName.Root, StoreName.My, StoreName.TrustedPeople, StoreName.AuthRoot }; + + foreach (var storeLocation in storeLocations) + foreach (var storeName in storeNames) + { + X509Store store = null; + try + { + store = new X509Store(storeName, storeLocation); + store.Open(OpenFlags.ReadOnly); + + foreach (var cert in store.Certificates) + { + if (cert.SubjectName?.Name?.Contains(clientCertName) == true + || cert.Subject?.Contains(clientCertName) == true) + { + debugXml.Add(GetDebugStepXElement($"Client certificate founded: {cert.Subject ?? cert.SubjectName?.Name}")); + return cert; + } + } + } + catch (Exception ex) + { + debugXml.Add(GetDebugStepXElement($"Error while reading store {storeName} for {storeLocation}")); + + debugXml.Add(GetXElementFromException(ex)); + } + finally + { + store?.Close(); + } + } + + throw new Exception($"Cannot find any certificate by name {clientCertName}"); + } + + /// + /// Generates an XML element with a standard format for debug steps + /// + /// Name for this step in the process + /// XElement representing a debug step + private static XElement GetDebugStepXElement(string stepName) { return new XElement( "Step", diff --git a/README.md b/README.md index 1180301..5b49fae 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,18 @@ If you're waiting for me or have any questions for me, bug me! Pass a CSV of protocols from the [SecurityProtocolType Enum](https://docs.microsoft.com/en-us/dotnet/api/system.net.securityprotocoltype) Example: `Tls12,Tls11,Tls` + +- encoding + + Encoding of http request content. Default is ASCII + + Example: `utf-8` + +- client_certificate_name + + For mTLS support, pass a client certificate name to locate it in the server's certificate store by Subject or Subject Name and use it in the HTTP request. + + Example: `Cert's Subject Name` - timeout From 66e469da7913509ce54eeb7dcf2f04e218992ec8 Mon Sep 17 00:00:00 2001 From: aspyankov Date: Thu, 24 Jul 2025 15:25:32 +0300 Subject: [PATCH 2/2] code clean up --- ClrHttpRequest/clr_http_request.cs | 168 ++++++++++++++--------------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/ClrHttpRequest/clr_http_request.cs b/ClrHttpRequest/clr_http_request.cs index df57920..3d7636f 100644 --- a/ClrHttpRequest/clr_http_request.cs +++ b/ClrHttpRequest/clr_http_request.cs @@ -139,14 +139,14 @@ public static SqlXml clr_http_request(string requestMethod, string url, string p } debugXml.Add(GetDebugStepXElement("Processed Headers")); - if (options.ContainsKey("client_certificate_name")) - { - var clientCertName = options["client_certificate_name"]; - request.ClientCertificates.Add(ReadClientCertificate(clientCertName, debugXml)); - } + if (options.ContainsKey("client_certificate_name")) + { + var clientCertName = options["client_certificate_name"]; + request.ClientCertificates.Add(ReadClientCertificate(clientCertName, debugXml)); + } - // Set the timeout if provided as an option - if (options.ContainsKey("timeout")) + // Set the timeout if provided as an option + if (options.ContainsKey("timeout")) { request.Timeout = int.Parse(options["timeout"]); } @@ -162,13 +162,13 @@ public static SqlXml clr_http_request(string requestMethod, string url, string p // Add in non-GET parameters provided if (requestMethod.ToUpper() != "GET" && !string.IsNullOrWhiteSpace(parameters)) - { - var encoding = GetEncoding(options, debugXml); - // Convert to byte array - var parameterData = encoding.GetBytes(parameters); - - // Set content info - if (!contentLengthSetFromHeaders) + { + var encoding = GetEncoding(options, debugXml); + // Convert to byte array + var parameterData = encoding.GetBytes(parameters); + + // Set content info + if (!contentLengthSetFromHeaders) { request.ContentLength = parameterData.Length; } @@ -309,77 +309,77 @@ public static SqlXml clr_http_request(string requestMethod, string url, string p // Return data return new SqlXml((new XElement("Response", debugXml, GetXElementFromException(ex))).CreateReader()); } - } - - /// - /// Tries to get encoding from options - /// - private static Encoding GetEncoding(Dictionary options, XElement debugXml) - { - var encodingKey = "encoding"; - Encoding result = Encoding.ASCII; - try - { - if (options.ContainsKey(encodingKey)) - { - result = Encoding.GetEncoding(options[encodingKey]); - } - } - catch (Exception ex) - { - debugXml.Add(GetDebugStepXElement($"Error while parse specified encoding value {options[encodingKey]}")); - - debugXml.Add(GetXElementFromException(ex)); - } - - debugXml.Add(GetDebugStepXElement($"Set encoding to {result}")); - - return result; - } - - /// - /// Tries to read certificate by its name from certificates store - /// - /// CN or Subject Distinguished name - /// Client certificate - private static X509Certificate2 ReadClientCertificate(string clientCertName, XElement debugXml) - { - var storeLocations = new StoreLocation[] { StoreLocation.LocalMachine, StoreLocation.CurrentUser }; - var storeNames = new StoreName[] { StoreName.Root, StoreName.My, StoreName.TrustedPeople, StoreName.AuthRoot }; - - foreach (var storeLocation in storeLocations) - foreach (var storeName in storeNames) - { - X509Store store = null; - try - { - store = new X509Store(storeName, storeLocation); - store.Open(OpenFlags.ReadOnly); - - foreach (var cert in store.Certificates) - { - if (cert.SubjectName?.Name?.Contains(clientCertName) == true - || cert.Subject?.Contains(clientCertName) == true) - { - debugXml.Add(GetDebugStepXElement($"Client certificate founded: {cert.Subject ?? cert.SubjectName?.Name}")); - return cert; - } - } - } - catch (Exception ex) - { - debugXml.Add(GetDebugStepXElement($"Error while reading store {storeName} for {storeLocation}")); - - debugXml.Add(GetXElementFromException(ex)); - } - finally - { - store?.Close(); - } - } + } - throw new Exception($"Cannot find any certificate by name {clientCertName}"); - } + /// + /// Tries to get encoding from options + /// + private static Encoding GetEncoding(Dictionary options, XElement debugXml) + { + var encodingKey = "encoding"; + Encoding result = Encoding.ASCII; + try + { + if (options.ContainsKey(encodingKey)) + { + result = Encoding.GetEncoding(options[encodingKey]); + } + } + catch (Exception ex) + { + debugXml.Add(GetDebugStepXElement($"Error while parse specified encoding value {options[encodingKey]}")); + + debugXml.Add(GetXElementFromException(ex)); + } + + debugXml.Add(GetDebugStepXElement($"Set encoding to {result}")); + + return result; + } + + /// + /// Tries to read certificate by its name from certificates store + /// + /// CN or Subject Distinguished name + /// Client certificate + private static X509Certificate2 ReadClientCertificate(string clientCertName, XElement debugXml) + { + var storeLocations = new StoreLocation[] { StoreLocation.LocalMachine, StoreLocation.CurrentUser }; + var storeNames = new StoreName[] { StoreName.Root, StoreName.My, StoreName.TrustedPeople, StoreName.AuthRoot }; + + foreach (var storeLocation in storeLocations) + foreach (var storeName in storeNames) + { + X509Store store = null; + try + { + store = new X509Store(storeName, storeLocation); + store.Open(OpenFlags.ReadOnly); + + foreach (var cert in store.Certificates) + { + if (cert.SubjectName?.Name?.Contains(clientCertName) == true + || cert.Subject?.Contains(clientCertName) == true) + { + debugXml.Add(GetDebugStepXElement($"Client certificate founded: {cert.Subject ?? cert.SubjectName?.Name}")); + return cert; + } + } + } + catch (Exception ex) + { + debugXml.Add(GetDebugStepXElement($"Error while reading store {storeName} for {storeLocation}")); + + debugXml.Add(GetXElementFromException(ex)); + } + finally + { + store?.Close(); + } + } + + throw new Exception($"Cannot find any certificate by name {clientCertName}"); + } /// /// Generates an XML element with a standard format for debug steps