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();
}
}
}