2012-08-22 15 views
6

Các mã sau đây được trở về không đúng cách, từ những gì tôi hiểu:HttpServletRequest getRemoteAddr() không làm việc thế nào tôi sẽ mong đợi

HttpServletRequest httpRequest = (HttpServletRequest) request; 
String userIPAddress = httpRequest.getRemoteAddr(); 

// Actual 
// "0:0:0:0:0:0:0:1%0" 

// Expected 
// "0:0:0:0:0:0:0:1" 

Bất cứ ý tưởng tại sao% 0 là có? Khi tôi vòng qua

InetAddress.getAllByName("localhost") 

tôi nhận được như sau:

// ["192.168.100.1", "127.0.0.1", "0:0:0:0:0:0:1"] 

Làm thế nào tôi sẽ thử nghiệm cho localhost nếu getRemoteAddr() được trở về định dạng không hợp lệ, hoặc tôi đang làm điều gì sai?

Cảm ơn!

Trả lời

4

Vấn đề là hai chức năng

1) java.net.InetAddress.getAllByName (String)

2) javax.servlet.ServletRequest.getRemoteAddr()

Là rất khác nhau. Hàm đầu tiên là một phần của thời gian chạy Java chuẩn và hàm thứ hai được thực hiện bởi thùng chứa Java EE của bạn. Bạn đang sử dụng Tomcat7 vì vậy tham số vùng tùy chọn% 0 đang được thêm vào.

Tóm lại, bạn không nên thực hiện so sánh chuỗi trên các địa chỉ ip giống như bạn.

Điều bạn thực sự nên làm là sử dụng org.apache.catalina.filters.RemoteIpFilter. Điều này làm những gì bạn đang cố gắng làm theo một cách được xác định rõ.

Ví dụ:

<filter> 
    <filter-name>RemoteIpFilter</filter-name> 
    <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class> 
    <init-param> 
    <param-name>allowedInternalProxies</param-name> 
    <param-value>192\.168\.0\.10|192\.168\.0\.11</param-value> 
    </init-param> 
    <init-param> 
    <param-name>remoteIpHeader</param-name> 
    <param-value>x-forwarded-for</param-value> 
    </init-param> 
    <init-param> 
    <param-name>remoteIpProxiesHeader</param-name> 
    <param-value>x-forwarded-by</param-value> 
    </init-param> 
    <init-param> 
    <param-name>protocolHeader</param-name> 
    <param-value>x-forwarded-proto</param-value> 
    </init-param> 
</filter> 

Xem http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#Remote_IP_Filter để biết thêm.

+0

+1 để có thông tin/suy nghĩ tốt về thời gian chạy Java so với vùng chứa để thực thi cho hai phương thức. –

+0

Cảm ơn Phillip. –

2

0:0:0:0:0:0:0:1%0 là biểu mẫu dài hợp lệ cho máy chủ cục bộ IPv6. %0 chỉ định chỉ mục vùng tùy chọn.

Dưới đây là thông tin thêm về IPv6 Zone Indices.

Tôi không biết lý do tại sao một cuộc gọi đến httpRequest.getRemoteAddr(); đang trở lại chỉ số khu vực bắt buộc của% 0, và

InetAddress.getAllByName("localhost") 

không. Tuy nhiên, đề nghị của tôi là nếu bạn đang tìm kiếm để phù hợp trên localhost, bạn phù hợp trên cả hai mẫu, hoặc làm một trận đấu startsWith.

+0

Điều đó rất tốt để biết và thật kỳ lạ khi chúng trả về các kết quả khác nhau. Tôi không, tuy nhiên, muốn kiểm tra để bao gồm hoặc startsWith. Quá nhiều trường hợp lạ: 192.168.100.1> 192.168.100.12, v.v. – andrewpthorp

+1

Tài liệu cho InetAddress cho biết "có thể bao gồm chỉ mục phạm vi", vì vậy không có niềm vui theo cách đó ... http://download.java.net/jdk7/archive/b123/ docs/api/java/net/InetAddress.html # getAllByName% 28java.lang.String% 29 – Alfabravo

+0

Tôi đoán tôi hơi mơ hồ khi tôi đề cập đến "khớp trên cả hai mẫu hoặc thực hiện kết quả startWith". Xin cho phép tôi làm rõ. Câu hỏi của bạn được đề cập cụ thể không thể khớp với vì dấu '% 0'. Để khớp với địa chỉ IPv6, bạn nên bỏ qua chỉ mục vùng tùy chọn và chỉ khớp với '0: 0: 0: 0: 0: 0: 0: 1'. Chỉ số vùng tùy chọn này sẽ phụ thuộc vào hệ điều hành.Ví dụ, trên Linux, vòng lặp IPv6 của bạn có thể là '0: 0: 0: 0: 0: 0: 0: 1% eth0' và trên Windows, nó có thể là' 0: 0: 0: 0: 0: 0: 0: 1% 0' –

Các vấn đề liên quan