diff --git a/src/Tgstation.Server.Host/Utils/GitHub/GitHubClientFactory.cs b/src/Tgstation.Server.Host/Utils/GitHub/GitHubClientFactory.cs index a424e1b4d5..2a1554f0e9 100644 --- a/src/Tgstation.Server.Host/Utils/GitHub/GitHubClientFactory.cs +++ b/src/Tgstation.Server.Host/Utils/GitHub/GitHubClientFactory.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Linq; +using System.Net.Http; using System.Security.Cryptography; using System.Text; using System.Threading; @@ -12,6 +13,7 @@ using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using Octokit; +using Octokit.Internal; using Tgstation.Server.Api.Models; using Tgstation.Server.Host.Configuration; @@ -38,6 +40,11 @@ namespace Tgstation.Server.Host.Utils.GitHub /// readonly IAssemblyInformationProvider assemblyInformationProvider; + /// + /// The for the . + /// + readonly IHttpMessageHandlerFactory httpMessageHandlerFactory; + /// /// The for the . /// @@ -62,14 +69,17 @@ namespace Tgstation.Server.Host.Utils.GitHub /// Initializes a new instance of the class. /// /// The value of . + /// The value of . /// The value of . /// The containing the value of . public GitHubClientFactory( IAssemblyInformationProvider assemblyInformationProvider, + IHttpMessageHandlerFactory httpMessageHandlerFactory, ILogger logger, IOptions generalConfigurationOptions) { this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider)); + this.httpMessageHandlerFactory = httpMessageHandlerFactory ?? throw new ArgumentNullException(nameof(httpMessageHandlerFactory)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); @@ -315,10 +325,33 @@ namespace Tgstation.Server.Host.Utils.GitHub GitHubClient CreateUnauthenticatedClient() { var product = assemblyInformationProvider.ProductInfoHeaderValue.Product!; - return new GitHubClient( - new ProductHeaderValue( - product.Name, - product.Version)); +#pragma warning disable CA2000 // Dispose objects before losing scope + var handler = httpMessageHandlerFactory.CreateHandler(); + try + { + var clientAdapter = new HttpClientAdapter(() => handler); +#pragma warning restore CA2000 // Dispose objects before losing scope + handler = null; + try + { + return new GitHubClient( + new Connection( + new ProductHeaderValue( + product.Name, + product.Version), + clientAdapter)); + } + catch + { + clientAdapter.Dispose(); + throw; + } + } + catch + { + handler?.Dispose(); + throw; + } } } } diff --git a/tests/Tgstation.Server.Host.Tests/BasicHttpMessageHandlerFactory.cs b/tests/Tgstation.Server.Host.Tests/BasicHttpMessageHandlerFactory.cs new file mode 100644 index 0000000000..94dd57d3ea --- /dev/null +++ b/tests/Tgstation.Server.Host.Tests/BasicHttpMessageHandlerFactory.cs @@ -0,0 +1,19 @@ +using System; +using System.Net.Http; + +namespace Tgstation.Server.Host.Tests +{ + /// + /// Basic implementation for testiong + /// + public sealed class BasicHttpMessageHandlerFactory : IHttpMessageHandlerFactory, IDisposable + { + readonly HttpClientHandler handler = new(); + + public HttpMessageHandler CreateHandler(string name) + => handler; + + public void Dispose() + => handler.Dispose(); + } +} diff --git a/tests/Tgstation.Server.Host.Tests/Utils/GitHub/TestGitHubClientFactory.cs b/tests/Tgstation.Server.Host.Tests/Utils/GitHub/TestGitHubClientFactory.cs index 5132f8ab01..01bb7bac1f 100644 --- a/tests/Tgstation.Server.Host.Tests/Utils/GitHub/TestGitHubClientFactory.cs +++ b/tests/Tgstation.Server.Host.Tests/Utils/GitHub/TestGitHubClientFactory.cs @@ -1,4 +1,5 @@ using System; +using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading; @@ -15,6 +16,7 @@ using Octokit; using Tgstation.Server.Api.Models; using Tgstation.Server.Host.Configuration; using Tgstation.Server.Host.System; +using Tgstation.Server.Host.Tests; namespace Tgstation.Server.Host.Utils.GitHub.Tests { @@ -42,9 +44,10 @@ namespace Tgstation.Server.Host.Utils.GitHub.Tests [TestMethod] public void TestContructionThrows() { - Assert.ThrowsException(() => new GitHubClientFactory(null, null, null)); - Assert.ThrowsException(() => new GitHubClientFactory(Mock.Of(), null, null)); - Assert.ThrowsException(() => new GitHubClientFactory(Mock.Of(), Mock.Of>(), null)); + Assert.ThrowsException(() => new GitHubClientFactory(null, null, null, null)); + Assert.ThrowsException(() => new GitHubClientFactory(Mock.Of(), null, null, null)); + Assert.ThrowsException(() => new GitHubClientFactory(Mock.Of(), Mock.Of(), null, null)); + Assert.ThrowsException(() => new GitHubClientFactory(Mock.Of(), Mock.Of(), Mock.Of>(), null)); } [TestMethod] @@ -58,7 +61,7 @@ namespace Tgstation.Server.Host.Utils.GitHub.Tests var gc = new GeneralConfiguration(); Assert.IsNull(gc.GitHubAccessToken); mockOptions.SetupGet(x => x.Value).Returns(gc); - var factory = new GitHubClientFactory(mockApp.Object, loggerFactory.CreateLogger(), mockOptions.Object); + var factory = new GitHubClientFactory(mockApp.Object, new BasicHttpMessageHandlerFactory(), loggerFactory.CreateLogger(), mockOptions.Object); var client = await factory.CreateClient(CancellationToken.None); Assert.IsNotNull(client); @@ -84,7 +87,7 @@ namespace Tgstation.Server.Host.Utils.GitHub.Tests var mockOptions = new Mock>(); mockOptions.SetupGet(x => x.Value).Returns(new GeneralConfiguration()); - var factory = new GitHubClientFactory(mockApp.Object, loggerFactory.CreateLogger(), mockOptions.Object); + var factory = new GitHubClientFactory(mockApp.Object, new BasicHttpMessageHandlerFactory(), loggerFactory.CreateLogger(), mockOptions.Object); await Assert.ThrowsExceptionAsync(() => factory.CreateClient(null, CancellationToken.None).AsTask()); @@ -106,7 +109,7 @@ namespace Tgstation.Server.Host.Utils.GitHub.Tests var mockOptions = new Mock>(); mockOptions.SetupGet(x => x.Value).Returns(new GeneralConfiguration()); - var factory = new GitHubClientFactory(mockApp.Object, loggerFactory.CreateLogger(), mockOptions.Object); + var factory = new GitHubClientFactory(mockApp.Object, new BasicHttpMessageHandlerFactory(), loggerFactory.CreateLogger(), mockOptions.Object); var appID = Environment.GetEnvironmentVariable("TGS_TEST_APP_ID"); var privateKey = Environment.GetEnvironmentVariable("TGS_TEST_APP_PRIVATE_KEY"); @@ -144,7 +147,7 @@ namespace Tgstation.Server.Host.Utils.GitHub.Tests var mockOptions = new Mock>(); mockOptions.SetupGet(x => x.Value).Returns(new GeneralConfiguration()); - var factory = new GitHubClientFactory(mockApp.Object, loggerFactory.CreateLogger(), mockOptions.Object); + var factory = new GitHubClientFactory(mockApp.Object, new BasicHttpMessageHandlerFactory(), loggerFactory.CreateLogger(), mockOptions.Object); await Assert.ThrowsExceptionAsync(() => factory.CreateClient(null, CancellationToken.None).AsTask()); @@ -192,7 +195,7 @@ vTdVAoGBAI/jjUMdjkY43zhe3w2piwT0fhGfqm9ikdAB9IcgcptuS0ML0ZaWV/eO var mockOptions = new Mock>(); mockOptions.SetupGet(x => x.Value).Returns(new GeneralConfiguration()); - var factory = new GitHubClientFactory(mockApp.Object, loggerFactory.CreateLogger(), mockOptions.Object); + var factory = new GitHubClientFactory(mockApp.Object, new BasicHttpMessageHandlerFactory(), loggerFactory.CreateLogger(), mockOptions.Object); var client1 = await factory.CreateClient(CancellationToken.None); var client2 = await factory.CreateClient("asdf", CancellationToken.None); diff --git a/tests/Tgstation.Server.Tests/Live/TestingGitHubService.cs b/tests/Tgstation.Server.Tests/Live/TestingGitHubService.cs index 585dd56999..48434bd142 100644 --- a/tests/Tgstation.Server.Tests/Live/TestingGitHubService.cs +++ b/tests/Tgstation.Server.Tests/Live/TestingGitHubService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net.Http; using System.Threading; using System.Threading.Tasks; @@ -38,7 +39,7 @@ namespace Tgstation.Server.Tests.Live GitHubAccessToken = Environment.GetEnvironmentVariable("TGS_TEST_GITHUB_TOKEN") }); - var gitHubClientFactory = new GitHubClientFactory(new AssemblyInformationProvider(), Mock.Of>(), mockOptions.Object); + var gitHubClientFactory = new GitHubClientFactory(new AssemblyInformationProvider(), Mock.Of(), Mock.Of>(), mockOptions.Object); RealClient = gitHubClientFactory.CreateClient(CancellationToken.None).GetAwaiter().GetResult(); } diff --git a/tests/Tgstation.Server.Tests/Tgstation.Server.Tests.csproj b/tests/Tgstation.Server.Tests/Tgstation.Server.Tests.csproj index 32edf3de15..342d841f8e 100644 --- a/tests/Tgstation.Server.Tests/Tgstation.Server.Tests.csproj +++ b/tests/Tgstation.Server.Tests/Tgstation.Server.Tests.csproj @@ -13,6 +13,7 @@ +