dev.core.tunnel.psm1
Import-Module "$PSScriptRoot\dev.core.utils.psm1" -DisableNameChecking; $TunnelAppFolder = "$Home\AppData\Local\DevPowerShell\dev.core.tunnel"; $TunnelPackagesFolder = "${TunnelAppFolder}\packages"; $TunnelAppVersion = "1.0.0"; # # Private functions # function Install-TunnelApp { [CmdletBinding()] param (); $TunnelAppPath = "$TunnelPackagesFolder\HttpTunnel.${TunnelAppVersion}"; if (!(Test-Path -Path $TunnelAppPath -PathType Container)) { Write-Verbose "Installing http tunnel $TunnelAppVersion..."; $DownloadLink = "https://github.com/Yaming-Hub/HttpTunnel/raw/main/file/HttpTunnel.${TunnelAppVersion}.nupkg"; Invoke-WebRequest -Uri $DownloadLink -Method Get -OutFile "$TunnelPackagesFolder\HttpTunnel.${TunnelAppVersion}.zip"; Expand-Archive -Path "$TunnelPackagesFolder\HttpTunnel.${TunnelAppVersion}.zip" -DestinationPath "$TunnelPackagesFolder\HttpTunnel.${TunnelAppVersion}"; } } <# { "Forward": { "TunnelHost": "localhost", "TunnelPort": 6000, "Apps": [F { "Port": 6001, "Path": "/F" } ], "UrlReplaceRules": [ { "Name": "Replace :6001/B to :7001/B", "Pattern": "https://localhost:6001/B", "Replacement": "https://localhost:7001/B" } ] }, "Backward": { "TunnelPort": 6000, "Apps": [ { "Port": 6001, "Path": "/B" } ], "UrlReplaceRules": [ { "Name": "Replace :6001/F to :7001/F", "Pattern": "https://localhost:6001/F", "Replacement": "https://localhost:7001/F" } ] } } #> function New-TunnelSetting { [CmdletBinding()] param([Parameter(Mandatory=$true)][int]$TunnelPort); $setting = [PSCustomObject]@{ TunnelPort = $TunnelPort; Apps = @(); UrlReplaceRules = @(); }; $setting.PSTypeNames.Insert(0, "Tunnel.Setting"); return $setting; } # # Public functions # function New-TunnelForwardSetting { [CmdletBinding()] param( [Parameter(Mandatory=$true)][string]$TunnelHost, [Parameter(Mandatory=$true)][int]$TunnelPort); $setting = New-TunnelSetting -TunnelPort $TunnelPort; $setting | Add-Member -MemberType NoteProperty -Name "TunnelHost" -Value $TunnelHost | Out-Null; $setting.PSTypeNames.Insert(0, "Tunnel.ForwardSetting"); return $setting; } function New-TunnelBackwardSetting { [CmdletBinding()] param([Parameter(Mandatory=$true)][int]$TunnelPort); $setting = New-TunnelSetting -TunnelPort $TunnelPort; $setting.PSTypeNames.Insert(0, "Tunnel.BackwardSetting"); return $setting; } function Add-TunnelApp { [CmdletBinding()] param( [Parameter(Mandatory=$true, ValueFromPipeline=$true)][PSTypeName("Tunnel.Setting")]$Setting, [int]$Port, [string]$Path); # Normalize the path to "/", "/Path", "/The/Path" format. if (!$Path) { $Path = "/"; } elseif (!$Path.StartsWith("/")) { $Path = "/" + $Path; } if ($Path -ne "/") { $Path = $Path.TrimEnd("/"); } $setting.Apps += [PSCustomObject]@{ Port = $Port; Path = $Path }; return $setting; } function Add-TunnelReplaceRule { [CmdletBinding()] param( [Parameter(Mandatory=$true, ValueFromPipeline=$true)][PSTypeName("Tunnel.Setting")]$Setting, [string]$Name, [string]$Pattern, [string]$Replacement); $setting.UrlReplaceRules += [PSCustomObject]@{ Name = $Name; Pattern = $Pattern; Replacement = $Replacement }; return $setting; } function Start-Tunnel { [CmdletBinding()] param( [PSTypeName("Tunnel.ForwardSetting")]$ForwardSettings, [PSTypeName("Tunnel.BackwardSetting")]$BackwardSettings, [Parameter(Mandatory=$true)][string]$Path, [switch]$PauseOnStart ); if (!$ForwardSettings -and !$BackwardSettings) { throw "Neither ForwardSettings nor BackwardSettings is specified"; } $ExecutionGuid = New-Guid; $ExecutionPath = "$Path\$ExecutionGuid"; $ExecutionAppPath = "$Path\$ExecutionGuid\app"; $ExecutionDataPath = "$Path\$ExecutionGuid\data"; $TunnelAppPath = "$TunnelPackagesFolder\HttpTunnel.${TunnelAppVersion}"; New-Item -Path $ExecutionAppPath -ItemType Container -Force | Out-Null; New-Item -Path $ExecutionDataPath -ItemType Container -Force | Out-Null; # Copy execution file under. Copy-Item -Path "$TunnelAppPath\lib\net5.0\*.*" -Destination $ExecutionAppPath; # Generate appsettings.json file $mode = @() if ($BackwardSettings) { $mode += "backward" }; if ($ForwardSettings) { $mode += "forward" }; $ShouldPauseOnStart = if ($PauseOnStart) { $true } else { $false }; $Settings = [PSCustomObject]@{ "PauseOnStart" = $ShouldPauseOnStart; "mode" = ($mode -join ","); "Forward" = $ForwardSettings; "BackwardSettings" = $BackwardSettings; }; $appSettingsJson = ConvertTo-Json -InputObject $Settings -Depth 32; Set-Content -Path "$ExecutionAppPath\appsettings.json" -Value $appSettingsJson; $cmd = "${env:SystemRoot}\System32\cmd.exe"; Write-Host "Execution Path: $ExecutionAppPath"; Start-Process -FilePath $cmd -ArgumentList @("/c", "dotnet.exe", "$ExecutionAppPath\httptunnel.dll") -WorkingDirectory $ExecutionAppPath; } # # Module Initialization # New-DirectoryIfNotExist -Path $TunnelPackagesFolder | Out-Null; Install-TunnelApp; <# Test script $ForwardSettings = New-TunnelForwardSetting -TunnelHost 10.68.32.200 -TunnelPort 444 ` | Add-TunnelApp -Port 444 -Path "/sts" ` | Add-TunnelApp -Port 444 -Path "/dsapi" ` | Add-TunnelApp -Port 444 -Path "/actions" ` | Add-TunnelApp -Port 444 -Path "/DWEngineV2B2" ` | Add-TunnelApp -Port 444 -Path "/ecp" ` | Add-TunnelApp -Port 444 -Path "/swss" ` | Add-TunnelApp -Port 444 -Path "/search" ` | Add-TunnelApp -Port 444 -Path "/TaskEnrichment" ` | Add-TunnelApp -Port 444 -Path "/userknowledgebase" ` | Add-TunnelReplaceRule -Name ExchangelabsToLocalhost -Pattern "https://exchangelabs\.live-int\.com" -Replacement "https://localhost" ` | Add-TunnelReplaceRule -Name 443To444 -Pattern "https://([\w\d\.\-_]+)(:443)?/" -Replacement "https://`$1:444/"; $BackwardSettings = New-TunnelBackwardSetting -TunnelPort 444 ` | Add-TunnelApp -Port 444 -Path "/WeveNovaB2" ` | Add-TunnelReplaceRule -Name LocalhostToExchangelabs -Pattern "https://localhost" -Replacement "https://exchangelabs.live-int.com"; Run-Tunnel -ForwardSettings $ForwardSettings #> Export-ModuleMember -Function New-TunnelForwardSetting; Export-ModuleMember -Function New-TunnelBackwardSetting; Export-ModuleMember -Function Add-TunnelApp; Export-ModuleMember -Function Add-TunnelReplaceRule Export-ModuleMember -Function Start-Tunnel; |