diff --git a/src/main/java/com/alibaba/druid/support/http/StatViewServlet.java b/src/main/java/com/alibaba/druid/support/http/StatViewServlet.java index 9b88f4cc5b..241a11c959 100644 --- a/src/main/java/com/alibaba/druid/support/http/StatViewServlet.java +++ b/src/main/java/com/alibaba/druid/support/http/StatViewServlet.java @@ -1,5 +1,8 @@ package com.alibaba.druid.support.http; +import com.alibaba.druid.util.IpUtils; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -40,12 +43,30 @@ public class StatViewServlet extends HttpServlet { public String templatePage; private static DateFormat format = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss:SSS"); + private String permittedIp; + private Pattern ipCheckPattern; + public void init() throws ServletException { try { templatePage = IOUtils.readFromResource(TEMPLATE_PAGE_RESOURCE_PATH); + } catch (IOException e) { throw new ServletException("error read templatePage:" + TEMPLATE_PAGE_RESOURCE_PATH, e); } + permittedIp = getServletConfig().getInitParameter("permittedIp"); + if (permittedIp != null ) { + this.ipCheckPattern = IpUtils.buildIpCheckPattern(permittedIp); + } + } + + private boolean isPermittedRequest(HttpServletRequest request) { + //if nothing is configured, every host can access the stat result(default) + if (permittedIp == null || permittedIp.trim().equals("")) { + return true; + } + String remoteIp = request.getRemoteAddr(); + Matcher matcher = ipCheckPattern.matcher(remoteIp); + return matcher.matches(); } public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { @@ -55,11 +76,19 @@ public class StatViewServlet extends HttpServlet { response.setCharacterEncoding("utf-8"); + + if (contextPath == null) { // root context contextPath = ""; } String uri = contextPath + servletPath; String path = requestURI.substring(contextPath.length() + servletPath.length()); + + if (!isPermittedRequest(request)) { + path = "/nopermit.html"; + returnResourceFile(path, uri, response); + return; + } if ("".equals(path)) { if (contextPath == null || contextPath.equals("") || contextPath.equals("/")) { diff --git a/src/main/java/com/alibaba/druid/util/IpUtils.java b/src/main/java/com/alibaba/druid/util/IpUtils.java new file mode 100644 index 0000000000..4b70ed5aac --- /dev/null +++ b/src/main/java/com/alibaba/druid/util/IpUtils.java @@ -0,0 +1,18 @@ +package com.alibaba.druid.util; + +import java.util.regex.Pattern; + +public class IpUtils { + + public static Pattern buildIpCheckPattern(String permittedIP) { + String[] addrs = permittedIP.split(","); + StringBuilder sb = new StringBuilder(); + for (String addr : addrs ) { + addr = addr.trim(); + addr = addr.replace("*", "\\d{1,3}"); + sb.append(addr.trim()).append("|"); + } + return Pattern.compile(sb.toString()); + } + +} diff --git a/src/main/resources/support/http/resources/nopermit.html b/src/main/resources/support/http/resources/nopermit.html new file mode 100644 index 0000000000..81fd17d83a --- /dev/null +++ b/src/main/resources/support/http/resources/nopermit.html @@ -0,0 +1,14 @@ + + + + + + + + +
+
+

Sorry, you are not permitted to view this page.

+
+ + diff --git a/src/test/java/com/alibaba/druid/util/IpUtilsTest.java b/src/test/java/com/alibaba/druid/util/IpUtilsTest.java new file mode 100644 index 0000000000..aa9ea23c6a --- /dev/null +++ b/src/test/java/com/alibaba/druid/util/IpUtilsTest.java @@ -0,0 +1,47 @@ +package com.alibaba.druid.util; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.junit.Test; +import org.junit.Assert; + + +public class IpUtilsTest { + + + @Test + public void testBuildIpCheckPattern() { + + Pattern pat = IpUtils.buildIpCheckPattern("192.168.0.*"); + String[] validIps = {"192.168.0.1", "192.168.0.2","192.168.0.15","192.168.0.250"}; + String[] inValidIps = {"192.168.15.1", "192.168.7.1","10.8.9.25","168.2.3.10"}; + checkIp(pat, validIps, inValidIps); + + pat = IpUtils.buildIpCheckPattern("192.168.0.1"); + validIps = new String[] {"192.168.0.1"}; + inValidIps = new String[] {"192.168.0.2", "192.168.1.0","10.15.255.3"}; + checkIp(pat, validIps, inValidIps); + + pat = IpUtils.buildIpCheckPattern("192.168.0.1,192.168.0.2,192.168.1.*"); + validIps = new String[] {"192.168.0.1","192.168.0.2","192.168.1.15"}; + inValidIps = new String[] {"192.168.0.3", "192.168.10.2","10.15.255.3","16.8.155.3"}; + checkIp(pat, validIps, inValidIps); + + + } + + private void checkIp(Pattern pat, String[] validIps, String[] inValidIps) { + Matcher matcher = null; + for (String validIp : validIps) { + matcher = pat.matcher(validIp); + Assert.assertTrue(matcher.matches()); + } + + for (String inValidIp : inValidIps) { + matcher = pat.matcher(inValidIp); + Assert.assertFalse(matcher.matches()); + } + } + +}