feat: get client IP from the request headers#233
Conversation
This will allow us to re-use the handling of packets in the Caddy server where serving is handled separately.
Instead, make the connection an association by wrapping it with the client address and pass that to the `Handle()` function. Each connection will call `Handle()` only once.
| // GetClientIPFromRequest retrieves the client's IP address from the request. | ||
| // This checks common headers that forward the client IP, falling back to the | ||
| // request's `RemoteAddr`. | ||
| func GetClientIPFromRequest(r *http.Request) (net.IP, error) { |
There was a problem hiding this comment.
I need the request to fallback to the RemoteAddr. I could move that out of this function, but I think I'll leave this right now and revisit in a refactor that will likely do away with this function altogether.
| // `Forwarded` (RFC 7239). | ||
| forwardedHeader := r.Header.Get("Forwarded") | ||
| if forwardedHeader != "" { | ||
| parts := strings.Split(forwardedHeader, ",") |
There was a problem hiding this comment.
This is acceptable for this PR, but you need to update it later to use proper libraries to parse this format.
I believe https://pkg.go.dev/net/textproto#Reader.ReadMIMEHeader will give you the list of values, which you can then split. We need to figure out what the format is based on the RFC. We can look into what the net lib does.
There was a problem hiding this comment.
Yeah I think the gorilla library actually has some basic function for this as well: https://github.com/gorilla/handlers/blob/9c61bd81e701cf500437e1b516b675cdd3b73ca7/proxy_headers.go#L21 I'll likely revisit this when moving to that.
This checks the headers for common client IP forwarding headers, falling back to the request's
RemoteAddrif they don't exist.I started with the most common headers:
Forwarded,X-Forwarded-For, andX-Client-IP. I think that covers most cases, but we can add more in a future PR.