mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-09 09:06:36 +08:00
[优化] 新增 GeoIP 测试功能,更新相关 API 路由和前端组件
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"atsflare/utils/geoip"
|
||||
"errors"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type GeoIPLookupView struct {
|
||||
Provider string `json:"provider"`
|
||||
IP string `json:"ip"`
|
||||
ISOCode string `json:"iso_code"`
|
||||
Name string `json:"name"`
|
||||
Latitude *float64 `json:"latitude,omitempty"`
|
||||
Longitude *float64 `json:"longitude,omitempty"`
|
||||
}
|
||||
|
||||
func LookupGeoIP(provider string, rawIP string) (*GeoIPLookupView, error) {
|
||||
trimmedProvider := strings.TrimSpace(provider)
|
||||
if !geoip.IsValidProvider(trimmedProvider) {
|
||||
return nil, errors.New("归属方式仅支持 disabled、mmdb、ip-api、geojs、ipinfo")
|
||||
}
|
||||
|
||||
trimmedIP := strings.TrimSpace(rawIP)
|
||||
if trimmedIP == "" {
|
||||
return nil, errors.New("IP 不能为空")
|
||||
}
|
||||
parsedIP := net.ParseIP(trimmedIP)
|
||||
if parsedIP == nil {
|
||||
return nil, errors.New("IP 格式无效")
|
||||
}
|
||||
|
||||
info, err := geoip.LookupGeoInfoWithProvider(trimmedProvider, parsedIP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if info == nil {
|
||||
return nil, errors.New("未获取到 IP 归属结果")
|
||||
}
|
||||
|
||||
return &GeoIPLookupView{
|
||||
Provider: trimmedProvider,
|
||||
IP: parsedIP.String(),
|
||||
ISOCode: info.ISOCode,
|
||||
Name: info.Name,
|
||||
Latitude: info.Latitude,
|
||||
Longitude: info.Longitude,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"atsflare/utils/geoip"
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type fakeLookupProvider struct{}
|
||||
|
||||
func (f *fakeLookupProvider) Name() string {
|
||||
return "fake-lookup"
|
||||
}
|
||||
|
||||
func (f *fakeLookupProvider) GetGeoInfo(ip net.IP) (*geoip.GeoInfo, error) {
|
||||
return &geoip.GeoInfo{
|
||||
ISOCode: "US",
|
||||
Name: "United States",
|
||||
Latitude: geoipFloat(37.7749),
|
||||
Longitude: geoipFloat(-122.4194),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (f *fakeLookupProvider) UpdateDatabase() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeLookupProvider) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestLookupGeoIP(t *testing.T) {
|
||||
previousFactory := geoip.ProviderFactoryForTest()
|
||||
geoip.SetProviderFactoryForTest(func(provider string) (geoip.GeoIPService, error) {
|
||||
return &fakeLookupProvider{}, nil
|
||||
})
|
||||
defer geoip.SetProviderFactoryForTest(previousFactory)
|
||||
|
||||
view, err := LookupGeoIP("ipinfo", "8.8.8.8")
|
||||
if err != nil {
|
||||
t.Fatalf("LookupGeoIP failed: %v", err)
|
||||
}
|
||||
if view.Provider != "ipinfo" {
|
||||
t.Fatalf("expected provider ipinfo, got %s", view.Provider)
|
||||
}
|
||||
if view.IP != "8.8.8.8" {
|
||||
t.Fatalf("expected IP 8.8.8.8, got %s", view.IP)
|
||||
}
|
||||
if view.ISOCode != "US" || view.Name != "United States" {
|
||||
t.Fatalf("unexpected lookup view: %+v", view)
|
||||
}
|
||||
if view.Latitude == nil || view.Longitude == nil {
|
||||
t.Fatalf("expected coordinates, got %+v", view)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLookupGeoIPRejectsInvalidInput(t *testing.T) {
|
||||
if _, err := LookupGeoIP("invalid", "8.8.8.8"); err == nil {
|
||||
t.Fatal("expected invalid provider to fail")
|
||||
}
|
||||
if _, err := LookupGeoIP("ipinfo", "not-an-ip"); err == nil {
|
||||
t.Fatal("expected invalid IP to fail")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user