@Before public void setUp() throws Exception { Resource configRes = Resource.newClassPathResource("/org/eclipse/jetty/monitor/jetty-monitor-service.xml"); XmlConfiguration xmlConfig = new XmlConfiguration(configRes.getURL()); xmlConfig.configure(); }
/* ------------------------------------------------------------ */ @Test public void testEncoding() throws Exception { Resource r = Resource.newResource("/tmp/a file with,spe#ials/"); assertTrue(r.getURL().toString().indexOf("a%20file%20with,spe%23ials") > 0); assertTrue(r.getFile().toString().indexOf("a file with,spe#ials") > 0); r.delete(); assertFalse("File should have been deleted.", r.exists()); }
/** * Check if this jar:file: resource is contained in the named resource. Eg <code> * jar:file:///a/b/c/foo.jar!/x.html</code> isContainedIn <code>file:///a/b/c/foo.jar</code> * * @param resource * @return true if resource is contained in the named resource * @throws MalformedURLException */ @Override public boolean isContainedIn(Resource resource) throws MalformedURLException { String string = _urlString; int index = string.indexOf("!/"); if (index > 0) string = string.substring(0, index); if (string.startsWith("jar:")) string = string.substring(4); URL url = new URL(string); return url.sameFile(resource.getURL()); }
/** * Look for any web-fragment.xml fragments in META-INF of jars in WEB-INF/lib * * @throws Exception */ public void findWebFragments(final WebAppContext context, final MetaData metaData) throws Exception { @SuppressWarnings("unchecked") List<Resource> frags = (List<Resource>) context.getAttribute(FRAGMENT_RESOURCES); if (frags != null) { for (Resource frag : frags) { if (frag .isDirectory()) // tolerate the case where the library is a directory, not a jar. useful // for OSGi for example { metaData.addFragment( frag, Resource.newResource(frag.getURL() + "/META-INF/web-fragment.xml")); } else // the standard case: a jar most likely inside WEB-INF/lib { metaData.addFragment( frag, Resource.newResource("jar:" + frag.getURL() + "!/META-INF/web-fragment.xml")); } } } }
/** * Overriden method which, contrary to the original implementation in the parent class, add * directly the web-fragment.xml resource to the MetaData, instead of re-creating it with a forced * jar prefix. */ @Override @SuppressWarnings("unchecked") public void findWebFragments(final WebAppContext context, final MetaData metaData) throws Exception { List<Resource> frags = (List<Resource>) context.getAttribute(FRAGMENT_RESOURCES); if (frags != null) { for (Resource frag : frags) { Resource parentResource = Util.chop(frag.getURL(), "/META-INF/web-fragment.xml"); metaData.addFragment(parentResource, frag); } } }
@Test public void testStandardTestWar() throws Exception { PreconfigureStandardTestWar.main(new String[] {}); WebDescriptor descriptor = new WebDescriptor( Resource.newResource( "./target/test-standard-preconfigured/WEB-INF/quickstart-web.xml")); descriptor.setValidating(true); descriptor.parse(); Node node = descriptor.getRoot(); assertThat(node, Matchers.notNullValue()); System.setProperty("jetty.home", "target"); // war file or dir to start String war = "target/test-standard-preconfigured"; // optional jetty context xml file to configure the webapp Resource contextXml = Resource.newResource("src/test/resources/test.xml"); Server server = new Server(0); QuickStartWebApp webapp = new QuickStartWebApp(); webapp.setAutoPreconfigure(true); webapp.setWar(war); webapp.setContextPath("/"); // apply context xml file if (contextXml != null) { // System.err.println("Applying "+contextXml); XmlConfiguration xmlConfiguration = new XmlConfiguration(contextXml.getURL()); xmlConfiguration.configure(webapp); } server.setHandler(webapp); server.start(); URL url = new URL( "http://127.0.0.1:" + server.getBean(NetworkConnector.class).getLocalPort() + "/test/dump/info"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); assertEquals(200, connection.getResponseCode()); assertThat( IO.toString((InputStream) connection.getContent()), Matchers.containsString("Dump Servlet")); server.stop(); }
public void addJars(Resource lib) throws IOException { if (lib == null || !lib.exists()) throw new IllegalStateException("No such lib: " + lib); String[] list = lib.list(); if (list == null) return; for (String path : list) { if (".".equals(path) || "..".equals(path)) continue; try (Resource item = lib.addPath(path)) { if (item.isDirectory()) addJars(item); else { if (path.toLowerCase().endsWith(".jar") || path.toLowerCase().endsWith(".zip")) { URL url = item.getURL(); _classpath.add(url); } } } } }
/** * Parse all classes in a directory * * @param dir * @param resolver * @throws Exception */ public void parseDir(Resource dir, ClassNameResolver resolver) throws Exception { // skip dirs whose name start with . (ie hidden) if (!dir.isDirectory() || !dir.exists() || dir.getName().startsWith(".")) return; if (LOG.isDebugEnabled()) { LOG.debug("Scanning dir {}", dir); } ; String[] files = dir.list(); for (int f = 0; files != null && f < files.length; f++) { try { Resource res = dir.addPath(files[f]); if (res.isDirectory()) parseDir(res, resolver); else { // we've already verified the directories, so just verify the class file name String filename = res.getFile().getName(); if (isValidClassFileName(filename)) { String name = res.getName(); if ((resolver == null) || (!resolver.isExcluded(name) && (!isParsed(name) || resolver.shouldOverride(name)))) { Resource r = Resource.newResource(res.getURL()); if (LOG.isDebugEnabled()) { LOG.debug("Scanning class {}", r); } ; scanClass(r.getInputStream()); } } } } catch (Exception ex) { LOG.warn(Log.EXCEPTION, ex); } } }
/** * @param context * @param descriptor * @param node */ public void visitContextParam(WebAppContext context, Descriptor descriptor, XmlParser.Node node) throws Exception { String name = node.getString("param-name", false, true); String value = node.getString("param-value", false, true); List<String> values = new ArrayList<>(); // extract values switch (name) { case ServletContext.ORDERED_LIBS: case AnnotationConfiguration.CONTAINER_INITIALIZERS: case MetaInfConfiguration.METAINF_TLDS: case MetaInfConfiguration.METAINF_RESOURCES: context.removeAttribute(name); QuotedStringTokenizer tok = new QuotedStringTokenizer(value, ","); while (tok.hasMoreElements()) values.add(tok.nextToken().trim()); break; default: values.add(value); } // handle values switch (name) { case ServletContext.ORDERED_LIBS: { List<Object> libs = new ArrayList<>(); Object o = context.getAttribute(ServletContext.ORDERED_LIBS); if (o instanceof Collection<?>) libs.addAll((Collection<?>) o); libs.addAll(values); if (libs.size() > 0) context.setAttribute(ServletContext.ORDERED_LIBS, libs); break; } case AnnotationConfiguration.CONTAINER_INITIALIZERS: { for (String i : values) visitContainerInitializer( context, new ContainerInitializer(Thread.currentThread().getContextClassLoader(), i)); break; } case MetaInfConfiguration.METAINF_TLDS: { List<Object> tlds = new ArrayList<>(); String war = context.getBaseResource().getURI().toString(); Object o = context.getAttribute(MetaInfConfiguration.METAINF_TLDS); if (o instanceof Collection<?>) tlds.addAll((Collection<?>) o); for (String i : values) { Resource r = Resource.newResource(i.replace("${WAR}/", war)); if (r.exists()) tlds.add(r.getURL()); else throw new IllegalArgumentException("TLD not found: " + r); } if (tlds.size() > 0) context.setAttribute(MetaInfConfiguration.METAINF_TLDS, tlds); break; } case MetaInfConfiguration.METAINF_RESOURCES: { String war = context.getBaseResource().getURI().toString(); for (String i : values) { Resource r = Resource.newResource(i.replace("${WAR}/", war)); if (r.exists()) visitMetaInfResource(context, r); else throw new IllegalArgumentException("Resource not found: " + r); } break; } default: } }
/** * Configure a jetty instance and deploy the webapps presented as args * * @param args the command line arguments * @throws Exception if unable to configure */ public void configure(String[] args) throws Exception { // handle classpath bits first so we can initialize the log mechanism. for (int i = 0; i < args.length; i++) { if ("--lib".equals(args[i])) { try (Resource lib = Resource.newResource(args[++i])) { if (!lib.exists() || !lib.isDirectory()) usage("No such lib directory " + lib); _classpath.addJars(lib); } } else if ("--jar".equals(args[i])) { try (Resource jar = Resource.newResource(args[++i])) { if (!jar.exists() || jar.isDirectory()) usage("No such jar " + jar); _classpath.addPath(jar); } } else if ("--classes".equals(args[i])) { try (Resource classes = Resource.newResource(args[++i])) { if (!classes.exists() || !classes.isDirectory()) usage("No such classes directory " + classes); _classpath.addPath(classes); } } else if (args[i].startsWith("--")) i++; } initClassLoader(); LOG.info("Runner"); LOG.debug("Runner classpath {}", _classpath); String contextPath = __defaultContextPath; boolean contextPathSet = false; int port = __defaultPort; String host = null; int stopPort = 0; String stopKey = null; boolean runnerServerInitialized = false; for (int i = 0; i < args.length; i++) { switch (args[i]) { case "--port": port = Integer.parseInt(args[++i]); break; case "--host": host = args[++i]; break; case "--stop-port": stopPort = Integer.parseInt(args[++i]); break; case "--stop-key": stopKey = args[++i]; break; case "--log": _logFile = args[++i]; break; case "--out": String outFile = args[++i]; PrintStream out = new PrintStream(new RolloverFileOutputStream(outFile, true, -1)); LOG.info("Redirecting stderr/stdout to " + outFile); System.setErr(out); System.setOut(out); break; case "--path": contextPath = args[++i]; contextPathSet = true; break; case "--config": if (_configFiles == null) _configFiles = new ArrayList<>(); _configFiles.add(args[++i]); break; case "--lib": ++i; // skip break; case "--jar": ++i; // skip break; case "--classes": ++i; // skip break; case "--stats": _enableStats = true; _statsPropFile = args[++i]; _statsPropFile = ("unsecure".equalsIgnoreCase(_statsPropFile) ? null : _statsPropFile); break; default: // process contexts if (!runnerServerInitialized) // log handlers not registered, server maybe not created, // etc { if (_server == null) // server not initialized yet { // build the server _server = new Server(); } // apply jetty config files if there are any if (_configFiles != null) { for (String cfg : _configFiles) { try (Resource resource = Resource.newResource(cfg)) { XmlConfiguration xmlConfiguration = new XmlConfiguration(resource.getURL()); xmlConfiguration.configure(_server); } } } // check that everything got configured, and if not, make the handlers HandlerCollection handlers = (HandlerCollection) _server.getChildHandlerByClass(HandlerCollection.class); if (handlers == null) { handlers = new HandlerCollection(); _server.setHandler(handlers); } // check if contexts already configured _contexts = (ContextHandlerCollection) handlers.getChildHandlerByClass(ContextHandlerCollection.class); if (_contexts == null) { _contexts = new ContextHandlerCollection(); prependHandler(_contexts, handlers); } if (_enableStats) { // if no stats handler already configured if (handlers.getChildHandlerByClass(StatisticsHandler.class) == null) { StatisticsHandler statsHandler = new StatisticsHandler(); Handler oldHandler = _server.getHandler(); statsHandler.setHandler(oldHandler); _server.setHandler(statsHandler); ServletContextHandler statsContext = new ServletContextHandler(_contexts, "/stats"); statsContext.addServlet(new ServletHolder(new StatisticsServlet()), "/"); statsContext.setSessionHandler(new SessionHandler()); if (_statsPropFile != null) { HashLoginService loginService = new HashLoginService("StatsRealm", _statsPropFile); Constraint constraint = new Constraint(); constraint.setName("Admin Only"); constraint.setRoles(new String[] {"admin"}); constraint.setAuthenticate(true); ConstraintMapping cm = new ConstraintMapping(); cm.setConstraint(constraint); cm.setPathSpec("/*"); ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler(); securityHandler.setLoginService(loginService); securityHandler.setConstraintMappings(Collections.singletonList(cm)); securityHandler.setAuthenticator(new BasicAuthenticator()); statsContext.setSecurityHandler(securityHandler); } } } // ensure a DefaultHandler is present if (handlers.getChildHandlerByClass(DefaultHandler.class) == null) { handlers.addHandler(new DefaultHandler()); } // ensure a log handler is present _logHandler = (RequestLogHandler) handlers.getChildHandlerByClass(RequestLogHandler.class); if (_logHandler == null) { _logHandler = new RequestLogHandler(); handlers.addHandler(_logHandler); } // check a connector is configured to listen on Connector[] connectors = _server.getConnectors(); if (connectors == null || connectors.length == 0) { ServerConnector connector = new ServerConnector(_server); connector.setPort(port); if (host != null) connector.setHost(host); _server.addConnector(connector); if (_enableStats) connector.addBean(new ConnectorStatistics()); } else { if (_enableStats) { for (Connector connector : connectors) { ((AbstractConnector) connector).addBean(new ConnectorStatistics()); } } } runnerServerInitialized = true; } // Create a context try (Resource ctx = Resource.newResource(args[i])) { if (!ctx.exists()) usage("Context '" + ctx + "' does not exist"); if (contextPathSet && !(contextPath.startsWith("/"))) contextPath = "/" + contextPath; // Configure the context if (!ctx.isDirectory() && ctx.toString().toLowerCase().endsWith(".xml")) { // It is a context config file XmlConfiguration xmlConfiguration = new XmlConfiguration(ctx.getURL()); xmlConfiguration.getIdMap().put("Server", _server); ContextHandler handler = (ContextHandler) xmlConfiguration.configure(); if (contextPathSet) handler.setContextPath(contextPath); _contexts.addHandler(handler); handler.setAttribute( "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", __containerIncludeJarPattern); } else { // assume it is a WAR file WebAppContext webapp = new WebAppContext(_contexts, ctx.toString(), contextPath); webapp.setConfigurationClasses(__plusConfigurationClasses); webapp.setAttribute( "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", __containerIncludeJarPattern); } } // reset contextPathSet = false; contextPath = __defaultContextPath; break; } } if (_server == null) usage("No Contexts defined"); _server.setStopAtShutdown(true); switch ((stopPort > 0 ? 1 : 0) + (stopKey != null ? 2 : 0)) { case 1: usage("Must specify --stop-key when --stop-port is specified"); break; case 2: usage("Must specify --stop-port when --stop-key is specified"); break; case 3: ShutdownMonitor monitor = ShutdownMonitor.getInstance(); monitor.setPort(stopPort); monitor.setKey(stopKey); monitor.setExitVm(true); break; } if (_logFile != null) { NCSARequestLog requestLog = new NCSARequestLog(_logFile); requestLog.setExtended(false); _logHandler.setRequestLog(requestLog); } }
public void addPath(Resource path) { if (path == null || !path.exists()) throw new IllegalStateException("No such path: " + path); _classpath.add(path.getURL()); }
/** * Create a canonical name for a webapp temp directory. The form of the name is: <code> * "Jetty_"+host+"_"+port+"__"+resourceBase+"_"+context+"_"+virtualhost+base36_hashcode_of_whole_string * </code> host and port uniquely identify the server context and virtual host uniquely identify * the webapp * * @return the canonical name for the webapp temp directory */ public static String getCanonicalNameForWebAppTmpDir(WebAppContext context) { StringBuffer canonicalName = new StringBuffer(); canonicalName.append("jetty-"); // get the host and the port from the first connector Server server = context.getServer(); if (server != null) { Connector[] connectors = context.getServer().getConnectors(); if (connectors.length > 0) { // Get the host String host = (connectors == null || connectors[0] == null ? "" : connectors[0].getHost()); if (host == null) host = "0.0.0.0"; canonicalName.append(host); // Get the port canonicalName.append("-"); // try getting the real port being listened on int port = (connectors == null || connectors[0] == null ? 0 : connectors[0].getLocalPort()); // if not available (eg no connectors or connector not started), // try getting one that was configured. if (port < 0) port = connectors[0].getPort(); canonicalName.append(port); canonicalName.append("-"); } } // Resource base try { Resource resource = context.getBaseResource(); if (resource == null) { if (context.getWar() == null || context.getWar().length() == 0) resource = context.newResource(context.getResourceBase()); // Set dir or WAR resource = context.newResource(context.getWar()); } String tmp = URIUtil.decodePath(resource.getURL().getPath()); if (tmp.endsWith("/")) tmp = tmp.substring(0, tmp.length() - 1); if (tmp.endsWith("!")) tmp = tmp.substring(0, tmp.length() - 1); // get just the last part which is the filename int i = tmp.lastIndexOf("/"); canonicalName.append(tmp.substring(i + 1, tmp.length())); canonicalName.append("-"); } catch (Exception e) { LOG.warn("Can't generate resourceBase as part of webapp tmp dir name", e); } // Context name String contextPath = context.getContextPath(); contextPath = contextPath.replace('/', '_'); contextPath = contextPath.replace('\\', '_'); canonicalName.append(contextPath); // Virtual host (if there is one) canonicalName.append("-"); String[] vhosts = context.getVirtualHosts(); if (vhosts == null || vhosts.length <= 0) canonicalName.append("any"); else canonicalName.append(vhosts[0]); // sanitize for (int i = 0; i < canonicalName.length(); i++) { char c = canonicalName.charAt(i); if (!Character.isJavaIdentifierPart(c) && "-.".indexOf(c) < 0) canonicalName.setCharAt(i, '.'); } canonicalName.append("-"); return canonicalName.toString(); }
/* ------------------------------------------------------------ */ @Override public ContextHandler createContextHandler(final App app) throws Exception { Resource resource = Resource.newResource(app.getOriginId()); File file = resource.getFile(); if (!resource.exists()) throw new IllegalStateException("App resouce does not exist " + resource); String context = file.getName(); if (resource.exists() && FileID.isXmlFile(file)) { XmlConfiguration xmlc = new XmlConfiguration(resource.getURL()); xmlc.getIdMap().put("Server", getDeploymentManager().getServer()); if (getConfigurationManager() != null) xmlc.getProperties().putAll(getConfigurationManager().getProperties()); return (ContextHandler) xmlc.configure(); } else if (file.isDirectory()) { // must be a directory } else if (FileID.isWebArchiveFile(file)) { // Context Path is the same as the archive. context = context.substring(0, context.length() - 4); } else { throw new IllegalStateException("unable to create ContextHandler for " + app); } // Ensure "/" is Not Trailing in context paths. if (context.endsWith("/") && context.length() > 0) { context = context.substring(0, context.length() - 1); } // Start building the webapplication WebAppContext wah = new WebAppContext(); wah.setDisplayName(context); // special case of archive (or dir) named "root" is / context if (context.equalsIgnoreCase("root")) { context = URIUtil.SLASH; } else if (context.toLowerCase().startsWith("root-")) { int dash = context.toLowerCase().indexOf('-'); String virtual = context.substring(dash + 1); wah.setVirtualHosts(new String[] {virtual}); context = URIUtil.SLASH; } // Ensure "/" is Prepended to all context paths. if (context.charAt(0) != '/') { context = "/" + context; } wah.setContextPath(context); wah.setWar(file.getAbsolutePath()); if (_defaultsDescriptor != null) { wah.setDefaultsDescriptor(_defaultsDescriptor); } wah.setExtractWAR(_extractWars); wah.setParentLoaderPriority(_parentLoaderPriority); if (_configurationClasses != null) { wah.setConfigurationClasses(_configurationClasses); } if (_tempDirectory != null) { /* Since the Temp Dir is really a context base temp directory, * Lets set the Temp Directory in a way similar to how WebInfConfiguration does it, * instead of setting the * WebAppContext.setTempDirectory(File). * If we used .setTempDirectory(File) all webapps will wind up in the * same temp / work directory, overwriting each others work. */ wah.setAttribute(WebAppContext.BASETEMPDIR, _tempDirectory); } return wah; }