/** Starts the server for end-to-end tests. */ private Server createServer(int port) throws Exception { Server newServer = new Server(port); // Attach the test resources in /endtoend as static content for the test ResourceHandler resources = new ResourceHandler(); URL resource = EndToEndTest.class.getResource("/endtoend"); resources.setBaseResource(Resource.newResource(resource)); newServer.addHandler(resources); Context context = new Context(newServer, "/", Context.SESSIONS); context.addEventListener(new GuiceServletContextListener()); Map<String, String> initParams = Maps.newHashMap(); String modules = Joiner.on(":") .join( SampleModule.class.getName(), DefaultGuiceModule.class.getName(), PropertiesModule.class.getName(), OAuthModule.class.getName()); initParams.put(GuiceServletContextListener.MODULES_ATTRIBUTE, modules); context.setInitParams(initParams); // Attach the gadget rendering servlet ServletHolder gadgetServletHolder = new ServletHolder(new GadgetRenderingServlet()); context.addServlet(gadgetServletHolder, GADGET_BASE); // Attach DataServiceServlet, wrapped in a proxy to fake errors ServletHolder restServletHolder = new ServletHolder(new ForceErrorServlet(new DataServiceServlet())); restServletHolder.setInitParameter("handlers", "org.apache.shindig.social.handlers"); context.addServlet(restServletHolder, REST_BASE); context.addFilter(AuthenticationServletFilter.class, REST_BASE, 0); // Attach JsonRpcServlet, wrapped in a proxy to fake errors ServletHolder rpcServletHolder = new ServletHolder(new ForceErrorServlet(new JsonRpcServlet())); rpcServletHolder.setInitParameter("handlers", "org.apache.shindig.social.handlers"); context.addServlet(rpcServletHolder, JSON_RPC_BASE); context.addFilter(AuthenticationServletFilter.class, JSON_RPC_BASE, 0); // Attach the ConcatProxyServlet - needed for rewritten JS ServletHolder concatHolder = new ServletHolder(new ConcatProxyServlet()); context.addServlet(concatHolder, CONCAT_BASE); // Attach the JsServlet - needed for rewritten JS ServletHolder jsHolder = new ServletHolder(new JsServlet()); context.addServlet(jsHolder, JS_BASE); // Attach MakeRequestServlet ServletHolder makeRequestHolder = new ServletHolder(new MakeRequestServlet()); context.addServlet(makeRequestHolder, MAKE_REQUEST_BASE); // Attach an EchoServlet, used to test proxied rendering ServletHolder echoHolder = new ServletHolder(new EchoServlet()); context.addServlet(echoHolder, "/echo"); return newServer; }
/** * Get the resource list as a HTML directory listing. * * @param base The base URL * @param parent True if the parent directory should be included * @return String of HTML */ public String getListHTML(String base, boolean parent) throws IOException { if (!isDirectory()) return null; String[] ls = list(); if (ls == null) return null; Arrays.sort(ls); String title = "Directory: " + base; StringBuffer buf = new StringBuffer(4096); buf.append("<HTML><HEAD><TITLE>"); buf.append(title); buf.append("</TITLE></HEAD><BODY>\n<H1>"); buf.append(title); buf.append("</H1><TABLE BORDER=0>"); if (parent) { buf.append("<TR><TD><A HREF="); buf.append(URIUtil.encodePath(URIUtil.addPaths(base, "../"))); buf.append(">Parent Directory</A></TD><TD></TD><TD></TD></TR>\n"); } DateFormat dfmt = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM); for (int i = 0; i < ls.length; i++) { String encoded = URIUtil.encodePath(ls[i]); Resource item = addPath(encoded); buf.append("<TR><TD><A HREF=\""); String path = URIUtil.addPaths(base, encoded); if (item.isDirectory() && !path.endsWith("/")) path = URIUtil.addPaths(path, "/"); buf.append(path); buf.append("\">"); buf.append(StringUtil.replace(StringUtil.replace(ls[i], "<", "<"), ">", ">")); buf.append(" "); buf.append("</TD><TD ALIGN=right>"); buf.append(item.length()); buf.append(" bytes </TD><TD>"); buf.append(dfmt.format(new Date(item.lastModified()))); buf.append("</TD></TR>\n"); } buf.append("</TABLE>\n"); buf.append("</BODY></HTML>\n"); return buf.toString(); }
/** {@inheritDoc} */ public void configureWebApp() throws Exception { log.debug("Configuring Jetty webapp"); // Get context WebAppContext context = getWebAppContext(); // If app is already started... if (context.isStarted()) { log.debug("Cannot configure webapp after it is started"); return; } // Get WEB_INF directory Resource webInf = context.getWebInf(); if (webInf != null && webInf.isDirectory()) { // Get properties file with virtualHosts and context path Resource config = webInf.addPath("red5-web.properties"); if (config.exists()) { log.debug("Configuring red5-web.properties"); // Load configuration properties Properties props = new Properties(); props.load(config.getInputStream()); // Get context path and virtual hosts String contextPath = props.getProperty("webapp.contextPath"); String virtualHosts = props.getProperty("webapp.virtualHosts"); // Get hostnames String[] hostnames = virtualHosts.split(","); for (int i = 0; i < hostnames.length; i++) { hostnames[i] = hostnames[i].trim(); if (hostnames[i].equals("*")) { // A virtual host "null" must be used so requests for // any host will be served. hostnames = null; break; } } // Set virtual hosts and context path to context context.setVirtualHosts(hostnames); context.setContextPath(contextPath); LoaderBase.setRed5ApplicationContext(contextPath, new JettyApplicationContext(context)); } } else if (webInf == null) { // No WEB-INF directory found, register as default application log.info( "No WEB-INF directory found for " + context.getContextPath() + ", creating default application."); BeanFactoryLocator bfl = ContextSingletonBeanFactoryLocator.getInstance("red5.xml"); BeanFactoryReference bfr = bfl.useBeanFactory("red5.common"); // Create WebScope dynamically WebScope scope = new WebScope(); IServer server = (IServer) bfr.getFactory().getBean(IServer.ID); scope.setServer(server); scope.setGlobalScope(server.getGlobal("default")); // Get default Red5 context from context loader that is JettyLoader in this case ApplicationContext appCtx = JettyLoader.getApplicationContext(); ContextLoader loader = (ContextLoader) appCtx.getBean("context.loader"); appCtx = loader.getContext("default.context"); // Create context for the WebScope and initialize Context scopeContext = new Context(); scopeContext.setContextPath("/"); scopeContext.setClientRegistry((IClientRegistry) appCtx.getBean("global.clientRegistry")); scopeContext.setMappingStrategy((IMappingStrategy) appCtx.getBean("global.mappingStrategy")); scopeContext.setServiceInvoker((IServiceInvoker) appCtx.getBean("global.serviceInvoker")); scopeContext.setScopeResolver((IScopeResolver) appCtx.getBean("red5.scopeResolver")); // The context needs an ApplicationContext so resources can be // resolved GenericWebApplicationContext webCtx = new GenericWebApplicationContext(); webCtx.setDisplayName("Automatic generated WebAppContext"); webCtx.setParent(appCtx); webCtx.setServletContext(ContextHandler.getCurrentContext()); scopeContext.setApplicationContext(webCtx); // Store context in scope scope.setContext(scopeContext); // Use default ApplicationAdapter as handler scope.setHandler(new ApplicationAdapter()); // Make available as "/<directoryName>" and allow access from all // hosts scope.setContextPath(context.getContextPath()); scope.setVirtualHosts("*"); LoaderBase.setRed5ApplicationContext( context.getContextPath(), new JettyApplicationContext(context)); // Register WebScope in server scope.register(); } }
private Set<File> getDependencyFiles() { List<Resource> overlays = new ArrayList<Resource>(); Set<File> dependencies = getClasspath().getFiles(); logger.debug("Adding dependencies {} for WEB-INF/lib ", dependencies); // todo incorporate overlays when our resolved dependencies provide type information // if (artifact.getType().equals("war")) { // try { // Resource r = Resource.newResource("jar:" + // artifact.getFile().toURL().toString() + "!/"); // overlays.add(r); // getExtraScanTargets().add(artifact.getFile()); // } // catch (Exception e) { // throw new RuntimeException(e); // } // continue; // } if (!overlays.isEmpty()) { try { Resource resource = getWebAppConfig().getBaseResource(); ResourceCollection rc = new ResourceCollection(); if (resource == null) { // nothing configured, so we automagically enable the overlays int size = overlays.size() + 1; Resource[] resources = new Resource[size]; resources[0] = Resource.newResource(getWebAppSourceDirectory().toURI().toURL()); for (int i = 1; i < size; i++) { resources[i] = overlays.get(i - 1); logger.info("Adding overlay: " + resources[i]); } rc.setResources(resources); } else { if (resource instanceof ResourceCollection) { // there was a preconfigured ResourceCollection ... append the artifact wars Resource[] old = ((ResourceCollection) resource).getResources(); int size = old.length + overlays.size(); Resource[] resources = new Resource[size]; System.arraycopy(old, 0, resources, 0, old.length); for (int i = old.length; i < size; i++) { resources[i] = overlays.get(i - old.length); logger.info("Adding overlay: " + resources[i]); } rc.setResources(resources); } else { // baseResource was already configured w/c could be src/main/webapp if (!resource.isDirectory() && String.valueOf(resource.getFile()).endsWith(".war")) { // its a war resource = Resource.newResource("jar:" + resource.getURL().toString() + "!/"); } int size = overlays.size() + 1; Resource[] resources = new Resource[size]; resources[0] = resource; for (int i = 1; i < size; i++) { resources[i] = overlays.get(i - 1); logger.info("Adding overlay: " + resources[i]); } rc.setResources(resources); } } getWebAppConfig().setBaseResource(rc); } catch (Exception e) { throw new RuntimeException(e); } } return dependencies; }
/* ------------------------------------------------------------ */ public static void extract(Resource resource, File directory, boolean deleteOnExit) throws IOException { if (Log.isDebugEnabled()) Log.debug("Extract " + resource + " to " + directory); String urlString = resource.getURL().toExternalForm().trim(); int endOfJarUrl = urlString.indexOf("!/"); int startOfJarUrl = (endOfJarUrl >= 0 ? 4 : 0); if (endOfJarUrl < 0) throw new IOException("Not a valid jar url: " + urlString); URL jarFileURL = new URL(urlString.substring(startOfJarUrl, endOfJarUrl)); String subEntryName = (endOfJarUrl + 2 < urlString.length() ? urlString.substring(endOfJarUrl + 2) : null); boolean subEntryIsDir = (subEntryName != null && subEntryName.endsWith("/") ? true : false); if (Log.isDebugEnabled()) Log.debug("Extracting entry = " + subEntryName + " from jar " + jarFileURL); InputStream is = jarFileURL.openConnection().getInputStream(); JarInputStream jin = new JarInputStream(is); JarEntry entry = null; boolean shouldExtract = true; while ((entry = jin.getNextJarEntry()) != null) { String entryName = entry.getName(); if ((subEntryName != null) && (entryName.startsWith(subEntryName))) { // if there is a particular subEntry that we are looking for, only // extract it. if (subEntryIsDir) { // if it is a subdirectory we are looking for, then we // are looking to extract its contents into the target // directory. Remove the name of the subdirectory so // that we don't wind up creating it too. entryName = entryName.substring(subEntryName.length()); if (!entryName.equals("")) { // the entry is shouldExtract = true; } else shouldExtract = false; } else shouldExtract = true; } else if ((subEntryName != null) && (!entryName.startsWith(subEntryName))) { // there is a particular entry we are looking for, and this one // isn't it shouldExtract = false; } else { // we are extracting everything shouldExtract = true; } if (!shouldExtract) { if (Log.isDebugEnabled()) Log.debug("Skipping entry: " + entryName); continue; } File file = new File(directory, entryName); if (entry.isDirectory()) { // Make directory if (!file.exists()) file.mkdirs(); } else { // make directory (some jars don't list dirs) File dir = new File(file.getParent()); if (!dir.exists()) dir.mkdirs(); // Make file FileOutputStream fout = null; try { fout = new FileOutputStream(file); IO.copy(jin, fout); } finally { IO.close(fout); } // touch the file. if (entry.getTime() >= 0) file.setLastModified(entry.getTime()); } if (deleteOnExit) file.deleteOnExit(); } }