-
Notifications
You must be signed in to change notification settings - Fork 5
/
utils.go
47 lines (43 loc) · 1.34 KB
/
utils.go
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
// Copyright 2021 Changkun Ou. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.
package main
import (
"log"
"net"
"net/http"
"strings"
)
// logging is a basic logger that prints the request history.
func logging(logger *log.Logger) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
logger.Println(readIP(r), r.Method, r.URL.Path)
}()
next.ServeHTTP(w, r)
})
}
}
// readIP implements a best effort approach to return the real client IP,
// it parses X-Real-IP and X-Forwarded-For in order to work properly with
// reverse-proxies such us: nginx or haproxy. Use X-Forwarded-For before
// X-Real-Ip as nginx uses X-Real-Ip with the proxy's IP.
func readIP(r *http.Request) string {
clientIP := r.Header.Get("X-Forwarded-For")
clientIP = strings.TrimSpace(strings.Split(clientIP, ",")[0])
if clientIP == "" {
clientIP = strings.TrimSpace(r.Header.Get("X-Real-Ip"))
}
if clientIP != "" {
return clientIP
}
if addr := r.Header.Get("X-Appengine-Remote-Addr"); addr != "" {
return addr
}
ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr))
if err != nil {
return "unknown" // use unknown to guarantee non empty string
}
return ip
}