Browse Source

fix: read client ip from x-real-ip

master 1.8.2
OhYee 2 weeks ago
parent
commit
80c7365320
Signed by: OhYee
GPG Key ID: 5A9E1F63ED274FBB
  1. 4
      api/comments.go
  2. 3
      register/context.go
  3. 9
      register/context_http.go
  4. 9
      register/context_websocket.go
  5. 5
      register/register.go
  6. 23
      register/utils.go
  7. 15
      utils/geoip/geoip.go
  8. 63
      utils/geoip/geoip_test.go

4
api/comments.go

@ -7,7 +7,6 @@ import ( @@ -7,7 +7,6 @@ import (
"github.com/OhYee/blotter/api/pkg/comment"
"github.com/OhYee/blotter/register"
"github.com/OhYee/blotter/utils/geoip"
)
// CommentsRequest request of comments api
@ -62,8 +61,7 @@ func CommentAdd(context register.HandleContext) (err error) { @@ -62,8 +61,7 @@ func CommentAdd(context register.HandleContext) (err error) {
return
}
req := context.GetRequest()
ipAddr := geoip.GetIPFromHeader(&req.Header)
ipAddr := context.GetClientIP()
if err = comment.Add(args.URL, args.Reply, args.Email, args.Recv, args.Raw, ipAddr); err != nil {
if errors.Is(err, comment.ErrShake) {

3
register/context.go

@ -50,4 +50,7 @@ type HandleContext interface { @@ -50,4 +50,7 @@ type HandleContext interface {
// GetContext get global context
GetContext(key string) (interface{}, bool)
// GetClientIP
GetClientIP() string
}

9
register/context_http.go

@ -205,3 +205,12 @@ func (context *HTTPContext) GetUser() *user.TypeDB { @@ -205,3 +205,12 @@ func (context *HTTPContext) GetUser() *user.TypeDB {
func (context *HTTPContext) GetContext(key string) (value interface{}, ok bool) {
return GetContext(key)
}
// GetClientIP returns client ip
func (context *HTTPContext) GetClientIP() string {
clientIP := getIPFromHeader(&context.Request.Header, X_Real_IP)
if clientIP == "" {
clientIP = getIPFromHeader(&context.Request.Header, X_FORWARDED_FOR)
}
return clientIP
}

9
register/context_websocket.go

@ -124,3 +124,12 @@ func (context *WebSocketContext) GetUser() *user.TypeDB { @@ -124,3 +124,12 @@ func (context *WebSocketContext) GetUser() *user.TypeDB {
func (context *WebSocketContext) GetContext(key string) (value interface{}, ok bool) {
return GetContext(key)
}
// GetClientIP returns client ip
func (context *WebSocketContext) GetClientIP() string {
clientIP := getIPFromHeader(&context.Request.Header, X_Real_IP)
if clientIP == "" {
clientIP = getIPFromHeader(&context.Request.Header, X_FORWARDED_FOR)
}
return clientIP
}

5
register/register.go

@ -54,14 +54,15 @@ func Call(name string, context *HTTPContext) (err error) { @@ -54,14 +54,15 @@ func Call(name string, context *HTTPContext) (err error) {
defer func() {
rec := recover()
if rec != nil {
err = fmt.Errorf("Recover error: %+v", rec)
err = fmt.Errorf("recover error: %+v", rec)
output.ErrOutput.Println(err)
}
}()
output.Log("%s:%s [%s] %s\nCall api %s, %s, %s [%s]",
output.Log("%s:%s [%s] %s %s\nCall api %s, %s, %s [%s]",
context.Request.Method,
context.Request.Host,
context.GetClientIP(),
context.Request.Header.Get("nginx"),
context.Request.UserAgent(),
name,

23
register/utils.go

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
package register
import (
"net/http"
"strings"
)
const (
X_Real_IP = "X-Real-Ip"
X_FORWARDED_FOR = "X-Forwarded-For"
)
func getIPFromHeader(header *http.Header, headerName string) string {
IPs := header.Values(headerName)
if len(IPs) > 0 {
remoteIP := IPs[0]
arr := strings.Split(remoteIP, ",")
if len(arr) > 0 {
return strings.TrimSpace(arr[0])
}
}
return ""
}

15
utils/geoip/geoip.go

@ -7,24 +7,9 @@ import ( @@ -7,24 +7,9 @@ import (
"net/http"
"strings"
_ "embed"
"github.com/OhYee/rainbow/log"
)
func GetIPFromHeader(header *http.Header) string {
xForwardedFor := header.Values("X-Forwarded-For")
if len(xForwardedFor) > 0 {
remoteIP := xForwardedFor[0]
arr := strings.Split(remoteIP, ",")
if len(arr) > 0 {
return strings.ReplaceAll(arr[0], " ", "")
}
return ""
}
return ""
}
type IPInfo struct {
Status string
Country string

63
utils/geoip/geoip_test.go

@ -1,63 +0,0 @@ @@ -1,63 +0,0 @@
package geoip
import (
_ "embed"
"net/http"
"testing"
)
func TestGetIPFromHeader(t *testing.T) {
tests := []struct {
name string
header *http.Header
want string
}{
{
name: "empty header",
header: &http.Header{},
want: "",
},
{
name: "empty X-Forwarded-For",
header: &http.Header{
"X-Forwarded-For": []string{},
},
want: "",
},
{
name: "one ip",
header: &http.Header{
"X-Forwarded-For": []string{"127.0.0.1"},
},
want: "127.0.0.1",
},
{
name: "one ip",
header: &http.Header{
"X-Forwarded-For": []string{"127.0.0.1"},
},
want: "127.0.0.1",
},
{
name: "two ip in arr",
header: &http.Header{
"X-Forwarded-For": []string{"127.0.0.1", "127.0.0.2"},
},
want: "127.0.0.1",
},
{
name: "two ip in string",
header: &http.Header{
"X-Forwarded-For": []string{"127.0.0.1, 127.0.0.2"},
},
want: "127.0.0.1",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := GetIPFromHeader(tt.header); got != tt.want {
t.Errorf("GetIPFromHeader() = %v, want %v", got, tt.want)
}
})
}
}
Loading…
Cancel
Save