/* * Copyright 2011-2017 the original author or authors. * * 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 org.glowroot.agent.plugin.servlet; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.Map; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.google.common.base.Strings; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.junit.After; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.glowroot.agent.it.harness.AppUnderTest; import org.glowroot.agent.it.harness.Container; import org.glowroot.agent.it.harness.Containers; import org.glowroot.wire.api.model.TraceOuterClass.Trace; import static org.assertj.core.api.Assertions.assertThat; public class RequestParameterIT { private static final String PLUGIN_ID = "servlet"; private static Container container; @BeforeClass public static void setUp() throws Exception { container = Containers.create(); } @AfterClass public static void tearDown() throws Exception { container.close(); } @After public void afterEachTest() throws Exception { container.checkAndReset(); } @Test public void testRequestParameters() throws Exception { // when Trace trace = container.execute(GetParameter.class); // then Map<String, Object> requestParameters = ResponseHeaderIT.getDetailMap(trace, "Request parameters"); assertThat(requestParameters).hasSize(3); assertThat(requestParameters.get("xYz")).isEqualTo("aBc"); assertThat(requestParameters.get("jpassword1")).isEqualTo("****"); @SuppressWarnings("unchecked") List<String> multi = (List<String>) requestParameters.get("multi"); assertThat(multi).containsExactly("m1", "m2"); } @Test public void testWithoutCaptureRequestParameters() throws Exception { // given container.getConfigService().setPluginProperty(PLUGIN_ID, "captureRequestParameters", ""); // when Trace trace = container.execute(GetParameter.class); // then assertThat(trace.getHeader().getDetailEntryList()).hasSize(1); assertThat(trace.getHeader().getDetailEntryList().get(0).getName()) .isEqualTo("Request http method"); } @Test public void testRequestParameterMap() throws Exception { // when container.execute(GetParameterMap.class); // then don't throw IllegalStateException (see MockCatalinaHttpServletRequest) } @Test public void testBadRequestParameterMap() throws Exception { // when Trace trace = container.execute(GetBadParameterMap.class); // then Map<String, Object> requestParameters = ResponseHeaderIT.getDetailMap(trace, "Request parameters"); assertThat(requestParameters).hasSize(1); assertThat(requestParameters.get("n")).isEqualTo("x"); } @Test public void testExtraBadRequestParameterMap() throws Exception { // when Trace trace = container.execute(GetExtraBadParameterMap.class); // then Map<String, Object> requestParameters = ResponseHeaderIT.getDetailMap(trace, "Request parameters"); assertThat(requestParameters).hasSize(1); assertThat(requestParameters.get("n")).isEqualTo("x"); } @Test public void testLargeRequestParameters() throws Exception { // when Trace trace = container.execute(GetLargeParameter.class); // then Map<String, Object> requestParameters = ResponseHeaderIT.getDetailMap(trace, "Request parameters"); assertThat(requestParameters).hasSize(1); assertThat(requestParameters.get("large")).isEqualTo( Strings.repeat("0123456789", 1000) + " [truncated to 10000 characters]"); } @Test public void testOutsideServlet() throws Exception { // when container.executeNoExpectedTrace(GetParameterOutsideServlet.class); // then // basically just testing that it should not generate any errors } @SuppressWarnings("serial") public static class GetParameter extends TestServlet { @Override protected void before(HttpServletRequest request, HttpServletResponse response) { ((MockHttpServletRequest) request).setParameter("xYz", "aBc"); ((MockHttpServletRequest) request).setParameter("jpassword1", "mask me"); ((MockHttpServletRequest) request).setParameter("multi", new String[] {"m1", "m2"}); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { request.getParameter("xYz"); } } @SuppressWarnings("serial") public static class GetParameterMap extends TestServlet { @Override protected void before(HttpServletRequest request, HttpServletResponse response) { ((MockHttpServletRequest) request).setParameter("xy", "abc"); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { request.getParameterValues("z"); } } @SuppressWarnings("serial") public static class GetBadParameterMap extends TestServlet { @Override public void executeApp() throws Exception { MockHttpServletRequest request = new BadMockHttpServletRequest("GET", "/testservlet"); MockHttpServletResponse response = new PatchedMockHttpServletResponse(); service((ServletRequest) request, (ServletResponse) response); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { request.getParameterValues("z"); } } @SuppressWarnings("serial") public static class GetExtraBadParameterMap extends TestServlet { @Override public void executeApp() throws Exception { MockHttpServletRequest request = new ExtraBadMockHttpServletRequest("GET", "/testservlet"); MockHttpServletResponse response = new PatchedMockHttpServletResponse(); service((ServletRequest) request, (ServletResponse) response); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { request.getParameterValues("z"); } } @SuppressWarnings("serial") public static class GetLargeParameter extends TestServlet { @Override protected void before(HttpServletRequest request, HttpServletResponse response) { ((MockHttpServletRequest) request).setParameter("large", Strings.repeat("0123456789", 2000)); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { request.getParameter("large"); } } public static class GetParameterOutsideServlet implements AppUnderTest { @Override public void executeApp() throws Exception { MockHttpServletRequest request = new MockCatalinaHttpServletRequest("GET", "/testservlet"); request.setParameter("xYz", "aBc"); request.setParameter("jpassword1", "mask me"); request.setParameter("multi", new String[] {"m1", "m2"}); request.getParameter("xYz"); } } public static class BadMockHttpServletRequest extends MockHttpServletRequest { public BadMockHttpServletRequest(String method, String requestURI) { super(method, requestURI); } @Override public Map<String, String[]> getParameterMap() { Map<String, String[]> parameterMap = Maps.newHashMap(); parameterMap.put(null, new String[] {"v"}); parameterMap.put("m", null); parameterMap.put("n", new String[] {null, "x"}); return parameterMap; } } public static class ExtraBadMockHttpServletRequest extends MockHttpServletRequest { public ExtraBadMockHttpServletRequest(String method, String requestURI) { super(method, requestURI); } @Override public Map<String, String[]> getParameterMap() { throw new NullPointerException(); } @Override public Enumeration<String> getParameterNames() { return Collections.enumeration(Lists.newArrayList(null, "m", "n")); } @Override public String[] getParameterValues(String name) { if (name.equals("m")) { return null; } if (name.equals("n")) { return new String[] {null, "x"}; } return new String[0]; } } }