@@ -245,13 +245,81 @@ private void OnCancellation() {
245245
246246 async Task OnBeforeTunnelConnectRequest ( object sender , TunnelConnectSessionEventArgs e ) {
247247 // Ensures that only the targeted Https domains are proxyied
248- if ( ! IsProxiedHost ( e . HttpClient . Request . RequestUri . Host ) ) {
248+ if ( ! IsProxiedHost ( e . HttpClient . Request . RequestUri . Host ) ||
249+ ! IsProxiedProcess ( e ) ) {
249250 e . DecryptSsl = false ;
250251 }
251252 await Task . CompletedTask ;
252253 }
253254
254- async Task OnRequest ( object sender , SessionEventArgs e ) {
255+ private int GetProcessId ( TunnelConnectSessionEventArgs e )
256+ {
257+ if ( RunTime . IsWindows ) {
258+ return e . HttpClient . ProcessId . Value ;
259+ }
260+
261+ var psi = new ProcessStartInfo {
262+ FileName = "lsof" ,
263+ Arguments = $ "-i :{ e . ClientRemoteEndPoint . Port } ",
264+ UseShellExecute = false ,
265+ RedirectStandardOutput = true ,
266+ CreateNoWindow = true
267+ } ;
268+ var proc = new Process {
269+ StartInfo = psi
270+ } ;
271+ proc . Start ( ) ;
272+ var output = proc . StandardOutput . ReadToEnd ( ) ;
273+ proc . WaitForExit ( ) ;
274+
275+ var lines = output . Split ( new [ ] { Environment . NewLine } , StringSplitOptions . RemoveEmptyEntries ) ;
276+ var matchingLine = lines . FirstOrDefault ( l => l . Contains ( $ "{ e . ClientRemoteEndPoint . Port } ->") ) ;
277+ if ( matchingLine is null ) {
278+ return - 1 ;
279+ }
280+ var pidString = Regex . Matches ( matchingLine , @"^.*?\s+(\d+)" ) ? . FirstOrDefault ( ) ? . Groups [ 1 ] ? . Value ;
281+ if ( pidString is null ) {
282+ return - 1 ;
283+ }
284+
285+ var pid = - 1 ;
286+ if ( int . TryParse ( pidString , out pid ) )
287+ {
288+ return pid ;
289+ }
290+ else {
291+ return - 1 ;
292+ }
293+ }
294+
295+ private bool IsProxiedProcess ( TunnelConnectSessionEventArgs e ) {
296+ // If no process names or IDs are specified, we proxy all processes
297+ if ( ! _config . WatchPids . Any ( ) &&
298+ ! _config . WatchProcessNames . Any ( ) ) {
299+ return true ;
300+ }
301+
302+ var processId = GetProcessId ( e ) ;
303+ if ( processId == - 1 ) {
304+ return false ;
305+ }
306+
307+ if ( _config . WatchPids . Any ( ) &&
308+ _config . WatchPids . Contains ( processId ) ) {
309+ return true ;
310+ }
311+
312+ if ( _config . WatchProcessNames . Any ( ) ) {
313+ var processName = Process . GetProcessById ( processId ) . ProcessName ;
314+ if ( _config . WatchProcessNames . Contains ( processName ) ) {
315+ return true ;
316+ }
317+ }
318+
319+ return false ;
320+ }
321+
322+ async Task OnRequest ( object sender , SessionEventArgs e ) {
255323 var method = e . HttpClient . Request . Method . ToUpper ( ) ;
256324 // The proxy does not intercept or alter OPTIONS requests
257325 if ( method is not "OPTIONS" && IsProxiedHost ( e . HttpClient . Request . RequestUri . Host ) ) {
@@ -276,6 +344,7 @@ private void HandleRequest(SessionEventArgs e) {
276344
277345 private bool IsProxiedHost ( string hostName ) => _hostsToWatch . Any ( h => h . IsMatch ( hostName ) ) ;
278346
347+
279348 // Modify response
280349 async Task OnBeforeResponse ( object sender , SessionEventArgs e ) {
281350 // read response headers
0 commit comments