@Test public void testResponseFilterOriginalRequestNotModified() throws IOException { mockServer .when(request().withMethod("GET").withPath("/modifiedendpoint"), Times.exactly(1)) .respond(response().withStatusCode(200).withBody("success")); proxy = new BrowserMobProxyServer(); proxy.start(); proxy.addRequestFilter( new RequestFilter() { @Override public HttpResponse filterRequest( HttpRequest request, HttpMessageContents contents, HttpMessageInfo messageInfo) { if (request.getUri().endsWith("/originalendpoint")) { request.setUri(request.getUri().replaceAll("originalendpoint", "modifiedendpoint")); } return null; } }); final AtomicReference<String> originalRequestUri = new AtomicReference<>(); proxy.addResponseFilter( new ResponseFilter() { @Override public void filterResponse( HttpResponse response, HttpMessageContents contents, HttpMessageInfo messageInfo) { originalRequestUri.set(messageInfo.getOriginalRequest().getUri()); } }); try (CloseableHttpClient httpClient = NewProxyServerTestUtil.getNewHttpClient(proxy.getPort())) { CloseableHttpResponse response = httpClient.execute( new HttpGet("http://localhost:" + mockServerPort + "/originalendpoint")); assertEquals( "Expected server to return a 200", 200, response.getStatusLine().getStatusCode()); assertThat( "Expected URI on originalRequest to match actual URI of original HTTP request", originalRequestUri.get(), endsWith("/originalendpoint")); } }
@Test public void testRequestFilterCanModifyHttpsRequestBody() throws IOException { final String originalText = "original body"; final String newText = "modified body"; mockServer .when( request().withMethod("PUT").withPath("/modifyrequest").withBody(newText), Times.exactly(1)) .respond(response().withStatusCode(200).withBody("success")); proxy = new BrowserMobProxyServer(); proxy.setTrustAllServers(true); proxy.start(); proxy.addRequestFilter( new RequestFilter() { @Override public HttpResponse filterRequest( HttpRequest request, HttpMessageContents contents, HttpMessageInfo messageInfo) { if (contents.isText()) { if (contents.getTextContents().equals(originalText)) { contents.setTextContents(newText); } } return null; } }); try (CloseableHttpClient httpClient = NewProxyServerTestUtil.getNewHttpClient(proxy.getPort())) { HttpPut request = new HttpPut("https://localhost:" + mockServerPort + "/modifyrequest"); request.setEntity(new StringEntity(originalText)); CloseableHttpResponse response = httpClient.execute(request); String responseBody = NewProxyServerTestUtil.toStringAndClose(response.getEntity().getContent()); assertEquals( "Expected server to return a 200", 200, response.getStatusLine().getStatusCode()); assertEquals("Did not receive expected response from mock server", "success", responseBody); } }
@Test public void testMitmDisabledHttpsRequestFilterNotAvailable() throws IOException { mockServer .when(request().withMethod("GET").withPath("/mitmdisabled"), Times.exactly(1)) .respond(response().withStatusCode(200).withBody("success")); proxy = new BrowserMobProxyServer(); proxy.setMitmDisabled(true); proxy.start(); final AtomicBoolean connectRequestFilterFired = new AtomicBoolean(false); final AtomicBoolean getRequestFilterFired = new AtomicBoolean(false); proxy.addRequestFilter( new RequestFilter() { @Override public HttpResponse filterRequest( HttpRequest request, HttpMessageContents contents, HttpMessageInfo messageInfo) { if (request.getMethod().equals(HttpMethod.CONNECT)) { connectRequestFilterFired.set(true); } else if (request.getMethod().equals(HttpMethod.GET)) { getRequestFilterFired.set(true); } return null; } }); try (CloseableHttpClient httpClient = NewProxyServerTestUtil.getNewHttpClient(proxy.getPort())) { CloseableHttpResponse response = httpClient.execute(new HttpGet("https://localhost:" + mockServerPort + "/mitmdisabled")); assertEquals( "Expected server to return a 200", 200, response.getStatusLine().getStatusCode()); assertTrue("Expected request filter to fire on CONNECT", connectRequestFilterFired.get()); assertFalse( "Expected request filter to fail to fire on GET because MITM is disabled", getRequestFilterFired.get()); } }
@Post @At("/:port/filter/request") public Reply<?> addRequestFilter(@Named("port") int port, Request<String> request) throws IOException, ScriptException { LegacyProxyServer legacyProxy = proxyManager.get(port); if (legacyProxy == null) { return Reply.saying().notFound(); } if (!(legacyProxy instanceof BrowserMobProxyServer)) { return Reply.saying().badRequest(); } BrowserMobProxy proxy = (BrowserMobProxy) legacyProxy; JavascriptRequestResponseFilter requestResponseFilter = new JavascriptRequestResponseFilter(); String script = getEntityBodyFromRequest(request); requestResponseFilter.setRequestFilterScript(script); proxy.addRequestFilter(requestResponseFilter); return Reply.saying().ok(); }
@Test public void testHttpsResponseFilterUrlReflectsModifications() throws IOException { mockServer .when(request().withMethod("GET").withPath("/urlreflectsmodifications"), Times.exactly(1)) .respond(response().withStatusCode(200).withBody("success")); proxy = new BrowserMobProxyServer(); proxy.setTrustAllServers(true); proxy.start(); final AtomicReference<String> requestFilterOriginalUrl = new AtomicReference<>(); final AtomicReference<String> requestFilterUrl = new AtomicReference<>(); proxy.addRequestFilter( new RequestFilter() { @Override public HttpResponse filterRequest( HttpRequest request, HttpMessageContents contents, HttpMessageInfo messageInfo) { requestFilterOriginalUrl.set(messageInfo.getOriginalUrl()); requestFilterUrl.set(messageInfo.getUrl()); return null; } }); // request filters get added to the beginning of the filter chain, so add this uri-modifying // request filter after // adding the capturing request filter above. proxy.addRequestFilter( new RequestFilter() { @Override public HttpResponse filterRequest( HttpRequest request, HttpMessageContents contents, HttpMessageInfo messageInfo) { if (request.getUri().endsWith("/originalurl")) { String newUrl = request.getUri().replaceAll("originalurl", "urlreflectsmodifications"); request.setUri(newUrl); } return null; } }); final AtomicReference<String> responseFilterOriginalUrl = new AtomicReference<>(); final AtomicReference<String> responseFilterUrl = new AtomicReference<>(); proxy.addResponseFilter( new ResponseFilter() { @Override public void filterResponse( HttpResponse response, HttpMessageContents contents, HttpMessageInfo messageInfo) { responseFilterOriginalUrl.set(messageInfo.getOriginalUrl()); responseFilterUrl.set(messageInfo.getUrl()); } }); try (CloseableHttpClient httpClient = NewProxyServerTestUtil.getNewHttpClient(proxy.getPort())) { String originalRequestUrl = "https://localhost:" + mockServerPort + "/originalurl"; String modifiedRequestUrl = "https://localhost:" + mockServerPort + "/urlreflectsmodifications"; CloseableHttpResponse response = httpClient.execute(new HttpGet(originalRequestUrl)); assertEquals( "Expected server to return a 200", 200, response.getStatusLine().getStatusCode()); assertEquals( "Expected originalUrl in request filter to match actual request URL", originalRequestUrl, requestFilterOriginalUrl.get()); assertEquals( "Expected url in request filter to match modified request URL", modifiedRequestUrl, requestFilterUrl.get()); assertEquals( "Expected originalUrl in response filter to match actual request URL", originalRequestUrl, responseFilterOriginalUrl.get()); assertEquals( "Expected url in response filter to match modified request URL", modifiedRequestUrl, responseFilterUrl.get()); } }
@Test public void testHttpResponseFilterMessageInfoPopulated() throws IOException { mockServer .when( request() .withMethod("GET") .withPath("/httpmessageinfopopulated") .withQueryStringParameter("param1", "value1"), Times.exactly(1)) .respond(response().withStatusCode(200).withBody("success")); proxy = new BrowserMobProxyServer(); proxy.start(); final AtomicReference<ChannelHandlerContext> requestCtx = new AtomicReference<>(); final AtomicReference<HttpRequest> requestOriginalRequest = new AtomicReference<>(); final AtomicBoolean requestIsHttps = new AtomicBoolean(false); final AtomicReference<String> requestFilterOriginalUrl = new AtomicReference<>(); final AtomicReference<String> requestFilterUrl = new AtomicReference<>(); proxy.addRequestFilter( new RequestFilter() { @Override public HttpResponse filterRequest( HttpRequest request, HttpMessageContents contents, HttpMessageInfo messageInfo) { requestCtx.set(messageInfo.getChannelHandlerContext()); requestOriginalRequest.set(messageInfo.getOriginalRequest()); requestIsHttps.set(messageInfo.isHttps()); requestFilterOriginalUrl.set(messageInfo.getOriginalUrl()); requestFilterUrl.set(messageInfo.getUrl()); return null; } }); final AtomicReference<ChannelHandlerContext> responseCtx = new AtomicReference<>(); final AtomicReference<HttpRequest> responseOriginalRequest = new AtomicReference<>(); final AtomicBoolean responseIsHttps = new AtomicBoolean(false); final AtomicReference<String> responseFilterOriginalUrl = new AtomicReference<>(); final AtomicReference<String> responseFilterUrl = new AtomicReference<>(); proxy.addResponseFilter( new ResponseFilter() { @Override public void filterResponse( HttpResponse response, HttpMessageContents contents, HttpMessageInfo messageInfo) { responseCtx.set(messageInfo.getChannelHandlerContext()); responseOriginalRequest.set(messageInfo.getOriginalRequest()); responseIsHttps.set(messageInfo.isHttps()); responseFilterOriginalUrl.set(messageInfo.getOriginalUrl()); responseFilterUrl.set(messageInfo.getUrl()); } }); try (CloseableHttpClient httpClient = NewProxyServerTestUtil.getNewHttpClient(proxy.getPort())) { String requestUrl = "http://localhost:" + mockServerPort + "/httpmessageinfopopulated?param1=value1"; CloseableHttpResponse response = httpClient.execute(new HttpGet(requestUrl)); assertEquals( "Expected server to return a 200", 200, response.getStatusLine().getStatusCode()); assertNotNull( "Expected ChannelHandlerContext to be populated in request filter", requestCtx.get()); assertNotNull( "Expected originalRequest to be populated in request filter", requestOriginalRequest.get()); assertFalse("Expected isHttps to return false in request filter", requestIsHttps.get()); assertEquals( "Expected originalUrl in request filter to match actual request URL", requestUrl, requestFilterOriginalUrl.get()); assertEquals( "Expected url in request filter to match actual request URL", requestUrl, requestFilterUrl.get()); assertNotNull( "Expected ChannelHandlerContext to be populated in response filter", responseCtx.get()); assertNotNull( "Expected originalRequest to be populated in response filter", responseOriginalRequest.get()); assertFalse("Expected isHttps to return false in response filter", responseIsHttps.get()); assertEquals( "Expected originalUrl in response filter to match actual request URL", requestUrl, responseFilterOriginalUrl.get()); assertEquals( "Expected url in response filter to match actual request URL", requestUrl, responseFilterUrl.get()); } }