first commit
This commit is contained in:
41
.gitignore
vendored
Normal file
41
.gitignore
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.exe~
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
api
|
||||||
|
|
||||||
|
# Test binary, built with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Go workspace file
|
||||||
|
go.work
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
vendor/
|
||||||
|
|
||||||
|
# IDE files
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Environment files
|
||||||
|
.env
|
||||||
|
*.env
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
tmp/
|
||||||
|
temp/
|
||||||
38
build.sh
Executable file
38
build.sh
Executable file
@@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# User Expiry API - Linux Build Script
|
||||||
|
# 用户到期API - Linux构建脚本
|
||||||
|
|
||||||
|
echo "开始构建Linux版本..."
|
||||||
|
echo "Building Linux version..."
|
||||||
|
|
||||||
|
# 设置构建参数
|
||||||
|
export GOOS=linux
|
||||||
|
export GOARCH=amd64
|
||||||
|
|
||||||
|
# 构建可执行文件
|
||||||
|
echo "正在编译..."
|
||||||
|
go build -o api main.go
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "✅ 构建成功!"
|
||||||
|
echo "✅ Build successful!"
|
||||||
|
echo ""
|
||||||
|
echo "生成的文件: api"
|
||||||
|
echo "Generated file: api"
|
||||||
|
echo ""
|
||||||
|
echo "部署说明:"
|
||||||
|
echo "Deployment instructions:"
|
||||||
|
echo "1. 上传 api 和 users.json 到Linux服务器"
|
||||||
|
echo " Upload api and users.json to Linux server"
|
||||||
|
echo "2. 添加执行权限: chmod +x api"
|
||||||
|
echo " Add execute permission: chmod +x api"
|
||||||
|
echo "3. 运行: ./api"
|
||||||
|
echo " Run: ./api"
|
||||||
|
echo ""
|
||||||
|
ls -la api
|
||||||
|
else
|
||||||
|
echo "❌ 构建失败!"
|
||||||
|
echo "❌ Build failed!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
185
main.go
Normal file
185
main.go
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// User 用户数据结构
|
||||||
|
type User struct {
|
||||||
|
IP string `json:"ip"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
ExpiryDate string `json:"expiryDate"`
|
||||||
|
Phone string `json:"phone"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserData 用户数据容器
|
||||||
|
type UserData struct {
|
||||||
|
Users []User `json:"users"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// APIResponse API响应结构
|
||||||
|
type APIResponse struct {
|
||||||
|
Expiry string `json:"expiry"`
|
||||||
|
ServerTime string `json:"serverTime"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// getClientIP 获取客户端真实IP地址
|
||||||
|
func getClientIP(r *http.Request) string {
|
||||||
|
// 优先检查代理头
|
||||||
|
if xForwardedFor := r.Header.Get("X-Forwarded-For"); xForwardedFor != "" {
|
||||||
|
// X-Forwarded-For 可能包含多个IP,取第一个
|
||||||
|
ips := strings.Split(xForwardedFor, ",")
|
||||||
|
if len(ips) > 0 {
|
||||||
|
return strings.TrimSpace(ips[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if xRealIP := r.Header.Get("X-Real-IP"); xRealIP != "" {
|
||||||
|
return xRealIP
|
||||||
|
}
|
||||||
|
|
||||||
|
if xClientIP := r.Header.Get("X-Client-IP"); xClientIP != "" {
|
||||||
|
return xClientIP
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从RemoteAddr获取IP
|
||||||
|
ip, _, err := net.SplitHostPort(r.RemoteAddr)
|
||||||
|
if err != nil {
|
||||||
|
return r.RemoteAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理IPv6回环地址
|
||||||
|
if ip == "::1" {
|
||||||
|
return "127.0.0.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除IPv6前缀
|
||||||
|
if strings.HasPrefix(ip, "::ffff:") {
|
||||||
|
return strings.TrimPrefix(ip, "::ffff:")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ip
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadUserData 加载用户数据
|
||||||
|
func loadUserData() ([]User, error) {
|
||||||
|
data, err := os.ReadFile("users.json")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var userData UserData
|
||||||
|
err = json.Unmarshal(data, &userData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return userData.Users, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// findUserByIP 根据IP查找用户
|
||||||
|
func findUserByIP(users []User, ip string) *User {
|
||||||
|
for _, user := range users {
|
||||||
|
if user.IP == ip {
|
||||||
|
return &user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// setCORSHeaders 设置CORS头
|
||||||
|
func setCORSHeaders(w http.ResponseWriter) {
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
|
||||||
|
w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
|
||||||
|
}
|
||||||
|
|
||||||
|
// healthHandler 健康检查处理器
|
||||||
|
func healthHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
setCORSHeaders(w)
|
||||||
|
|
||||||
|
if r.Method == "OPTIONS" {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
||||||
|
response := map[string]interface{}{
|
||||||
|
"status": "ok",
|
||||||
|
"time": time.Now().Format(time.RFC3339),
|
||||||
|
}
|
||||||
|
|
||||||
|
json.NewEncoder(w).Encode(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkExpiryHandler 检查到期时间处理器
|
||||||
|
func checkExpiryHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
setCORSHeaders(w)
|
||||||
|
|
||||||
|
if r.Method == "OPTIONS" {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取客户端IP
|
||||||
|
clientIP := getClientIP(r)
|
||||||
|
log.Printf("收到来自 %s 的请求", clientIP)
|
||||||
|
|
||||||
|
// 获取当前服务器时间
|
||||||
|
serverTime := time.Now().Format(time.RFC3339)
|
||||||
|
|
||||||
|
// 加载用户数据
|
||||||
|
users, err := loadUserData()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("读取用户数据失败: %v", err)
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查找用户
|
||||||
|
user := findUserByIP(users, clientIP)
|
||||||
|
if user == nil {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 找到用户,返回到期时间
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
json.NewEncoder(w).Encode(APIResponse{
|
||||||
|
Expiry: user.ExpiryDate,
|
||||||
|
ServerTime: serverTime,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// 定义命令行参数
|
||||||
|
portFlag := flag.String("port", "3763", "服务器端口号")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
// 设置路由
|
||||||
|
http.HandleFunc("/health", healthHandler)
|
||||||
|
http.HandleFunc("/api/check-expiry", checkExpiryHandler)
|
||||||
|
|
||||||
|
port := ":" + *portFlag
|
||||||
|
fmt.Printf("服务器运行在端口 %s\n", port)
|
||||||
|
fmt.Printf("健康检查: http://localhost%s/health\n", port)
|
||||||
|
fmt.Printf("API接口: http://localhost%s/api/check-expiry\n", port)
|
||||||
|
|
||||||
|
// 启动服务器
|
||||||
|
log.Fatal(http.ListenAndServe(port, nil))
|
||||||
|
}
|
||||||
18
users.json
Normal file
18
users.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"users": [
|
||||||
|
{
|
||||||
|
"ip": "118.114.191.136",
|
||||||
|
"expiryDate": "2025-12-17T00:48:38+08:00",
|
||||||
|
"username": "user1",
|
||||||
|
"phone": "13800138000",
|
||||||
|
"versions": "旗舰版"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ip": "127.0.0.1",
|
||||||
|
"expiryDate": "2025-12-17T00:48:38+08:00",
|
||||||
|
"username": "user1",
|
||||||
|
"phone": "13800138000",
|
||||||
|
"versions": "旗舰版"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user