Some checks failed
Go Benchmark / Performance Regression Check (push) Has been cancelled
Cerberus Integration / Cerberus Security Stack Integration (push) Has been cancelled
Upload Coverage to Codecov / Backend Codecov Upload (push) Has been cancelled
Upload Coverage to Codecov / Frontend Codecov Upload (push) Has been cancelled
CodeQL - Analyze / CodeQL analysis (go) (push) Has been cancelled
CodeQL - Analyze / CodeQL analysis (javascript-typescript) (push) Has been cancelled
CrowdSec Integration / CrowdSec Bouncer Integration (push) Has been cancelled
Docker Build, Publish & Test / build-and-push (push) Has been cancelled
Quality Checks / Auth Route Protection Contract (push) Has been cancelled
Quality Checks / Codecov Trigger/Comment Parity Guard (push) Has been cancelled
Quality Checks / Backend (Go) (push) Has been cancelled
Quality Checks / Frontend (React) (push) Has been cancelled
Rate Limit integration / Rate Limiting Integration (push) Has been cancelled
Security Scan (PR) / Trivy Binary Scan (push) Has been cancelled
Supply Chain Verification (PR) / Verify Supply Chain (push) Has been cancelled
WAF integration / Coraza WAF Integration (push) Has been cancelled
Docker Build, Publish & Test / Security Scan PR Image (push) Has been cancelled
Repo Health Check / Repo health (push) Has been cancelled
History Rewrite Dry-Run / Dry-run preview for history rewrite (push) Has been cancelled
Prune Renovate Branches / prune (push) Has been cancelled
Renovate / renovate (push) Has been cancelled
Nightly Build & Package / sync-development-to-nightly (push) Has been cancelled
Nightly Build & Package / Trigger Nightly Validation Workflows (push) Has been cancelled
Nightly Build & Package / build-and-push-nightly (push) Has been cancelled
Nightly Build & Package / test-nightly-image (push) Has been cancelled
Nightly Build & Package / verify-nightly-supply-chain (push) Has been cancelled
Update GeoLite2 Checksum / update-checksum (push) Has been cancelled
Container Registry Prune / prune-ghcr (push) Has been cancelled
Container Registry Prune / prune-dockerhub (push) Has been cancelled
Container Registry Prune / summarize (push) Has been cancelled
Supply Chain Verification / Verify SBOM (push) Has been cancelled
Supply Chain Verification / Verify Release Artifacts (push) Has been cancelled
Supply Chain Verification / Verify Docker Image Supply Chain (push) Has been cancelled
Monitor Caddy Major Release / check-caddy-major (push) Has been cancelled
Weekly Nightly to Main Promotion / Verify Nightly Branch Health (push) Has been cancelled
Weekly Nightly to Main Promotion / Create Promotion PR (push) Has been cancelled
Weekly Nightly to Main Promotion / Trigger Missing Required Checks (push) Has been cancelled
Weekly Nightly to Main Promotion / Notify on Failure (push) Has been cancelled
Weekly Nightly to Main Promotion / Workflow Summary (push) Has been cancelled
Weekly Security Rebuild / Security Rebuild & Scan (push) Has been cancelled
76 lines
1.6 KiB
Go
Executable File
76 lines
1.6 KiB
Go
Executable File
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type SystemHandler struct{}
|
|
|
|
func NewSystemHandler() *SystemHandler {
|
|
return &SystemHandler{}
|
|
}
|
|
|
|
type MyIPResponse struct {
|
|
IP string `json:"ip"`
|
|
Source string `json:"source"`
|
|
}
|
|
|
|
// GetMyIP returns the client's public IP address
|
|
func (h *SystemHandler) GetMyIP(c *gin.Context) {
|
|
// Try to get the real IP from various headers (in order of preference)
|
|
// This handles proxies, load balancers, and CDNs
|
|
ip := getClientIP(c.Request)
|
|
|
|
source := "direct"
|
|
switch {
|
|
case c.GetHeader("X-Forwarded-For") != "":
|
|
source = "X-Forwarded-For"
|
|
case c.GetHeader("X-Real-IP") != "":
|
|
source = "X-Real-IP"
|
|
case c.GetHeader("CF-Connecting-IP") != "":
|
|
source = "Cloudflare"
|
|
}
|
|
|
|
c.JSON(http.StatusOK, MyIPResponse{
|
|
IP: ip,
|
|
Source: source,
|
|
})
|
|
}
|
|
|
|
// getClientIP extracts the real client IP from the request
|
|
// Checks headers in order of trust/reliability
|
|
func getClientIP(r *http.Request) string {
|
|
// Cloudflare
|
|
if ip := r.Header.Get("CF-Connecting-IP"); ip != "" {
|
|
return ip
|
|
}
|
|
|
|
// Other CDNs/proxies
|
|
if ip := r.Header.Get("X-Real-IP"); ip != "" {
|
|
return ip
|
|
}
|
|
|
|
// Standard proxy header (can be a comma-separated list)
|
|
if forwarded := r.Header.Get("X-Forwarded-For"); forwarded != "" {
|
|
// Take the first IP in the list (client IP)
|
|
ips := strings.Split(forwarded, ",")
|
|
if len(ips) > 0 {
|
|
return strings.TrimSpace(ips[0])
|
|
}
|
|
}
|
|
|
|
// Fallback to RemoteAddr (format: "IP:port")
|
|
if ip := r.RemoteAddr; ip != "" {
|
|
// Remove port if present
|
|
if idx := strings.LastIndex(ip, ":"); idx != -1 {
|
|
return ip[:idx]
|
|
}
|
|
return ip
|
|
}
|
|
|
|
return "unknown"
|
|
}
|