/** * Copyright © 2010-2011 Nokia * * 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.github.restdriver.serverdriver.acceptance; import static com.github.restdriver.serverdriver.RestServerDriver.*; import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.Matchers.*; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.eclipse.jetty.proxy.ProxyServlet; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import com.github.restdriver.SocketUtil; import com.github.restdriver.clientdriver.ClientDriverRequest; import com.github.restdriver.clientdriver.ClientDriverResponse; import com.github.restdriver.clientdriver.ClientDriverRule; import com.github.restdriver.serverdriver.http.exception.RuntimeConnectException; public class ProxyAcceptanceTest { /* These are set when you call startLocalProxy() */ private int proxyPort; private Server proxyServer; private int proxyHits = 0; // increments every time the proxy is used @Rule public ClientDriverRule driver = new ClientDriverRule(); @Rule public ExpectedException thrown = ExpectedException.none(); @Test public void testWithSpecifiedProxyFailsIfProxyIsNotAvailable() throws IOException { thrown.expect(RuntimeConnectException.class); driver.addExpectation(new ClientDriverRequest("/foo"), new ClientDriverResponse("Content", "text/plain")); get(driver.getBaseUrl() + "/foo", usingProxy("localhost", SocketUtil.getFreePort())); } @Test public void testWithSpecifiedProxyPassesIfProxyIsAvailable() { startLocalProxy(); driver.addExpectation(new ClientDriverRequest("/foo"), new ClientDriverResponse("Content", "text/plain")); get(driver.getBaseUrl() + "/foo", usingProxy("localhost", proxyPort)); assertThat(proxyHits, is(1)); stopLocalProxy(); } @Test public void testWithNoProxyDoesntTryToUseAProxy() { driver.addExpectation(new ClientDriverRequest("/foo"), new ClientDriverResponse("Content", "text/plain")); get(driver.getBaseUrl() + "/foo", notUsingProxy()); assertThat(proxyHits, is(0)); } @Test public void whenMultipleProxiesAreSpecifiedLastOneWinsNoProxy() throws IOException { driver.addExpectation(new ClientDriverRequest("/foo"), new ClientDriverResponse("Content", "text/plain")); get(driver.getBaseUrl() + "/foo", usingProxy("localhost", SocketUtil.getFreePort()), notUsingProxy()); assertThat(proxyHits, is(0)); } @Test public void whenMultipleProxiesAreSpecifiedLastOneWinsWithProxy() { startLocalProxy(); driver.addExpectation(new ClientDriverRequest("/foo"), new ClientDriverResponse("Content", "text/plain")); get(driver.getBaseUrl() + "/foo", notUsingProxy(), usingProxy("localhost", proxyPort)); stopLocalProxy(); assertThat(proxyHits, is(1)); } @Test public void twoCallsWithOnlyOneProxiedOnlyUsesProxyOnce() { driver.addExpectation(new ClientDriverRequest("/foo"), new ClientDriverResponse("Content", "text/plain")); driver.addExpectation(new ClientDriverRequest("/foo"), new ClientDriverResponse("Content", "text/plain")); driver.addExpectation(new ClientDriverRequest("/foo"), new ClientDriverResponse("Content", "text/plain")); startLocalProxy(); get(driver.getBaseUrl() + "/foo"); assertThat(proxyHits, is(0)); get(driver.getBaseUrl() + "/foo", usingProxy("localhost", proxyPort)); assertThat(proxyHits, is(1)); get(driver.getBaseUrl() + "/foo", notUsingProxy()); assertThat(proxyHits, is(1)); stopLocalProxy(); } @Test public void systemProxyUsesSystemProperties() { startLocalProxy(); System.setProperty("http.proxyHost", "localhost"); System.setProperty("http.proxyPort", "" + proxyPort); driver.addExpectation(new ClientDriverRequest("/foo"), new ClientDriverResponse("Content", "text/plain")); get(driver.getBaseUrl() + "/foo", usingSystemProxy()); assertThat(proxyHits, is(1)); } @Test public void systemProxyUsesNoProxyIfNoSystemPropertiesSet() { startLocalProxy(); System.setProperty("http.proxyHost", ""); System.setProperty("http.proxyPort", ""); driver.addExpectation(new ClientDriverRequest("/foo"), new ClientDriverResponse("Content", "text/plain")); get(driver.getBaseUrl() + "/foo", usingSystemProxy()); assertThat(proxyHits, is(0)); stopLocalProxy(); } // ////////////////// // Proxy helper stuff // ////////////////// private void startLocalProxy() { try { int port = SocketUtil.getFreePort(); proxyServer = new Server(port); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); proxyServer.setHandler(context); context.addServlet(new ServletHolder("CountingProxyServlet", new CountingProxyServlet()), "/*"); proxyServer.start(); proxyPort = port; } catch (Exception e) { throw new RuntimeException("Proxy setup oops", e); } } private class CountingProxyServlet extends ProxyServlet { @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { proxyHits++; super.service(req, res); } } public void stopLocalProxy() { try { proxyServer.stop(); } catch (Exception e) { throw new RuntimeException("Problem stopping Jetty proxy", e); } } }