mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-04-18 14:17:27 +00:00
140 lines
2.7 KiB
Go
140 lines
2.7 KiB
Go
package jsrt
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"maps"
|
|
"net/http"
|
|
"sync"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// 请求
|
|
type JSReq struct {
|
|
Method string `json:"method"`
|
|
URL string `json:"url"`
|
|
Headers map[string]string `json:"headers"`
|
|
Body any `json:"body"`
|
|
UserAgent string `json:"userAgent"`
|
|
RemoteIP string `json:"remoteIP"`
|
|
Extra map[string]any `json:"extra"`
|
|
}
|
|
|
|
type JSResponse struct {
|
|
StatusCode int `json:"statusCode"`
|
|
Headers map[string]string `json:"headers"`
|
|
Body string `json:"body"`
|
|
}
|
|
|
|
type responseWriter struct {
|
|
gin.ResponseWriter
|
|
body *bytes.Buffer
|
|
statusCode int
|
|
headerMap http.Header
|
|
written bool
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
func createJSReq(c *gin.Context) *JSReq {
|
|
var bodyBytes []byte
|
|
if c.Request != nil && c.Request.Body != nil {
|
|
bodyBytes, _ = io.ReadAll(c.Request.Body)
|
|
c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
|
|
}
|
|
|
|
// headers map
|
|
headers := make(map[string]string)
|
|
if c.Request != nil && c.Request.Header != nil {
|
|
for key, values := range c.Request.Header {
|
|
if len(values) > 0 {
|
|
headers[key] = values[0]
|
|
}
|
|
}
|
|
}
|
|
|
|
method := ""
|
|
url := ""
|
|
userAgent := ""
|
|
remoteIP := ""
|
|
contentType := ""
|
|
|
|
if c.Request != nil {
|
|
method = c.Request.Method
|
|
if c.Request.URL != nil {
|
|
url = c.Request.URL.String()
|
|
}
|
|
userAgent = c.Request.UserAgent()
|
|
contentType = c.ContentType()
|
|
}
|
|
|
|
if c != nil {
|
|
remoteIP = c.ClientIP()
|
|
}
|
|
|
|
parsedBody := parseBodyByType(bodyBytes, contentType)
|
|
|
|
return &JSReq{
|
|
Method: method,
|
|
URL: url,
|
|
Headers: headers,
|
|
Body: parsedBody,
|
|
UserAgent: userAgent,
|
|
RemoteIP: remoteIP,
|
|
Extra: make(map[string]any),
|
|
}
|
|
}
|
|
|
|
func newResponseWriter(w gin.ResponseWriter) *responseWriter {
|
|
return &responseWriter{
|
|
ResponseWriter: w,
|
|
body: &bytes.Buffer{},
|
|
statusCode: 200,
|
|
headerMap: make(http.Header),
|
|
written: false,
|
|
}
|
|
}
|
|
|
|
func (w *responseWriter) Write(data []byte) (int, error) {
|
|
w.mu.Lock()
|
|
defer w.mu.Unlock()
|
|
|
|
if !w.written {
|
|
w.WriteHeader(200)
|
|
}
|
|
return w.body.Write(data)
|
|
}
|
|
|
|
func (w *responseWriter) WriteString(s string) (int, error) {
|
|
w.mu.Lock()
|
|
defer w.mu.Unlock()
|
|
|
|
if !w.written {
|
|
w.WriteHeader(200)
|
|
}
|
|
return w.body.WriteString(s)
|
|
}
|
|
|
|
func (w *responseWriter) WriteHeader(statusCode int) {
|
|
w.mu.Lock()
|
|
defer w.mu.Unlock()
|
|
|
|
if w.written {
|
|
return
|
|
}
|
|
w.statusCode = statusCode
|
|
w.written = true
|
|
|
|
maps.Copy(w.headerMap, w.ResponseWriter.Header())
|
|
}
|
|
|
|
func (w *responseWriter) Header() http.Header {
|
|
w.mu.RLock()
|
|
defer w.mu.RUnlock()
|
|
|
|
if w.headerMap == nil {
|
|
w.headerMap = make(http.Header)
|
|
}
|
|
return w.headerMap
|
|
}
|