This commit is contained in:
2025-08-24 13:01:09 +08:00
parent 61e51ad014
commit f028913eb8
36 changed files with 10420 additions and 70 deletions

View File

@@ -0,0 +1,369 @@
/*
handlers.go - 请求处理器
实现了各种HTTP请求的处理逻辑
*/
package server
import (
"encoding/json"
"net/http"
"runtime"
"strconv"
"time"
"webserver/models"
"github.com/gorilla/mux"
)
// Response 通用响应结构
type Response struct {
Status string `json:"status"`
Message string `json:"message,omitempty"`
Data interface{} `json:"data,omitempty"`
Error string `json:"error,omitempty"`
Count int `json:"count,omitempty"`
}
// HealthResponse 健康检查响应
type HealthResponse struct {
Status string `json:"status"`
Timestamp string `json:"timestamp"`
Uptime string `json:"uptime"`
Version string `json:"version"`
}
// StatsResponse 统计信息响应
type StatsResponse struct {
Status string `json:"status"`
Timestamp string `json:"timestamp"`
Uptime string `json:"uptime"`
Version string `json:"version"`
GoVersion string `json:"go_version"`
NumCPU int `json:"num_cpu"`
NumGoroutine int `json:"num_goroutine"`
MemStats runtime.MemStats `json:"mem_stats"`
}
var (
startTime = time.Now()
version = "1.0.0"
)
// HomeHandler 首页处理器
func HomeHandler(w http.ResponseWriter, r *http.Request) {
html := `
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Go Web服务器</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; background-color: #f5f5f5; }
.container { max-width: 800px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
h1 { color: #333; text-align: center; }
.api-list { background: #f8f9fa; padding: 20px; border-radius: 5px; margin: 20px 0; }
.api-item { margin: 10px 0; padding: 10px; background: white; border-left: 4px solid #007bff; }
.method { font-weight: bold; color: #007bff; }
.endpoint { font-family: monospace; background: #e9ecef; padding: 2px 6px; border-radius: 3px; }
.description { color: #666; margin-top: 5px; }
</style>
</head>
<body>
<div class="container">
<h1>🚀 Go Web服务器</h1>
<p>欢迎使用Go语言编写的简单Web服务器这个项目演示了HTTP服务器、RESTful API、JSON处理等功能。</p>
<h2>📚 API接口</h2>
<div class="api-list">
<div class="api-item">
<span class="method">GET</span> <span class="endpoint">/health</span>
<div class="description">健康检查</div>
</div>
<div class="api-item">
<span class="method">GET</span> <span class="endpoint">/api/stats</span>
<div class="description">服务器统计信息</div>
</div>
<div class="api-item">
<span class="method">GET</span> <span class="endpoint">/api/users</span>
<div class="description">获取所有用户</div>
</div>
<div class="api-item">
<span class="method">POST</span> <span class="endpoint">/api/users</span>
<div class="description">创建新用户</div>
</div>
<div class="api-item">
<span class="method">GET</span> <span class="endpoint">/api/users/{id}</span>
<div class="description">获取指定用户</div>
</div>
<div class="api-item">
<span class="method">PUT</span> <span class="endpoint">/api/users/{id}</span>
<div class="description">更新用户信息</div>
</div>
<div class="api-item">
<span class="method">DELETE</span> <span class="endpoint">/api/users/{id}</span>
<div class="description">删除用户</div>
</div>
</div>
<h2>🛠️ 使用示例</h2>
<pre style="background: #f8f9fa; padding: 15px; border-radius: 5px; overflow-x: auto;">
# 获取所有用户
curl http://localhost:8080/api/users
# 创建新用户
curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{"name":"张三","email":"zhangsan@example.com","age":25}'
# 健康检查
curl http://localhost:8080/health
</pre>
</div>
</body>
</html>`
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusOK)
w.Write([]byte(html))
}
// HealthHandler 健康检查处理器
func HealthHandler(w http.ResponseWriter, r *http.Request) {
uptime := time.Since(startTime)
response := HealthResponse{
Status: "healthy",
Timestamp: time.Now().Format(time.RFC3339),
Uptime: uptime.String(),
Version: version,
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(response)
}
// StatsHandler 统计信息处理器
func StatsHandler(w http.ResponseWriter, r *http.Request) {
uptime := time.Since(startTime)
var memStats runtime.MemStats
runtime.ReadMemStats(&memStats)
response := StatsResponse{
Status: "success",
Timestamp: time.Now().Format(time.RFC3339),
Uptime: uptime.String(),
Version: version,
GoVersion: runtime.Version(),
NumCPU: runtime.NumCPU(),
NumGoroutine: runtime.NumGoroutine(),
MemStats: memStats,
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(response)
}
// GetUsersHandler 获取所有用户
func GetUsersHandler(w http.ResponseWriter, r *http.Request) {
users, err := models.GetAllUsers()
if err != nil {
sendErrorResponse(w, "获取用户列表失败", http.StatusInternalServerError)
return
}
response := Response{
Status: "success",
Data: users,
Count: len(users),
}
sendJSONResponse(w, response, http.StatusOK)
}
// GetUserHandler 获取指定用户
func GetUserHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
sendErrorResponse(w, "无效的用户ID", http.StatusBadRequest)
return
}
user, err := models.GetUserByID(id)
if err != nil {
sendErrorResponse(w, "用户不存在", http.StatusNotFound)
return
}
response := Response{
Status: "success",
Data: user,
}
sendJSONResponse(w, response, http.StatusOK)
}
// CreateUserHandler 创建新用户
func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
var user models.User
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
sendErrorResponse(w, "无效的JSON数据", http.StatusBadRequest)
return
}
// 验证用户数据
if err := user.Validate(); err != nil {
sendErrorResponse(w, err.Error(), http.StatusBadRequest)
return
}
// 创建用户
createdUser, err := models.CreateUser(user)
if err != nil {
sendErrorResponse(w, "创建用户失败", http.StatusInternalServerError)
return
}
response := Response{
Status: "success",
Message: "用户创建成功",
Data: createdUser,
}
sendJSONResponse(w, response, http.StatusCreated)
}
// UpdateUserHandler 更新用户信息
func UpdateUserHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
sendErrorResponse(w, "无效的用户ID", http.StatusBadRequest)
return
}
var user models.User
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
sendErrorResponse(w, "无效的JSON数据", http.StatusBadRequest)
return
}
// 设置用户ID
user.ID = id
// 验证用户数据
if err := user.Validate(); err != nil {
sendErrorResponse(w, err.Error(), http.StatusBadRequest)
return
}
// 更新用户
updatedUser, err := models.UpdateUser(user)
if err != nil {
sendErrorResponse(w, "更新用户失败", http.StatusInternalServerError)
return
}
response := Response{
Status: "success",
Message: "用户更新成功",
Data: updatedUser,
}
sendJSONResponse(w, response, http.StatusOK)
}
// DeleteUserHandler 删除用户
func DeleteUserHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
sendErrorResponse(w, "无效的用户ID", http.StatusBadRequest)
return
}
if err := models.DeleteUser(id); err != nil {
sendErrorResponse(w, "删除用户失败", http.StatusInternalServerError)
return
}
response := Response{
Status: "success",
Message: "用户删除成功",
}
sendJSONResponse(w, response, http.StatusOK)
}
// APIDocHandler API文档处理器
func APIDocHandler(w http.ResponseWriter, r *http.Request) {
doc := map[string]interface{}{
"title": "Go Web服务器 API",
"version": version,
"description": "一个简单的RESTful API服务器",
"endpoints": map[string]interface{}{
"health": map[string]string{
"method": "GET",
"path": "/health",
"description": "健康检查",
},
"stats": map[string]string{
"method": "GET",
"path": "/api/stats",
"description": "服务器统计信息",
},
"users": map[string]interface{}{
"list": map[string]string{
"method": "GET",
"path": "/api/users",
"description": "获取所有用户",
},
"get": map[string]string{
"method": "GET",
"path": "/api/users/{id}",
"description": "获取指定用户",
},
"create": map[string]string{
"method": "POST",
"path": "/api/users",
"description": "创建新用户",
},
"update": map[string]string{
"method": "PUT",
"path": "/api/users/{id}",
"description": "更新用户信息",
},
"delete": map[string]string{
"method": "DELETE",
"path": "/api/users/{id}",
"description": "删除用户",
},
},
},
}
sendJSONResponse(w, doc, http.StatusOK)
}
// sendJSONResponse 发送JSON响应
func sendJSONResponse(w http.ResponseWriter, data interface{}, statusCode int) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(statusCode)
if err := json.NewEncoder(w).Encode(data); err != nil {
http.Error(w, "JSON编码失败", http.StatusInternalServerError)
}
}
// sendErrorResponse 发送错误响应
func sendErrorResponse(w http.ResponseWriter, message string, statusCode int) {
response := Response{
Status: "error",
Error: message,
}
sendJSONResponse(w, response, statusCode)
}

View File

@@ -0,0 +1,147 @@
/*
middleware.go - 中间件
实现了各种HTTP中间件功能
*/
package server
import (
"log"
"net/http"
"runtime/debug"
"time"
)
// LoggingMiddleware 日志记录中间件
func LoggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
// 创建响应记录器来捕获状态码
recorder := &responseRecorder{
ResponseWriter: w,
statusCode: http.StatusOK,
}
// 调用下一个处理器
next.ServeHTTP(recorder, r)
// 记录请求日志
duration := time.Since(start)
log.Printf("[%s] %s %s %d %v",
r.Method,
r.RequestURI,
r.RemoteAddr,
recorder.statusCode,
duration,
)
})
}
// responseRecorder 响应记录器
type responseRecorder struct {
http.ResponseWriter
statusCode int
}
// WriteHeader 记录状态码
func (rr *responseRecorder) WriteHeader(code int) {
rr.statusCode = code
rr.ResponseWriter.WriteHeader(code)
}
// CORSMiddleware CORS中间件
func CORSMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 设置CORS头
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", "Content-Type, Authorization")
// 处理预检请求
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
// 调用下一个处理器
next.ServeHTTP(w, r)
})
}
// RecoveryMiddleware 恢复中间件处理panic
func RecoveryMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
// 记录panic信息
log.Printf("❌ Panic recovered: %v\n%s", err, debug.Stack())
// 返回500错误
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
}()
// 调用下一个处理器
next.ServeHTTP(w, r)
})
}
// AuthMiddleware 认证中间件(示例)
func AuthMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 检查Authorization头
token := r.Header.Get("Authorization")
if token == "" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// 这里可以添加实际的token验证逻辑
// 为了演示我们简单检查token是否为"Bearer valid-token"
if token != "Bearer valid-token" {
http.Error(w, "Invalid token", http.StatusUnauthorized)
return
}
// 调用下一个处理器
next.ServeHTTP(w, r)
})
}
// RateLimitMiddleware 限流中间件(简化版)
func RateLimitMiddleware(next http.Handler) http.Handler {
// 这里可以实现基于IP的限流逻辑
// 为了简化,我们只是一个示例框架
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 实际实现中,这里会检查请求频率
// 如果超过限制返回429状态码
// 调用下一个处理器
next.ServeHTTP(w, r)
})
}
// ContentTypeMiddleware 内容类型中间件
func ContentTypeMiddleware(contentType string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", contentType)
next.ServeHTTP(w, r)
})
}
}
// SecurityMiddleware 安全头中间件
func SecurityMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 设置安全相关的HTTP头
w.Header().Set("X-Content-Type-Options", "nosniff")
w.Header().Set("X-Frame-Options", "DENY")
w.Header().Set("X-XSS-Protection", "1; mode=block")
w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
// 调用下一个处理器
next.ServeHTTP(w, r)
})
}

View File

@@ -0,0 +1,59 @@
/*
router.go - 路由管理
实现了HTTP路由和中间件管理功能
*/
package server
import (
"net/http"
"github.com/gorilla/mux"
)
// Router 路由器结构体
type Router struct {
*mux.Router
}
// NewRouter 创建新的路由器
func NewRouter() *Router {
return &Router{
Router: mux.NewRouter(),
}
}
// Use 添加中间件
func (r *Router) Use(middleware func(http.Handler) http.Handler) {
r.Router.Use(middleware)
}
// Methods 设置HTTP方法链式调用
func (r *Router) Methods(methods ...string) *mux.Route {
return r.Router.Methods(methods...)
}
// PathPrefix 路径前缀
func (r *Router) PathPrefix(tpl string) *mux.Router {
return r.Router.PathPrefix(tpl)
}
// Subrouter 创建子路由
func (r *Router) Subrouter() *mux.Router {
return r.Router.NewRoute().Subrouter()
}
// HandleFunc 处理函数路由
func (r *Router) HandleFunc(path string, f func(http.ResponseWriter, *http.Request)) *mux.Route {
return r.Router.HandleFunc(path, f)
}
// Handle 处理器路由
func (r *Router) Handle(path string, handler http.Handler) *mux.Route {
return r.Router.Handle(path, handler)
}
// ServeHTTP 实现http.Handler接口
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
r.Router.ServeHTTP(w, req)
}

View File

@@ -0,0 +1,94 @@
/*
server.go - HTTP服务器核心
实现了HTTP服务器的基本功能和生命周期管理
*/
package server
import (
"context"
"fmt"
"net/http"
"time"
)
// Server HTTP服务器结构体
type Server struct {
httpServer *http.Server
router *Router
addr string
}
// NewServer 创建新的服务器实例
func NewServer(addr string) *Server {
router := NewRouter()
return &Server{
httpServer: &http.Server{
Addr: addr,
Handler: router,
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
IdleTimeout: 60 * time.Second,
},
router: router,
addr: addr,
}
}
// SetupRoutes 设置路由
func (s *Server) SetupRoutes() {
// 添加中间件
s.router.Use(LoggingMiddleware)
s.router.Use(CORSMiddleware)
s.router.Use(RecoveryMiddleware)
// 静态文件服务
s.router.HandleFunc("/", HomeHandler).Methods("GET")
s.router.PathPrefix("/static/").Handler(
http.StripPrefix("/static/", http.FileServer(http.Dir("./static/"))),
)
// 健康检查
s.router.HandleFunc("/health", HealthHandler).Methods("GET")
// API路由
apiRouter := s.router.PathPrefix("/api").Subrouter()
// 用户管理API
apiRouter.HandleFunc("/users", GetUsersHandler).Methods("GET")
apiRouter.HandleFunc("/users", CreateUserHandler).Methods("POST")
apiRouter.HandleFunc("/users/{id:[0-9]+}", GetUserHandler).Methods("GET")
apiRouter.HandleFunc("/users/{id:[0-9]+}", UpdateUserHandler).Methods("PUT")
apiRouter.HandleFunc("/users/{id:[0-9]+}", DeleteUserHandler).Methods("DELETE")
// 服务器统计
apiRouter.HandleFunc("/stats", StatsHandler).Methods("GET")
// API文档
apiRouter.HandleFunc("", APIDocHandler).Methods("GET")
}
// Start 启动服务器
func (s *Server) Start() error {
fmt.Printf("✅ 服务器启动成功,监听地址: %s\n", s.addr)
return s.httpServer.ListenAndServe()
}
// Shutdown 优雅关闭服务器
func (s *Server) Shutdown() error {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
return s.httpServer.Shutdown(ctx)
}
// GetRouter 获取路由器
func (s *Server) GetRouter() *Router {
return s.router
}
// GetHTTPServer 获取HTTP服务器
func (s *Server) GetHTTPServer() *http.Server {
return s.httpServer
}