// 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") } } 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, RemoteAddr: getClientIP(r), Host: r.Host, Body: msg, Hostname: r.Header.Get("hostname"), } pb.Route = cleanURL(r.URL.Path) return pb, err }