package aQute.bnd.deployer.http; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import java.io.File; import java.io.InputStream; import java.net.URL; import java.util.Properties; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import aQute.lib.io.IO; import aQute.service.reporter.Reporter; import junit.framework.TestCase; import test.lib.NanoHTTPD; public class HttpRedirectionTest extends TestCase { public void testFollowRedirect() throws Exception { Reporter reporter = mock(Reporter.class); NanoHTTPD httpd = new NanoHTTPD(0, new File(".")) { @Override public Response serve(String uri, String method, Properties header, Properties parms, Properties files) { Response r; if ("/foo".equals(uri)) { r = new Response("302 Found", "text/plain", "over there"); r.header.put("Location", "/bar"); } else if ("/bar".equals(uri)) { r = new Response(NanoHTTPD.HTTP_OK, "text/plain", "got it"); } else { r = new Response(NanoHTTPD.HTTP_BADREQUEST, "text/plain", "sod off"); } return r; } }; String baseUrl = "http://localhost:" + httpd.getPort() + "/"; String originalUrl = baseUrl + "foo"; String redirectUrl = baseUrl + "bar"; DefaultURLConnector connector = new DefaultURLConnector(); connector.setReporter(reporter); InputStream stream = connector.connect(new URL(originalUrl)); String result = IO.collect(stream); assertEquals("got it", result); verify(reporter).warning("HTTP address redirected from %s to %s", originalUrl, redirectUrl); } public void testDetectRedirectLoop() throws Exception { final NanoHTTPD httpd = new NanoHTTPD(0, new File(".")) { @Override public Response serve(String uri, String method, Properties header, Properties parms, Properties files) { Response r; if ("/foo".equals(uri)) { r = new Response("302 Found", "text/plain", "over there"); r.header.put("Location", "/bar"); } else if ("/bar".equals(uri)) { r = new Response("302 Found", "text/plain", "go back"); r.header.put("Location", "/foo"); } else { r = new Response(NanoHTTPD.HTTP_BADREQUEST, "text/plain", "sod off"); } return r; } }; // Use a future to ensure we timeout after 1s if the redirect does // actually loop forever ExecutorService executor = Executors.newSingleThreadExecutor(); Future< ? > future = executor.submit(new Runnable() { public void run() { DefaultURLConnector connector = new DefaultURLConnector(); try { InputStream stream = connector.connect(new URL("http://localhost:" + httpd.getPort() + "/foo")); IO.collect(stream); } catch (Exception e) { e.printStackTrace(); } } }); try { future.get(1, TimeUnit.SECONDS); } finally { future.cancel(true); executor.shutdownNow(); } } }