From 8747b5fb3e29375412fe4cbca515adff9dd141cb Mon Sep 17 00:00:00 2001 From: MattMo Date: Mon, 19 Feb 2024 08:05:48 -0800 Subject: [PATCH] Modifying client generator to allow modifying requests before they are sent. --- Rest.Net.Example/Client.cs | 32 ++++++++++++++++++-- Rest.Net.Example/Program.cs | 15 +++++++++- Rest.Net.Example/StaticClient.cs | 32 ++++++++++++++++++-- Rest.Net/RestCSharpClientGenerator.cs | 36 +++++++++++++++++------ Rest.Net/RestJavascriptClientGenerator.cs | 15 ++++++++-- 5 files changed, 114 insertions(+), 16 deletions(-) diff --git a/Rest.Net.Example/Client.cs b/Rest.Net.Example/Client.cs index 9805641..c2ef796 100644 --- a/Rest.Net.Example/Client.cs +++ b/Rest.Net.Example/Client.cs @@ -1,4 +1,4 @@ -//Generated using MontoyaTech.Rest.Net +//Generated using MontoyaTech.Rest.Net - 2/18/2024 public class Client { @@ -10,6 +10,8 @@ public class Client public System.Net.Http.HttpClient HttpClient; + public System.Action RequestHandler; + public TestApi Test; public AuthApi Auth; @@ -18,7 +20,7 @@ public class Client public FormApi Form; - public Client(string baseUrl, System.Net.Http.HttpMessageHandler handler = null) + public Client(string baseUrl, System.Net.Http.HttpMessageHandler handler = null, System.Action requestHandler = null) { if (string.IsNullOrWhiteSpace(baseUrl)) throw new System.ArgumentException("baseUrl must not be null or whitespace."); @@ -43,6 +45,8 @@ public class Client this.MessageHandler = handler; + this.RequestHandler = requestHandler; + this.HttpClient = new System.Net.Http.HttpClient(handler); this.HttpClient.DefaultRequestHeaders.Add("Accept", "*/*"); @@ -73,6 +77,8 @@ public class Client { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"{this.Client.BaseUrl}/status"); + this.Client.RequestHandler?.Invoke(message); + var response = this.Client.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -94,6 +100,8 @@ public class Client { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, $"{this.Client.BaseUrl}/add/{a}/{b}"); + this.Client.RequestHandler?.Invoke(message); + var response = this.Client.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -115,6 +123,8 @@ public class Client { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"{this.Client.BaseUrl}/compress"); + this.Client.RequestHandler?.Invoke(message); + var response = this.Client.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -136,6 +146,8 @@ public class Client { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"{this.Client.BaseUrl}/file/compress"); + this.Client.RequestHandler?.Invoke(message); + var response = this.Client.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -167,6 +179,8 @@ public class Client { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"{this.Client.BaseUrl}/auth/{name}"); + this.Client.RequestHandler?.Invoke(message); + var response = this.Client.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -188,6 +202,8 @@ public class Client { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, $"{this.Client.BaseUrl}/auth/signup"); + this.Client.RequestHandler?.Invoke(message); + if (compress) { using (var uncompressedStream = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(request)))) @@ -220,6 +236,8 @@ public class Client { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"{this.Client.BaseUrl}/auth/"); + this.Client.RequestHandler?.Invoke(message); + var response = this.Client.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -241,6 +259,8 @@ public class Client { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"{this.Client.BaseUrl}/auth/dynamic"); + this.Client.RequestHandler?.Invoke(message); + var response = this.Client.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -262,6 +282,8 @@ public class Client { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"{this.Client.BaseUrl}/auth/role"); + this.Client.RequestHandler?.Invoke(message); + var response = this.Client.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -293,6 +315,8 @@ public class Client { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, $"{this.Client.BaseUrl}/upload"); + this.Client.RequestHandler?.Invoke(message); + request.Seek(0, System.IO.SeekOrigin.Begin); message.Content = new System.Net.Http.StreamContent(request); @@ -307,6 +331,8 @@ public class Client { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"{this.Client.BaseUrl}/download"); + this.Client.RequestHandler?.Invoke(message); + var response = this.Client.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -337,6 +363,8 @@ public class Client { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, $"{this.Client.BaseUrl}/form"); + this.Client.RequestHandler?.Invoke(message); + var response = this.Client.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) diff --git a/Rest.Net.Example/Program.cs b/Rest.Net.Example/Program.cs index 8237d14..1624cc2 100644 --- a/Rest.Net.Example/Program.cs +++ b/Rest.Net.Example/Program.cs @@ -9,6 +9,8 @@ using MontoyaTech.Rest.Net; using System.Net.Mime; using System.Collections; using Newtonsoft.Json.Linq; +using System.Web; +using System.Net.Http; namespace MontoyaTech.Rest.Net.Example { @@ -119,7 +121,18 @@ namespace MontoyaTech.Rest.Net.Example Console.WriteLine($"Rest api server running at {listener.BaseUrl}"); - StaticClient.Init(listener.BaseUrl); + StaticClient.Init(listener.BaseUrl, requestHandler: (message) => + { + var builder = new UriBuilder(message.RequestUri); + + var query = HttpUtility.ParseQueryString(builder.Query); + query.Add("authToken", "test"); + builder.Query = query.ToString(); + + message.RequestUri = builder.Uri; + + message.Headers.Add("Auth", "Test"); + }); using (var stream = new MemoryStream()) { diff --git a/Rest.Net.Example/StaticClient.cs b/Rest.Net.Example/StaticClient.cs index 4690633..642c955 100644 --- a/Rest.Net.Example/StaticClient.cs +++ b/Rest.Net.Example/StaticClient.cs @@ -1,4 +1,4 @@ -//Generated using MontoyaTech.Rest.Net +//Generated using MontoyaTech.Rest.Net - 2/18/2024 public class StaticClient { @@ -10,7 +10,9 @@ public class StaticClient public static System.Net.Http.HttpClient HttpClient; - public static void Init(string baseUrl, System.Net.Http.HttpMessageHandler handler = null) + public static System.Action RequestHandler; + + public static void Init(string baseUrl, System.Net.Http.HttpMessageHandler handler = null, System.Action requestHandler = null) { if (string.IsNullOrWhiteSpace(baseUrl)) throw new System.ArgumentException("baseUrl must not be null or whitespace."); @@ -35,6 +37,8 @@ public class StaticClient StaticClient.MessageHandler = handler; + StaticClient.RequestHandler = requestHandler; + StaticClient.HttpClient = new System.Net.Http.HttpClient(handler); StaticClient.HttpClient.DefaultRequestHeaders.Add("Accept", "*/*"); @@ -50,6 +54,8 @@ public class StaticClient { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"{StaticClient.BaseUrl}/status"); + StaticClient.RequestHandler?.Invoke(message); + var response = StaticClient.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -71,6 +77,8 @@ public class StaticClient { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, $"{StaticClient.BaseUrl}/add/{a}/{b}"); + StaticClient.RequestHandler?.Invoke(message); + var response = StaticClient.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -92,6 +100,8 @@ public class StaticClient { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"{StaticClient.BaseUrl}/compress"); + StaticClient.RequestHandler?.Invoke(message); + var response = StaticClient.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -113,6 +123,8 @@ public class StaticClient { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"{StaticClient.BaseUrl}/file/compress"); + StaticClient.RequestHandler?.Invoke(message); + var response = StaticClient.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -137,6 +149,8 @@ public class StaticClient { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"{StaticClient.BaseUrl}/auth/{name}"); + StaticClient.RequestHandler?.Invoke(message); + var response = StaticClient.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -158,6 +172,8 @@ public class StaticClient { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, $"{StaticClient.BaseUrl}/auth/signup"); + StaticClient.RequestHandler?.Invoke(message); + if (compress) { using (var uncompressedStream = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(request)))) @@ -190,6 +206,8 @@ public class StaticClient { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"{StaticClient.BaseUrl}/auth/"); + StaticClient.RequestHandler?.Invoke(message); + var response = StaticClient.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -211,6 +229,8 @@ public class StaticClient { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"{StaticClient.BaseUrl}/auth/dynamic"); + StaticClient.RequestHandler?.Invoke(message); + var response = StaticClient.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -232,6 +252,8 @@ public class StaticClient { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"{StaticClient.BaseUrl}/auth/role"); + StaticClient.RequestHandler?.Invoke(message); + var response = StaticClient.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -256,6 +278,8 @@ public class StaticClient { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, $"{StaticClient.BaseUrl}/upload"); + StaticClient.RequestHandler?.Invoke(message); + request.Seek(0, System.IO.SeekOrigin.Begin); message.Content = new System.Net.Http.StreamContent(request); @@ -270,6 +294,8 @@ public class StaticClient { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"{StaticClient.BaseUrl}/download"); + StaticClient.RequestHandler?.Invoke(message); + var response = StaticClient.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) @@ -293,6 +319,8 @@ public class StaticClient { var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, $"{StaticClient.BaseUrl}/form"); + StaticClient.RequestHandler?.Invoke(message); + var response = StaticClient.HttpClient.Send(message, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) diff --git a/Rest.Net/RestCSharpClientGenerator.cs b/Rest.Net/RestCSharpClientGenerator.cs index 3da7e4a..6780072 100644 --- a/Rest.Net/RestCSharpClientGenerator.cs +++ b/Rest.Net/RestCSharpClientGenerator.cs @@ -33,7 +33,7 @@ namespace MontoyaTech.Rest.Net var writer = new CodeWriter(); - writer.WriteLine("//Generated using MontoyaTech.Rest.Net"); + writer.WriteLine($"//Generated using MontoyaTech.Rest.Net - {DateTime.Now.ToShortDateString()}"); writer.WriteBreak().WriteLine($"public class {this.ClientName}").WriteLine("{").Indent(); @@ -61,6 +61,12 @@ namespace MontoyaTech.Rest.Net else writer.WriteBreak().WriteLine("public System.Net.Http.HttpClient HttpClient;"); + //Create the request handler field + if (this.StaticCode) + writer.WriteBreak().WriteLine("public static System.Action RequestHandler;"); + else + writer.WriteBreak().WriteLine("public System.Action RequestHandler;"); + //Create fields foreach route group so they can be accessed. if (!this.StaticCode) foreach (var group in routeGroups) @@ -69,7 +75,7 @@ namespace MontoyaTech.Rest.Net //Create the client constructor or init method if (this.StaticCode) { - writer.WriteBreak().WriteLine("public static void Init(string baseUrl, System.Net.Http.HttpMessageHandler handler = null)").WriteLine("{").Indent(); + writer.WriteBreak().WriteLine("public static void Init(string baseUrl, System.Net.Http.HttpMessageHandler messageHandler = null, System.Action requestHandler = null)").WriteLine("{").Indent(); //Make sure the base url isn't null or whitespace writer.WriteBreak().WriteLine("if (string.IsNullOrWhiteSpace(baseUrl))"); @@ -86,9 +92,9 @@ namespace MontoyaTech.Rest.Net writer.WriteBreak().WriteLine($"{this.ClientName}.CookieContainer = new System.Net.CookieContainer();"); //Init the client handler - writer.WriteBreak().WriteLine("if (handler == null)"); + writer.WriteBreak().WriteLine("if (messageHandler == null)"); writer.WriteLine("{").Indent(); - writer.WriteLine($"handler = new System.Net.Http.HttpClientHandler()"); + writer.WriteLine($"messageHandler = new System.Net.Http.HttpClientHandler()"); writer.WriteLine("{").Indent(); writer.WriteLine("AllowAutoRedirect = true,"); writer.WriteLine("UseCookies = true,"); @@ -98,7 +104,10 @@ namespace MontoyaTech.Rest.Net writer.Outdent().WriteLine("}"); //Store the message handler - writer.WriteBreak().WriteLine($"{this.ClientName}.MessageHandler = handler;"); + writer.WriteBreak().WriteLine($"{this.ClientName}.MessageHandler = messageHandler;"); + + //Store the request handler + writer.WriteBreak().WriteLine($"{this.ClientName}.RequestHandler = requestHandler;"); //Init the http client writer.WriteBreak().WriteLine($"{this.ClientName}.HttpClient = new System.Net.Http.HttpClient(handler);"); @@ -110,7 +119,7 @@ namespace MontoyaTech.Rest.Net } else { - writer.WriteBreak().WriteLine($"public {this.ClientName}(string baseUrl, System.Net.Http.HttpMessageHandler handler = null)").WriteLine("{").Indent(); + writer.WriteBreak().WriteLine($"public {this.ClientName}(string baseUrl, System.Net.Http.HttpMessageHandler messageHandler = null, System.Action requestHandler = null)").WriteLine("{").Indent(); //Make sure the base url isn't null or whitespace writer.WriteBreak().WriteLine("if (string.IsNullOrWhiteSpace(baseUrl))"); @@ -127,9 +136,9 @@ namespace MontoyaTech.Rest.Net writer.WriteBreak().WriteLine("this.CookieContainer = new System.Net.CookieContainer();"); //Init the client handler - writer.WriteBreak().WriteLine("if (handler == null)"); + writer.WriteBreak().WriteLine("if (messageHandler == null)"); writer.WriteLine("{").Indent(); - writer.WriteLine("handler = new System.Net.Http.HttpClientHandler()"); + writer.WriteLine("messageHandler = new System.Net.Http.HttpClientHandler()"); writer.WriteLine("{").Indent(); writer.WriteLine("AllowAutoRedirect = true,"); writer.WriteLine("UseCookies = true,"); @@ -139,7 +148,10 @@ namespace MontoyaTech.Rest.Net writer.Outdent().WriteLine("}"); //Store the message handler - writer.WriteBreak().WriteLine("this.MessageHandler = handler;"); + writer.WriteBreak().WriteLine("this.MessageHandler = messageHandler;"); + + //Store the request handler + writer.WriteBreak().WriteLine("this.RequestHandler = requestHandler;"); //Init the http client writer.WriteBreak().WriteLine("this.HttpClient = new System.Net.Http.HttpClient(handler);"); @@ -491,6 +503,12 @@ namespace MontoyaTech.Rest.Net writer.Write('"').WriteLine(");"); + //Invoke the request handler if needed. + if (this.StaticCode) + writer.WriteBreak().WriteLine($"{this.ClientName}.RequestHandler?.Invoke(message);"); + else + writer.WriteBreak().WriteLine($"this.Client.RequestHandler?.Invoke(message);"); + //Add the request content if any. if (routeRequest != null) { diff --git a/Rest.Net/RestJavascriptClientGenerator.cs b/Rest.Net/RestJavascriptClientGenerator.cs index 4d05da7..ccce9ed 100644 --- a/Rest.Net/RestJavascriptClientGenerator.cs +++ b/Rest.Net/RestJavascriptClientGenerator.cs @@ -33,7 +33,7 @@ namespace MontoyaTech.Rest.Net var writer = new CodeWriter(); - writer.WriteLine("//Generated using MontoyaTech.Rest.Net"); + writer.WriteLine($"//Generated using MontoyaTech.Rest.Net - {DateTime.Now.ToShortDateString()}"); writer.WriteBreak().WriteLine($"class {this.ClientName} {{").Indent(); @@ -49,6 +49,17 @@ namespace MontoyaTech.Rest.Net writer.WriteLine("BaseUrl = null;"); } + //Create the request handler field. + if (this.StaticCode) + { + writer.WriteBreak().WriteLine("/** @type {Function} */"); + } + else + { + writer.WriteBreak().WriteLine("/** @type {Function} */"); + + } + //Create fields foreach route group so they can be accessed. if (!this.StaticCode) { @@ -67,7 +78,7 @@ namespace MontoyaTech.Rest.Net writer.WriteLine("Initializes the api client with a given baseUrl of where to send requests."); writer.WriteLine("@param {string} baseUrl"); writer.Outdent().WriteLine("*/"); - writer.Write("static Init(baseUrl) ").WriteLine("{").Indent(); + writer.Write("static Init(baseUrl, requestHandler) ").WriteLine("{").Indent(); //Make sure the baseUrl isn't null or whitespace writer.WriteBreak().WriteLine("if (baseUrl == null || baseUrl == undefined || baseUrl.trim() == '') {").Indent();