diff --git a/internal/handler/metrics.go b/internal/handler/metrics.go index 74c4844..7153e89 100644 --- a/internal/handler/metrics.go +++ b/internal/handler/metrics.go @@ -47,23 +47,40 @@ func (h *ProxyHandler) MetricsHandler(w http.ResponseWriter, r *http.Request) { return } - var avgLatency int64 - if latency, ok := stats["avg_latency"]; ok && latency != nil { - avgLatency = latency.(int64) + // 添加安全的类型转换函数 + safeInt64 := func(v interface{}) int64 { + if v == nil { + return 0 + } + if i, ok := v.(int64); ok { + return i + } + return 0 } + safeInt := func(v interface{}) int { + if v == nil { + return 0 + } + if i, ok := v.(int); ok { + return i + } + return 0 + } + + totalRequests := safeInt64(stats["total_requests"]) metrics := Metrics{ Uptime: uptime.String(), - ActiveRequests: stats["active_requests"].(int64), - TotalRequests: stats["total_requests"].(int64), - TotalErrors: stats["total_errors"].(int64), - ErrorRate: float64(stats["total_errors"].(int64)) / float64(stats["total_requests"].(int64)), - NumGoroutine: stats["num_goroutine"].(int), + ActiveRequests: safeInt64(stats["active_requests"]), + TotalRequests: totalRequests, + TotalErrors: safeInt64(stats["total_errors"]), + ErrorRate: float64(safeInt64(stats["total_errors"])) / float64(max(totalRequests, 1)), + NumGoroutine: safeInt(stats["num_goroutine"]), MemoryUsage: stats["memory_usage"].(string), - AverageResponseTime: metrics.FormatDuration(time.Duration(avgLatency)), - TotalBytes: stats["total_bytes"].(int64), - BytesPerSecond: float64(stats["total_bytes"].(int64)) / metrics.Max(uptime.Seconds(), 1), - RequestsPerSecond: float64(stats["total_requests"].(int64)) / metrics.Max(uptime.Seconds(), 1), + AverageResponseTime: metrics.FormatDuration(time.Duration(safeInt64(stats["avg_latency"]))), + TotalBytes: safeInt64(stats["total_bytes"]), + BytesPerSecond: float64(safeInt64(stats["total_bytes"])) / metrics.Max(uptime.Seconds(), 1), + RequestsPerSecond: float64(totalRequests) / metrics.Max(uptime.Seconds(), 1), StatusCodeStats: stats["status_code_stats"].(map[string]int64), TopPaths: stats["top_paths"].([]models.PathMetrics), RecentRequests: stats["recent_requests"].([]models.RequestLog), @@ -76,6 +93,14 @@ func (h *ProxyHandler) MetricsHandler(w http.ResponseWriter, r *http.Request) { } } +// 辅助函数 +func max(a, b int64) int64 { + if a > b { + return a + } + return b +} + // 修改模板,添加登录页面 var loginTemplate = ` diff --git a/internal/handler/proxy.go b/internal/handler/proxy.go index 48e7523..ad6670d 100644 --- a/internal/handler/proxy.go +++ b/internal/handler/proxy.go @@ -6,6 +6,7 @@ import ( "log" "net/http" "net/url" + "path" "proxy-go/internal/config" "proxy-go/internal/metrics" "proxy-go/internal/utils" @@ -22,7 +23,8 @@ const ( var bufferPool = sync.Pool{ New: func() interface{} { - return make([]byte, defaultBufferSize) + buf := make([]byte, defaultBufferSize) + return &buf }, } @@ -108,8 +110,17 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - // 确定基础URL - targetBase := utils.GetTargetURL(h.client, r, pathConfig, decodedPath) + // 确定标基础URL + targetBase := pathConfig.DefaultTarget + + // 检查文件扩展名 + if pathConfig.ExtensionMap != nil { + ext := strings.ToLower(path.Ext(decodedPath)) + if ext != "" { + ext = ext[1:] // 移除开头的点 + targetBase = pathConfig.GetTargetForExt(ext) + } + } // 重新编码路径,保留 '/' parts := strings.Split(decodedPath, "/") @@ -223,8 +234,10 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // 大响应使用流式传输 var bytesCopied int64 if f, ok := w.(http.Flusher); ok { - buf := bufferPool.Get().([]byte) - defer bufferPool.Put(buf) + bufPtr := bufferPool.Get().(*[]byte) + defer bufferPool.Put(bufPtr) + buf := *bufPtr + for { n, rerr := resp.Body.Read(buf) if n > 0 {