[string]$Domain = "mi-motor.local",
[string]$CaddyPath = "C:\tools\caddy",
$ErrorActionPreference = "Continue"
function Add-Result($Test, $Status, $Message, $Details = "") {
$results += [PSCustomObject]@{
function Write-TestResult($Test, $Status, $Message) {
$color = switch ($Status) {
$icon = switch ($Status) {
Write-Host "$icon $Test`: $Message" -ForegroundColor $color
Write-Host "🔍 Diagnóstico Completo de Caddy para $Domain" -ForegroundColor Cyan
# 1. Verificar proceso Caddy
$caddyProcess = Get-Process -Name "caddy" -ErrorAction Stop
Add-Result "Proceso Caddy" "PASS" "Ejecutándose (PID: $($caddyProcess.Id))" "Memoria: $([math]::Round($caddyProcess.WorkingSet64/1MB, 2)) MB"
Write-TestResult "Proceso Caddy" "PASS" "Ejecutándose (PID: $($caddyProcess.Id))"
Add-Result "Proceso Caddy" "FAIL" "No está ejecutándose" $_.Exception.Message
Write-TestResult "Proceso Caddy" "FAIL" "No está ejecutándose"
# 2. Verificar puertos críticos
foreach ($port in $ports) {
$connection = Test-NetConnection -ComputerName "localhost" -Port $port -InformationLevel Quiet -WarningAction SilentlyContinue
Add-Result "Puerto $port" "PASS" "Abierto y accesible"
Write-TestResult "Puerto $port" "PASS" "Abierto"
# Verificar qué proceso usa el puerto
$netstat = netstat -ano | Select-String ":$port "
Add-Result "Puerto $port" "FAIL" "Cerrado o inaccesible" $netstat
Write-TestResult "Puerto $port" "FAIL" "Cerrado"
Add-Result "Puerto $port" "FAIL" "Error verificando puerto" $_.Exception.Message
Write-TestResult "Puerto $port" "FAIL" "Error en verificación"
# 3. Verificar resolución DNS
$dns = Resolve-DnsName $Domain -ErrorAction Stop
Add-Result "DNS" "PASS" "Resuelve a $($dns.IPAddress)"
Write-TestResult "DNS" "PASS" "Resuelve correctamente"
$hostsContent = Get-Content "C:\Windows\System32\drivers\etc\hosts" -ErrorAction SilentlyContinue
$hostsEntry = $hostsContent | Select-String $Domain
Add-Result "DNS" "WARN" "No resuelve DNS pero existe en hosts" $hostsEntry
Write-TestResult "DNS" "WARN" "Solo en hosts file"
Add-Result "DNS" "FAIL" "No resuelve y no está en hosts" $_.Exception.Message
Write-TestResult "DNS" "FAIL" "No configurado"
# 4. Test conectividad HTTP
$httpResponse = Invoke-WebRequest -Uri "http://$Domain" -UseBasicParsing -TimeoutSec 10 -ErrorAction Stop
Add-Result "HTTP" "PASS" "Responde $($httpResponse.StatusCode)" "Content-Length: $($httpResponse.Content.Length)"
Write-TestResult "HTTP" "PASS" "Responde $($httpResponse.StatusCode)"
Add-Result "HTTP" "FAIL" "No responde" $_.Exception.Message
Write-TestResult "HTTP" "FAIL" "No responde"
# 5. Test conectividad HTTPS
$httpsResponse = Invoke-WebRequest -Uri "https://$Domain" -UseBasicParsing -TimeoutSec 10 -SkipCertificateCheck -ErrorAction Stop
Add-Result "HTTPS" "PASS" "Responde $($httpsResponse.StatusCode)" "SSL OK"
Write-TestResult "HTTPS" "PASS" "Responde $($httpsResponse.StatusCode)"
Add-Result "HTTPS" "FAIL" "No responde" $_.Exception.Message
Write-TestResult "HTTPS" "FAIL" "No responde"
# 6. Verificar configuración Caddy
$caddyfile = Join-Path $CaddyPath "Caddyfile"
if (Test-Path $caddyfile) {
$caddyExe = Join-Path $CaddyPath "caddy.exe"
$validation = & $caddyExe validate --config $caddyfile 2>&1
if ($LASTEXITCODE -eq 0) {
Add-Result "Configuración" "PASS" "Sintaxis válida"
Write-TestResult "Configuración" "PASS" "Sintaxis válida"
Add-Result "Configuración" "FAIL" "Sintaxis inválida" $validation
Write-TestResult "Configuración" "FAIL" "Sintaxis inválida"
Add-Result "Configuración" "FAIL" "Error validando" $_.Exception.Message
Write-TestResult "Configuración" "FAIL" "Error validando"
Add-Result "Configuración" "FAIL" "Caddyfile no encontrado" $caddyfile
Write-TestResult "Configuración" "FAIL" "Caddyfile no encontrado"
# 7. Verificar logs recientes
$logPath = Join-Path $CaddyPath "caddy.log"
if (Test-Path $logPath) {
$recentErrors = Get-Content $logPath -Tail 20 | Select-String -Pattern "error|failed|timeout" -CaseSensitive:$false
Add-Result "Logs" "WARN" "Errores recientes encontrados" ($recentErrors -join "`n")
Write-TestResult "Logs" "WARN" "$($recentErrors.Count) errores recientes"
Add-Result "Logs" "PASS" "Sin errores recientes"
Write-TestResult "Logs" "PASS" "Sin errores recientes"
Add-Result "Logs" "WARN" "Archivo de logs no encontrado" $logPath
Write-TestResult "Logs" "WARN" "Sin archivo de logs"
# 8. Test específicos de handlers
@{ Name = "Offer Handler"; Path = "/offer" }
@{ Name = "Checkout Handler"; Path = "/chk" }
@{ Name = "Purchase Handler"; Path = "/purchase" }
foreach ($handler in $handlers) {
$url = "https://$Domain$($handler.Path)"
$response = Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 5 -SkipCertificateCheck -ErrorAction Stop
Add-Result $handler.Name "PASS" "Responde $($response.StatusCode)"
Write-TestResult $handler.Name "PASS" "OK"
if ($_.Exception.Message -like "*404*") {
Add-Result $handler.Name "WARN" "Handler no configurado (404)"
Write-TestResult $handler.Name "WARN" "No configurado"
Add-Result $handler.Name "FAIL" "Error de conexión" $_.Exception.Message
Write-TestResult $handler.Name "FAIL" "Error"
Write-Host "`n" + "=" * 60
$passCount = ($results | Where-Object { $_.Status -eq "PASS" }).Count
$failCount = ($results | Where-Object { $_.Status -eq "FAIL" }).Count
$warnCount = ($results | Where-Object { $_.Status -eq "WARN" }).Count
Write-Host "📊 Resumen:" -ForegroundColor Cyan
Write-Host " ✅ Exitosos: $passCount" -ForegroundColor Green
Write-Host " ❌ Fallidos: $failCount" -ForegroundColor Red
Write-Host " ⚠️ Advertencias: $warnCount" -ForegroundColor Yellow
Write-Host "`n🎉 ¡Sistema funcionando correctamente!" -ForegroundColor Green
} elseif ($failCount -le 2) {
Write-Host "`n⚠️ Sistema con problemas menores" -ForegroundColor Yellow
Write-Host "`n🚨 Sistema con problemas críticos" -ForegroundColor Red
Write-Host "`n📋 Detalles completos:" -ForegroundColor Cyan
$results | Format-Table Test, Status, Message, Details -AutoSize
Write-Host "`n🏁 Diagnóstico completado" -ForegroundColor Cyan