mirror of
https://github.com/woodchen-ink/proxy-go.git
synced 2025-07-18 16:41:54 +08:00
refactor(internal): improve logging and byte format in proxy handlers
This commit is contained in:
parent
8f2c035e93
commit
b1b6a430cd
@ -128,13 +128,6 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
// 设置正确的 Content-Type
|
|
||||||
if strings.HasSuffix(strings.ToLower(decodedPath), ".mp4") {
|
|
||||||
w.Header().Set("Content-Type", "video/mp4")
|
|
||||||
} else if ct := resp.Header.Get("Content-Type"); ct != "" {
|
|
||||||
w.Header().Set("Content-Type", ct)
|
|
||||||
}
|
|
||||||
|
|
||||||
copyHeader(w.Header(), resp.Header)
|
copyHeader(w.Header(), resp.Header)
|
||||||
|
|
||||||
// 设置响应状态码
|
// 设置响应状态码
|
||||||
@ -172,9 +165,9 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 记录访问日志
|
// 记录访问日志
|
||||||
log.Printf("[%s] %s %s -> %s -> %d (%d bytes) [%v]",
|
log.Printf("[%s] %s %s -> %s -> %d (%s) [%v]",
|
||||||
getClientIP(r), r.Method, r.URL.Path, targetURL,
|
getClientIP(r), r.Method, r.URL.Path, targetURL,
|
||||||
resp.StatusCode, bytesCopied, time.Since(startTime))
|
resp.StatusCode, formatBytes(bytesCopied), time.Since(startTime))
|
||||||
}
|
}
|
||||||
|
|
||||||
func copyHeader(dst, src http.Header) {
|
func copyHeader(dst, src http.Header) {
|
||||||
@ -197,3 +190,19 @@ func getClientIP(r *http.Request) string {
|
|||||||
}
|
}
|
||||||
return r.RemoteAddr
|
return r.RemoteAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func formatBytes(bytes int64) string {
|
||||||
|
const (
|
||||||
|
MB = 1024 * 1024
|
||||||
|
KB = 1024
|
||||||
|
)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case bytes >= MB:
|
||||||
|
return fmt.Sprintf("%.2f MB", float64(bytes)/MB)
|
||||||
|
case bytes >= KB:
|
||||||
|
return fmt.Sprintf("%.2f KB", float64(bytes)/KB)
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("%d Bytes", bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"proxy-go/internal/config"
|
"proxy-go/internal/config"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FixedPathConfig struct {
|
type FixedPathConfig struct {
|
||||||
@ -18,6 +22,7 @@ type FixedPathConfig struct {
|
|||||||
func FixedPathProxyMiddleware(configs []config.FixedPathConfig) func(http.Handler) http.Handler {
|
func FixedPathProxyMiddleware(configs []config.FixedPathConfig) func(http.Handler) http.Handler {
|
||||||
return func(next http.Handler) http.Handler {
|
return func(next http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
startTime := time.Now() // 添加时间记录
|
||||||
// 检查是否匹配任何固定路径
|
// 检查是否匹配任何固定路径
|
||||||
for _, cfg := range configs {
|
for _, cfg := range configs {
|
||||||
if strings.HasPrefix(r.URL.Path, cfg.Path) {
|
if strings.HasPrefix(r.URL.Path, cfg.Path) {
|
||||||
@ -28,6 +33,8 @@ func FixedPathProxyMiddleware(configs []config.FixedPathConfig) func(http.Handle
|
|||||||
proxyReq, err := http.NewRequest(r.Method, targetURL, r.Body)
|
proxyReq, err := http.NewRequest(r.Method, targetURL, r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Error creating proxy request", http.StatusInternalServerError)
|
http.Error(w, "Error creating proxy request", http.StatusInternalServerError)
|
||||||
|
log.Printf("[%s] %s %s -> 500 (error creating request: %v) [%v]",
|
||||||
|
getClientIP(r), r.Method, r.URL.Path, err, time.Since(startTime))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +56,8 @@ func FixedPathProxyMiddleware(configs []config.FixedPathConfig) func(http.Handle
|
|||||||
resp, err := client.Do(proxyReq)
|
resp, err := client.Do(proxyReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Error forwarding request", http.StatusBadGateway)
|
http.Error(w, "Error forwarding request", http.StatusBadGateway)
|
||||||
|
log.Printf("[%s] %s %s -> 502 (proxy error: %v) [%v]",
|
||||||
|
getClientIP(r), r.Method, r.URL.Path, err, time.Since(startTime))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
@ -64,10 +73,16 @@ func FixedPathProxyMiddleware(configs []config.FixedPathConfig) func(http.Handle
|
|||||||
w.WriteHeader(resp.StatusCode)
|
w.WriteHeader(resp.StatusCode)
|
||||||
|
|
||||||
// 复制响应体
|
// 复制响应体
|
||||||
if _, err := io.Copy(w, resp.Body); err != nil {
|
bytesCopied, err := io.Copy(w, resp.Body)
|
||||||
// 已经发送了响应头,只能记录错误
|
if err := handleCopyError(err); err != nil {
|
||||||
log.Printf("Error copying response: %v", err)
|
log.Printf("[%s] Error copying response: %v", getClientIP(r), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 记录成功的请求
|
||||||
|
log.Printf("[%s] %s %s -> %s -> %d (%s) [%v]",
|
||||||
|
getClientIP(r), r.Method, r.URL.Path, targetURL,
|
||||||
|
resp.StatusCode, formatBytes(bytesCopied), time.Since(startTime))
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,3 +106,36 @@ func getClientIP(r *http.Request) string {
|
|||||||
}
|
}
|
||||||
return r.RemoteAddr
|
return r.RemoteAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleCopyError(err error) error {
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 忽略常见的连接关闭错误
|
||||||
|
if errors.Is(err, syscall.EPIPE) || // broken pipe
|
||||||
|
errors.Is(err, syscall.ECONNRESET) || // connection reset by peer
|
||||||
|
strings.Contains(err.Error(), "broken pipe") ||
|
||||||
|
strings.Contains(err.Error(), "connection reset by peer") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// formatBytes 将字节数转换为可读的格式(MB/KB/Bytes)
|
||||||
|
func formatBytes(bytes int64) string {
|
||||||
|
const (
|
||||||
|
MB = 1024 * 1024
|
||||||
|
KB = 1024
|
||||||
|
)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case bytes >= MB:
|
||||||
|
return fmt.Sprintf("%.2f MB", float64(bytes)/MB)
|
||||||
|
case bytes >= KB:
|
||||||
|
return fmt.Sprintf("%.2f KB", float64(bytes)/KB)
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("%d Bytes", bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user