summaryrefslogtreecommitdiff
path: root/reqToPB.go
blob: 019ad779c04e281e89af857b7c341f5753538287 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// 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,
		IP:            getClientIP(r),
		Host:          r.Host,
		ClientData:    msg,
		ClientDataLen: int64(len(msg)),
		Hostname:      r.Header.Get("hostname"),
	}
	pb.Route = cleanURL(r.URL.Path)

	return pb, err
}