diff --git a/cmd/web/handlers.go b/cmd/web/handlers.go index 3ea84e7..0dbba95 100644 --- a/cmd/web/handlers.go +++ b/cmd/web/handlers.go @@ -277,7 +277,7 @@ func (app *application) createVotesHandleKnownVotersElection(w http.ResponseWrit } func (app *application) createVotesHandleUnknownVotersElection(w http.ResponseWriter, r *http.Request, election *models.Election) (string, error) { - voterIdentity := r.RemoteAddr + voterIdentity := realIP(r) voterExists, err := app.voters.Exists(voterIdentity, election.ID) if err != nil { diff --git a/cmd/web/helpers.go b/cmd/web/helpers.go index 9668ab1..3aba5ce 100644 --- a/cmd/web/helpers.go +++ b/cmd/web/helpers.go @@ -5,7 +5,9 @@ import ( "code.dlmw.ch/dlmw/qv/internal/validator" "encoding/json" "io" + "net" "net/http" + "strings" ) func (app *application) serverError(w http.ResponseWriter, r *http.Request, err error) { @@ -67,3 +69,23 @@ func (app *application) unmarshalRequest(r *http.Request, dst any) error { return nil } + +func realIP(r *http.Request) string { + var ip string + + if tcip := r.Header.Get(http.CanonicalHeaderKey("True-Client-IP")); tcip != "" { + ip = tcip + } else if xrip := r.Header.Get(http.CanonicalHeaderKey("X-Real-IP")); xrip != "" { + ip = xrip + } else if xff := r.Header.Get(http.CanonicalHeaderKey("X-Forwarded-For")); xff != "" { + i := strings.Index(xff, ",") + if i == -1 { + i = len(xff) + } + ip = xff[:i] + } + if ip == "" || net.ParseIP(ip) == nil { + return "" + } + return ip +} diff --git a/cmd/web/middleware.go b/cmd/web/middleware.go index 220d110..d0dc1fd 100644 --- a/cmd/web/middleware.go +++ b/cmd/web/middleware.go @@ -20,7 +20,7 @@ func (app *application) recoverPanic(next http.Handler) http.Handler { func (app *application) logRequest(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var ( - ip = r.RemoteAddr + ip = realIP(r) proto = r.Proto method = r.Method uri = r.URL.RequestURI()