11// Copyright (c) Microsoft Corporation.
22// Licensed under the MIT License.
33
4- using Microsoft . Extensions . Configuration ;
5- using Microsoft . Extensions . Logging ;
64using Microsoft . DevProxy . Abstractions ;
75using System . CommandLine ;
86using System . CommandLine . Invocation ;
97
10- namespace Microsoft . DevProxy ;
8+ namespace Microsoft . DevProxy . CommandHandlers ;
119
1210public class ProxyCommandHandler : ICommandHandler
1311{
14- private readonly PluginEvents _pluginEvents ;
12+ private readonly IPluginEvents _pluginEvents ;
1513 private readonly Option [ ] _options ;
1614 private readonly ISet < UrlToWatch > _urlsToWatch ;
1715 private readonly ILogger _logger ;
1816
19- public ProxyCommandHandler ( PluginEvents pluginEvents ,
17+ public static ProxyConfiguration Configuration { get => ConfigurationFactory . Value ; }
18+
19+ public ProxyCommandHandler ( IPluginEvents pluginEvents ,
2020 Option [ ] options ,
2121 ISet < UrlToWatch > urlsToWatch ,
2222 ILogger logger )
@@ -33,6 +33,73 @@ public int Invoke(InvocationContext context)
3333 }
3434
3535 public async Task < int > InvokeAsync ( InvocationContext context )
36+ {
37+ ParseOptions ( context ) ;
38+ _pluginEvents . RaiseOptionsLoaded ( new OptionsLoadedArgs ( context , _options ) ) ;
39+ await CheckForNewVersion ( ) ;
40+
41+ try
42+ {
43+ var builder = WebApplication . CreateBuilder ( ) ;
44+ builder . Logging . AddFilter ( "Microsoft.Hosting.*" , LogLevel . Error ) ;
45+ builder . Logging . AddFilter ( "Microsoft.AspNetCore.*" , LogLevel . Error ) ;
46+
47+ builder . Services . AddSingleton < IProxyState , ProxyState > ( ) ;
48+ builder . Services . AddSingleton < IProxyConfiguration , ProxyConfiguration > ( sp => ConfigurationFactory . Value ) ;
49+ builder . Services . AddSingleton ( _pluginEvents ) ;
50+ builder . Services . AddSingleton ( _logger ) ;
51+ builder . Services . AddSingleton ( _urlsToWatch ) ;
52+ builder . Services . AddHostedService < ProxyEngine > ( ) ;
53+
54+ builder . Services . AddControllers ( ) ;
55+ builder . Services . AddEndpointsApiExplorer ( ) ;
56+ builder . Services . AddSwaggerGen ( ) ;
57+
58+ builder . Services . Configure < RouteOptions > ( options =>
59+ {
60+ options . LowercaseUrls = true ;
61+ } ) ;
62+
63+ builder . WebHost . ConfigureKestrel ( options =>
64+ {
65+ options . ListenLocalhost ( ConfigurationFactory . Value . ApiPort ) ;
66+ _logger . LogInformation ( "Dev Proxy API listening on http://localhost:{Port}..." , ConfigurationFactory . Value . ApiPort ) ;
67+ } ) ;
68+
69+ var app = builder . Build ( ) ;
70+
71+ if ( app . Environment . IsDevelopment ( ) )
72+ {
73+ app . UseSwagger ( ) ;
74+ app . UseSwaggerUI ( ) ;
75+ }
76+
77+ app . MapControllers ( ) ;
78+ app . Run ( ) ;
79+
80+
81+ return 0 ;
82+ }
83+ catch ( Exception ex )
84+ {
85+ _logger . LogError ( ex , "An error occurred while running Dev Proxy" ) ;
86+ var inner = ex . InnerException ;
87+
88+ while ( inner is not null )
89+ {
90+ _logger . LogError ( inner , "============ Inner exception ============" ) ;
91+ inner = inner . InnerException ;
92+ }
93+ #if DEBUG
94+ throw ; // so debug tools go straight to the source of the exception when attached
95+ #else
96+ return 1 ;
97+ #endif
98+ }
99+
100+ }
101+
102+ private void ParseOptions ( InvocationContext context )
36103 {
37104 var port = context . ParseResult . GetValueForOption < int ? > ( ProxyHost . PortOptionName , _options ) ;
38105 if ( port is not null )
@@ -79,11 +146,10 @@ public async Task<int> InvokeAsync(InvocationContext context)
79146 {
80147 Configuration . InstallCert = installCert . Value ;
81148 }
149+ }
82150
83- CancellationToken ? cancellationToken = ( CancellationToken ? ) context . BindingContext . GetService ( typeof ( CancellationToken ? ) ) ;
84-
85- _pluginEvents . RaiseOptionsLoaded ( new OptionsLoadedArgs ( context , _options ) ) ;
86-
151+ private async Task CheckForNewVersion ( )
152+ {
87153 var newReleaseInfo = await UpdateNotification . CheckForNewVersion ( Configuration . NewVersionNotification ) ;
88154 if ( newReleaseInfo != null )
89155 {
@@ -93,39 +159,14 @@ public async Task<int> InvokeAsync(InvocationContext context)
93159 Environment . NewLine
94160 ) ;
95161 }
96-
97- try
98- {
99- await new ProxyEngine ( Configuration , _urlsToWatch , _pluginEvents , _logger ) . Run ( cancellationToken ) ;
100- return 0 ;
101- }
102- catch ( Exception ex )
103- {
104- _logger . LogError ( ex , "An error occurred while running Dev Proxy" ) ;
105- var inner = ex . InnerException ;
106-
107- while ( inner is not null )
108- {
109- _logger . LogError ( inner , "============ Inner exception ============" ) ;
110- inner = inner . InnerException ;
111- }
112- #if DEBUG
113- throw ; // so debug tools go straight to the source of the exception when attached
114- #else
115- return 1 ;
116- #endif
117- }
118-
119162 }
120163
121- public static ProxyConfiguration Configuration { get => ConfigurationFactory . Value ; }
122-
123164 private static readonly Lazy < ProxyConfiguration > ConfigurationFactory = new ( ( ) =>
124165 {
125166 var builder = new ConfigurationBuilder ( ) ;
126167 var configuration = builder
127- . AddJsonFile ( ProxyHost . ConfigFile , optional : true , reloadOnChange : true )
128- . Build ( ) ;
168+ . AddJsonFile ( ProxyHost . ConfigFile , optional : true , reloadOnChange : true )
169+ . Build ( ) ;
129170 var configObject = new ProxyConfiguration ( ) ;
130171 configuration . Bind ( configObject ) ;
131172
0 commit comments