-
Notifications
You must be signed in to change notification settings - Fork 6
/
example_middleware_test.go
69 lines (56 loc) · 1.93 KB
/
example_middleware_test.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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package realclientip_test
import (
"context"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
"github.com/realclientip/realclientip-go"
)
func Example_middleware() {
// Choose the right strategy for our network configuration
strat, err := realclientip.NewRightmostNonPrivateStrategy("X-Forwarded-For")
if err != nil {
log.Fatal("realclientip.NewRightmostNonPrivateStrategy returned error (bad input)")
}
// Place our middleware before the handler
handlerWithMiddleware := clientIPMiddleware(strat, http.HandlerFunc(handler))
httpServer := httptest.NewServer(handlerWithMiddleware)
defer httpServer.Close()
req, _ := http.NewRequest("GET", httpServer.URL, nil)
req.Header.Add("X-Forwarded-For", "1.1.1.1, 2.2.2.2, 3.3.3.3, 192.168.1.1")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", b)
// Output:
// your IP: 3.3.3.3
}
type clientIPCtxKey struct{}
// Adds the "real" client IP to the request context under the clientIPCtxKey{} key.
// If the client IP couldn't be obtained, the value will be an empty string.
// We could use the RightmostNonPrivateStrategy concrete type, but instead we'll pass
// around the Strategy interface, in case we decide to change our strategy in the future.
func clientIPMiddleware(strat realclientip.Strategy, next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
clientIP := strat.ClientIP(r.Header, r.RemoteAddr)
if clientIP == "" {
// Write error log. Consider aborting the request depending on use.
log.Fatal("Failed to find client IP")
}
r = r.WithContext(context.WithValue(r.Context(), clientIPCtxKey{}, clientIP))
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
func handler(w http.ResponseWriter, r *http.Request) {
clientIP := r.Context().Value(clientIPCtxKey{})
fmt.Fprintln(w, "your IP:", clientIP)
}