11// Copyright (c) Martin Costello, 2024. All rights reserved.
22// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
33
4+ using System . Net ;
45using System . Security . Cryptography . X509Certificates ;
56using Microsoft . AspNetCore . Hosting ;
6- using Microsoft . AspNetCore . Hosting . Server ;
7- using Microsoft . AspNetCore . Hosting . Server . Features ;
8- using Microsoft . Extensions . DependencyInjection ;
9- using Microsoft . Extensions . Hosting ;
107
118namespace TodoApp ;
129
@@ -16,98 +13,22 @@ namespace TodoApp;
1613/// </summary>
1714public sealed class HttpServerFixture : TodoAppFixture
1815{
19- private bool _disposed ;
20- private IHost ? _host ;
21-
22- public string ServerAddress
16+ public HttpServerFixture ( )
2317 {
24- get
25- {
26- EnsureServer ( ) ;
27- return ClientOptions . BaseAddress . ToString ( ) ;
28- }
18+ // Configure the address for the server to listen on for HTTPS
19+ // requests on a dynamic port. with a self-signed TLS certificate.
20+ UseKestrel (
21+ ( server ) => server . Listen (
22+ IPAddress . Loopback , 0 , ( listener ) => listener . UseHttps (
23+ ( https ) => https . ServerCertificate = X509CertificateLoader . LoadPkcs12FromFile ( "localhost-dev.pfx" , "Pa55w0rd!" ) ) ) ) ;
2924 }
3025
31- public override IServiceProvider Services
26+ public string ServerAddress
3227 {
3328 get
3429 {
35- EnsureServer ( ) ;
36- return _host ! . Services ! ;
37- }
38- }
39-
40- protected override void ConfigureWebHost ( IWebHostBuilder builder )
41- {
42- base . ConfigureWebHost ( builder ) ;
43-
44- // Configure a self-signed TLS certificate for HTTPS
45- builder . ConfigureKestrel (
46- serverOptions => serverOptions . ConfigureHttpsDefaults (
47- httpsOptions => X509CertificateLoader . LoadPkcs12FromFile ( "localhost-dev.pfx" , "Pa55w0rd!" ) ) ) ;
48-
49- // Configure the server address for the server to
50- // listen on for HTTPS requests on a dynamic port.
51- builder . UseUrls ( "https://127.0.0.1:0" ) ;
52- }
53-
54- protected override IHost CreateHost ( IHostBuilder builder )
55- {
56- // Create the host for TestServer now before we
57- // modify the builder to use Kestrel instead.
58- var testHost = builder . Build ( ) ;
59-
60- // Modify the host builder to use Kestrel instead
61- // of TestServer so we can listen on a real address.
62- builder . ConfigureWebHost ( webHostBuilder => webHostBuilder . UseKestrel ( ) ) ;
63-
64- // Create and start the Kestrel server before the test server,
65- // otherwise due to the way the deferred host builder works
66- // for minimal hosting, the server will not get "initialized
67- // enough" for the address it is listening on to be available.
68- // See https://github.com/dotnet/aspnetcore/issues/33846.
69- _host = builder . Build ( ) ;
70- _host . Start ( ) ;
71-
72- // Extract the selected dynamic port out of the Kestrel server
73- // and assign it onto the client options for convenience so it
74- // "just works" as otherwise it'll be the default http://localhost
75- // URL, which won't route to the Kestrel-hosted HTTP server.
76- var server = _host . Services . GetRequiredService < IServer > ( ) ;
77- var addresses = server . Features . Get < IServerAddressesFeature > ( ) ;
78-
79- ClientOptions . BaseAddress = addresses ! . Addresses
80- . Select ( x => new Uri ( x ) )
81- . Last ( ) ;
82-
83- // Return the host that uses TestServer, rather than the real one.
84- // Otherwise the internals will complain about the host's server
85- // not being an instance of the concrete type TestServer.
86- // See https://github.com/dotnet/aspnetcore/pull/34702.
87- return testHost ;
88- }
89-
90- protected override void Dispose ( bool disposing )
91- {
92- base . Dispose ( disposing ) ;
93-
94- if ( ! _disposed )
95- {
96- if ( disposing )
97- {
98- _host ? . Dispose ( ) ;
99- }
100-
101- _disposed = true ;
102- }
103- }
104-
105- private void EnsureServer ( )
106- {
107- if ( _host is null )
108- {
109- // This forces WebApplicationFactory to bootstrap the server
110- using var _ = CreateDefaultClient ( ) ;
30+ StartServer ( ) ;
31+ return ClientOptions . BaseAddress . ToString ( ) ;
11132 }
11233 }
11334}
0 commit comments