1
0
mirror of https://github.com/fumiama/yamaih.git synced 2026-06-05 00:10:28 +08:00
Files
yamaih/procuratio.go
2025-03-31 01:56:54 +09:00

111 lines
2.5 KiB
Go

package yamaih
import (
"bytes"
"fmt"
"io"
"net/http"
"strings"
"time"
)
func (g *Gemini) handler(w http.ResponseWriter, r *http.Request) {
extractIP(r)
if len(r.URL.Path) <= 1 {
fmt.Println("[ERR]", r.RemoteAddr, "400 Invalid Path", r.URL.String())
http.Error(w, "400 Invalid Path", http.StatusBadRequest)
return
}
k := r.URL.Query().Get("key")
if k == "" {
fmt.Println("[ERR]", r.RemoteAddr, "400 Empty API Key", r.URL.String())
http.Error(w, "400 Empty API Key", http.StatusBadRequest)
return
}
v := &Visit{
UserKey: k,
Time: time.Now().UnixMilli(),
IP: r.RemoteAddr,
Method: r.Method,
Path: r.URL.Path,
Query: r.URL.RawQuery,
}
respstr := ""
defer func() {
v.WaitMilli = time.Now().UnixMilli() - v.Time
if respstr != "" {
v.Response = []byte(respstr)
}
g.visit(v)
fmt.Println(v)
}()
apiver, _, _ := strings.Cut(r.URL.Path[1:], "/")
if apiver != g.apiver {
respstr = "400 Invalid API Version"
v.Code = 400
http.Error(w, respstr, http.StatusBadRequest)
return
}
defer r.Body.Close()
data, err := io.ReadAll(r.Body)
if err != nil {
respstr = "400 Bad Request: " + err.Error()
v.Code = 400
http.Error(w, respstr, http.StatusBadRequest)
return
}
v.Request = data
req, err := http.NewRequest(
r.Method, api+r.URL.String(), bytes.NewReader(data),
)
if err != nil {
respstr = "400 Bad Request: " + err.Error()
v.Code = 400
http.Error(w, respstr, http.StatusBadRequest)
return
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
respstr = "500 Do: " + err.Error()
v.Code = 500
http.Error(w, respstr, http.StatusInternalServerError)
return
}
defer resp.Body.Close()
v.Code = resp.StatusCode
h := w.Header()
for k, vs := range resp.Header {
lk := strings.ToLower(k)
if len(vs) == 0 || strings.HasPrefix(lk, "x-") {
continue
}
h.Set(k, vs[0])
for _, v := range vs[1:] {
h.Add(k, v)
}
}
w.WriteHeader(resp.StatusCode)
var b []byte
if resp.ContentLength > 0 {
b = make([]byte, 0, resp.ContentLength)
}
buf := bytes.NewBuffer(b)
_, _ = io.Copy(io.MultiWriter(w, buf), resp.Body)
v.Response = buf.Bytes()
}
// extractIP parse real IP addr to r.RemoteAddr from proxy
func extractIP(r *http.Request) {
raddr := r.RemoteAddr
realr := r.Header.Get("X-Forwarded-For")
if len(realr) > 0 && !strings.Contains(realr, "@") {
raddr = realr
} else {
realr = r.Header.Get("X-Real-IP")
if len(realr) > 0 && !strings.Contains(realr, "@") {
raddr = realr
}
}
r.RemoteAddr = raddr
}