Nhìn vào http.Request bạn có thể tìm thấy các biến thành viên sau đây:
// HTTP defines that header names are case-insensitive.
// The request parser implements this by canonicalizing the
// name, making the first character and any characters
// following a hyphen uppercase and the rest lowercase.
//
// For client requests certain headers are automatically
// added and may override values in Header.
//
// See the documentation for the Request.Write method.
Header Header
// RemoteAddr allows HTTP servers and other software to record
// the network address that sent the request, usually for
// logging. This field is not filled in by ReadRequest and
// has no defined format. The HTTP server in this package
// sets RemoteAddr to an "IP:port" address before invoking a
// handler.
// This field is ignored by the HTTP client.
RemoteAddr string
Bạn có thể sử dụng RemoteAddr
để có được địa chỉ IP và cổng khách hàng từ xa (định dạng là "IP: port"), đó là địa chỉ của người yêu cầu ban đầu hoặc proxy cuối cùng (ví dụ: trình cân bằng tải ở trước máy chủ của bạn).
Đây là tất cả những gì bạn có.
Sau đó, bạn có thể điều tra các tiêu đề, đó là case-insensitive (mỗi tài liệu hướng dẫn ở trên), có nghĩa là tất cả các ví dụ của bạn sẽ làm việc và mang lại kết quả tương tự:
req.Header.Get("X-Forwarded-For") // capitalisation
req.Header.Get("x-forwarded-for") // doesn't
req.Header.Get("X-FORWARDED-FOR") // matter
Điều này là do trong nội bộ http.Header.Get
sẽ chuẩn hóa khóa cho bạn. (Nếu bạn muốn truy cập trực tiếp vào bản đồ tiêu đề và không thông qua Get
, trước tiên bạn sẽ cần phải sử dụng http.CanonicalHeaderKey.)
Cuối cùng, "X-Forwarded-For"
có lẽ là trường bạn muốn xem thêm thông tin về khách hàng IP. Điều này phụ thuộc rất nhiều vào phần mềm HTTP được sử dụng ở phía xa mặc dù, như khách hàng có thể đặt bất cứ điều gì trong đó nếu nó muốn. Ngoài ra, hãy lưu ý rằng expected format của trường này là danh sách địa chỉ IP được phân tách bằng dấu phẩy + dấu cách.Bạn sẽ cần phải phân tích nó một chút để có được một IP duy nhất của sự lựa chọn của bạn (có thể là người đầu tiên trong danh sách), ví dụ:
// Assuming format is as expected
ips := strings.Split("10.0.0.1, 10.0.0.2, 10.0.0.3", ", ")
for _, ip := range ips {
fmt.Println(ip)
}
sẽ sản xuất:
10.0.0.1
10.0.0.2
10.0.0.3
Cách tôi đọc tài liệu cho 'req.Header', bạn chỉ cần thực hiện' req.Header.Get ("X-Forwarded-For") ', như các trường hợp khác được chuẩn hóa vào đó bởi trình phân tích cú pháp. –
Có, tất nhiên, câu trả lời của tôi cho biết _all_ các biến thể sẽ hoạt động vì tiêu đề không phân biệt chữ hoa chữ thường. Tôi đã đề cập đến những điều này chỉ vì OP đã hỏi về độ nhạy của trường hợp, nhưng có thể thấy từ ngữ có thể gây nhầm lẫn. Sẽ nâng cấp. – tomasz
yep, tiêu đề phân biệt chữ hoa chữ thường, nhưng bạn sẽ sử dụng 'http.CanonicalHeaderKey' thay vì thử tất cả các kết hợp chữ hoa và chữ thường. – bithavoc