Skip to content

Commit

Permalink
pinpoint-apm#137 detect Actual ClientIP .
Browse files Browse the repository at this point in the history
  • Loading branch information
emeroad committed Jan 23, 2015
1 parent c097b52 commit c6549bd
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright 2014 NAVER Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.navercorp.pinpoint.bootstrap.interceptor;

/**
* @author emeroad
*/
public interface RemoteAddressResolver<T> {
String resolve(T target);
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public class StandardHostValveInvokeInterceptor extends SpanSimpleAroundIntercep
private final boolean isTrace = logger.isTraceEnabled();
private Filter<String> excludeUrlFilter;

private RemoteAddressResolver<HttpServletRequest> remoteAddressResolver;

public StandardHostValveInvokeInterceptor() {
super(StandardHostValveInvokeInterceptor.class);
}
Expand All @@ -58,7 +60,7 @@ protected void doInBeforeTrace(RecordableTrace trace, Object target, Object[] ar
final String endPoint = request.getServerName() + ":" + port;
trace.recordEndPoint(endPoint);

final String remoteAddr = request.getRemoteAddr();
final String remoteAddr = remoteAddressResolver.resolve(request);
trace.recordRemoteAddress(remoteAddr);
}

Expand All @@ -67,6 +69,62 @@ protected void doInBeforeTrace(RecordableTrace trace, Object target, Object[] ar
}
}

// TODO this code have a classLoader problem. CL problem can be solved by #117(Implement profiler plugin system)
public static class Bypass<T extends HttpServletRequest> implements RemoteAddressResolver<T> {

@Override
public String resolve(T servletRequest) {
return servletRequest.getRemoteAddr();
}
}

public static class Proxy<T extends HttpServletRequest> implements RemoteAddressResolver<T> {

public static final String X_FORWARDED_FOR = "x-forwarded-for";
public static final String UNKNOWN = "unknown";

private final String proxyHeaderName;
private final String emptyHeaderValue;

public Proxy() {
this(X_FORWARDED_FOR, UNKNOWN);
}

public Proxy(String proxyHeaderName, String emptyHeaderValue) {
if (proxyHeaderName == null) {
throw new NullPointerException("proxyHeaderName must not be null");
}
if (emptyHeaderValue == null) {
throw new NullPointerException("emptyHeaderValue must not be null");
}
this.proxyHeaderName = proxyHeaderName;
this.emptyHeaderValue = emptyHeaderValue;
}

@Override
public String resolve(T httpServletRequest) {
final String proxyHeader = httpServletRequest.getHeader(this.proxyHeaderName);

if (proxyHeader == null || proxyHeader.isEmpty()) {
return httpServletRequest.getRemoteAddr();
}

if (emptyHeaderValue.equalsIgnoreCase(proxyHeader)) {
return httpServletRequest.getRemoteAddr();
}

final int firstIndex = proxyHeader.indexOf(',');
if (firstIndex == -1) {
return proxyHeader;
} else {
return proxyHeader.substring(0, firstIndex);
}
}
}




@Override
protected Trace createTrace(Object target, Object[] args) {
final HttpServletRequest request = (HttpServletRequest) args[0];
Expand Down Expand Up @@ -218,5 +276,13 @@ public void setTraceContext(TraceContext traceContext) {
ProfilerConfig profilerConfig = traceContext.getProfilerConfig();

this.excludeUrlFilter = profilerConfig.getTomcatExcludeUrlFilter();

// TODO read configuration = profilerConfig.getTomcatProxyHeader();
boolean proxyHeaderExist = true;
if (proxyHeaderExist) {
remoteAddressResolver = new Proxy<HttpServletRequest>();
} else {
remoteAddressResolver = new Bypass<HttpServletRequest>();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright 2014 NAVER Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.navercorp.pinpoint.profiler.util;

/**
* @author emeroad
*/
public interface RemoteAddressResolver<T> {
String resolveRemoteAddress(T target);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2014 NAVER Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.navercorp.pinpoint.profiler.modifier.tomcat.interceptor;

import junit.framework.Assert;
import org.junit.Test;

import javax.servlet.http.HttpServletRequest;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class ProxyTest {

private final String xForwardedFor = StandardHostValveInvokeInterceptor.Proxy.X_FORWARDED_FOR;

@Test
public void testProxyHeader() {

HttpServletRequest mock = mock(HttpServletRequest.class);
when(mock.getHeader(xForwardedFor)).thenReturn("127.0.0.1");
when(mock.getRemoteAddr()).thenReturn("127.0.0.2");


StandardHostValveInvokeInterceptor.Proxy<HttpServletRequest> proxy = new StandardHostValveInvokeInterceptor.Proxy<HttpServletRequest>();
String resolve = proxy.resolve(mock);
Assert.assertEquals(resolve, "127.0.0.1");


}

@Test
public void testProxyHeader_proxy1() {

HttpServletRequest mock = mock(HttpServletRequest.class);
when(mock.getHeader(xForwardedFor)).thenReturn("127.0.0.1, proxy1, proxy2");
when(mock.getRemoteAddr()).thenReturn("127.0.0.2");

StandardHostValveInvokeInterceptor.Proxy<HttpServletRequest> proxy = new StandardHostValveInvokeInterceptor.Proxy<HttpServletRequest>();
String resolve = proxy.resolve(mock);
Assert.assertEquals(resolve, "127.0.0.1");

}

@Test
public void testProxyHeader_proxy2() {

HttpServletRequest mock = mock(HttpServletRequest.class);
when(mock.getHeader(xForwardedFor)).thenReturn("127.0.0.1,");
when(mock.getRemoteAddr()).thenReturn("127.0.0.2");

StandardHostValveInvokeInterceptor.Proxy<HttpServletRequest> proxy = new StandardHostValveInvokeInterceptor.Proxy<HttpServletRequest>();
String resolve = proxy.resolve(mock);
Assert.assertEquals(resolve, "127.0.0.1");
}

@Test
public void testProxyHeader_header_not_exist() {

HttpServletRequest mock = mock(HttpServletRequest.class);
when(mock.getRemoteAddr()).thenReturn("127.0.0.2");


StandardHostValveInvokeInterceptor.Proxy<HttpServletRequest> proxy = new StandardHostValveInvokeInterceptor.Proxy<HttpServletRequest>();
String resolve = proxy.resolve(mock);
Assert.assertEquals(resolve, "127.0.0.2");

}

}

0 comments on commit c6549bd

Please sign in to comment.