|
| 1 | +#requires -version 5.0 |
| 2 | +<# |
| 3 | + BrowserStack Proxy Detection and Validation |
| 4 | + - Detects proxy from environment variables |
| 5 | + - Tests BrowserStack API connectivity through proxy |
| 6 | + - Exports PROXY_HOST and PROXY_PORT if successful |
| 7 | +#> |
| 8 | + |
| 9 | +param( |
| 10 | + [string]$BrowserStackUsername, |
| 11 | + [string]$BrowserStackAccessKey |
| 12 | +) |
| 13 | + |
| 14 | +$ErrorActionPreference = 'Continue' |
| 15 | + |
| 16 | +# Test URL for connectivity check |
| 17 | +$TEST_URL = "https://www.browserstack.com/automate/browsers.json" |
| 18 | + |
| 19 | +# Function to parse proxy URL |
| 20 | +function Parse-ProxyUrl { |
| 21 | + param([string]$ProxyUrl) |
| 22 | + |
| 23 | + if ([string]::IsNullOrWhiteSpace($ProxyUrl)) { |
| 24 | + return $null |
| 25 | + } |
| 26 | + |
| 27 | + # Remove protocol (http:// or https://) |
| 28 | + $cleaned = $ProxyUrl -replace '^https?://', '' |
| 29 | + |
| 30 | + # Remove credentials if present (user:pass@) |
| 31 | + if ($cleaned -match '@') { |
| 32 | + $cleaned = $cleaned.Substring($cleaned.IndexOf('@') + 1) |
| 33 | + } |
| 34 | + |
| 35 | + # Extract host and port |
| 36 | + if ($cleaned -match '^([^:]+):(\d+)') { |
| 37 | + return @{ |
| 38 | + Host = $matches[1] |
| 39 | + Port = $matches[2] |
| 40 | + } |
| 41 | + } elseif ($cleaned -match '^([^:]+)') { |
| 42 | + # No port specified, use default |
| 43 | + return @{ |
| 44 | + Host = $matches[1] |
| 45 | + Port = "8080" # default proxy port |
| 46 | + } |
| 47 | + } |
| 48 | + |
| 49 | + return $null |
| 50 | +} |
| 51 | + |
| 52 | +# Detect proxy from environment variables (case-insensitive) |
| 53 | +$PROXY = $env:http_proxy |
| 54 | +if ([string]::IsNullOrWhiteSpace($PROXY)) { $PROXY = $env:HTTP_PROXY } |
| 55 | +if ([string]::IsNullOrWhiteSpace($PROXY)) { $PROXY = $env:https_proxy } |
| 56 | +if ([string]::IsNullOrWhiteSpace($PROXY)) { $PROXY = $env:HTTPS_PROXY } |
| 57 | + |
| 58 | +# Reset output variables |
| 59 | +$env:PROXY_HOST = "" |
| 60 | +$env:PROXY_PORT = "" |
| 61 | + |
| 62 | +# If no proxy configured, exit early |
| 63 | +if ([string]::IsNullOrWhiteSpace($PROXY)) { |
| 64 | + Write-Host "No proxy found in environment. Clearing proxy host and port variables." |
| 65 | + $env:PROXY_HOST = "" |
| 66 | + $env:PROXY_PORT = "" |
| 67 | + exit 0 |
| 68 | +} |
| 69 | + |
| 70 | +Write-Host "Proxy detected: $PROXY" |
| 71 | + |
| 72 | +# Parse proxy URL |
| 73 | +$proxyInfo = Parse-ProxyUrl -ProxyUrl $PROXY |
| 74 | +if (-not $proxyInfo) { |
| 75 | + Write-Host "❌ Failed to parse proxy URL: $PROXY" |
| 76 | + $env:PROXY_HOST = "" |
| 77 | + $env:PROXY_PORT = "" |
| 78 | + exit 1 |
| 79 | +} |
| 80 | + |
| 81 | +Write-Host "Testing reachability via proxy..." |
| 82 | +Write-Host " Proxy Host: $($proxyInfo.Host)" |
| 83 | +Write-Host " Proxy Port: $($proxyInfo.Port)" |
| 84 | + |
| 85 | +# Encode BrowserStack credentials in Base64 |
| 86 | +$base64Creds = "" |
| 87 | +if (-not [string]::IsNullOrWhiteSpace($BrowserStackUsername) -and |
| 88 | + -not [string]::IsNullOrWhiteSpace($BrowserStackAccessKey)) { |
| 89 | + $pair = "${BrowserStackUsername}:${BrowserStackAccessKey}" |
| 90 | + $bytes = [System.Text.Encoding]::UTF8.GetBytes($pair) |
| 91 | + $base64Creds = [System.Convert]::ToBase64String($bytes) |
| 92 | +} |
| 93 | + |
| 94 | +# Test connectivity through proxy |
| 95 | +try { |
| 96 | + $proxyUri = "http://$($proxyInfo.Host):$($proxyInfo.Port)" |
| 97 | + |
| 98 | + # Create web request with proxy |
| 99 | + $webProxy = New-Object System.Net.WebProxy($proxyUri) |
| 100 | + $webClient = New-Object System.Net.WebClient |
| 101 | + $webClient.Proxy = $webProxy |
| 102 | + |
| 103 | + # Add authorization header if credentials provided |
| 104 | + if (-not [string]::IsNullOrWhiteSpace($base64Creds)) { |
| 105 | + $webClient.Headers.Add("Authorization", "Basic $base64Creds") |
| 106 | + } |
| 107 | + |
| 108 | + # Attempt to download (with timeout) |
| 109 | + $null = $webClient.DownloadString($TEST_URL) |
| 110 | + |
| 111 | + # If we reach here, the request succeeded |
| 112 | + Write-Host "✅ Reachable. HTTP 200" |
| 113 | + Write-Host "Exporting PROXY_HOST=$($proxyInfo.Host)" |
| 114 | + Write-Host "Exporting PROXY_PORT=$($proxyInfo.Port)" |
| 115 | + |
| 116 | + $env:PROXY_HOST = $proxyInfo.Host |
| 117 | + $env:PROXY_PORT = $proxyInfo.Port |
| 118 | + |
| 119 | + exit 0 |
| 120 | + |
| 121 | +} catch { |
| 122 | + $statusCode = "Unknown" |
| 123 | + if ($_.Exception.InnerException -and $_.Exception.InnerException.Response) { |
| 124 | + $statusCode = [int]$_.Exception.InnerException.Response.StatusCode |
| 125 | + } |
| 126 | + |
| 127 | + Write-Host "❌ Not reachable (HTTP $statusCode). Clearing variables." |
| 128 | + Write-Host " Error: $($_.Exception.Message)" |
| 129 | + |
| 130 | + $env:PROXY_HOST = "" |
| 131 | + $env:PROXY_PORT = "" |
| 132 | + |
| 133 | + exit 0 # Exit successfully even if proxy check fails |
| 134 | +} |
| 135 | + |
0 commit comments