53 lines
1.1 KiB
Go
53 lines
1.1 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// IPFetcher 用于获取本机的公网 IPv4 和 IPv6
|
|
type IPFetcher struct {
|
|
client *http.Client
|
|
}
|
|
|
|
func NewIPFetcher() *IPFetcher {
|
|
return &IPFetcher{
|
|
client: &http.Client{Timeout: 5 * time.Second},
|
|
}
|
|
}
|
|
|
|
// GetIPv4 获取公网 IPv4
|
|
func (f *IPFetcher) GetIPv4(ctx context.Context) (string, error) {
|
|
return f.fetchIP(ctx, "https://api.ipify.org")
|
|
}
|
|
|
|
// GetIPv6 获取公网 IPv6
|
|
func (f *IPFetcher) GetIPv6(ctx context.Context) (string, error) {
|
|
return f.fetchIP(ctx, "https://api6.ipify.org")
|
|
}
|
|
|
|
func (f *IPFetcher) fetchIP(ctx context.Context, apiURL string) (string, error) {
|
|
req, err := http.NewRequestWithContext(ctx, "GET", apiURL, nil)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
resp, err := f.client.Do(req)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return "", http.ErrServerClosed // 简易错误
|
|
}
|
|
|
|
ipBytes, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return strings.TrimSpace(string(ipBytes)), nil
|
|
}
|