httppb/reqToPB.go

85 lines
2.1 KiB
Go

// Copyright 1994-2025 WIT.COM Inc Licensed GPL 3.0
package httppb
import (
"io/ioutil"
"log"
"net"
"net/http"
"strings"
)
// remove '?' part and trailing '/'
func cleanURL(url string) string {
url = "/" + strings.Trim(url, "/")
return url
}
func getIpSimple(r *http.Request) string {
host, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
log.Printf("could not split host port: %v", err)
return r.RemoteAddr // Fallback
}
return host
}
// getClientIP inspects the request for common headers to find the true client IP.
func getClientIP(r *http.Request) string {
// Caddy sets the X-Forwarded-For header.
if forwardedFor := r.Header.Get("X-Forwarded-For"); forwardedFor != "" {
// The header can be a comma-separated list of IPs. The first one is the original client.
ips := strings.Split(forwardedFor, ",")
return strings.TrimSpace(ips[0])
}
// Fallback to RemoteAddr if the header is not present.
host, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
return r.RemoteAddr
}
return host
}
// converts an *http.Request to an http PB
func ReqToPB(r *http.Request) (*HttpRequest, error) {
// Convert the header map. http.Header is a map[string][]string.
// We'll just take the first value for each header for simplicity.
headers := make(map[string]string)
for name, values := range r.Header {
if len(values) > 0 {
headers[name] = strings.Join(values, "\n")
}
}
query := make(map[string]string)
for param, values := range r.URL.Query() {
if len(values) > 0 {
query[param] = strings.Join(values, "\n")
}
}
msg, err := ioutil.ReadAll(r.Body) // Read the body as []byte
r.Body.Close()
// log.Info("TRYING TO MARSHAL bytes:", len(msg), err)
pb := &HttpRequest{
Method: r.Method,
URL: r.URL.String(),
Proto: r.Proto,
Headers: headers,
IP: getClientIP(r),
Host: r.Host,
ClientData: msg,
ClientDataLen: int64(len(msg)),
Hostname: r.Header.Get("hostname"),
UserAgent: r.UserAgent(),
Query: query,
RemoteAddr: r.RemoteAddr,
}
pb.Route = cleanURL(r.URL.Path)
return pb, err
}