Skip to content

Commit 11c2b95

Browse files
author
Peter
committed
added ip filter
1 parent b31b36c commit 11c2b95

File tree

9 files changed

+206
-14
lines changed

9 files changed

+206
-14
lines changed

graphhopper.sh

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,14 @@ if [ "x$ACTION" = "xui" ] || [ "x$ACTION" = "xweb" ]; then
218218
RC_BASE=./web/src/main/webapp
219219

220220
if [ "x$GH_FOREGROUND" = "x" ]; then
221-
exec "$JAVA" $JAVA_OPTS -jar "$WEB_JAR" jetty.resourcebase=$RC_BASE jetty.port=$JETTY_PORT jetty.host=$JETTY_HOST config=$CONFIG \
222-
$GH_WEB_OPTS graph.location="$GRAPH" osmreader.osm="$OSM_FILE"
221+
exec "$JAVA" $JAVA_OPTS -jar "$WEB_JAR" jetty.resourcebase=$RC_BASE \
222+
jetty.port=$JETTY_PORT jetty.host=$JETTY_HOST \
223+
config=$CONFIG $GH_WEB_OPTS graph.location="$GRAPH" osmreader.osm="$OSM_FILE"
223224
# foreground => we never reach this here
224225
else
225-
exec "$JAVA" $JAVA_OPTS -jar "$WEB_JAR" jetty.resourcebase=$RC_BASE jetty.port=$JETTY_PORT jetty.host=$JETTY_HOST config=$CONFIG \
226-
$GH_WEB_OPTS graph.location="$GRAPH" osmreader.osm="$OSM_FILE" <&- &
226+
exec "$JAVA" $JAVA_OPTS -jar "$WEB_JAR" jetty.resourcebase=$RC_BASE \
227+
jetty.port=$JETTY_PORT jetty.host=$JETTY_HOST \
228+
config=$CONFIG $GH_WEB_OPTS graph.location="$GRAPH" osmreader.osm="$OSM_FILE" <&- &
227229
if [ "x$GH_PID_FILE" != "x" ]; then
228230
echo $! > $GH_PID_FILE
229231
fi

web/src/main/java/com/graphhopper/http/GHServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ protected void configure()
112112
binder().requireExplicitBindings();
113113

114114
install(new DefaultModule(args));
115-
install(new GHServletModule());
115+
install(new GHServletModule(args));
116116

117117
bind(GuiceFilter.class);
118118
}

web/src/main/java/com/graphhopper/http/GHServletModule.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package com.graphhopper.http;
1919

2020
import com.google.inject.servlet.ServletModule;
21+
import com.graphhopper.util.CmdArgs;
2122
import java.util.HashMap;
2223
import java.util.Map;
2324
import javax.inject.Singleton;
@@ -28,9 +29,11 @@
2829
public class GHServletModule extends ServletModule
2930
{
3031
protected Map<String, String> params = new HashMap<String, String>();
32+
private final CmdArgs args;
3133

32-
public GHServletModule()
34+
public GHServletModule( CmdArgs args )
3335
{
36+
this.args = args;
3437
params.put("mimeTypes", "text/html,"
3538
+ "text/plain,"
3639
+ "text/xml,"
@@ -46,10 +49,13 @@ protected void configureServlets()
4649
{
4750
filter("*").through(GHGZIPHook.class, params);
4851
bind(GHGZIPHook.class).in(Singleton.class);
49-
52+
5053
filter("*").through(CORSFilter.class, params);
5154
bind(CORSFilter.class).in(Singleton.class);
5255

56+
filter("*").through(IPFilter.class);
57+
bind(IPFilter.class).toInstance(new IPFilter(args.get("jetty.whiteips", ""), args.get("jetty.blackips", "")));
58+
5359
serve("/i18n*").with(I18NServlet.class);
5460
bind(I18NServlet.class).in(Singleton.class);
5561

web/src/main/java/com/graphhopper/http/GraphHopperServlet.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import com.graphhopper.routing.util.FlagEncoder;
2424
import com.graphhopper.util.*;
2525
import com.graphhopper.util.Helper;
26-
import com.graphhopper.util.Translation;
2726
import com.graphhopper.util.shapes.GHPoint;
2827
import java.io.IOException;
2928
import java.util.*;

web/src/main/java/com/graphhopper/http/GuiceServletConfig.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,27 @@
2424
import com.graphhopper.util.CmdArgs;
2525

2626
/**
27-
* Replacement of web.xml
27+
* Replacement of web.xml used only for container deployment. Preferred method is to use GHServer.
2828
* <p/>
2929
* http://code.google.com/p/google-guice/wiki/ServletModule
3030
* <p/>
3131
* @author Peter Karich
3232
*/
3333
public class GuiceServletConfig extends GuiceServletContextListener
3434
{
35+
private final CmdArgs args;
36+
37+
public GuiceServletConfig()
38+
{
39+
try
40+
{
41+
args = CmdArgs.readFromConfig("config.properties", "graphhopper.config");
42+
} catch (Exception ex)
43+
{
44+
throw new RuntimeException(ex);
45+
}
46+
}
47+
3548
@Override
3649
protected Injector getInjector()
3750
{
@@ -40,11 +53,11 @@ protected Injector getInjector()
4053

4154
protected Module createDefaultModule()
4255
{
43-
return new DefaultModule(new CmdArgs());
56+
return new DefaultModule(args);
4457
}
4558

4659
protected Module createServletModule()
4760
{
48-
return new GHServletModule();
61+
return new GHServletModule(args);
4962
}
5063
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package com.graphhopper.http;
2+
3+
import java.io.IOException;
4+
import java.util.HashSet;
5+
import java.util.Set;
6+
import javax.servlet.*;
7+
import javax.servlet.http.HttpServletResponse;
8+
import org.slf4j.Logger;
9+
import org.slf4j.LoggerFactory;
10+
11+
/**
12+
* This IP filter class accepts a list of IPs for blacklisting OR for whitelisting (but not both).
13+
* <p>
14+
* Additionally to exact match a simple wildcard expression ala 1.2.3* or 1.*.3.4 is allowed.
15+
* <p>
16+
* The internal ip filter from jetty did not work (NP exceptions)
17+
* <p>
18+
* @author Peter Karich
19+
*/
20+
public class IPFilter implements Filter
21+
{
22+
private final Logger logger = LoggerFactory.getLogger(getClass());
23+
private final Set<String> whites;
24+
private final Set<String> blacks;
25+
26+
public IPFilter( String whiteList, String blackList )
27+
{
28+
whites = createSet(whiteList.split(","));
29+
blacks = createSet(blackList.split(","));
30+
if (!whites.isEmpty())
31+
logger.info("whitelist:" + whites);
32+
if (!blackList.isEmpty())
33+
logger.info("blacklist:" + blacks);
34+
35+
if (!blacks.isEmpty() && !whites.isEmpty())
36+
throw new IllegalArgumentException("blacklist and whitelist at the same time?");
37+
}
38+
39+
@Override
40+
public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException
41+
{
42+
String ip = request.getRemoteAddr();
43+
if (accept(ip))
44+
{
45+
chain.doFilter(request, response);
46+
} else
47+
{
48+
logger.warn("Did not accept IP " + ip);
49+
((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN);
50+
}
51+
}
52+
53+
public boolean accept( String ip )
54+
{
55+
if (whites.isEmpty() && blacks.isEmpty())
56+
return true;
57+
58+
if (!whites.isEmpty())
59+
{
60+
for (String w : whites)
61+
{
62+
if (simpleMatch(ip, w))
63+
return true;
64+
}
65+
return false;
66+
}
67+
68+
if (blacks.isEmpty())
69+
throw new IllegalStateException("cannot happen");
70+
71+
for (String b : blacks)
72+
{
73+
if (simpleMatch(ip, b))
74+
return false;
75+
}
76+
77+
return true;
78+
}
79+
80+
@Override
81+
public void init( FilterConfig filterConfig ) throws ServletException
82+
{
83+
}
84+
85+
@Override
86+
public void destroy()
87+
{
88+
}
89+
90+
private Set<String> createSet( String[] split )
91+
{
92+
Set<String> set = new HashSet<String>(split.length);
93+
for (String str : split)
94+
{
95+
str = str.trim();
96+
if (!str.isEmpty())
97+
set.add(str);
98+
}
99+
return set;
100+
}
101+
102+
public boolean simpleMatch( String ip, String pattern )
103+
{
104+
String[] ipParts = pattern.split("\\*");
105+
for (String ipPart : ipParts)
106+
{
107+
int idx = ip.indexOf(ipPart);
108+
if (idx == -1)
109+
return false;
110+
111+
ip = ip.substring(idx + ipPart.length());
112+
}
113+
114+
return true;
115+
}
116+
}

web/src/main/java/com/graphhopper/http/WebHelper.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ public static PointList decodePolyline( String encoded, int initCap, boolean is3
9494
// https://developers.google.com/maps/documentation/utilities/polylinealgorithm?hl=de
9595
public static String encodePolyline( PointList poly )
9696
{
97+
if (poly.isEmpty())
98+
return "";
99+
97100
return encodePolyline(poly, poly.is3D());
98101
}
99102

web/src/test/java/com/graphhopper/http/BaseServletTester.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,9 @@
2020
import com.google.inject.Guice;
2121
import com.google.inject.Injector;
2222
import com.google.inject.Module;
23-
import com.google.inject.servlet.GuiceFilter;
2423
import com.graphhopper.util.CmdArgs;
2524
import com.graphhopper.util.Downloader;
2625
import org.json.JSONObject;
27-
import org.junit.AfterClass;
2826
import org.slf4j.Logger;
2927
import org.slf4j.LoggerFactory;
3028

@@ -62,7 +60,7 @@ private void bootJetty( CmdArgs args, int retryCount )
6260
server = new GHServer(args);
6361

6462
if (injector == null)
65-
setUpGuice(new DefaultModule(args), new GHServletModule());
63+
setUpGuice(new DefaultModule(args), new GHServletModule(args));
6664

6765
for (int i = 0; i < retryCount; i++)
6866
{
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.graphhopper.http;
2+
3+
import org.junit.Test;
4+
import static org.junit.Assert.*;
5+
6+
/**
7+
*
8+
* @author Peter Karich
9+
*/
10+
public class IPFilterTest
11+
{
12+
@Test
13+
public void testAcceptWhite()
14+
{
15+
IPFilter instance = new IPFilter("1.2.3.4, 4.5.67.1", "");
16+
assertTrue(instance.accept("1.2.3.4"));
17+
assertTrue(instance.accept("4.5.67.1"));
18+
assertFalse(instance.accept("1.2.3.5"));
19+
20+
instance = new IPFilter("1.2.3*, 4.5.67.1, 7.8.*.3", "");
21+
assertTrue(instance.accept("1.2.3.4"));
22+
assertTrue(instance.accept("4.5.67.1"));
23+
assertTrue(instance.accept("1.2.3.5"));
24+
assertFalse(instance.accept("1.3.5.7"));
25+
26+
assertTrue(instance.accept("7.8.5.3"));
27+
assertFalse(instance.accept("7.88.5.3"));
28+
}
29+
30+
@Test
31+
public void testAcceptBlack()
32+
{
33+
IPFilter instance = new IPFilter("", "1.2.3.4, 4.5.67.1");
34+
35+
assertFalse(instance.accept("1.2.3.4"));
36+
assertFalse(instance.accept("4.5.67.1"));
37+
assertTrue(instance.accept("1.2.3.5"));
38+
}
39+
40+
@Test
41+
public void testFilterSpecialCases()
42+
{
43+
IPFilter instance = new IPFilter("", "");
44+
assertTrue(instance.accept("1.2.3.4"));
45+
46+
try
47+
{
48+
new IPFilter("1.2.3.4, 4.5.67.1", "8.9.7.3");
49+
assertFalse("black and white", true);
50+
} catch (Exception ex)
51+
{
52+
53+
}
54+
}
55+
}

0 commit comments

Comments
 (0)