package org.jvnet.hudson.test; import hudson.Util; import hudson.util.IOUtils; import org.apache.commons.io.FileUtils; import org.mortbay.jetty.Server; import org.mortbay.jetty.bio.SocketConnector; import org.mortbay.jetty.handler.ContextHandlerCollection; import org.mortbay.jetty.servlet.Context; import org.mortbay.jetty.servlet.ServletHolder; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.net.URL; /** * Acts as a reverse proxy to https://hudson.java.net/ , so that during a test * we can avoid hitting java.net. * * <p> * The contents are cached locally. * * @author Kohsuke Kawaguchi */ public class JavaNetReverseProxy extends HttpServlet { private final Server server; public final int localPort; private final File cacheFolder; public JavaNetReverseProxy(File cacheFolder) throws Exception { this.cacheFolder = cacheFolder; cacheFolder.mkdirs(); server = new Server(); ContextHandlerCollection contexts = new ContextHandlerCollection(); server.setHandler(contexts); Context root = new Context(contexts, "/", Context.SESSIONS); root.addServlet(new ServletHolder(this), "/"); SocketConnector connector = new SocketConnector(); server.addConnector(connector); server.start(); localPort = connector.getLocalPort(); } public void stop() throws Exception { server.stop(); } // class Response { // final URL url; // final String contentType; // final ByteArrayOutputStream data = new ByteArrayOutputStream(); // // Response(URL url) throws IOException { // this.url = url; // URLConnection con = url.openConnection(); // contentType = con.getContentType(); // IOUtils.copy(con.getInputStream(),data); // } // // void reproduceTo(HttpServletResponse rsp) throws IOException { // rsp.setContentType(contentType); // data.writeTo(rsp.getOutputStream()); // } // } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String path = req.getServletPath(); String d = Util.getDigestOf(path); File cache = new File(cacheFolder, d); if(!cache.exists()) { URL url = new URL("http://hudson-ci.org/" + path); FileUtils.copyURLToFile(url,cache); } resp.setContentType(getMimeType(path)); IOUtils.copy(cache,resp.getOutputStream()); } private String getMimeType(String path) { int idx = path.indexOf('?'); if(idx>=0) path = path.substring(0,idx); if(path.endsWith(".json")) return "text/javascript"; return getServletContext().getMimeType(path); } private static volatile JavaNetReverseProxy INSTANCE; /** * Gets the default instance. */ public static synchronized JavaNetReverseProxy getInstance() throws Exception { if(INSTANCE==null) // TODO: think of a better location --- ideally inside the target/ dir so that clean would wipe them out INSTANCE = new JavaNetReverseProxy(new File(new File(System.getProperty("java.io.tmpdir")),"hudson-ci.org-cache2")); return INSTANCE; } }