119 lines
2.7 KiB
Go
119 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func main() {
|
|
// Initialize data store with both IPv4 and IPv6 files
|
|
store, err := NewIPStore(
|
|
"IP2LOCATION-LITE-ASN.IPV6.CSV",
|
|
"IP2LOCATION-LITE-DB11.IPV6.CSV",
|
|
"IP2LOCATION-LITE-ASN.CSV",
|
|
"IP2LOCATION-LITE-DB11.CSV",
|
|
)
|
|
if err != nil {
|
|
log.Fatalf("Failed to initialize IP data store: %v", err)
|
|
}
|
|
log.Println("IP data loaded successfully")
|
|
|
|
// Initialize router
|
|
r := gin.Default()
|
|
|
|
// Serve static files
|
|
r.StaticFile("/", "./static/index.html")
|
|
r.Static("/static", "./static")
|
|
|
|
// API endpoints
|
|
r.GET("/my", func(c *gin.Context) {
|
|
ip := c.Request.Header.Get("X-Real-IP")
|
|
if ip == "" {
|
|
ip = c.Request.Header.Get("X-Forwarded-For")
|
|
}
|
|
if ip == "" {
|
|
ip = c.ClientIP()
|
|
}
|
|
info, err := store.GetIPInfo(ip, 200, ip)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, info)
|
|
})
|
|
|
|
r.GET("/:ip", func(c *gin.Context) {
|
|
input := c.Param("ip")
|
|
var info *IPInfo
|
|
var err error
|
|
|
|
timeout := c.Query("timeout")
|
|
timeoutInt, err := strconv.Atoi(timeout)
|
|
if err != nil || timeoutInt < 0 {
|
|
timeoutInt = 250 // значение по умолчанию
|
|
}
|
|
if timeoutInt > 10000 {
|
|
timeoutInt = 10000
|
|
}
|
|
|
|
items := strings.Split(input, ",")
|
|
log.Println(items)
|
|
|
|
if len(items) > 1 {
|
|
var resultItems []IPInfo
|
|
for _, elem := range items {
|
|
if(len(elem) == 0) {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Empty value"})
|
|
return
|
|
}
|
|
|
|
if store.IsValidIP(elem) {
|
|
info, _ := store.GetIPInfo(elem, timeoutInt, elem)
|
|
resultItems = append(resultItems, *info)
|
|
} else {
|
|
ip, resolveErr := store.ResolveDomain(elem, timeoutInt)
|
|
if resolveErr != nil {
|
|
continue
|
|
}
|
|
info, _ := store.GetIPInfo(ip, timeoutInt, elem)
|
|
resultItems = append(resultItems, *info)
|
|
}
|
|
}
|
|
c.JSON(http.StatusOK, IPsInfo {
|
|
Items: resultItems,
|
|
})
|
|
} else {
|
|
if store.IsValidIP(input) {
|
|
info, err = store.GetIPInfo(input, timeoutInt, input)
|
|
} else {
|
|
ip, resolveErr := store.ResolveDomain(input, timeoutInt)
|
|
if resolveErr != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Not a valid IP or domain: " + resolveErr.Error()})
|
|
return
|
|
}
|
|
info, err = store.GetIPInfo(ip, timeoutInt, input)
|
|
}
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, info)
|
|
}
|
|
})
|
|
|
|
// Get port or use default
|
|
port := os.Getenv("PORT")
|
|
if port == "" {
|
|
port = "8080"
|
|
}
|
|
|
|
log.Printf("Server starting on port %s", port)
|
|
if err := r.Run(":" + port); err != nil {
|
|
log.Fatalf("Failed to start server: %v", err)
|
|
}
|
|
} |