diff --git a/LICENSE.txt b/LICENSE.txt index 91006b4da417769bcd64bbabc45103ae3c22e9d3..7d5a6b828faa25a383fd35f3ebf035544a1ae169 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -177,10 +177,11 @@ Applications: By welterde. See licenses/LICENSE-GPLv2.txt - Jetty 6.1.26: - Copyright 1995-2009 Mort Bay Consulting Pty Ltd - See licenses/LICENSE-Jetty.txt + Jetty 7.6.8.v20121106: + See licenses/ABOUT-Jetty.html + See licenses/NOTICE-Jetty.html See licenses/LICENSE-Apache2.0.txt + See licenses/LICENSE-ECLIPSE-1.0.html See licenses/NOTICE-Commons-Logging.txt JRobin 1.5.9.1: diff --git a/apps/i2psnark/java/build.xml b/apps/i2psnark/java/build.xml index fddfe4b51da42df83af7657a68fc9b700062a432..025c3f1db9001e8e250582d9249240c6ac785af5 100644 --- a/apps/i2psnark/java/build.xml +++ b/apps/i2psnark/java/build.xml @@ -19,6 +19,7 @@ <pathelement location="../../ministreaming/java/build/obj" /> <pathelement location="../../jetty/jettylib/org.mortbay.jetty.jar" /> <pathelement location="../../jetty/jettylib/javax.servlet.jar" /> + <pathelement location="../../jetty/jettylib/jetty-servlet.jar" /> <pathelement location="../../jetty/jettylib/jetty-util.jar" /> </classpath> </depend> @@ -38,7 +39,7 @@ debug="true" deprecation="on" source="1.5" target="1.5" destdir="./build/obj" includeAntRuntime="false" - classpath="../../../core/java/build/i2p.jar:../../jetty/jettylib/org.mortbay.jetty.jar:../../jetty/jettylib/javax.servlet.jar:../../jetty/jettylib/jetty-util.jar:../../ministreaming/java/build/mstreaming.jar" > + classpath="../../../core/java/build/i2p.jar:../../jetty/jettylib/org.mortbay.jetty.jar:../../jetty/jettylib/javax.servlet.jar:../../jetty/jettylib/jetty-servlet.jar:../../jetty/jettylib/jetty-util.jar:../../ministreaming/java/build/mstreaming.jar" > <compilerarg line="${javac.compilerargs}" /> </javac> </target> @@ -103,9 +104,11 @@ <copy todir="build/icons/.icons" > <fileset dir="../icons/" /> </copy> + <!-- mime.properties must be in with the classes --> + <copy file="../mime.properties" todir="build/obj/org/klomp/snark/web" /> <war destfile="../i2psnark.war" webxml="../web.xml" > <!-- include only the web stuff, as of 0.7.12 the router will add i2psnark.jar to the classpath for the war --> - <classes dir="./build/obj" includes="**/web/*.class" /> + <classes dir="./build/obj" includes="**/web/*" /> <fileset dir="build/icons/" /> <manifest> <attribute name="Implementation-Version" value="${full.version}" /> diff --git a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java index 89ab2a01a7c0cce9f0bf1ddfc1947e0179996933..6ea7498b4ad76406985109b2a2f8ff1085fadac5 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java +++ b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java @@ -49,6 +49,7 @@ import org.klomp.snark.dht.KRPC; public class I2PSnarkUtil { private final I2PAppContext _context; private final Log _log; + private final String _baseName; private boolean _shouldProxy; private String _proxyHost; @@ -82,8 +83,17 @@ public class I2PSnarkUtil { public static final boolean DEFAULT_USE_DHT = true; public I2PSnarkUtil(I2PAppContext ctx) { + this(ctx, "i2psnark"); + } + + /** + * @param baseName generally "i2psnark" + * @since Jetty 7 + */ + public I2PSnarkUtil(I2PAppContext ctx, String baseName) { _context = ctx; _log = _context.logManager().getLog(Snark.class); + _baseName = baseName; _opts = new HashMap(); //setProxy("127.0.0.1", 4444); setI2CPConfig("127.0.0.1", 7654, null); @@ -99,7 +109,7 @@ public class I2PSnarkUtil { // This is used for both announce replies and .torrent file downloads, // so it must be available even if not connected to I2CP. // so much for multiple instances - _tmpDir = new SecureDirectory(ctx.getTempDir(), "i2psnark"); + _tmpDir = new SecureDirectory(ctx.getTempDir(), baseName); FileUtil.rmdir(_tmpDir, false); _tmpDir.mkdirs(); } @@ -253,7 +263,7 @@ public class I2PSnarkUtil { _connecting = false; } if (_shouldUseDHT && _manager != null && _dht == null) - _dht = new KRPC(_context, _manager.getSession()); + _dht = new KRPC(_context, _baseName, _manager.getSession()); return (_manager != null); } @@ -588,7 +598,7 @@ public class I2PSnarkUtil { public synchronized void setUseDHT(boolean yes) { _shouldUseDHT = yes; if (yes && _manager != null && _dht == null) { - _dht = new KRPC(_context, _manager.getSession()); + _dht = new KRPC(_context, _baseName, _manager.getSession()); } else if (!yes && _dht != null) { _dht.stop(); _dht = null; diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index 2b2338b45a3389e5bcac9e3aaca9a683aa4511b8..36b099f38662e9126474000ed1926d0142051639 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -57,6 +57,8 @@ public class SnarkManager implements CompleteListener { private /* FIXME final FIXME */ File _configFile; private Properties _config; private final I2PAppContext _context; + private final String _contextPath; + private final String _contextName; private final Log _log; private final Queue<String> _messages; private final I2PSnarkUtil _util; @@ -82,7 +84,7 @@ public class SnarkManager implements CompleteListener { public static final String PROP_META_PRIORITY_SUFFIX = ".priority"; public static final String PROP_META_MAGNET_PREFIX = "i2psnark.magnet."; - private static final String CONFIG_FILE = "i2psnark.config"; + private static final String CONFIG_FILE_SUFFIX = ".config"; public static final String PROP_FILES_PUBLIC = "i2psnark.filesPublic"; public static final String PROP_AUTO_START = "i2snark.autoStart"; // oops public static final String DEFAULT_AUTO_START = "false"; @@ -128,17 +130,24 @@ public class SnarkManager implements CompleteListener { /** comma delimited list of name=announceURL=baseURL for the trackers to be displayed */ public static final String PROP_TRACKERS = "i2psnark.trackers"; - public SnarkManager(I2PAppContext ctx) { + /** + * @param ctxPath generally "/i2psnark" + * @param ctxName generally "i2psnark" + */ + public SnarkManager(I2PAppContext ctx, String ctxPath, String ctxName) { _snarks = new ConcurrentHashMap(); _magnets = new ConcurrentHashSet(); _addSnarkLock = new Object(); _context = ctx; + _contextPath = ctxPath; + _contextName = ctxName; _log = _context.logManager().getLog(SnarkManager.class); _messages = new LinkedBlockingQueue(); - _util = new I2PSnarkUtil(_context); - _configFile = new File(CONFIG_FILE); + _util = new I2PSnarkUtil(_context, ctxName); + String cfile = ctxName + CONFIG_FILE_SUFFIX; + _configFile = new File(cfile); if (!_configFile.isAbsolute()) - _configFile = new File(_context.getConfigDir(), CONFIG_FILE); + _configFile = new File(_context.getConfigDir(), cfile); _trackerMap = new ConcurrentHashMap(4); loadConfig(null); } @@ -259,7 +268,7 @@ public class SnarkManager implements CompleteListener { } public File getDataDir() { - String dir = _config.getProperty(PROP_DIR, "i2psnark"); + String dir = _config.getProperty(PROP_DIR, _contextName); File f; if (areFilesPublic()) f = new File(dir); @@ -305,7 +314,7 @@ public class SnarkManager implements CompleteListener { if (!_config.containsKey(PROP_UPLOADERS_TOTAL)) _config.setProperty(PROP_UPLOADERS_TOTAL, "" + Snark.MAX_TOTAL_UPLOADERS); if (!_config.containsKey(PROP_DIR)) - _config.setProperty(PROP_DIR, "i2psnark"); + _config.setProperty(PROP_DIR, _contextName); if (!_config.containsKey(PROP_AUTO_START)) _config.setProperty(PROP_AUTO_START, DEFAULT_AUTO_START); if (!_config.containsKey(PROP_REFRESH_DELAY)) @@ -731,6 +740,11 @@ public class SnarkManager implements CompleteListener { public Properties getConfig() { return _config; } + /** @since Jetty 7 */ + public String getConfigFilename() { + return _configFile.getAbsolutePath(); + } + /** hardcoded for sanity. perhaps this should be customizable, for people who increase their ulimit, etc. */ public static final int MAX_FILES_PER_TORRENT = 512; @@ -1445,7 +1459,7 @@ public class SnarkManager implements CompleteListener { if (meta == null || storage == null) return; StringBuilder buf = new StringBuilder(256); - buf.append("<a href=\"/i2psnark/").append(storage.getBaseName()); + buf.append("<a href=\"").append(_contextPath).append('/').append(storage.getBaseName()); if (meta.getFiles() != null) buf.append('/'); buf.append("\">").append(storage.getBaseName()).append("</a>"); diff --git a/apps/i2psnark/java/src/org/klomp/snark/dht/KRPC.java b/apps/i2psnark/java/src/org/klomp/snark/dht/KRPC.java index b94c5f555fb5ff933ce5efca54c2a1e75be388f0..c0be11182e35c9287560d3ab62168446215fe17f 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/dht/KRPC.java +++ b/apps/i2psnark/java/src/org/klomp/snark/dht/KRPC.java @@ -152,12 +152,15 @@ public class KRPC implements I2PSessionMuxedListener, DHT { private static final long CLEAN_TIME = 63*1000; private static final long EXPLORE_TIME = 877*1000; private static final long BLACKLIST_CLEAN_TIME = 17*60*1000; - private static final String DHT_FILE = "i2psnark.dht.dat"; + private static final String DHT_FILE_SUFFIX = ".dht.dat"; private static final int SEND_CRYPTO_TAGS = 8; private static final int LOW_CRYPTO_TAGS = 4; - public KRPC (I2PAppContext ctx, I2PSession session) { + /** + * @param baseName generally "i2psnark" + */ + public KRPC (I2PAppContext ctx, String baseName, I2PSession session) { _context = ctx; _session = session; _log = ctx.logManager().getLog(KRPC.class); @@ -182,7 +185,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT { _myNID = new NID(_myID); } _myNodeInfo = new NodeInfo(_myNID, session.getMyDestination(), _qPort); - _dhtFile = new File(ctx.getConfigDir(), DHT_FILE); + _dhtFile = new File(ctx.getConfigDir(), baseName + DHT_FILE_SUFFIX); _knownNodes = new DHTNodes(ctx, _myNID); start(); diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/BasicServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/BasicServlet.java new file mode 100644 index 0000000000000000000000000000000000000000..85774605001433e6c2e313cecaec8d588fa1742e --- /dev/null +++ b/apps/i2psnark/java/src/org/klomp/snark/web/BasicServlet.java @@ -0,0 +1,550 @@ +// ======================================================================== +// Copyright 199-2004 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ======================================================================== + +package org.klomp.snark.web; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.UnavailableException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import net.i2p.I2PAppContext; +import net.i2p.data.ByteArray; +import net.i2p.util.ByteCache; +import net.i2p.util.Log; + + +/* ------------------------------------------------------------ */ +/** + * Based on DefaultServlet from Jetty 6.1.26, heavily simplified + * and modified to remove all dependencies on Jetty libs. + * + * Supports HEAD and GET only, for resources from the .war and local files. + * Supports files and resource only. + * Supports MIME types with local overrides and additions. + * Supports Last-Modified. + * + * Does not support directories or "welcome files". + * Does not support gzip. + * Does not support request ranges. + * Does not cache. + * + * HEAD and POST return 405. + * Directories return 403. + * Jar resources are sent with a long cache directive. + * + * ------------------------------------------------------------ + * + * The default servlet. + * This servlet, normally mapped to /, provides the handling for static + * content, OPTION and TRACE methods for the context. + * The following initParameters are supported, these can be set either + * on the servlet itself or as ServletContext initParameters with a prefix + * of org.mortbay.jetty.servlet.Default. : + * <PRE> + * + * resourceBase Set to replace the context resource base + + * warBase Path allowed for resource in war + * + * </PRE> + * + * + * @author Greg Wilkins (gregw) + * @author Nigel Canonizado + * + * @since Jetty 7 + */ +class BasicServlet extends HttpServlet +{ + protected final I2PAppContext _context; + protected final Log _log; + protected File _resourceBase; + private String _warBase; + + private final MimeTypes _mimeTypes; + + /** same as PeerState.PARTSIZE */ + private static final int BUFSIZE = 16*1024; + private ByteCache _cache = ByteCache.getInstance(16, BUFSIZE); + + private static final int WAR_CACHE_CONTROL_SECS = 24*60*60; + private static final int FILE_CACHE_CONTROL_SECS = 24*60*60; + + public BasicServlet() { + super(); + _context = I2PAppContext.getGlobalContext(); + _log = _context.logManager().getLog(getClass()); + _mimeTypes = new MimeTypes(); + } + + /* ------------------------------------------------------------ */ + public void init(ServletConfig cfg) throws ServletException { + super.init(cfg); + String rb=getInitParameter("resourceBase"); + if (rb!=null) + { + File f = new File(rb); + setResourceBase(f); + } + String wb = getInitParameter("warBase"); + if (wb != null) + setWarBase(wb); + } + + /** + * Files are served from here + */ + protected void setResourceBase(File base) throws UnavailableException { + if (!base.isDirectory()) + throw new UnavailableException("Resource base does not exist: " + base); + _resourceBase = base; + if (_log.shouldLog(Log.INFO)) + _log.info("Resource base is " + _resourceBase); + } + + /** + * Only paths starting with this in the path are served + */ + protected void setWarBase(String base) { + if (!base.startsWith("/")) + base = '/' + base; + if (!base.endsWith("/")) + base = base + '/'; + _warBase = base; + if (_log.shouldLog(Log.INFO)) + _log.info("War base is " + _warBase); + } + + /** get Resource to serve. + * Map a path to a resource. The default implementation calls + * HttpContext.getResource but derived servlets may provide + * their own mapping. + * @param pathInContext The path to find a resource for. + * @return The resource to serve or null if not existing + */ + public File getResource(String pathInContext) + { + if (_resourceBase==null) + return null; + File r = null; + if (!pathInContext.contains("..") && + !pathInContext.endsWith("/")) { + File f = new File(_resourceBase, pathInContext); + if (f.exists()) + r = f; + } + return r; + } + + /** get Resource to serve. + * Map a path to a resource. The default implementation calls + * HttpContext.getResource but derived servlets may provide + * their own mapping. + * @param pathInContext The path to find a resource for. + * @return The resource to serve or null. Returns null for directories + */ + public HttpContent getContent(String pathInContext) + { + if (_resourceBase==null) + return null; + HttpContent r = null; + if (_warBase != null && pathInContext.startsWith(_warBase)) { + r = new JarContent(pathInContext); + } else if (!pathInContext.contains("..") && + !pathInContext.endsWith("/")) { + File f = new File(_resourceBase, pathInContext); + // exists && !directory + if (f.isFile()) + r = new FileContent(f); + } + return r; + } + + /* ------------------------------------------------------------ */ + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + // always starts with a '/' + String servletpath = request.getServletPath(); + String pathInfo=request.getPathInfo(); + // ??? right?? + String pathInContext = addPaths(servletpath, pathInfo); + + // Find the resource and content + try { + HttpContent content = getContent(pathInContext); + + // Handle resource + if (content == null) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Not found: " + pathInContext); + response.sendError(404); + } else { + if (passConditionalHeaders(request, response, content)) { + if (_log.shouldLog(Log.INFO)) + _log.info("Sending: " + content); + sendData(request, response, content); + } else { + if (_log.shouldLog(Log.INFO)) + _log.info("Not modified: " + content); + } + } + } + catch(IllegalArgumentException e) + { + if (_log.shouldLog(Log.WARN)) + _log.warn("Error sending " + pathInContext, e); + if(!response.isCommitted()) + response.sendError(500, e.getMessage()); + } + catch(IOException e) + { + if (_log.shouldLog(Log.WARN)) + // typical browser abort + //_log.warn("Error sending", e); + _log.warn("Error sending " + pathInContext + ": " + e); + throw e; + } + } + + /* ------------------------------------------------------------ */ + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + response.sendError(405); + } + + /* ------------------------------------------------------------ */ + /* (non-Javadoc) + * @see javax.servlet.http.HttpServlet#doTrace(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + protected void doTrace(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + response.sendError(405); + } + + protected void doOptions(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + response.sendError(405); + } + + protected void doDelete(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + response.sendError(405); + } + + + /* ------------------------------------------------------------ */ + /** Check modification date headers. + * @return true to keep going, false if handled here + */ + protected boolean passConditionalHeaders(HttpServletRequest request,HttpServletResponse response, HttpContent content) + throws IOException + { + try + { + if (!request.getMethod().equals("HEAD") ) { + long ifmsl=request.getDateHeader("If-Modified-Since"); + if (ifmsl!=-1) + { + if (content.getLastModified()/1000 <= ifmsl/1000) + { + response.reset(); + response.setStatus(304); + response.flushBuffer(); + return false; + } + } + } + } + catch(IllegalArgumentException iae) + { + if(!response.isCommitted()) + response.sendError(400, iae.getMessage()); + throw iae; + } + return true; + } + + + /* ------------------------------------------------------------ */ + protected void sendData(HttpServletRequest request, + HttpServletResponse response, + HttpContent content) + throws IOException + { + InputStream in =null; + try { + in = content.getInputStream(); + } catch (IOException e) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Not found: " + content); + response.sendError(404); + return; + } + + OutputStream out =null; + try { + out = response.getOutputStream(); + } catch (IllegalStateException e) { + out = new WriterOutputStream(response.getWriter()); + } + + // Write content normally + long content_length = content.getContentLength(); + writeHeaders(response,content,content_length); + if (content_length >= 0 && request.getMethod().equals("HEAD")) { + // if we know the content length, don't send it to be counted + if (_log.shouldLog(Log.INFO)) + _log.info("HEAD: " + content); + } else { + // GET or unknown size for HEAD + copy(in, out); + } + + return; + } + + /* ------------------------------------------------------------ */ + protected void writeHeaders(HttpServletResponse response,HttpContent content,long count) + throws IOException + { + if (content.getContentType()!=null && response.getContentType()==null) + response.setContentType(content.getContentType()); + + long lml = content.getLastModified(); + if (lml > 0) + response.setDateHeader("Last-Modified",lml); + + if (count != -1) + { + if (count<Integer.MAX_VALUE) + response.setContentLength((int)count); + else + response.setHeader("Content-Length", Long.toString(count)); + } + + long ct = content.getCacheTime(); + if (ct>=0) + response.setHeader("Cache-Control", "public, max-age=" + ct); + + } + + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + /* I2P additions below here */ + + /** from Jetty HttpContent.java */ + public interface HttpContent + { + String getContentType(); + long getLastModified(); + /** in seconds */ + int getCacheTime(); + long getContentLength(); + InputStream getInputStream() throws IOException; + } + + private class FileContent implements HttpContent + { + private final File _file; + + public FileContent(File file) + { + _file = file; + } + + /* ------------------------------------------------------------ */ + public String getContentType() + { + //return _mimeTypes.getMimeByExtension(_file.toString()); + return getMimeType(_file.toString()); + } + + /* ------------------------------------------------------------ */ + public long getLastModified() + { + return _file.lastModified(); + } + + public int getCacheTime() + { + return FILE_CACHE_CONTROL_SECS; + } + + /* ------------------------------------------------------------ */ + public long getContentLength() + { + return _file.length(); + } + + /* ------------------------------------------------------------ */ + public InputStream getInputStream() throws IOException + { + return new BufferedInputStream(new FileInputStream(_file)); + } + + @Override + public String toString() { return "File \"" + _file + '"'; } + } + + private class JarContent implements HttpContent + { + private final String _path; + + public JarContent(String path) + { + _path = path; + } + + /* ------------------------------------------------------------ */ + public String getContentType() + { + return getMimeType(_path); + } + + /* ------------------------------------------------------------ */ + public long getLastModified() + { + String cpath = getServletContext().getContextPath(); + // this won't work if we aren't at top level + String cname = cpath == "" ? "i2psnark" : cpath.substring(1).replace("/", "_"); + return (new File(_context.getBaseDir(), "webapps/" + cname + ".war")).lastModified(); + } + + public int getCacheTime() + { + return WAR_CACHE_CONTROL_SECS; + } + + /* ------------------------------------------------------------ */ + public long getContentLength() + { + return -1; + } + + /* ------------------------------------------------------------ */ + public InputStream getInputStream() throws IOException + { + InputStream rv = getServletContext().getResourceAsStream(_path); + if (rv == null) + throw new IOException("Not found"); + return rv; + } + + @Override + public String toString() { return "Jar resource \"" + _path + '"'; } + } + + + /** + * @param resourcePath in the classpath, without ".properties" extension + */ + protected void loadMimeMap(String resourcePath) { + _mimeTypes.loadMimeMap(resourcePath); + } + + /* ------------------------------------------------------------ */ + /** Get the MIME type by filename extension. + * @param filename A file name + * @return MIME type matching the longest dot extension of the + * file name. + */ + protected String getMimeType(String filename) { + String rv = _mimeTypes.getMimeByExtension(filename); + if (rv != null) + return rv; + return getServletContext().getMimeType(filename); + } + + protected void addMimeMapping(String extension, String type) { + _mimeTypes.addMimeMapping(extension, type); + } + + /** + * Simple version of URIUtil.addPaths() + * @param path may be null + */ + protected static String addPaths(String base, String path) { + if (path == null) + return base; + return (new File(base, path)).toString(); + } + + /** + * Simple version of URIUtil.decodePath() + */ + protected static String decodePath(String path) throws MalformedURLException { + if (!path.contains("%")) + return path; + try { + URI uri = new URI(path); + return uri.getPath(); + } catch (URISyntaxException use) { + // for ease of use, since a USE is not an IOE but a MUE is... + throw new MalformedURLException(use.getMessage()); + } + } + + /** + * Simple version of URIUtil.encodePath() + */ + protected static String encodePath(String path) throws MalformedURLException { + try { + URI uri = new URI(null, null, path, null); + return uri.toString(); + } catch (URISyntaxException use) { + // for ease of use, since a USE is not an IOE but a MUE is... + throw new MalformedURLException(use.getMessage()); + } + } + + /** + * Write from in to out + */ + private void copy(InputStream in, OutputStream out) throws IOException { + ByteArray ba = _cache.acquire(); + byte[] buf = ba.getData(); + try { + int read = 0; + while ( (read = in.read(buf)) != -1) { + out.write(buf, 0, read); + } + } finally { + _cache.release(ba, false); + if (in != null) + try { in.close(); } catch (IOException ioe) {} + if (out != null) + try { out.close(); } catch (IOException ioe) {} + } + } +} diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index ce93fb93ec8d92e74c358e14aa154fe313b0d2de..518d1ef3a3b1cadd7bb69764beb18b0061cc65a4 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -24,6 +24,7 @@ import java.util.TreeSet; import javax.servlet.ServletConfig; import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -44,42 +45,48 @@ import org.klomp.snark.Tracker; import org.klomp.snark.TrackerClient; import org.klomp.snark.dht.DHT; -import org.mortbay.jetty.servlet.DefaultServlet; -import org.mortbay.resource.Resource; -import org.mortbay.util.URIUtil; - /** - * We extend Default instead of HTTPServlet so we can handle - * i2psnark/ file requests with http:// instead of the flaky and - * often-blocked-by-the-browser file:// + * Refactored to eliminate Jetty dependencies. */ -public class I2PSnarkServlet extends DefaultServlet { - private I2PAppContext _context; - private Log _log; +public class I2PSnarkServlet extends BasicServlet { + /** generally "/i2psnark" */ + private String _contextPath; + /** generally "i2psnark" */ + private String _contextName; private SnarkManager _manager; private static long _nonce; - private Resource _resourceBase; private String _themePath; private String _imgPath; private String _lastAnnounceURL; + private static final String DEFAULT_NAME = "i2psnark"; public static final String PROP_CONFIG_FILE = "i2psnark.configFile"; + public I2PSnarkServlet() { + super(); + } + @Override public void init(ServletConfig cfg) throws ServletException { - _context = I2PAppContext.getGlobalContext(); - _log = _context.logManager().getLog(I2PSnarkServlet.class); + super.init(cfg); + String cpath = getServletContext().getContextPath(); + _contextPath = cpath == "" ? "/" : cpath; + _contextName = cpath == "" ? DEFAULT_NAME : cpath.substring(1).replace("/", "_"); _nonce = _context.random().nextLong(); - _manager = new SnarkManager(_context); + // limited protection against overwriting other config files or directories + // in case you named your war "router.war" + String configName = _contextName; + if (!configName.equals(DEFAULT_NAME)) + configName = DEFAULT_NAME + '_' + _contextName; + _manager = new SnarkManager(_context, _contextPath, configName); String configFile = _context.getProperty(PROP_CONFIG_FILE); if ( (configFile == null) || (configFile.trim().length() <= 0) ) - configFile = "i2psnark.config"; + configFile = configName + ".config"; _manager.loadConfig(configFile); _manager.start(); - try { - _resourceBase = Resource.newResource(_manager.getDataDir().getAbsolutePath()); - } catch (IOException ioe) {} - super.init(cfg); + loadMimeMap("org/klomp/snark/web/mime"); + setResourceBase(_manager.getDataDir()); + setWarBase("/.icons/"); } @Override @@ -95,29 +102,36 @@ public class I2PSnarkServlet extends DefaultServlet { * and we can't get any resources (like icons) out of the .war */ @Override - public Resource getResource(String pathInContext) + public File getResource(String pathInContext) { if (pathInContext == null || pathInContext.equals("/") || pathInContext.equals("/index.jsp") || pathInContext.equals("/index.html") || pathInContext.startsWith("/.icons/")) return super.getResource(pathInContext); // files in the i2psnark/ directory - try { - return _resourceBase.addPath(pathInContext); - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } + return new File(_resourceBase, pathInContext); } /** - * Tell the browser to cache the icons + * Handle what we can here, calling super.doGet() for the rest. * @since 0.8.3 */ @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - super.doGet(request, response); + doGetAndPost(request, response); + } + + /** + * Handle what we can here, calling super.doPost() for the rest. + * @since Jetty 7 + */ + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + doGetAndPost(request, response); } /** + * Handle what we can here, calling super.doGet() or super.doPost() for the rest. + * * Some parts modified from: * <pre> // ======================================================================== @@ -137,14 +151,11 @@ public class I2PSnarkServlet extends DefaultServlet { * </pre> * */ - @Override - public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + private void doGetAndPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Service " + req.getMethod() + " \"" + req.getContextPath() + "\" \"" + req.getServletPath() + "\" \"" + req.getPathInfo() + '"'); // since we are not overriding handle*(), do this here String method = req.getMethod(); - if (!(method.equals("GET") || method.equals("HEAD") || method.equals("POST"))) { - resp.sendError(405); - return; - } _themePath = "/themes/snark/" + _manager.getTheme() + '/'; _imgPath = _themePath + "images/"; // this is the part after /i2psnark @@ -176,17 +187,18 @@ public class I2PSnarkServlet extends DefaultServlet { // index.jsp doesn't work, it is grabbed by the war handler before here if (!(path == null || path.equals("/") || path.equals("/index.jsp") || path.equals("/index.html") || path.equals("/_post") || isConfigure)) { if (path.endsWith("/")) { + // Listing of a torrent (torrent detail page) // bypass the horrid Resource.getListHTML() String pathInfo = req.getPathInfo(); - String pathInContext = URIUtil.addPaths(path, pathInfo); + String pathInContext = addPaths(path, pathInfo); req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8"); resp.setContentType("text/html; charset=UTF-8"); - Resource resource = getResource(pathInContext); - if (resource == null || (!resource.exists())) { + File resource = getResource(pathInContext); + if (resource == null) { resp.sendError(404); } else { - String base = URIUtil.addPaths(req.getRequestURI(), "/"); + String base = addPaths(req.getRequestURI(), "/"); String listing = getListHTML(resource, base, true, method.equals("POST") ? req.getParameterMap() : null); if (method.equals("POST")) { // P-R-G @@ -198,11 +210,19 @@ public class I2PSnarkServlet extends DefaultServlet { } } } else { - super.service(req, resp); + // local completed files in torrent directories + if (method.equals("GET") || method.equals("HEAD")) + super.doGet(req, resp); + else if (method.equals("POST")) + super.doPost(req, resp); + else + resp.sendError(405); } return; } + // Either the main page or /configure + req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8"); resp.setContentType("text/html; charset=UTF-8"); @@ -236,7 +256,7 @@ public class I2PSnarkServlet extends DefaultServlet { out.write("<script src=\"/js/ajax.js\" type=\"text/javascript\"></script>\n" + "<script type=\"text/javascript\">\n" + "var failMessage = \"<div class=\\\"routerdown\\\"><b>" + _("Router is down") + "<\\/b><\\/div>\";\n" + - "function requestAjax1() { ajax(\"/i2psnark/.ajax/xhr1.html" + peerString + "\", \"mainsection\", " + (delay*1000) + "); }\n" + + "function requestAjax1() { ajax(\"" + _contextPath + "/.ajax/xhr1.html" + peerString + "\", \"mainsection\", " + (delay*1000) + "); }\n" + "function initAjax() { setTimeout(requestAjax1, " + (delay*1000) +"); }\n" + "</script>\n"); } @@ -249,18 +269,24 @@ public class I2PSnarkServlet extends DefaultServlet { out.write("<center>"); List<Tracker> sortedTrackers = null; if (isConfigure) { - out.write("<div class=\"snarknavbar\"><a href=\"/i2psnark/\" title=\""); + out.write("<div class=\"snarknavbar\"><a href=\"" + _contextPath + "/\" title=\""); out.write(_("Torrents")); out.write("\" class=\"snarkRefresh\">"); out.write("<img alt=\"\" border=\"0\" src=\"" + _imgPath + "arrow_refresh.png\"> "); - out.write(_("I2PSnark")); + if (_contextName.equals(DEFAULT_NAME)) + out.write(_("I2PSnark")); + else + out.write(_contextName); out.write("</a>"); } else { - out.write("<div class=\"snarknavbar\"><a href=\"/i2psnark/" + peerString + "\" title=\""); + out.write("<div class=\"snarknavbar\"><a href=\"" + _contextPath + '/' + peerString + "\" title=\""); out.write(_("Refresh page")); out.write("\" class=\"snarkRefresh\">"); out.write("<img alt=\"\" border=\"0\" src=\"" + _imgPath + "arrow_refresh.png\"> "); - out.write(_("I2PSnark")); + if (_contextName.equals(DEFAULT_NAME)) + out.write(_("I2PSnark")); + else + out.write(_contextName); out.write("</a> <a href=\"http://forum.i2p/viewforum.php?f=21\" class=\"snarkRefresh\" target=\"_blank\">"); out.write(_("Forum")); out.write("</a>\n"); @@ -302,7 +328,7 @@ public class I2PSnarkServlet extends DefaultServlet { List<String> msgs = _manager.getMessages(); if (!msgs.isEmpty()) { out.write("<div class=\"snarkMessages\">"); - out.write("<a href=\"/i2psnark/"); + out.write("<a href=\"" + _contextPath + '/'); if (isConfigure) out.write("configure"); if (peerString.length() > 0) @@ -342,7 +368,7 @@ public class I2PSnarkServlet extends DefaultServlet { out.write(_("Status")); out.write("\"></th>\n<th>"); if (_manager.util().connected() && !snarks.isEmpty()) { - out.write(" <a href=\"/i2psnark/"); + out.write(" <a href=\"" + _contextPath + '/'); if (peerParam != null) { out.write("\">"); out.write("<img border=\"0\" src=\"" + _imgPath + "hidepeers.png\" title=\""); @@ -423,7 +449,7 @@ public class I2PSnarkServlet extends DefaultServlet { out.write(" "); } else if (_manager.util().connected()) { if (isDegraded) - out.write("<a href=\"/i2psnark/?action=StopAll&nonce=" + _nonce + "\"><img title=\""); + out.write("<a href=\"" + _contextPath + "/?action=StopAll&nonce=" + _nonce + "\"><img title=\""); else { // http://www.onenaught.com/posts/382/firefox-4-change-input-type-image-only-submits-x-and-y-not-name //out.write("<input type=\"image\" name=\"action\" value=\"StopAll\" title=\""); @@ -437,7 +463,7 @@ public class I2PSnarkServlet extends DefaultServlet { out.write("</a>"); } else if ((!_manager.util().isConnecting()) && !snarks.isEmpty()) { if (isDegraded) - out.write("<a href=\"/i2psnark/?action=StartAll&nonce=" + _nonce + "\"><img title=\""); + out.write("<a href=\"/" + _contextPath + "/?action=StartAll&nonce=" + _nonce + "\"><img title=\""); else out.write("<input type=\"image\" name=\"action_StartAll\" value=\"foo\" title=\""); out.write(_("Start all torrents and the I2P tunnel")); @@ -450,7 +476,7 @@ public class I2PSnarkServlet extends DefaultServlet { out.write(" "); } out.write("</th></tr></thead>\n"); - String uri = "/i2psnark/"; + String uri = _contextPath + '/'; boolean showDebug = "2".equals(peerParam); for (int i = 0; i < snarks.size(); i++) { Snark snark = (Snark)snarks.get(i); @@ -1245,7 +1271,7 @@ public class I2PSnarkServlet extends DefaultServlet { } else if (isRunning) { // Stop Button if (isDegraded) - out.write("<a href=\"/i2psnark/?action=Stop_" + b64 + "&nonce=" + _nonce + "\"><img title=\""); + out.write("<a href=\"" + _contextPath + "/?action=Stop_" + b64 + "&nonce=" + _nonce + "\"><img title=\""); else out.write("<input type=\"image\" name=\"action_Stop_" + b64 + "\" value=\"foo\" title=\""); out.write(_("Stop the torrent")); @@ -1259,7 +1285,7 @@ public class I2PSnarkServlet extends DefaultServlet { // Start Button // This works in Opera but it's displayed a little differently, so use noThinsp here too so all 3 icons are consistent if (noThinsp) - out.write("<a href=\"/i2psnark/?action=Start_" + b64 + "&nonce=" + _nonce + "\"><img title=\""); + out.write("<a href=\"/" + _contextPath + "/?action=Start_" + b64 + "&nonce=" + _nonce + "\"><img title=\""); else out.write("<input type=\"image\" name=\"action_Start_" + b64 + "\" value=\"foo\" title=\""); out.write(_("Start the torrent")); @@ -1273,7 +1299,7 @@ public class I2PSnarkServlet extends DefaultServlet { // Remove Button // Doesnt work with Opera so use noThinsp instead of isDegraded if (noThinsp) - out.write("<a href=\"/i2psnark/?action=Remove_" + b64 + "&nonce=" + _nonce + "\"><img title=\""); + out.write("<a href=\"" + _contextPath + "/?action=Remove_" + b64 + "&nonce=" + _nonce + "\"><img title=\""); else out.write("<input type=\"image\" name=\"action_Remove_" + b64 + "\" value=\"foo\" title=\""); out.write(_("Remove the torrent from the active list, deleting the .torrent file")); @@ -1293,7 +1319,7 @@ public class I2PSnarkServlet extends DefaultServlet { // Delete Button // Doesnt work with Opera so use noThinsp instead of isDegraded if (noThinsp) - out.write("<a href=\"/i2psnark/?action=Delete_" + b64 + "&nonce=" + _nonce + "\"><img title=\""); + out.write("<a href=\"" + _contextPath + "/?action=Delete_" + b64 + "&nonce=" + _nonce + "\"><img title=\""); else out.write("<input type=\"image\" name=\"action_Delete_" + b64 + "\" value=\"foo\" title=\""); out.write(_("Delete the .torrent file and the associated data file(s)")); @@ -1620,7 +1646,7 @@ public class I2PSnarkServlet extends DefaultServlet { boolean useDHT = _manager.util().shouldUseDHT(); //int seedPct = 0; - out.write("<form action=\"/i2psnark/configure\" method=\"POST\">\n" + + out.write("<form action=\"" + _contextPath + "/configure\" method=\"POST\">\n" + "<div class=\"configsectionpanel\"><div class=\"snarkConfig\">\n" + "<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n" + "<input type=\"hidden\" name=\"action\" value=\"Save\" >\n" + @@ -1632,7 +1658,8 @@ public class I2PSnarkServlet extends DefaultServlet { out.write(_("Data directory")); out.write(": <td><code>" + dataDir + "</code> <i>("); - out.write(_("Edit i2psnark.config and restart to change")); + // translators: parameter is a file name + out.write(_("Edit {0} and restart to change", _manager.getConfigFilename())); out.write(")</i><br>\n" + "<tr><td>"); @@ -1802,7 +1829,7 @@ public class I2PSnarkServlet extends DefaultServlet { /** @since 0.9 */ private void writeTrackerForm(PrintWriter out, HttpServletRequest req) throws IOException { StringBuilder buf = new StringBuilder(1024); - buf.append("<form action=\"/i2psnark/configure\" method=\"POST\">\n" + + buf.append("<form action=\"" + _contextPath + "/configure\" method=\"POST\">\n" + "<div class=\"configsectionpanel\"><div class=\"snarkConfig\">\n" + "<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n" + "<input type=\"hidden\" name=\"action\" value=\"Save2\" >\n" + @@ -2031,7 +2058,7 @@ public class I2PSnarkServlet extends DefaultServlet { * @return String of HTML or null if postParams != null * @since 0.7.14 */ - private String getListHTML(Resource r, String base, boolean parent, Map postParams) + private String getListHTML(File r, String base, boolean parent, Map postParams) throws IOException { String[] ls = null; @@ -2040,9 +2067,10 @@ public class I2PSnarkServlet extends DefaultServlet { Arrays.sort(ls, Collator.getInstance()); } // if r is not a directory, we are only showing torrent info section - String title = URIUtil.decodePath(base); - if (title.startsWith("/i2psnark/")) - title = title.substring("/i2psnark/".length()); + String title = decodePath(base); + String cpath = _contextPath + '/'; + if (title.startsWith(cpath)) + title = title.substring(cpath.length()); // Get the snark associated with this directory String torrentName; @@ -2067,8 +2095,13 @@ public class I2PSnarkServlet extends DefaultServlet { title = _("Torrent") + ": " + title; buf.append(title); buf.append("</TITLE>").append(HEADER_A).append(_themePath).append(HEADER_B).append("<link rel=\"shortcut icon\" href=\"" + _themePath + "favicon.ico\">" + - "</HEAD><BODY>\n<center><div class=\"snarknavbar\"><a href=\"/i2psnark/\" title=\"Torrents\""); - buf.append(" class=\"snarkRefresh\"><img alt=\"\" border=\"0\" src=\"" + _imgPath + "arrow_refresh.png\"> I2PSnark</a></div></center>\n"); + "</HEAD><BODY>\n<center><div class=\"snarknavbar\"><a href=\"").append(_contextPath).append("/\" title=\"Torrents\""); + buf.append(" class=\"snarkRefresh\"><img alt=\"\" border=\"0\" src=\"" + _imgPath + "arrow_refresh.png\"> "); + if (_contextName.equals(DEFAULT_NAME)) + buf.append(_("I2PSnark")); + else + buf.append(_contextName); + buf.append("</a></div></center>\n"); if (parent) // always true buf.append("<div class=\"page\"><div class=\"mainsection\">"); @@ -2089,7 +2122,7 @@ public class I2PSnarkServlet extends DefaultServlet { buf.append("<tr><td>") .append("<img alt=\"\" border=\"0\" src=\"" + _imgPath + "file.png\" > <b>") .append(_("Torrent file")) - .append(":</b> <a href=\"/i2psnark/").append(baseName).append("\">") + .append(":</b> <a href=\"").append(_contextPath).append('/').append(baseName).append("\">") .append(fullPath) .append("</a></td></tr>\n"); @@ -2228,7 +2261,7 @@ public class I2PSnarkServlet extends DefaultServlet { .append("\"></th>\n"); buf.append("</tr>\n</thead>\n"); buf.append("<tr><td colspan=\"" + (showPriority ? '5' : '4') + "\" class=\"ParentDir\"><A HREF=\""); - buf.append(URIUtil.addPaths(base,"../")); + buf.append(addPaths(base,"../")); buf.append("\"><img alt=\"\" border=\"0\" src=\"" + _imgPath + "up.png\"> ") .append(_("Up to higher level directory")) .append("</A></td></tr>\n"); @@ -2239,12 +2272,12 @@ public class I2PSnarkServlet extends DefaultServlet { boolean showSaveButton = false; for (int i=0 ; i< ls.length ; i++) { - String encoded=URIUtil.encodePath(ls[i]); + String encoded = encodePath(ls[i]); // bugfix for I2P - Backport from Jetty 6 (zero file lengths and last-modified times) // http://jira.codehaus.org/browse/JETTY-361?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel#issue-tabs // See resource.diff attachment //Resource item = addPath(encoded); - Resource item = r.addPath(ls[i]); + File item = new File(r, ls[i]); String rowClass = (i % 2 == 0 ? "snarkTorrentEven" : "snarkTorrentOdd"); buf.append("<TR class=\"").append(rowClass).append("\">"); @@ -2264,7 +2297,7 @@ public class I2PSnarkServlet extends DefaultServlet { } else { Storage storage = snark.getStorage(); try { - File f = item.getFile(); + File f = item; if (f != null) { long remaining = storage.remaining(f.getCanonicalPath()); if (remaining < 0) { @@ -2294,9 +2327,9 @@ public class I2PSnarkServlet extends DefaultServlet { } } - String path=URIUtil.addPaths(base,encoded); + String path=addPaths(base,encoded); if (item.isDirectory() && !path.endsWith("/")) - path=URIUtil.addPaths(path,"/"); + path=addPaths(path,"/"); String icon = toIcon(item); buf.append("<TD class=\"snarkFileIcon ") @@ -2331,7 +2364,7 @@ public class I2PSnarkServlet extends DefaultServlet { buf.append("</TD>"); if (showPriority) { buf.append("<td class=\"priority\">"); - File f = item.getFile(); + File f = item; if ((!complete) && (!item.isDirectory()) && f != null) { int pri = snark.getStorage().getPriority(f.getCanonicalPath()); buf.append("<input type=\"radio\" value=\"5\" name=\"pri.").append(f.getCanonicalPath()).append("\" "); @@ -2368,7 +2401,7 @@ public class I2PSnarkServlet extends DefaultServlet { } /** @since 0.7.14 */ - private String toIcon(Resource item) { + private String toIcon(File item) { if (item.isDirectory()) return "folder"; return toIcon(item.toString()); @@ -2381,40 +2414,32 @@ public class I2PSnarkServlet extends DefaultServlet { */ private String toIcon(String path) { String icon; - // Should really just add to the mime.properties file in org.mortbay.jetty.jar - // instead of this mishmash. We can't get to HttpContext.setMimeMapping() - // from here? We could do it from a web.xml perhaps. - // Or could we put our own org/mortbay/http/mime.properties file in the war? + // Note that for this to work well, our custom mime.properties file must be loaded. String plc = path.toLowerCase(Locale.US); - String mime = getServletContext().getMimeType(path); + String mime = getMimeType(path); if (mime == null) mime = ""; if (mime.equals("text/html")) icon = "html"; - else if (mime.equals("text/plain") || plc.endsWith(".nfo") || + else if (mime.equals("text/plain") || mime.equals("application/rtf")) icon = "page"; - else if (mime.equals("application/java-archive") || plc.endsWith(".war") || + else if (mime.equals("application/java-archive") || plc.endsWith(".deb")) icon = "package"; else if (plc.endsWith(".xpi2p")) icon = "plugin"; else if (mime.equals("application/pdf")) icon = "page_white_acrobat"; - else if (mime.startsWith("image/") || plc.endsWith(".ico")) + else if (mime.startsWith("image/")) icon = "photo"; - else if (mime.startsWith("audio/") || mime.equals("application/ogg") || - plc.endsWith(".flac") || plc.endsWith(".m4a") || plc.endsWith(".wma") || - plc.endsWith(".ape") || plc.endsWith(".oga")) + else if (mime.startsWith("audio/") || mime.equals("application/ogg")) icon = "music"; - else if (mime.startsWith("video/") || plc.endsWith(".mkv") || plc.endsWith(".m4v") || - plc.endsWith(".mp4") || plc.endsWith(".wmv") || plc.endsWith(".flv") || - plc.endsWith(".ogm") || plc.endsWith(".ogv")) + else if (mime.startsWith("video/")) icon = "film"; else if (mime.equals("application/zip") || mime.equals("application/x-gtar") || mime.equals("application/compress") || mime.equals("application/gzip") || - mime.equals("application/x-tar") || - plc.endsWith(".rar") || plc.endsWith(".bz2") || plc.endsWith(".7z")) + mime.equals("application/x-tar")) icon = "compress"; else if (plc.endsWith(".exe")) icon = "application"; @@ -2426,13 +2451,13 @@ public class I2PSnarkServlet extends DefaultServlet { } /** @since 0.7.14 */ - private static String toImg(String icon) { - return "<img alt=\"\" height=\"16\" width=\"16\" src=\"/i2psnark/.icons/" + icon + ".png\">"; + private String toImg(String icon) { + return "<img alt=\"\" height=\"16\" width=\"16\" src=\"" + _contextPath + "/.icons/" + icon + ".png\">"; } /** @since 0.8.2 */ - private static String toImg(String icon, String altText) { - return "<img alt=\"" + altText + "\" height=\"16\" width=\"16\" src=\"/i2psnark/.icons/" + icon + ".png\">"; + private String toImg(String icon, String altText) { + return "<img alt=\"" + altText + "\" height=\"16\" width=\"16\" src=\"" + _contextPath + "/.icons/" + icon + ".png\">"; } /** @since 0.8.1 */ diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/MimeTypes.java b/apps/i2psnark/java/src/org/klomp/snark/web/MimeTypes.java new file mode 100644 index 0000000000000000000000000000000000000000..e24764ff5e662eeda41684077fdbcf3aa234d9f4 --- /dev/null +++ b/apps/i2psnark/java/src/org/klomp/snark/web/MimeTypes.java @@ -0,0 +1,131 @@ +// ======================================================================== +// Copyright 2000-2005 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ======================================================================== + +package org.klomp.snark.web; + +import java.util.Enumeration; +import java.util.Locale; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.concurrent.ConcurrentHashMap; + +import javax.servlet.ServletContext; + + +/* ------------------------------------------------------------ */ +/** + * Based on MimeTypes from Jetty 6.1.26, heavily simplified + * and modified to remove all dependencies on Jetty libs. + * + * Supports mime types only, not encodings. + * Does not support a default "*" mapping. + * + * This is only for local mappings. + * Caller should use getServletContext().getMimeType() if this returns null. + * + * + * ------------------------------------------------------------ + * + * @author Greg Wilkins + * + * @since Jetty 7 + */ +class MimeTypes +{ + + private final Map<String, String> _mimeMap; + + public MimeTypes() { + _mimeMap = new ConcurrentHashMap(); + } + + /* ------------------------------------------------------------ */ + /** + * @param resourcePath A Map of file extension to mime-type. + */ + public void loadMimeMap(String resourcePath) { + loadMimeMap(_mimeMap, resourcePath); + } + + /** + * Tries both webapp and system class loader, since Jetty blocks + * its classes from the webapp class loader. + */ + private static void loadMimeMap(Map<String, String> map, String resourcePath) { + try + { + ResourceBundle mime; + try { + mime = ResourceBundle.getBundle(resourcePath); + } catch(MissingResourceException e) { + // Jetty 7 webapp classloader blocks jetty classes + // http://wiki.eclipse.org/Jetty/Reference/Jetty_Classloading + //System.out.println("No mime types loaded from " + resourcePath + ", trying system classloader"); + mime = ResourceBundle.getBundle(resourcePath, Locale.getDefault(), ClassLoader.getSystemClassLoader()); + } + Enumeration<String> i = mime.getKeys(); + while(i.hasMoreElements()) + { + String ext = i.nextElement(); + String m = mime.getString(ext); + map.put(ext.toLowerCase(Locale.US), m); + } + //System.out.println("Loaded " + map.size() + " mime types from " + resourcePath); + } catch(MissingResourceException e) { + //System.out.println("No mime types loaded from " + resourcePath); + } + } + + /* ------------------------------------------------------------ */ + /** Get the MIME type by filename extension. + * + * Returns ONLY local mappings. + * Caller should use getServletContext().getMimeType() if this returns null. + * + * @param filename A file name + * @return MIME type matching the longest dot extension of the + * file name. + */ + public String getMimeByExtension(String filename) + { + String type=null; + + if (filename!=null) + { + int i=-1; + while(type==null) + { + i=filename.indexOf(".",i+1); + + if (i<0 || i>=filename.length()) + break; + + String ext=filename.substring(i+1).toLowerCase(Locale.US); + type = _mimeMap.get(ext); + } + } + return type; + } + + /* ------------------------------------------------------------ */ + /** Set a mime mapping + * @param extension + * @param type + */ + public void addMimeMapping(String extension, String type) + { + _mimeMap.put(extension.toLowerCase(Locale.US), type); + } +} diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/RunStandalone.java b/apps/i2psnark/java/src/org/klomp/snark/web/RunStandalone.java index 543fc8a7ee07c1e579cd9776e88a80032bb87ce2..30700dd4d76830514d23d57787b3c0a4414d6002 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/RunStandalone.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/RunStandalone.java @@ -5,7 +5,7 @@ import java.io.File; import net.i2p.I2PAppContext; import net.i2p.util.FileUtil; -import org.mortbay.jetty.Server; +import org.eclipse.jetty.server.Server; public class RunStandalone { static { diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/WriterOutputStream.java b/apps/i2psnark/java/src/org/klomp/snark/web/WriterOutputStream.java new file mode 100644 index 0000000000000000000000000000000000000000..c4aa37bc54f5e5bdcbf5096c849fda224a1ce5ac --- /dev/null +++ b/apps/i2psnark/java/src/org/klomp/snark/web/WriterOutputStream.java @@ -0,0 +1,19 @@ +package org.klomp.snark.web; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; + +/** + * Treat a writer as an output stream. Quick 'n dirty, none + * of that "intarnasheeonaleyzayshun" stuff. So we can treat + * the jsp's PrintWriter as an OutputStream + * + * @since Jetty 7 copied from routerconsole + */ +class WriterOutputStream extends OutputStream { + private final Writer _writer; + + public WriterOutputStream(Writer writer) { _writer = writer; } + public void write(int b) throws IOException { _writer.write(b); } +} diff --git a/apps/i2psnark/mime.properties b/apps/i2psnark/mime.properties new file mode 100644 index 0000000000000000000000000000000000000000..4fc8f7a5e4a81604139684dedec6d66fe2438034 --- /dev/null +++ b/apps/i2psnark/mime.properties @@ -0,0 +1,17 @@ +7z = application/x-7z-compressed +ape = audio/ape +bz2 = application/x-bzip2 +flac = audio/ogg +flv = video/x-flv +m4a = audio/mp4a-latm +m4v = video/x-m4v +mkv = video/x-matroska +mp4 = video/mp4 +nfo = text/plain +ogm = video/ogg +ogv = video/ogg +oga = audio/ogg +rar = application/x-rar-compressed +war = application/java-archive +wma = audio/x-ms-wma +wmv = video/x-ms-wmv diff --git a/apps/jetty/README-i2p.txt b/apps/jetty/README-i2p.txt new file mode 100644 index 0000000000000000000000000000000000000000..3aa81e1ec118388374427ea9bc2ab6edafda2447 --- /dev/null +++ b/apps/jetty/README-i2p.txt @@ -0,0 +1,3 @@ +jetty-distribution-xxx is only what we need out of jetty-distribution-xxx.zip. + +NOTICE and LICENSE files moved to ../../../licenses diff --git a/apps/jetty/build.xml b/apps/jetty/build.xml index 04f988b90d73b26e3a5d21ccfcc07562b251b29b..b0f72eb0f6c63bb316539a85f2776fd9e2a44157 100644 --- a/apps/jetty/build.xml +++ b/apps/jetty/build.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="UTF-8"?> <project basedir="." default="all" name="jetty"> - <property name="jetty.ver" value="6.1.26" /> - <property name="jetty.base" value="jetty-${jetty.ver}" /> - <property name="jetty.sha1" value="9485913f1a1945a849a90f1a34853d22350bc524" /> + <property name="jetty.ver" value="7.6.8.v20121106" /> + <property name="jetty.base" value="jetty-distribution-${jetty.ver}" /> + <property name="jetty.sha1" value="6fcdc3f532c5ab72843e12cbac3d7cb797cdb5b9" /> <property name="jetty.filename" value="${jetty.base}.zip" /> - <property name="jetty.url" value="http://dist.codehaus.org/jetty/${jetty.base}/${jetty.filename}" /> + <property name="jetty.url" value="http://download.eclipse.org/jetty/${jetty.ver}/dist/${jetty.filename}" /> <property name="verified.filename" value="verified.txt" /> <property name="javac.compilerargs" value="" /> <property name="tomcat.lib" value="apache-tomcat-deployer/lib" /> @@ -89,20 +89,40 @@ Reasons for inclusion: start.jar: Needed for clients.config startup of eepsites jetty-util-xxx.jar: LifeCycle (base class for stuff), URIUtil (used in i2psnark) - jetty-sslengine-xxx.jar: SSL NIO Connector for console - jetty-java5-threadpool-xxx.jar: Concurrent thread pool for eepsite + jetty-deploy, -http, -io, -security, -servlet, -webapp: All split out from main server jar in Jetty 7 + jetty-continuation-xxx.jar: Needed? Useful? + jetty-servlets-xxx.jar: Needed for CGI for eepsite + jetty-sslengine-xxx.jar: Old Jetty 6, now a dummy + jetty-java5-threadpool-xxx.jar: Old Jetty 6, now a dummy glassfish 2.1: Not used, too old, see Tomcat below. jetty-rewrite-handler: Not used by I2P, but only 20KB and could be useful for eepsites jetty-management: Not used by I2P, but only 34KB and could be useful for eepsites, and we bundled it with Jetty 5 All of these are available in the Ubuntu packages libjetty-java and libjetty-extra-java --> <copy preservelastmodified="true" file="${jetty.base}/start.jar" tofile="jettylib/jetty-start.jar" /> - <copy file="${jetty.base}/lib/${jetty.base}.jar" tofile="jettylib/org.mortbay.jetty.jar" /> + <copy file="${jetty.base}/lib/jetty-server-${jetty.ver}.jar" tofile="jettylib/org.mortbay.jetty.jar" /> + <copy preservelastmodified="true" file="${jetty.base}/lib/jetty-continuation-${jetty.ver}.jar" tofile="jettylib/jetty-continuation.jar" /> + <copy preservelastmodified="true" file="${jetty.base}/lib/jetty-deploy-${jetty.ver}.jar" tofile="jettylib/jetty-deploy.jar" /> + <copy preservelastmodified="true" file="${jetty.base}/lib/jetty-http-${jetty.ver}.jar" tofile="jettylib/jetty-http.jar" /> + <copy preservelastmodified="true" file="${jetty.base}/lib/jetty-io-${jetty.ver}.jar" tofile="jettylib/jetty-io.jar" /> + <copy preservelastmodified="true" file="${jetty.base}/lib/jetty-jmx-${jetty.ver}.jar" tofile="jettylib/org.mortbay.jmx.jar" /> + <copy preservelastmodified="true" file="${jetty.base}/lib/jetty-rewrite-${jetty.ver}.jar" tofile="jettylib/jetty-rewrite-handler.jar" /> + <copy preservelastmodified="true" file="${jetty.base}/lib/jetty-security-${jetty.ver}.jar" tofile="jettylib/jetty-security.jar" /> + <copy preservelastmodified="true" file="${jetty.base}/lib/jetty-servlet-${jetty.ver}.jar" tofile="jettylib/jetty-servlet.jar" /> + <copy preservelastmodified="true" file="${jetty.base}/lib/jetty-servlets-${jetty.ver}.jar" tofile="jettylib/jetty-servlets.jar" /> <copy preservelastmodified="true" file="${jetty.base}/lib/jetty-util-${jetty.ver}.jar" tofile="jettylib/jetty-util.jar" /> - <copy preservelastmodified="true" file="${jetty.base}/lib/ext/jetty-java5-threadpool-${jetty.ver}.jar" tofile="jettylib/jetty-java5-threadpool.jar" /> - <copy preservelastmodified="true" file="${jetty.base}/lib/ext/jetty-rewrite-handler-${jetty.ver}.jar" tofile="jettylib/jetty-rewrite-handler.jar" /> - <copy preservelastmodified="true" file="${jetty.base}/lib/ext/jetty-sslengine-${jetty.ver}.jar" tofile="jettylib/jetty-sslengine.jar" /> - <copy preservelastmodified="true" file="${jetty.base}/lib/management/jetty-management-${jetty.ver}.jar" tofile="jettylib/org.mortbay.jmx.jar" /> + <copy preservelastmodified="true" file="${jetty.base}/lib/jetty-webapp-${jetty.ver}.jar" tofile="jettylib/jetty-webapp.jar" /> + <copy preservelastmodified="true" file="${jetty.base}/lib/jetty-xml-${jetty.ver}.jar" tofile="jettylib/jetty-xml.jar" /> + <jar destfile="jettylib/jetty-java5-threadpool.jar" > + <manifest> + <attribute name="Note" value="Intentionally empty" /> + </manifest> + </jar> + <jar destfile="jettylib/jetty-sslengine.jar" > + <manifest> + <attribute name="Note" value="Intentionally empty" /> + </manifest> + </jar> <delete file="jetty.tar" /> <!-- <delete dir="${jetty.base}" /> @@ -155,15 +175,16 @@ <target name="build" depends="jar" /> <target name="builddep" /> + <target name="compile" depends="builddep, ensureJettylib" > <mkdir dir="./build" /> <mkdir dir="./build/obj" /> <javac srcdir="./java/src" - debug="true" source="1.5" target="1.5" + debug="true" deprecation="on" source="1.5" target="1.5" destdir="./build/obj" includeAntRuntime="false" - classpath="../../core/java/build/i2p.jar:./jettylib/commons-logging.jar:./jettylib/javax.servlet.jar:./jettylib/org.mortbay.jetty.jar:./jettylib/jetty-util.jar" > + classpath="../../core/java/build/i2p.jar:./jettylib/commons-logging.jar:./jettylib/javax.servlet.jar:./jettylib/org.mortbay.jetty.jar:./jettylib/jetty-http.jar:./jettylib/jetty-io.jar:./jettylib/jetty-util.jar:./jettylib/jetty-xml.jar" > <compilerarg line="${javac.compilerargs}" /> </javac> </target> diff --git a/apps/jetty/java/src/net/i2p/jetty/I2PLogger.java b/apps/jetty/java/src/net/i2p/jetty/I2PLogger.java index 6329464c345053cff74570a59243ca48545b16d7..309d8819fbd12156e57f9211415ed7b16811d61b 100644 --- a/apps/jetty/java/src/net/i2p/jetty/I2PLogger.java +++ b/apps/jetty/java/src/net/i2p/jetty/I2PLogger.java @@ -17,13 +17,13 @@ package net.i2p.jetty; import net.i2p.I2PAppContext; import net.i2p.util.Log; -import org.mortbay.jetty.Server; -import org.mortbay.log.Logger; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.log.Logger; /** * Modified from Jetty 6.1.26 StdErrLog.java and Slf4jLog.java * - * Usage: org.mortbay.log.Log.setLog(new I2PLogger(ctx)); + * Usage: org.eclipse.log.Log.setLog(new I2PLogger(ctx)); * * @since Jetty 6 */ @@ -182,5 +182,80 @@ public class I2PLogger implements Logger return "I2PLogger"; } + /** + * @since Jetty 7 + */ + public void ignore(Throwable ignored) + { + warn("IGNORED", ignored); + } + + /** + * @since Jetty 7 + */ + public void debug(Throwable thrown) + { + debug("", thrown); + } + + /** + * @since Jetty 7 + */ + public void debug(String msg, Object... args) + { + Object a1 = args.length > 0 ? args[0] : null; + Object a2 = args.length > 1 ? args[1] : null; + debug(msg, a1, a2); + } + + /** + * @since Jetty 7 + */ + public void info(Throwable thrown) + { + info("", thrown); + } + + /** + * @since Jetty 7 + */ + public void info(String msg, Object... args) + { + Object a1 = args.length > 0 ? args[0] : null; + Object a2 = args.length > 1 ? args[1] : null; + info(msg, a1, a2); + } + + /** + * @since Jetty 7 + */ + public void info(String msg, Throwable th) + { + _log.info(msg,th); + } + + /** + * @since Jetty 7 + */ + public void warn(Throwable thrown) + { + warn("", thrown); + } + + /** + * @since Jetty 7 + */ + public void warn(String msg, Object... args) + { + Object a1 = args.length > 0 ? args[0] : null; + Object a2 = args.length > 1 ? args[1] : null; + warn(msg, a1, a2); + } + /** + * @since Jetty 7 + */ + public String getName() { + return "net.i2p.jetty.I2PLogger"; + } } diff --git a/apps/jetty/java/src/net/i2p/jetty/I2PRequestLog.java b/apps/jetty/java/src/net/i2p/jetty/I2PRequestLog.java index 6aa001146f75ed2d543166396870907775ffb702..77d9afa052d7e8e721ab6c771940935ab680a5e1 100644 --- a/apps/jetty/java/src/net/i2p/jetty/I2PRequestLog.java +++ b/apps/jetty/java/src/net/i2p/jetty/I2PRequestLog.java @@ -24,18 +24,18 @@ import java.util.TimeZone; import javax.servlet.http.Cookie; -import org.mortbay.component.AbstractLifeCycle; -import org.mortbay.jetty.HttpHeaders; -import org.mortbay.jetty.Request; -import org.mortbay.jetty.RequestLog; -import org.mortbay.jetty.Response; -import org.mortbay.jetty.servlet.PathMap; -import org.mortbay.log.Log; -import org.mortbay.util.DateCache; -import org.mortbay.util.RolloverFileOutputStream; -import org.mortbay.util.StringUtil; -import org.mortbay.util.TypeUtil; -import org.mortbay.util.Utf8StringBuffer; +import org.eclipse.jetty.http.HttpHeaders; +import org.eclipse.jetty.http.PathMap; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.RequestLog; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.util.DateCache; +import org.eclipse.jetty.util.RolloverFileOutputStream; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.util.Utf8StringBuilder; +import org.eclipse.jetty.util.component.AbstractLifeCycle; +import org.eclipse.jetty.util.log.Log; /** * This {@link RequestLog} implementation outputs logs in the pseudo-standard NCSA common log format. @@ -56,8 +56,6 @@ import org.mortbay.util.Utf8StringBuffer; * * So that we will work with system Jetty 6 packages, we just copy the whole thing * and modify log() as required. - * We leave the package as org.mortbay.http for compatibility with old - * jetty.xml files. * * @author Greg Wilkins * @author Nigel Canonizado @@ -259,13 +257,13 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog if (_fileOut == null) return; - Utf8StringBuffer u8buf; - StringBuffer buf; + Utf8StringBuilder u8buf; + StringBuilder buf; synchronized(_writer) { int size=_buffers.size(); - u8buf = size==0?new Utf8StringBuffer(160):(Utf8StringBuffer)_buffers.remove(size-1); - buf = u8buf.getStringBuffer(); + u8buf = size==0?new Utf8StringBuilder(160):(Utf8StringBuilder)_buffers.remove(size-1); + buf = u8buf.getStringBuilder(); } synchronized(buf) // for efficiency until we can use StringBuilder @@ -398,7 +396,7 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog if (_logLatency) { _writer.write(' '); - _writer.write(TypeUtil.toString(System.currentTimeMillis() - request.getTimeStamp())); + _writer.write(Long.toString(System.currentTimeMillis() - request.getTimeStamp())); } _writer.write(StringUtil.__LINE_SEPARATOR); diff --git a/apps/jetty/java/src/net/i2p/jetty/JettyStart.java b/apps/jetty/java/src/net/i2p/jetty/JettyStart.java index f5b3295b546deeff4525c7aceab865df990c72d6..af396876993398f385c1d82388ad0d0d9975ed59 100644 --- a/apps/jetty/java/src/net/i2p/jetty/JettyStart.java +++ b/apps/jetty/java/src/net/i2p/jetty/JettyStart.java @@ -19,15 +19,16 @@ package net.i2p.jetty; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.Properties; import net.i2p.I2PAppContext; import net.i2p.app.*; import static net.i2p.app.ClientAppState.*; -import org.mortbay.component.LifeCycle; -import org.mortbay.resource.Resource; -import org.mortbay.xml.XmlConfiguration; +import org.eclipse.jetty.util.component.LifeCycle; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.xml.XmlConfiguration; /** * Start Jetty where the args are one or more XML files. @@ -73,8 +74,11 @@ public class JettyStart implements ClientApp { XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(args[i]).getURL()); if (last!=null) configuration.getIdMap().putAll(last.getIdMap()); - if (properties.size()>0) - configuration.setProperties(properties); + if (properties.size()>0) { + // to avoid compiler errror + Map foo = configuration.getProperties(); + foo.putAll(properties); + } Object o = configuration.configure(); if (o instanceof LifeCycle) _jettys.add((LifeCycle)o); diff --git a/apps/jetty/jetty-6.1.26/README-i2p.txt b/apps/jetty/jetty-6.1.26/README-i2p.txt deleted file mode 100644 index efbecbcdc7a8b90db10fd45cbc8727525f48b5ba..0000000000000000000000000000000000000000 --- a/apps/jetty/jetty-6.1.26/README-i2p.txt +++ /dev/null @@ -1,3 +0,0 @@ -This is only what we need out of the 25 MB Jetty-6.1.26.zip. - -NOTICE and LICENSE files moved to ../../../licenses diff --git a/apps/jetty/jetty-6.1.26/lib/ext/jetty-java5-threadpool-6.1.26.jar b/apps/jetty/jetty-6.1.26/lib/ext/jetty-java5-threadpool-6.1.26.jar deleted file mode 100644 index fb75a1c62882bfc792ca09d52746d75eccbe2d9e..0000000000000000000000000000000000000000 Binary files a/apps/jetty/jetty-6.1.26/lib/ext/jetty-java5-threadpool-6.1.26.jar and /dev/null differ diff --git a/apps/jetty/jetty-6.1.26/lib/ext/jetty-rewrite-handler-6.1.26.jar b/apps/jetty/jetty-6.1.26/lib/ext/jetty-rewrite-handler-6.1.26.jar deleted file mode 100644 index 3d0a7fbe4aaecac516914cd10dabf57e52756bec..0000000000000000000000000000000000000000 Binary files a/apps/jetty/jetty-6.1.26/lib/ext/jetty-rewrite-handler-6.1.26.jar and /dev/null differ diff --git a/apps/jetty/jetty-6.1.26/lib/ext/jetty-sslengine-6.1.26.jar b/apps/jetty/jetty-6.1.26/lib/ext/jetty-sslengine-6.1.26.jar deleted file mode 100644 index 051efb59d6b215888b9630336bb1fa4f705d3b4f..0000000000000000000000000000000000000000 Binary files a/apps/jetty/jetty-6.1.26/lib/ext/jetty-sslengine-6.1.26.jar and /dev/null differ diff --git a/apps/jetty/jetty-6.1.26/lib/jetty-6.1.26.jar b/apps/jetty/jetty-6.1.26/lib/jetty-6.1.26.jar deleted file mode 100644 index 2cbe07aeefa47ad6321addf0e75e010858f72fba..0000000000000000000000000000000000000000 Binary files a/apps/jetty/jetty-6.1.26/lib/jetty-6.1.26.jar and /dev/null differ diff --git a/apps/jetty/jetty-6.1.26/lib/jetty-util-6.1.26.jar b/apps/jetty/jetty-6.1.26/lib/jetty-util-6.1.26.jar deleted file mode 100644 index cd237528add68b792f2e6e030344f27d9d07ec31..0000000000000000000000000000000000000000 Binary files a/apps/jetty/jetty-6.1.26/lib/jetty-util-6.1.26.jar and /dev/null differ diff --git a/apps/jetty/jetty-6.1.26/lib/management/jetty-management-6.1.26.jar b/apps/jetty/jetty-6.1.26/lib/management/jetty-management-6.1.26.jar deleted file mode 100644 index b5eeecb3278908eced646acb954042a0b9589c57..0000000000000000000000000000000000000000 Binary files a/apps/jetty/jetty-6.1.26/lib/management/jetty-management-6.1.26.jar and /dev/null differ diff --git a/apps/jetty/jetty-6.1.26/start.jar b/apps/jetty/jetty-6.1.26/start.jar deleted file mode 100644 index d3a94bcfae630a90d4103437bd3c2da0d37d98c9..0000000000000000000000000000000000000000 Binary files a/apps/jetty/jetty-6.1.26/start.jar and /dev/null differ diff --git a/apps/routerconsole/java/build.xml b/apps/routerconsole/java/build.xml index 4f533ca4d6a1e29f848a588c8d5d2c9a150a71cc..becd01c63a47c62bb5a114fe9ef35a758beee71f 100644 --- a/apps/routerconsole/java/build.xml +++ b/apps/routerconsole/java/build.xml @@ -63,9 +63,13 @@ <pathelement location="../../../core/java/build/i2p.jar" /> <pathelement location="../../../router/java/build/router.jar" /> <pathelement location="../../jetty/jettylib/org.mortbay.jetty.jar" /> + <pathelement location="../../jetty/jettylib/jetty-http.jar" /> + <pathelement location="../../jetty/jettylib/jetty-io.jar" /> + <pathelement location="../../jetty/jettylib/jetty-security.jar" /> + <pathelement location="../../jetty/jettylib/jetty-servlet.jar" /> + <pathelement location="../../jetty/jettylib/jetty-servlets.jar" /> <pathelement location="../../jetty/jettylib/jetty-util.jar" /> - <pathelement location="../../jetty/jettylib/jetty-sslengine.jar" /> - <pathelement location="../../jetty/jettylib/jetty-java5-threadpool.jar" /> + <pathelement location="../../jetty/jettylib/jetty-webapp.jar" /> <pathelement location="../../jetty/jettylib/javax.servlet.jar" /> <pathelement location="../../jetty/jettylib/jsp-api.jar" /> <pathelement location="../../jetty/jettylib/jetty-i2p.jar" /> diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java index 851b7ab0b96535135224dacf09974b52d15e5bdc..761694fb158bab95c6c7a82e7c8d6055c56b5ce8 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java @@ -17,7 +17,7 @@ import net.i2p.router.startup.LoadClientAppsJob; import net.i2p.router.update.ConsoleUpdateManager; import static net.i2p.update.UpdateType.*; -import org.mortbay.jetty.handler.ContextHandlerCollection; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; /** * Saves changes to clients.config or webapps.config diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConsolePasswordManager.java b/apps/routerconsole/java/src/net/i2p/router/web/ConsolePasswordManager.java index 2d8f6c96357031c8a3d3419de4094db54fedc4fd..58ce43ec69afeee5fa82b4c28c870b2f6df4d205 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConsolePasswordManager.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConsolePasswordManager.java @@ -12,7 +12,7 @@ import net.i2p.router.Router; import net.i2p.router.RouterContext; import net.i2p.router.util.RouterPasswordManager; -//import org.mortbay.jetty.security.UnixCrypt; +//import org.eclipse.jetty.util.security.UnixCrypt; /** * Manage both plaintext and salted/hashed password storage in diff --git a/apps/routerconsole/java/src/net/i2p/router/web/LocaleWebAppHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/LocaleWebAppHandler.java index bbc27ed3e554a2ebfc138c6d21398220890f62e6..74ce11a197abd4fdb68c489e55d2a19304845316 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/LocaleWebAppHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/LocaleWebAppHandler.java @@ -1,5 +1,6 @@ package net.i2p.router.web; +import java.io.File; import java.io.IOException; import java.util.Locale; import java.util.Map; @@ -10,7 +11,11 @@ import javax.servlet.http.HttpServletResponse; import net.i2p.I2PAppContext; -import org.mortbay.jetty.webapp.WebAppContext; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.handler.HandlerWrapper; +import org.eclipse.jetty.server.session.SessionHandler; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.webapp.WebAppContext; /** * Convert foo.jsp to foo_xx.jsp for language xx. @@ -21,14 +26,22 @@ import org.mortbay.jetty.webapp.WebAppContext; * * @author zzz */ -public class LocaleWebAppHandler extends WebAppContext +public class LocaleWebAppHandler extends HandlerWrapper { private final I2PAppContext _context; + private final WebAppContext _wac; - public LocaleWebAppHandler(I2PAppContext ctx, String path, String warPath) { - super(warPath, path); + public LocaleWebAppHandler(I2PAppContext ctx, String path, String warPath, + File tmpdir, ServletHandler servletHandler) { + super(); _context = ctx; + _wac = new WebAppContext(warPath, path); setInitParams(WebAppStarter.INIT_PARAMS); + _wac.setTempDirectory(tmpdir); + _wac.setExtractWAR(false); + _wac.setSessionHandler(new SessionHandler()); + _wac.setServletHandler(servletHandler); + setHandler(_wac); } /** @@ -37,19 +50,12 @@ public class LocaleWebAppHandler extends WebAppContext * or as specified in the routerconsole.lang property. * Unless language == "en". */ - @Override public void handle(String pathInContext, + Request baseRequest, HttpServletRequest httpRequest, - HttpServletResponse httpResponse, - int dispatch) + HttpServletResponse httpResponse) throws IOException, ServletException { - // Handle OPTIONS (nothing to override) - if ("OPTIONS".equals(httpRequest.getMethod())) - { - handleOptions(httpRequest, httpResponse); - return; - } // transparent rewriting if (pathInContext.equals("/") || pathInContext.equals("/index.html")) { @@ -77,7 +83,7 @@ public class LocaleWebAppHandler extends WebAppContext if (lang != null && lang.length() > 0 && !lang.equals("en")) { String testPath = pathInContext.substring(0, len - 4) + '_' + lang + ".jsp"; // Do we have a servlet for the new path that isn't the catchall *.jsp? - Map.Entry servlet = getServletHandler().getHolderEntry(testPath); + Map.Entry servlet = _wac.getServletHandler().getHolderEntry(testPath); if (servlet != null) { String servletPath = (String) servlet.getKey(); if (servletPath != null && !servletPath.startsWith("*")) { @@ -90,7 +96,7 @@ public class LocaleWebAppHandler extends WebAppContext } } //System.err.println("New path: " + newPath); - super.handle(newPath, httpRequest, httpResponse, dispatch); + super.handle(newPath, baseRequest, httpRequest, httpResponse); //System.err.println("Was handled? " + httpRequest.isHandled()); } @@ -112,10 +118,28 @@ public class LocaleWebAppHandler extends WebAppContext * Not an override * @since 0.8 */ +/**** not in Jetty 7 public void handleOptions(HttpServletRequest request, HttpServletResponse response) throws IOException { response.sendError(405); } +****/ + + /** + * Mysteriously removed from Jetty 7 + */ + private void setInitParams(Map params) { + setInitParams(_wac, params); + } + + /** + * @since Jetty 7 + */ + public static void setInitParams(WebAppContext context, Map<?,?> params) { + for (Map.Entry e : params.entrySet()) { + context.setInitParameter((String)e.getKey(), (String)e.getValue()); + } + } } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java index 27cea16d991e54ac6e7d6693b15cceb090eca996..6e92ff9d84c9302bc93e9e9bb0a02e10136f47c3 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java @@ -7,7 +7,7 @@ import net.i2p.I2PAppContext; import net.i2p.util.FileUtil; import net.i2p.util.VersionComparator; -import org.mortbay.jetty.Server; +import org.eclipse.jetty.server.Server; import org.tanukisoftware.wrapper.WrapperManager; public class LogsHelper extends HelperBase { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java b/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java index 7ec9b7895e991766b5a124fdad5a6b1cdc6a3d15..7074ca116c03a7beb0b8fa53c4e96bf0e87417c7 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java @@ -34,7 +34,7 @@ import net.i2p.util.Log; import net.i2p.util.Translate; import net.i2p.util.VersionComparator; -import org.mortbay.jetty.handler.ContextHandlerCollection; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; /** diff --git a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java index cf9fe8cc9233ba4defbc4bb0b1b8f6cfef581c85..94cf36622aa41b53c070dbdce3c7a8dc4dceb19f 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java @@ -42,30 +42,33 @@ import net.i2p.util.ShellCommand; import net.i2p.util.SystemVersion; import net.i2p.util.VersionComparator; -import org.mortbay.jetty.AbstractConnector; -import org.mortbay.jetty.Connector; -import org.mortbay.jetty.NCSARequestLog; -import org.mortbay.jetty.Server; -import org.mortbay.jetty.bio.SocketConnector; -import org.mortbay.jetty.handler.ContextHandlerCollection; -import org.mortbay.jetty.handler.DefaultHandler; -import org.mortbay.jetty.handler.HandlerCollection; -import org.mortbay.jetty.handler.RequestLogHandler; -import org.mortbay.jetty.nio.SelectChannelConnector; -import org.mortbay.jetty.security.Credential.MD5; -import org.mortbay.jetty.security.DigestAuthenticator; -import org.mortbay.jetty.security.HashUserRealm; -import org.mortbay.jetty.security.Constraint; -import org.mortbay.jetty.security.ConstraintMapping; -import org.mortbay.jetty.security.SecurityHandler; -import org.mortbay.jetty.security.SslSocketConnector; -import org.mortbay.jetty.security.SslSelectChannelConnector; -import org.mortbay.jetty.servlet.ServletHandler; -import org.mortbay.jetty.servlet.ServletHolder; -import org.mortbay.jetty.servlet.SessionHandler; -import org.mortbay.jetty.webapp.WebAppContext; -import org.mortbay.thread.QueuedThreadPool; -import org.mortbay.thread.concurrent.ThreadPool; +import org.eclipse.jetty.security.HashLoginService; +import org.eclipse.jetty.security.ConstraintMapping; +import org.eclipse.jetty.security.ConstraintSecurityHandler; +import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.security.authentication.DigestAuthenticator; +import org.eclipse.jetty.server.AbstractConnector; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.NCSARequestLog; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.bio.SocketConnector; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; +import org.eclipse.jetty.server.handler.DefaultHandler; +import org.eclipse.jetty.server.handler.HandlerCollection; +import org.eclipse.jetty.server.handler.HandlerWrapper; +import org.eclipse.jetty.server.handler.RequestLogHandler; +import org.eclipse.jetty.server.nio.SelectChannelConnector; +import org.eclipse.jetty.server.ssl.SslSocketConnector; +import org.eclipse.jetty.server.ssl.SslSelectChannelConnector; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.util.security.Constraint; +import org.eclipse.jetty.util.security.Credential; +import org.eclipse.jetty.util.security.Credential.MD5; +import org.eclipse.jetty.util.thread.ExecutorThreadPool; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.util.thread.ThreadPool; /** * Start the router console. @@ -293,7 +296,7 @@ public class RouterConsoleRunner implements RouterApp { // System.err.println("INFO: I2P Jetty logging class not found, logging to wrapper log"); //} // This way it doesn't try to load Slf4jLog first - System.setProperty("org.mortbay.log.class", "net.i2p.jetty.I2PLogger"); + System.setProperty("org.eclipse.jetty.util.log.class", "net.i2p.jetty.I2PLogger"); // so Jetty can find WebAppConfiguration System.setProperty("jetty.class.path", _context.getBaseDir() + "/lib/routerconsole.jar"); @@ -302,7 +305,8 @@ public class RouterConsoleRunner implements RouterApp { try { ThreadPool ctp = new CustomThreadPoolExecutor(); - ctp.prestartAllCoreThreads(); + // Gone in Jetty 7 + //ctp.prestartAllCoreThreads(); _server.setThreadPool(ctp); } catch (Throwable t) { // class not found... @@ -315,7 +319,9 @@ public class RouterConsoleRunner implements RouterApp { HandlerCollection hColl = new HandlerCollection(); ContextHandlerCollection chColl = new ContextHandlerCollection(); - _server.addHandler(hColl); + // gone in Jetty 7 + //_server.addHandler(hColl); + _server.setHandler(hColl); hColl.addHandler(chColl); hColl.addHandler(new DefaultHandler()); @@ -351,7 +357,7 @@ public class RouterConsoleRunner implements RouterApp { if (!_webAppsDir.endsWith("/")) _webAppsDir += '/'; - WebAppContext rootWebApp = null; + HandlerWrapper rootWebApp = null; ServletHandler rootServletHandler = null; List<Connector> connectors = new ArrayList(4); try { @@ -507,17 +513,14 @@ public class RouterConsoleRunner implements RouterApp { return; } - rootWebApp = new LocaleWebAppHandler(_context, - "/", _webAppsDir + ROUTERCONSOLE + ".war"); File tmpdir = new SecureDirectory(workDir, ROUTERCONSOLE + "-" + (_listenPort != null ? _listenPort : _sslListenPort)); tmpdir.mkdir(); - rootWebApp.setTempDirectory(tmpdir); - rootWebApp.setExtractWAR(false); - rootWebApp.setSessionHandler(new SessionHandler()); rootServletHandler = new ServletHandler(); - rootWebApp.setServletHandler(rootServletHandler); - initialize(_context, rootWebApp); + rootWebApp = new LocaleWebAppHandler(_context, + "/", _webAppsDir + ROUTERCONSOLE + ".war", + tmpdir, rootServletHandler); + initialize(_context, (WebAppContext)(rootWebApp.getHandler())); chColl.addHandler(rootWebApp); } catch (Exception ioe) { @@ -727,7 +730,7 @@ public class RouterConsoleRunner implements RouterApp { * Add all users and passwords. */ static void initialize(RouterContext ctx, WebAppContext context) { - SecurityHandler sec = new SecurityHandler(); + ConstraintSecurityHandler sec = new ConstraintSecurityHandler(); List<ConstraintMapping> constraints = new ArrayList(4); ConsolePasswordManager mgr = new ConsolePasswordManager(ctx); boolean enable = ctx.getBooleanProperty(PROP_PW_ENABLE); @@ -737,14 +740,13 @@ public class RouterConsoleRunner implements RouterApp { enable = false; ctx.router().saveConfig(PROP_CONSOLE_PW, "false"); } else { - HashUserRealm realm = new HashUserRealm(JETTY_REALM); - sec.setUserRealm(realm); + HashLoginService realm = new HashLoginService(JETTY_REALM); + sec.setLoginService(realm); sec.setAuthenticator(authenticator); for (Map.Entry<String, String> e : userpw.entrySet()) { String user = e.getKey(); String pw = e.getValue(); - realm.put(user, MD5.__TYPE + pw); - realm.addUserToRole(user, JETTY_ROLE); + realm.putUser(user, Credential.getCredential(MD5.__TYPE + pw), new String[] {JETTY_ROLE}); Constraint constraint = new Constraint(user, JETTY_ROLE); constraint.setAuthenticate(true); ConstraintMapping cm = new ConstraintMapping(); @@ -843,11 +845,13 @@ public class RouterConsoleRunner implements RouterApp { * Just to set the name and set Daemon * @since Jetty 6 */ - private static class CustomThreadPoolExecutor extends ThreadPool { + private static class CustomThreadPoolExecutor extends ExecutorThreadPool { public CustomThreadPoolExecutor() { super(MIN_THREADS, MAX_THREADS, MAX_IDLE_TIME, TimeUnit.MILLISECONDS, - new SynchronousQueue(), new CustomThreadFactory(), - new ThreadPoolExecutor.CallerRunsPolicy()); + new SynchronousQueue() /** , following args not available in Jetty 7 + new CustomThreadFactory(), + new ThreadPoolExecutor.CallerRunsPolicy() **/ + ); } } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/WebAppConfiguration.java b/apps/routerconsole/java/src/net/i2p/router/web/WebAppConfiguration.java index 74c744170b0abb11d8502fd3ee69b67e0e6eed84..17c5e3432b36673165c9fd75db361ae2b83cf854 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/WebAppConfiguration.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/WebAppConfiguration.java @@ -10,9 +10,9 @@ import java.util.StringTokenizer; import net.i2p.I2PAppContext; -import org.mortbay.jetty.webapp.Configuration; -import org.mortbay.jetty.webapp.WebAppClassLoader; -import org.mortbay.jetty.webapp.WebAppContext; +import org.eclipse.jetty.webapp.Configuration; +import org.eclipse.jetty.webapp.WebAppClassLoader; +import org.eclipse.jetty.webapp.WebAppContext; /** @@ -38,23 +38,15 @@ import org.mortbay.jetty.webapp.WebAppContext; * @author zzz */ public class WebAppConfiguration implements Configuration { - private WebAppContext _wac; private static final String CLASSPATH = ".classpath"; - public void setWebAppContext(WebAppContext context) { - _wac = context; - } - - public WebAppContext getWebAppContext() { - return _wac; - } - /** - * This was the interface in Jetty 5, now it's configureClassLoader() + * This was the interface in Jetty 5, in Jetty 6 was configureClassLoader(), + * now it's configure() */ - private void configureClassPath() throws Exception { - String ctxPath = _wac.getContextPath(); + private void configureClassPath(WebAppContext wac) throws Exception { + String ctxPath = wac.getContextPath(); //System.err.println("Configure Class Path " + ctxPath); if (ctxPath.equals("/")) return; @@ -110,7 +102,7 @@ public class WebAppConfiguration implements Configuration { } if (buf.length() <= 0) return; - ClassLoader cl = _wac.getClassLoader(); + ClassLoader cl = wac.getClassLoader(); if (cl != null && cl instanceof WebAppClassLoader) { WebAppClassLoader wacl = (WebAppClassLoader) cl; wacl.addClassPath(buf.toString()); @@ -118,7 +110,7 @@ public class WebAppConfiguration implements Configuration { // This was not working because the WebAppClassLoader already exists // and it calls getExtraClasspath in its constructor // Not sure why WACL already exists... - _wac.setExtraClasspath(buf.toString()); + wac.setExtraClasspath(buf.toString()); } } @@ -133,14 +125,25 @@ public class WebAppConfiguration implements Configuration { return rv; } - public void configureDefaults() {} - public void configureWebApp() {} + /** @since Jetty 7 */ + public void deconfigure(WebAppContext context) {} - /** @since Jetty 6 */ - public void deconfigureWebApp() {} + /** @since Jetty 7 */ + public void configure(WebAppContext context) throws Exception { + configureClassPath(context); + } - /** @since Jetty 6 */ - public void configureClassLoader() throws Exception { - configureClassPath(); + /** @since Jetty 7 */ + public void cloneConfigure(WebAppContext template, WebAppContext context) { + // no state, nothing to be done } + + /** @since Jetty 7 */ + public void destroy(WebAppContext context) {} + + /** @since Jetty 7 */ + public void preConfigure(WebAppContext context) {} + + /** @since Jetty 7 */ + public void postConfigure(WebAppContext context) {} } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/WebAppStarter.java b/apps/routerconsole/java/src/net/i2p/router/web/WebAppStarter.java index a7506d65fb9375a789df4243078c999a89b15c82..d0690a01b648315d116a2cebd5b3ba49d7132022 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/WebAppStarter.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/WebAppStarter.java @@ -10,11 +10,11 @@ import net.i2p.router.RouterContext; import net.i2p.util.FileUtil; import net.i2p.util.SecureDirectory; -import org.mortbay.jetty.Handler; -import org.mortbay.jetty.Server; -import org.mortbay.jetty.webapp.WebAppContext; -import org.mortbay.jetty.handler.ContextHandler; -import org.mortbay.jetty.handler.ContextHandlerCollection; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; +import org.eclipse.jetty.webapp.WebAppContext; /** @@ -56,7 +56,7 @@ public class WebAppStarter { File tmpdir = new SecureDirectory(ctx.getTempDir(), "jetty-work-" + appName + ctx.random().nextInt()); WebAppContext wac = addWebApp(ctx, server, appName, warPath, tmpdir); //_log.debug("Loading war from: " + warPath); - wac.setInitParams(INIT_PARAMS); + LocaleWebAppHandler.setInitParams(wac, INIT_PARAMS); wac.start(); } @@ -155,6 +155,8 @@ public class WebAppStarter { return null; String path = '/'+ appName; for (int i = 0; i < handlers.length; i++) { + if (!(handlers[i] instanceof ContextHandler)) + continue; ContextHandler ch = (ContextHandler) handlers[i]; if (path.equals(ch.getContextPath())) return ch; diff --git a/apps/routerconsole/jsp/error.jsp b/apps/routerconsole/jsp/error.jsp index 7d5552fd58fa61b540efdcab2dbaf776265c5697..22b2e16fa1ffb231eb9670d5795c089ebd280ccf 100644 --- a/apps/routerconsole/jsp/error.jsp +++ b/apps/routerconsole/jsp/error.jsp @@ -4,9 +4,9 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <% // Let's make this easy... - final Integer ERROR_CODE = (Integer) request.getAttribute(org.mortbay.jetty.servlet.ServletHandler.__J_S_ERROR_STATUS_CODE); - final String ERROR_URI = (String) request.getAttribute(org.mortbay.jetty.servlet.ServletHandler.__J_S_ERROR_REQUEST_URI); - final String ERROR_MESSAGE = (String) request.getAttribute(org.mortbay.jetty.servlet.ServletHandler.__J_S_ERROR_MESSAGE); + final Integer ERROR_CODE = (Integer) request.getAttribute(org.eclipse.jetty.server.Dispatcher.ERROR_STATUS_CODE); + final String ERROR_URI = (String) request.getAttribute(org.eclipse.jetty.server.Dispatcher.ERROR_REQUEST_URI); + final String ERROR_MESSAGE = (String) request.getAttribute(org.eclipse.jetty.server.Dispatcher.ERROR_MESSAGE); if (ERROR_CODE != null && ERROR_MESSAGE != null) { // this is deprecated but we don't want sendError() response.setStatus(ERROR_CODE.intValue(), ERROR_MESSAGE); diff --git a/apps/routerconsole/jsp/error500.jsp b/apps/routerconsole/jsp/error500.jsp index 5939ea4711650a3c896fdcdda9110e133461276f..66ef4f414fd3e913060fff255906966216b5e82a 100644 --- a/apps/routerconsole/jsp/error500.jsp +++ b/apps/routerconsole/jsp/error500.jsp @@ -3,11 +3,11 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <% // Let's make this easy... - final Integer ERROR_CODE = (Integer) request.getAttribute(org.mortbay.jetty.servlet.ServletHandler.__J_S_ERROR_STATUS_CODE); - final String ERROR_URI = (String) request.getAttribute(org.mortbay.jetty.servlet.ServletHandler.__J_S_ERROR_REQUEST_URI); - final String ERROR_MESSAGE = (String) request.getAttribute(org.mortbay.jetty.servlet.ServletHandler.__J_S_ERROR_MESSAGE); - final Class ERROR_CLASS = (Class)request.getAttribute(org.mortbay.jetty.servlet.ServletHandler.__J_S_ERROR_EXCEPTION_TYPE); - final Throwable ERROR_THROWABLE = (Throwable)request.getAttribute(org.mortbay.jetty.servlet.ServletHandler.__J_S_ERROR_EXCEPTION); + final Integer ERROR_CODE = (Integer) request.getAttribute(org.eclipse.jetty.server.Dispatcher.ERROR_STATUS_CODE); + final String ERROR_URI = (String) request.getAttribute(org.eclipse.jetty.server.Dispatcher.ERROR_REQUEST_URI); + final String ERROR_MESSAGE = (String) request.getAttribute(org.eclipse.jetty.server.Dispatcher.ERROR_MESSAGE); + final Class ERROR_CLASS = (Class)request.getAttribute(org.eclipse.jetty.server.Dispatcher.ERROR_EXCEPTION_TYPE); + final Throwable ERROR_THROWABLE = (Throwable)request.getAttribute(org.eclipse.jetty.server.Dispatcher.ERROR_EXCEPTION); if (ERROR_CODE != null && ERROR_MESSAGE != null) { // this is deprecated but we don't want sendError() response.setStatus(ERROR_CODE.intValue(), ERROR_MESSAGE); diff --git a/apps/susimail/build.xml b/apps/susimail/build.xml index e56e8cd8d8dc4b0df3369dfcdb9dd55f78bbdc74..ad5d98fa05f9d4609d5c6df320eec15ecc2af63d 100644 --- a/apps/susimail/build.xml +++ b/apps/susimail/build.xml @@ -25,6 +25,7 @@ <pathelement location="../jetty/jettylib/javax.servlet.jar" /> <pathelement location="../jetty/jettylib/org.mortbay.jetty.jar" /> <pathelement location="../jetty/jettylib/jetty-util.jar" /> + <pathelement location="../jetty/jettylib/jetty-http.jar" /> <pathelement location="../../core/java/build/i2p.jar" /> </classpath> </javac> diff --git a/apps/susimail/src/src/org/mortbay/servlet/MultiPartRequest.java b/apps/susimail/src/src/org/mortbay/servlet/MultiPartRequest.java index 5effd4ea578746188afd48f5c3e819f756934506..5491f6b96f1bf1540680d463c485e3a5d2497f3b 100644 --- a/apps/susimail/src/src/org/mortbay/servlet/MultiPartRequest.java +++ b/apps/susimail/src/src/org/mortbay/servlet/MultiPartRequest.java @@ -29,10 +29,10 @@ import javax.servlet.http.HttpServletRequest; //import org.apache.commons.logging.Log; //import org.mortbay.log.LogFactory; -import org.mortbay.jetty.HttpHeaders; +import org.eclipse.jetty.http.HttpHeaders; +import org.eclipse.jetty.util.MultiMap; +import org.eclipse.jetty.util.StringUtil; import org.mortbay.util.LineInput; -import org.mortbay.util.MultiMap; -import org.mortbay.util.StringUtil; /* ------------------------------------------------------------ */ /** Multipart Form Data request. diff --git a/build.xml b/build.xml index 30547d666c004029a2f3a149a020b4541a547959..b55583d06afbe735d957bb3206a9473ff76955d0 100644 --- a/build.xml +++ b/build.xml @@ -1040,11 +1040,11 @@ <!-- *nix here --> <exec executable="sh" osfamily="unix" failonerror="true"> <arg value="-c" /> - <arg value="for i in pkg-temp/lib/*.jar pkg-temp/webapps/*war; do if [ $i = pkg-temp/lib/jasper-compiler.jar -o $i = pkg-temp/lib/jbigi.jar ]; then continue; fi; echo pack200 $i; mv $i $i.jar; pack200 -g $i.pack $i.jar; rm -f $i.jar; done" /> + <arg value="for i in pkg-temp/lib/*.jar pkg-temp/webapps/*war; do if [ $i = pkg-temp/lib/jasper-compiler.jar -o $i = pkg-temp/lib/jbigi.jar -o $i = pkg-temp/lib/jetty-java5-threadpool.jar -o $i = pkg-temp/lib/jetty-sslengine.jar ]; then continue; fi; echo pack200 $i; mv $i $i.jar; pack200 -g $i.pack $i.jar; rm -f $i.jar; done" /> </exec> <exec executable="sh" osfamily="mac" failonerror="true"> <arg value="-c" /> - <arg value="for i in pkg-temp/lib/*.jar pkg-temp/webapps/*war; do if [ $i = pkg-temp/lib/jasper-compiler.jar -o $i = pkg-temp/lib/jbigi.jar ]; then continue; fi; echo pack200 $i; mv $i $i.jar; pack200 -g $i.pack $i.jar; rm -f $i.jar; done" /> + <arg value="for i in pkg-temp/lib/*.jar pkg-temp/webapps/*war; do if [ $i = pkg-temp/lib/jasper-compiler.jar -o $i = pkg-temp/lib/jbigi.jar -o $i = pkg-temp/lib/jetty-java5-threadpool.jar -o $i = pkg-temp/lib/jetty-sslengine.jar ]; then continue; fi; echo pack200 $i; mv $i $i.jar; pack200 -g $i.pack $i.jar; rm -f $i.jar; done" /> </exec> <!-- windoz here : i admit, i hate escaped symbols in xml, indeed = =! --> <exec executable="cmd" osfamily="windows" failonerror="true"> @@ -1153,13 +1153,13 @@ <!-- We have to package the new eepsite files for MigrateJetty.java, but we can't overwrite an existing eepsite dir in a non-split configuration. --> - <copy todir="pkg-temp/eepsite-jetty6" > + <copy todir="pkg-temp/eepsite-jetty7" > <fileset dir="installer/resources/eepsite" includes="*.xml contexts/* etc/*" /> </copy> </target> <target name="delete-j6-update"> - <delete dir="pkg-temp/eepsite-jetty6" /> + <delete dir="pkg-temp/eepsite-jetty7" /> </target> <!-- Jetty 6 I2P logging addons, not really fixes --> diff --git a/installer/resources/clients.config b/installer/resources/clients.config index 8dc6573381073a17b680d4271377d88b49019cbe..cd68fb5c04fb1bed1dfd9cd0cf285dbfe0519631 100644 --- a/installer/resources/clients.config +++ b/installer/resources/clients.config @@ -40,7 +40,7 @@ clientApp.2.args=i2ptunnel.config clientApp.2.startOnLoad=true # run our own eepsite with a seperate jetty instance -clientApp.3.main=org.mortbay.start.Main +clientApp.3.main=net.i2p.jetty.JettyStart clientApp.3.name=I2P webserver (eepsite) ## To use the rewrite handler, edit jetty-rewrite.xml and use: #clientApp.3.args="/path/to/jetty.xml" "/path/to/jetty-rewrite.xml" diff --git a/installer/resources/eepsite/contexts/base-context.xml b/installer/resources/eepsite/contexts/base-context.xml index 4eaf2daea396432a1d2213d3698cdc5f943db4e1..36ca36784be6764aa940e391b3ad050edde37e93 100644 --- a/installer/resources/eepsite/contexts/base-context.xml +++ b/installer/resources/eepsite/contexts/base-context.xml @@ -1,29 +1,23 @@ <?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"> +<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd"> <!-- Configure a custom context for the eepsite. -This context contains only a Context with a default servlet +This context contains only a ServletContextHandler with a default servlet to serve static html files and images. --> -<Configure class="org.mortbay.jetty.servlet.Context"> +<Configure class="org.eclipse.jetty.servlet.ServletContextHandler"> <Set name="contextPath">/</Set> <Set name="resourceBase">./eepsite/docroot/</Set> - <Call name="setInitParams"> - <Arg> - <Map> - <Entry> - <Item>org.mortbay.jetty.servlet.Default.cacheControl</Item> - <Item>max-age=3600,public</Item> - </Entry> - </Map> - </Arg> + <Call name="setInitParameter"> + <Arg>cacheControl</Arg> + <Arg>max-age=3600,public</Arg> </Call> <Call name="setMimeTypes"> <Arg> - <New class="org.mortbay.jetty.MimeTypes"> + <New class="org.eclipse.jetty.http.MimeTypes"> <Call name="addMimeMapping"> <Arg>sud</Arg> <Arg>application/zip</Arg> @@ -40,7 +34,7 @@ to serve static html files and images. </Arg> </Call> <Call name="addServlet"> - <Arg>org.mortbay.jetty.servlet.DefaultServlet</Arg> + <Arg>org.eclipse.jetty.servlet.DefaultServlet</Arg> <Arg>/</Arg> </Call> </Configure> diff --git a/installer/resources/eepsite/contexts/cgi-context.xml b/installer/resources/eepsite/contexts/cgi-context.xml index 4a0b0b6d212d4afe8378b4a6bf3aef2ab575e67c..3ae8f390d12dc3758f70577a4185b2fd37475fd6 100644 --- a/installer/resources/eepsite/contexts/cgi-context.xml +++ b/installer/resources/eepsite/contexts/cgi-context.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"> +<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd"> <!-- Configure a custom context for the eepsite. @@ -22,21 +22,15 @@ Configure a custom context for the eepsite. * parameter value. --> -<Configure class="org.mortbay.jetty.servlet.Context"> +<Configure class="org.eclipse.jetty.servlet.ServletContextHandler"> <Set name="contextPath">/cgi-bin</Set> <Set name="resourceBase">./eepsite/cgi-bin/</Set> - <Call name="setInitParams"> - <Arg> - <Map> - <Entry> - <Item>Path</Item> - <Item>/usr/local/bin:/bin:/usr/bin</Item> - </Entry> - </Map> - </Arg> + <Call name="setInitParameter"> + <Arg>Path</Arg> + <Arg>/usr/local/bin:/bin:/usr/bin</Arg> </Call> <Call name="addServlet"> - <Arg>org.mortbay.servlet.CGI</Arg> + <Arg>org.eclipse.jetty.servlets.CGI</Arg> <Arg>/</Arg> </Call> </Configure> diff --git a/installer/resources/eepsite/etc/webdefault.xml b/installer/resources/eepsite/etc/webdefault.xml index e13916f101fa2dc1d90355c344cdcaa8919cdafd..d0a6f4bf675178cf2b436d2e6df3b553bb5eb90b 100644 --- a/installer/resources/eepsite/etc/webdefault.xml +++ b/installer/resources/eepsite/etc/webdefault.xml @@ -35,23 +35,23 @@ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- UNCOMMENT TO ACTIVATE <context-param> - <param-name>org.mortbay.jetty.servlet.SessionDomain</param-name> + <param-name>org.eclipse.jetty.servlet.SessionDomain</param-name> <param-value>127.0.0.1</param-value> </context-param> <context-param> - <param-name>org.mortbay.jetty.servlet.SessionPath</param-name> + <param-name>org.eclipse.jetty.servlet.SessionPath</param-name> <param-value>/</param-value> </context-param> <context-param> - <param-name>org.mortbay.jetty.servlet.MaxAge</param-name> + <param-name>org.eclipse.jetty.servlet.MaxAge</param-name> <param-value>-1</param-value> </context-param> --> <context-param> - <param-name>org.mortbay.jetty.webapp.NoTLDJarPattern</param-name> + <param-name>org.eclipse.jetty.webapp.NoTLDJarPattern</param-name> <param-value>start.jar|ant-.*\.jar|dojo-.*\.jar|jetty-.*\.jar|jsp-api-.*\.jar|junit-.*\.jar|servlet-api-.*\.jar|dnsns\.jar|rt\.jar|jsse\.jar|tools\.jar|sunpkcs11\.jar|sunjce_provider\.jar|xerces.*\.jar</param-value> </context-param> @@ -112,7 +112,7 @@ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <servlet> <servlet-name>default</servlet-name> - <servlet-class>org.mortbay.jetty.servlet.DefaultServlet</servlet-class> + <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class> <init-param> <param-name>acceptRanges</param-name> <param-value>true</param-value> @@ -306,7 +306,7 @@ <!-- Uncomment for dynamic invocation <servlet> <servlet-name>invoker</servlet-name> - <servlet-class>org.mortbay.jetty.servlet.Invoker</servlet-class> + <servlet-class>org.eclipse.jetty.servlet.Invoker</servlet-class> <init-param> <param-name>verbose</param-name> <param-value>false</param-value> diff --git a/installer/resources/eepsite/jetty-jmx.xml b/installer/resources/eepsite/jetty-jmx.xml index dbf076858de72f4610cfcbbb01fd8f1183bb4fea..4db0dbb473ac0c81474ab9689bc619ad60f4540e 100644 --- a/installer/resources/eepsite/jetty-jmx.xml +++ b/installer/resources/eepsite/jetty-jmx.xml @@ -1,89 +1,103 @@ <?xml version="1.0"?> -<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"> +<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd"> +<!-- ============================================================================ --> +<!-- To correctly start Jetty with JMX module enabled, this configuration --> +<!-- file must appear first in the list of the configuration files. --> +<!-- The simplest way to achieve this is to add etc/jetty-jmx.xml as the --> +<!-- first file in configuration file list at the end of start.ini file. --> +<!-- ============================================================================ --> +<Configure id="Server" class="org.eclipse.jetty.server.Server"> -<!-- =============================================================== --> -<!-- Configure the JVM JMX Server --> -<!-- this configuration file should be used in combination with --> -<!-- other configuration files. e.g. --> -<!-- java -jar start.jar etc/jetty-jmx.xml etc/jetty.xml --> -<!-- See jetty-jmx-mx4j.xml for a non JVM server solution --> -<!-- =============================================================== --> -<Configure id="Server" class="org.mortbay.jetty.Server"> + <!-- =========================================================== --> + <!-- Set the java.rmi.server.hostname property in case you've --> + <!-- got a misconfigured /etc/hosts entry or the like. --> + <!-- =========================================================== --> + <!-- + <Call class="java.lang.System" name="setProperty"> + <Arg>java.rmi.server.hostname</Arg> + <Arg>127.0.0.1</Arg> + </Call> + --> + + <!-- =========================================================== --> + <!-- Initialize an mbean server --> + <!-- =========================================================== --> + <Call id="MBeanServer" class="java.lang.management.ManagementFactory" + name="getPlatformMBeanServer" /> - <!-- =========================================================== --> - <!-- Initialize an mbean server --> - <!-- =========================================================== --> - <!-- Use the jdk 1.5 platformMBeanServer --> - <Call id="MBeanServer" class="java.lang.management.ManagementFactory" name="getPlatformMBeanServer"/> + <!-- =========================================================== --> + <!-- Initialize the Jetty MBean container --> + <!-- =========================================================== --> + <New id="MBeanContainer" class="org.eclipse.jetty.jmx.MBeanContainer"> + <Arg><Ref id="MBeanServer" /></Arg> + <Call name="start"/> + </New> - <!-- =========================================================== --> - <!-- Initialize the Jetty MBean container --> - <!-- =========================================================== --> - <Get id="Container" name="container"> - <Call name="addEventListener"> - <Arg> - <New class="org.mortbay.management.MBeanContainer"> - <Arg><Ref id="MBeanServer"/></Arg> - <Call name="start" /> - </New> - </Arg> - </Call> - </Get> - - <!-- =========================================================== --> - <!-- Enable stats (why else are you using JMX? --> - <!-- Sneakily replace the top-level handler with a StatisticsHandler --> - <!-- Note we could use AtomicStatisticsHandler in jetty-java5-stats.jar (4KB) --> - <!-- but it really isn't worth bundling it. --> - <!-- http://blog.markfeeney.com/2010/10/jmx-statistics-in-jetty-6-6122.html --> - <!-- =========================================================== --> - <Get id="oldhandler" name="handler"/> - <Set name="handler"> - <New id="StatsHandler" class="org.mortbay.jetty.handler.StatisticsHandler"> - <Set name="handler"><Ref id="oldhandler"/></Set> - </New> - </Set> - - - <!-- - When setting up the JMXConnectorServer via RMI, two TCP ports are used to communicate with - the remote server: - * the rmiregistry port (by default 1099) from where the RMI stub is downloaded - * the rmi server port (by default randomly chosen) where the actual RMI communication happens - The JMXServiceURL for the default configuration is therefore: - - service:jmx:rmi:///jndi/rmi://<remotehost>:1099/jmxrmi - - In case a firewall is restricting port access, you need to make sure that the rmi server port - is not chosen randomly, and this can be specified with the following JMXServiceURL: - - service:jmx:rmi://<host>:2100/jndi/rmi://<host>:2099/jmxrmi - - where 2099 is the rmiregistry port and 2100 is the rmi server port. - Make sure the firewall allow access to those ports. + <!-- Add to the Server to listen for object events --> + <Get id="Container" name="container"> + <Call name="addEventListener"> + <Arg><Ref id="MBeanContainer" /></Arg> + </Call> + </Get> - When using the XML configuration below, you don't need to specify any of the JMX system properties - on the command line (see http://java.sun.com/j2se/1.5.0/docs/guide/management/agent.html). - --> + <!-- Add to the Server as a managed lifecycle --> + <Call name="addBean"> + <Arg><Ref id="MBeanContainer"/></Arg> + <Arg type="boolean">true</Arg> + </Call> - <!-- Setup the RMIRegistry on a specific port - <Call id="rmiRegistry" class="java.rmi.registry.LocateRegistry" name="createRegistry"> - <Arg type="int">2099</Arg> - </Call> - --> - <!-- Setup the JMXConnectorServer on a specific rmi server port - <Call id="jmxConnectorServer" class="javax.management.remote.JMXConnectorServerFactory" name="newJMXConnectorServer"> + <!-- Add the static log --> + <Ref id="MBeanContainer"> + <Call name="addBean"> <Arg> - <New class="javax.management.remote.JMXServiceURL"> - <Arg>service:jmx:rmi://localhost:2100/jndi/rmi://localhost:2099/jmxrmi</Arg> - </New> + <New class="org.eclipse.jetty.util.log.Log"/> </Arg> - <Arg/> - <Arg><Ref id="MBeanServer"/></Arg> - <Call name="start"/> </Call> - --> + </Ref> + + <!-- In order to connect to the JMX server remotely from a different + process, possibly running on a different host, Jetty JMX module + can create a remote JMX connector. It requires RMI registry to + be started prior to creating the connector server because the + JMX specification uses RMI to facilitate connections. + --> + <!-- Optionally start the RMI registry. Normally RMI registry runs on + port 1099. The argument below can be changed in order to comply + with the firewall requirements. + --> + <!-- + <Call name="createRegistry" class="java.rmi.registry.LocateRegistry"> + <Arg type="java.lang.Integer"><SystemProperty name="jetty.jmxrmiport" default="1099"/></Arg> + <Call name="sleep" class="java.lang.Thread"> + <Arg type="java.lang.Integer">1000</Arg> + </Call> + </Call> + --> + + <!-- Optionally add a remote JMX connector. The parameters of the constructor + below specify the JMX service URL, and the object name string for the + connector server bean. The parameters of the JMXServiceURL constructor + specify the protocol that clients will use to connect to the remote JMX + connector (RMI), the hostname of the server (local hostname), port number + (automatically assigned), and the URL path. Note that URL path contains + the RMI registry hostname and port number, that may need to be modified + in order to comply with the firewall requirements. + --> + <!-- + <New id="ConnectorServer" class="org.eclipse.jetty.jmx.ConnectorServer"> + <Arg> + <New class="javax.management.remote.JMXServiceURL"> + <Arg type="java.lang.String">rmi</Arg> + <Arg type="java.lang.String" /> + <Arg type="java.lang.Integer"><SystemProperty name="jetty.jmxrmiport" default="1099"/></Arg> + <Arg type="java.lang.String">/jndi/rmi://<SystemProperty name="jetty.jmxrmihost" default="localhost"/>:<SystemProperty name="jetty.jmxrmiport" default="1099"/>/jmxrmi</Arg> + </New> + </Arg> + <Arg>org.eclipse.jetty.jmx:name=rmiconnectorserver</Arg> + <Call name="start" /> + </New> + --> </Configure> diff --git a/installer/resources/eepsite/jetty-rewrite.xml b/installer/resources/eepsite/jetty-rewrite.xml index ef5043aac00bea97acb40f55ea55276abdc5553d..1d208f8bfc82327aa272f86fe9a6052dcbf1c5a6 100644 --- a/installer/resources/eepsite/jetty-rewrite.xml +++ b/installer/resources/eepsite/jetty-rewrite.xml @@ -1,149 +1,117 @@ <?xml version="1.0"?> -<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"> +<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd"> <!-- =============================================================== --> <!-- Mixin the RewriteHandler --> <!-- =============================================================== --> -<Configure id="Server" class="org.mortbay.jetty.Server"> +<Configure id="Server" class="org.eclipse.jetty.server.Server"> <!-- =========================================================== --> - <!-- Configure Rewrite Handler --> + <!-- configure rewrite handler --> <!-- =========================================================== --> <Get id="oldhandler" name="handler"/> <Set name="handler"> - <New id="Rewrite" class="org.mortbay.jetty.handler.rewrite.RewriteHandler"> - + <New id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RewriteHandler"> <Set name="handler"><Ref id="oldhandler"/></Set> <Set name="rewriteRequestURI">true</Set> <Set name="rewritePathInfo">false</Set> <Set name="originalPathAttribute">requestedPath</Set> - <Set name="rules"> - <Array type="org.mortbay.jetty.handler.rewrite.Rule"> - - <!-- return an error message if low on threads; put this at the top so it will be processed first --> - <Item> - <New id="lowThreads" class="org.mortbay.jetty.handler.rewrite.LowThreadsRuleContainer"> - <!-- set the trigger for low threads ridiculously low - uncomment the block below to see it in action --> - <!--Ref id="Server"> - <Get id="serverThreadPool" name="threadPool"> - <Set name="minThreads">3</Set> - <Set name="maxThreads">4</Set> - <Set name="lowThreads">0</Set> - </Get> - </Ref> - - <Set name="threadPool"><Ref id="serverThreadPool"/></Set--> - - <Call name="addRule"> - <Arg> - <New id="busyresponse" class="org.mortbay.jetty.handler.rewrite.ResponsePatternRule"> - <Set name="pattern">/*</Set> - <Set name="code">500</Set> - <Set name="reason">Server busy</Set> - </New> - </Arg> - </Call> - </New> - </Item> - - <!-- Add rule to protect against IE ssl bug --> - <Item> - <New class="org.mortbay.jetty.handler.rewrite.MsieSslRule"/> - </Item> - - <!-- protect favicon handling --> - <Item> - <New class="org.mortbay.jetty.handler.rewrite.HeaderPatternRule"> - <Set name="pattern">/favicon.ico</Set> - <Set name="name">Cache-Control</Set> - <Set name="value">Max-Age=3600,public</Set> - <Set name="terminating">true</Set> - </New> - </Item> - - - <!-- add a regex rule --> - <Item> - <New class="org.mortbay.jetty.handler.rewrite.RewriteRegexRule"> - <Set name="regex">/rewrite/dump/regex/([^/]*)/(.*)</Set> - <Set name="replacement">/test/dump/$2/$1</Set> - </New> - </Item> - - <!-- add a rewrite rule --> - <Item> - <New id="" class="org.mortbay.jetty.handler.rewrite.RewritePatternRule"> - <Set name="pattern">/rewrite</Set> - <Set name="replacement">/rewrittento</Set> - </New> - </Item> - - <!-- add a response rule --> - <Item> - <New id="response" class="org.mortbay.jetty.handler.rewrite.ResponsePatternRule"> - <Set name="pattern">/rewrite/session/</Set> - <Set name="code">401</Set> - <Set name="reason">Setting error code 401</Set> - </New> - </Item> - - <!-- add a header pattern rule --> - <Item> - <New id="header" class="org.mortbay.jetty.handler.rewrite.HeaderPatternRule"> - <Set name="pattern">*.jsp</Set> - <Set name="name">Server</Set> - <Set name="value">Server for JSP</Set> - </New> - </Item> - - <!-- add a redirect --> - <Item> - <New id="redirect" class="org.mortbay.jetty.handler.rewrite.RedirectPatternRule"> - <Set name="pattern">/rewrite/dispatch</Set> - <Set name="location">http://jetty.mortbay.org</Set> - </New> - </Item> - - <Item> - <New id="forwardedHttps" class="org.mortbay.jetty.handler.rewrite.ForwardedSchemeHeaderRule"> - <Set name="header">X-Forwarded-Scheme</Set> - <Set name="headerValue">https</Set> - <Set name="scheme">https</Set> - </New> - </Item> - - <Item> - <New id="virtualHost" class="org.mortbay.jetty.handler.rewrite.VirtualHostRuleContainer"> - - <Set name="virtualHosts"> - <Array type="java.lang.String"> - <Item>mortbay.com</Item> - <Item>www.mortbay.com</Item> - <Item>mortbay.org</Item> - <Item>www.mortbay.org</Item> - </Array> - </Set> - - <Call name="addRule"> - <Arg> - <New class="org.mortbay.jetty.handler.rewrite.CookiePatternRule"> - <Set name="pattern">/*</Set> - <Set name="name">CookiePatternRule</Set> - <Set name="value">1</Set> - </New> - </Arg> - </Call> - - </New> - </Item> - </Array> - </Set> - </New> + <!-- Add rule to protect against IE ssl bug --> + <Call name="addRule"> + <Arg> + <New class="org.eclipse.jetty.rewrite.handler.MsieSslRule"/> + </Arg> + </Call> + + <!-- protect favicon handling --> + <Call name="addRule"> + <Arg> + <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule"> + <Set name="pattern">/favicon.ico</Set> + <Set name="name">Cache-Control</Set> + <Set name="value">Max-Age=3600,public</Set> + <Set name="terminating">true</Set> + </New> + </Arg> + </Call> + + <!-- redirect from the welcome page to a specific page --> + <Call name="addRule"> + <Arg> + <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule"> + <Set name="pattern">/rewrite/</Set> + <Set name="replacement">/rewrite/info.html</Set> + </New> + </Arg> + </Call> + + <!-- replace the entire request URI --> + <Call name="addRule"> + <Arg> + <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule"> + <Set name="pattern">/some/old/context</Set> + <Set name="replacement">/rewritten/newcontext</Set> + </New> + </Arg> + </Call> + + <!-- replace the beginning of the request URI --> + <Call name="addRule"> + <Arg> + <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule"> + <Set name="pattern">/rewrite/for/*</Set> + <Set name="replacement">/rewritten/</Set> + </New> + </Arg> + </Call> + + <!-- reverse the order of the path sections --> + <Call name="addRule"> + <Arg> + <New class="org.eclipse.jetty.rewrite.handler.RewriteRegexRule"> + <Set name="regex">(.*?)/reverse/([^/]*)/(.*)</Set> + <Set name="replacement">$1/reverse/$3/$2</Set> + </New> + </Arg> + </Call> + + <!-- add a cookie to each path visited --> + <Call name="addRule"> + <Arg> + <New class="org.eclipse.jetty.rewrite.handler.CookiePatternRule"> + <Set name="pattern">/*</Set> + <Set name="name">visited</Set> + <Set name="value">yes</Set> + </New> + </Arg> + </Call> + + <!-- actual redirect, instead of internal rewrite --> + <Call name="addRule"> + <Arg> + <New class="org.eclipse.jetty.rewrite.handler.RedirectPatternRule"> + <Set name="pattern">/redirect/*</Set> + <Set name="location">/redirected</Set> + </New> + </Arg> + </Call> + + <!-- add a response rule --> + <Call name="addRule"> + <Arg> + <New class="org.eclipse.jetty.rewrite.handler.ResponsePatternRule"> + <Set name="pattern">/400Error</Set> + <Set name="code">400</Set> + <Set name="reason">ResponsePatternRule Demo</Set> + </New> + </Arg> + </Call> + + </New> </Set> </Configure> diff --git a/installer/resources/eepsite/jetty-ssl.xml b/installer/resources/eepsite/jetty-ssl.xml index 787635f563cbc1bbeb866e3907a4e24cbb8c4ffb..f86c0250705785f711a1332af9124c4e085c6f22 100644 --- a/installer/resources/eepsite/jetty-ssl.xml +++ b/installer/resources/eepsite/jetty-ssl.xml @@ -1,35 +1,35 @@ <?xml version="1.0"?> -<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"> +<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd"> <!-- =============================================================== --> <!-- Configure SSL for the Jetty Server --> <!-- this configuration file should be used in combination with --> <!-- other configuration files. e.g. --> -<!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml --> +<!-- java -jar start.jar etc/jetty-ssl.xml --> +<!-- --> +<!-- alternately, add to the start.ini for easier usage --> <!-- =============================================================== --> -<Configure id="Server" class="org.mortbay.jetty.Server"> - +<Configure id="Server" class="org.eclipse.jetty.server.Server"> + <!-- if NIO is not available, use org.eclipse.jetty.server.ssl.SslSocketConnector --> + + <New id="sslContextFactory" class="org.eclipse.jetty.http.ssl.SslContextFactory"> + <Set name="KeyStore">./eepsite/etc/keystore</Set> + <Set name="KeyStorePassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set> + <Set name="KeyManagerPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set> + <Set name="TrustStore">./eepsite/etc/keystore</Set> + <Set name="TrustStorePassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set> + </New> <Call name="addConnector"> <Arg> - <New class="org.mortbay.jetty.security.SslSocketConnector"> + <New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector"> + <Arg><Ref id="sslContextFactory" /></Arg> <Set name="Port">8443</Set> <Set name="maxIdleTime">30000</Set> <Set name="useDirectBuffers">false</Set> - <Set name="handshakeTimeout">2000</Set> - <Set name="keystore">./eepsite/etc/keystore.ks</Set> - <Set name="password">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set> - <Set name="keyPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set> - <Set name="truststore">./eepsite/etc/keystore.ks</Set> - <Set name="trustPassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set> - <Set name="handshakeTimeout">2000</Set> - <!-- Set name="ThreadPool"> - <New class="org.mortbay.thread.QueuedThreadPool"> - <Set name="minThreads">0</Set> - <Set name="maxThreads">16</Set> - </New> - </Set --> + <Set name="Acceptors">2</Set> + <Set name="AcceptQueueSize">100</Set> </New> </Arg> </Call> diff --git a/installer/resources/eepsite/jetty.xml b/installer/resources/eepsite/jetty.xml index 0e873ca7709e5fea1d4818035b137562779d705a..7a57fa3fc05e79e5cc37dfec3b04f0d854929695 100644 --- a/installer/resources/eepsite/jetty.xml +++ b/installer/resources/eepsite/jetty.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure 1.2//EN" "http://jetty.mortbay.org/configure_1_2.dtd"> +<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd"> <!-- ========================================================================= --> <!-- This file configures the Jetty server. --> @@ -18,8 +18,8 @@ <!-- war files placed in the webapps/ dir. --> <!-- * Uncomment the line to allow Jetty to follow symlinks --> <!-- --> -<!-- I2P uses Jetty 6.1.26. If you need web server features not found --> -<!-- in Jetty 6, you may install and run Jetty 7 or 8 in a different JVM --> +<!-- I2P uses Jetty 7. If you need web server features not found --> +<!-- in Jetty 7, you may install and run Jetty 7 or 8 in a different JVM --> <!-- or run any other web server such as Apache. If you do run another web --> <!-- server instead, be sure and disable the Jetty 6 server for your --> <!-- eepsite on http://127.0.0.1:7657/configclients.jsp . --> @@ -44,7 +44,7 @@ <!-- =============================================================== --> -<Configure id="Server" class="org.mortbay.jetty.Server"> +<Configure id="Server" class="org.eclipse.jetty.server.Server"> <!-- =========================================================== --> <!-- Server Thread Pool --> @@ -57,7 +57,7 @@ Requests above the max will be queued --> <!-- - <New class="org.mortbay.thread.QueuedThreadPool"> + <New class="org.eclipse.jetty.util.thread.QueuedThreadPool"> <Set name="minThreads">1</Set> <Set name="maxThreads">16</Set> <Set name="lowThreads">2</Set> @@ -73,10 +73,13 @@ set the thread name, set daemon, etc. See RouterConsoleRunner. --> - <New class="org.mortbay.thread.concurrent.ThreadPool"> - <Arg type="int">0</Arg> - <Set name="corePoolSize">1</Set> - <Set name="maximumPoolSize">24</Set> + <New class="org.eclipse.jetty.util.thread.ExecutorThreadPool"> + <!-- corePoolSize (must be at least 3) --> + <Arg type="int">3</Arg> + <!-- maximumPoolSize --> + <Arg type="int">16</Arg> + <!-- keepAliveTime (milliseconds) --> + <Arg type="long">60000</Arg> </New> </Set> @@ -97,7 +100,7 @@ --> <Call name="addConnector"> <Arg> - <New class="org.mortbay.jetty.nio.SelectChannelConnector"> + <New class="org.eclipse.jetty.server.nio.SelectChannelConnector"> <Set name="host">127.0.0.1</Set> <Set name="port">7658</Set> <Set name="maxIdleTime">60000</Set> @@ -106,7 +109,7 @@ <Set name="confidentialPort">8443</Set> <Set name="lowResourcesConnections">5000</Set> <Set name="lowResourcesMaxIdleTime">5000</Set> - <Set name="useDirectBuffers">false</Set> + <Set name="useDirectBuffers">false</Set> </New> </Arg> </Call> @@ -117,7 +120,7 @@ <!-- <Call name="addConnector"> <Arg> - <New class="org.mortbay.jetty.bio.SocketConnector"> + <New class="org.eclipse.jetty.server.bio.SocketConnector"> <Set name="host">127.0.0.1</Set> <Set name="port">7658</Set> <Set name="maxIdleTime">60000</Set> @@ -155,7 +158,7 @@ <!-- =========================================================== --> <!-- <Set name="sessionIdManager"> - <New class="org.mortbay.jetty.servlet.HashSessionIdManager"> + <New class="org.eclipse.jetty.server.session.HashSessionIdManager"> <Set name="workerName">node1</Set> </New> </Set> @@ -165,23 +168,48 @@ <!-- Set handler Collection Structure --> <!-- =========================================================== --> <Set name="handler"> - <New id="Handlers" class="org.mortbay.jetty.handler.HandlerCollection"> + <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection"> <Set name="handlers"> - <Array type="org.mortbay.jetty.Handler"> + <Array type="org.eclipse.jetty.server.Handler"> <Item> - <New id="Contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection"/> + <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/> </Item> <Item> - <New id="DefaultHandler" class="org.mortbay.jetty.handler.DefaultHandler"/> + <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/> </Item> <Item> - <New id="RequestLog" class="org.mortbay.jetty.handler.RequestLogHandler"/> + <New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"/> </Item> </Array> </Set> </New> </Set> - + + <!-- =============================================================== --> + <!-- Create the deployment manager --> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <!-- The deplyment manager handles the lifecycle of deploying web --> + <!-- applications. Apps are provided by instances of the --> + <!-- AppProvider interface. Typically these are provided by --> + <!-- one or more of: --> + <!-- jetty-webapps.xml - monitors webapps for wars and dirs --> + <!-- jetty-contexts.xml - monitors contexts for context xml --> + <!-- jetty-templates.xml - monitors contexts and templates --> + <!-- =============================================================== --> + <Call name="addBean"> + <Arg> + <New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager"> + <Set name="contexts"> + <Ref id="Contexts" /> + </Set> + <Call name="setContextAttribute"> + <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg> + <Arg>.*/.*jsp-api-[^/]*\.jar$|.*/.*jsp-[^/]*\.jar$|.*/.*taglibs[^/]*\.jar$</Arg> + </Call> + </New> + </Arg> + </Call> + <!-- =========================================================== --> <!-- Configure the context deployer --> <!-- A context deployer will deploy contexts described in --> @@ -193,16 +221,16 @@ <!-- in the $JETTY_HOME/contexts directory --> <!-- --> <!-- =========================================================== --> - <Call name="addLifeCycle"> - <Arg> - <New class="org.mortbay.jetty.deployer.ContextDeployer"> - <Set name="contexts"><Ref id="Contexts"/></Set> - <Set name="configurationDir">./eepsite/contexts</Set> - <!-- set to 60 to have it check for changes once a minute --> - <Set name="scanInterval">0</Set> - </New> - </Arg> - </Call> + <Ref id="DeploymentManager"> + <Call name="addAppProvider"> + <Arg> + <New class="org.eclipse.jetty.deploy.providers.ContextProvider"> + <Set name="monitoredDirName">./eepsite/contexts</Set> + <Set name="scanInterval">30</Set> + </New> + </Arg> + </Call> + </Ref> <!-- =========================================================== --> <!-- Configure the webapp deployer. --> @@ -219,7 +247,7 @@ <!-- =========================================================== --> <Call name="addLifeCycle"> <Arg> - <New class="org.mortbay.jetty.deployer.WebAppDeployer"> + <New class="org.eclipse.jetty.deploy.WebAppDeployer"> <Set name="contexts"><Ref id="Contexts"/></Set> <Set name="webAppDir">./eepsite/webapps</Set> <Set name="parentLoaderPriority">false</Set> @@ -231,6 +259,20 @@ </Arg> </Call> +<!-- FIXME Above is deprecated, but this doesn't work + java.lang.IllegalStateException: No Method: <Call name="addAppProvider"><New class="org.eclipse.jetty.deploy.providers.WebAppProvider"><Set name="monitoredDirName">./eepsite/webapps</Set><Set name="parentLoaderPriority">false</Set><Set name="extractWars">false</Set><Set name="defaultsDescriptor">./eepsite/etc/webdefault.xml</Set></New></Call> on class org.eclipse.jetty.deploy.DeploymentManager + <Ref id="DeploymentManager"> + <Call id="webappprovider" name="addAppProvider"> + <New class="org.eclipse.jetty.deploy.providers.WebAppProvider"> + <Set name="monitoredDirName">./eepsite/webapps</Set> + <Set name="parentLoaderPriority">false</Set> + <Set name="extractWars">false</Set> + <Set name="defaultsDescriptor">./eepsite/etc/webdefault.xml</Set> + </New> + </Call> + </Ref> +--> + <!-- =========================================================== --> <!-- Configure Authentication Realms --> <!-- Realms may be configured for the entire server here, or --> @@ -240,9 +282,9 @@ <!-- =========================================================== --> <!-- UNCOMMENT TO ACTIVATE <Set name="UserRealms"> - <Array type="org.mortbay.jetty.security.UserRealm"> + <Array type="org.eclipse.jetty.security.LoginService"> <Item> - <New class="org.mortbay.jetty.security.HashUserRealm"> + <New class="org.eclipse.jetty.security.HashLoginService"> <Set name="name">Test Realm</Set> <Set name="config">./eepsite/etc/realm.properties</Set> <Set name="refreshInterval">0</Set> diff --git a/licenses/ABOUT-Jetty.html b/licenses/ABOUT-Jetty.html new file mode 100644 index 0000000000000000000000000000000000000000..7c9303249df42d3e1abbddae583ec50a1f222026 --- /dev/null +++ b/licenses/ABOUT-Jetty.html @@ -0,0 +1,20 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/> +<title>About</title> +</head> +<body lang="EN-US"> +<h2>About This Content</h2> + +<p>19 May, 2009</p> +<h3>License</h3> + +<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). The Content is dual licensed and is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 ("EPL") as well as the Apache Software License Version 2.0. A copy of the EPL is available +at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>. A copy of the ASL is available at <a href="http://www.apache.org/licenses/LICENSE-2.0.html">http://www.apache.org/licenses/LICENSE-2.0.html</a>. For purposes of the EPL, "Program" will mean the Content.</p> + +<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party ("Redistributor") and different terms and conditions may apply to your use of any object code in the Content. Check the Redistributor's license that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise indicated below, the terms and conditions of the EPL still apply to any source code in the Content and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p> + +</body> +</html> \ No newline at end of file diff --git a/licenses/LICENSE-ECLIPSE-1.0.html b/licenses/LICENSE-ECLIPSE-1.0.html new file mode 100644 index 0000000000000000000000000000000000000000..9320c9f37cf0a4261329192f1c67bc8fd61b182e --- /dev/null +++ b/licenses/LICENSE-ECLIPSE-1.0.html @@ -0,0 +1,320 @@ +<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40"><head> + + +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> +<meta name="ProgId" content="Word.Document"> +<meta name="Generator" content="Microsoft Word 9"> +<meta name="Originator" content="Microsoft Word 9"> +<link rel="File-List" href="http://www.eclipse.org/legal/Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml"> +<title>Eclipse Public License - Version 1.0</title> +<!--[if gte mso 9]><xml> + <o:DocumentProperties> + <o:Revision>2</o:Revision> + <o:TotalTime>3</o:TotalTime> + <o:Created>2004-03-05T23:03:00Z</o:Created> + <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved> + <o:Pages>4</o:Pages> + <o:Words>1626</o:Words> + <o:Characters>9270</o:Characters> + <o:Lines>77</o:Lines> + <o:Paragraphs>18</o:Paragraphs> + <o:CharactersWithSpaces>11384</o:CharactersWithSpaces> + <o:Version>9.4402</o:Version> + </o:DocumentProperties> +</xml><![endif]--><!--[if gte mso 9]><xml> + <w:WordDocument> + <w:TrackRevisions/> + </w:WordDocument> +</xml><![endif]--> +<style> +<!-- + /* Font Definitions */ +@font-face + {font-family:Tahoma; + panose-1:2 11 6 4 3 5 4 4 2 4; + mso-font-charset:0; + mso-generic-font-family:swiss; + mso-font-pitch:variable; + mso-font-signature:553679495 -2147483648 8 0 66047 0;} + /* Style Definitions */ +p.MsoNormal, li.MsoNormal, div.MsoNormal + {mso-style-parent:""; + margin:0in; + margin-bottom:.0001pt; + mso-pagination:widow-orphan; + font-size:12.0pt; + font-family:"Times New Roman"; + mso-fareast-font-family:"Times New Roman";} +p + {margin-right:0in; + mso-margin-top-alt:auto; + mso-margin-bottom-alt:auto; + margin-left:0in; + mso-pagination:widow-orphan; + font-size:12.0pt; + font-family:"Times New Roman"; + mso-fareast-font-family:"Times New Roman";} +p.BalloonText, li.BalloonText, div.BalloonText + {mso-style-name:"Balloon Text"; + margin:0in; + margin-bottom:.0001pt; + mso-pagination:widow-orphan; + font-size:8.0pt; + font-family:Tahoma; + mso-fareast-font-family:"Times New Roman";} +@page Section1 + {size:8.5in 11.0in; + margin:1.0in 1.25in 1.0in 1.25in; + mso-header-margin:.5in; + mso-footer-margin:.5in; + mso-paper-source:0;} +div.Section1 + {page:Section1;} +--> +</style> +</head><body style="" lang="EN-US"> + +<div class="Section1"> + +<p style="text-align: center;" align="center"><b>Eclipse Public License - v 1.0</b> +</p> + +<p><span style="font-size: 10pt;">THE ACCOMPANYING PROGRAM IS PROVIDED UNDER +THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, +REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE +OF THIS AGREEMENT.</span> </p> + +<p><b><span style="font-size: 10pt;">1. DEFINITIONS</span></b> </p> + +<p><span style="font-size: 10pt;">"Contribution" means:</span> </p> + +<p class="MsoNormal" style="margin-left: 0.5in;"><span style="font-size: 10pt;">a) +in the case of the initial Contributor, the initial code and documentation +distributed under this Agreement, and<br clear="left"> +b) in the case of each subsequent Contributor:</span></p> + +<p class="MsoNormal" style="margin-left: 0.5in;"><span style="font-size: 10pt;">i) +changes to the Program, and</span></p> + +<p class="MsoNormal" style="margin-left: 0.5in;"><span style="font-size: 10pt;">ii) +additions to the Program;</span></p> + +<p class="MsoNormal" style="margin-left: 0.5in;"><span style="font-size: 10pt;">where +such changes and/or additions to the Program originate from and are distributed +by that particular Contributor. A Contribution 'originates' from a Contributor +if it was added to the Program by such Contributor itself or anyone acting on +such Contributor's behalf. Contributions do not include additions to the +Program which: (i) are separate modules of software distributed in conjunction +with the Program under their own license agreement, and (ii) are not derivative +works of the Program. </span></p> + +<p><span style="font-size: 10pt;">"Contributor" means any person or +entity that distributes the Program.</span> </p> + +<p><span style="font-size: 10pt;">"Licensed Patents " mean patent +claims licensable by a Contributor which are necessarily infringed by the use +or sale of its Contribution alone or when combined with the Program. </span></p> + +<p><span style="font-size: 10pt;">"Program" means the Contributions +distributed in accordance with this Agreement.</span> </p> + +<p><span style="font-size: 10pt;">"Recipient" means anyone who +receives the Program under this Agreement, including all Contributors.</span> </p> + +<p><b><span style="font-size: 10pt;">2. GRANT OF RIGHTS</span></b> </p> + +<p class="MsoNormal" style="margin-left: 0.5in;"><span style="font-size: 10pt;">a) +Subject to the terms of this Agreement, each Contributor hereby grants Recipient +a non-exclusive, worldwide, royalty-free copyright license to<span style="color: red;"> </span>reproduce, prepare derivative works of, publicly +display, publicly perform, distribute and sublicense the Contribution of such +Contributor, if any, and such derivative works, in source code and object code +form.</span></p> + +<p class="MsoNormal" style="margin-left: 0.5in;"><span style="font-size: 10pt;">b) +Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide,<span style="color: green;"> </span>royalty-free +patent license under Licensed Patents to make, use, sell, offer to sell, import +and otherwise transfer the Contribution of such Contributor, if any, in source +code and object code form. This patent license shall apply to the combination +of the Contribution and the Program if, at the time the Contribution is added +by the Contributor, such addition of the Contribution causes such combination +to be covered by the Licensed Patents. The patent license shall not apply to +any other combinations which include the Contribution. No hardware per se is +licensed hereunder. </span></p> + +<p class="MsoNormal" style="margin-left: 0.5in;"><span style="font-size: 10pt;">c) +Recipient understands that although each Contributor grants the licenses to its +Contributions set forth herein, no assurances are provided by any Contributor +that the Program does not infringe the patent or other intellectual property +rights of any other entity. Each Contributor disclaims any liability to Recipient +for claims brought by any other entity based on infringement of intellectual +property rights or otherwise. As a condition to exercising the rights and +licenses granted hereunder, each Recipient hereby assumes sole responsibility +to secure any other intellectual property rights needed, if any. For example, +if a third party patent license is required to allow Recipient to distribute +the Program, it is Recipient's responsibility to acquire that license before +distributing the Program.</span></p> + +<p class="MsoNormal" style="margin-left: 0.5in;"><span style="font-size: 10pt;">d) +Each Contributor represents that to its knowledge it has sufficient copyright +rights in its Contribution, if any, to grant the copyright license set forth in +this Agreement. </span></p> + +<p><b><span style="font-size: 10pt;">3. REQUIREMENTS</span></b> </p> + +<p><span style="font-size: 10pt;">A Contributor may choose to distribute the +Program in object code form under its own license agreement, provided that:</span> +</p> + +<p class="MsoNormal" style="margin-left: 0.5in;"><span style="font-size: 10pt;">a) +it complies with the terms and conditions of this Agreement; and</span></p> + +<p class="MsoNormal" style="margin-left: 0.5in;"><span style="font-size: 10pt;">b) +its license agreement:</span></p> + +<p class="MsoNormal" style="margin-left: 0.5in;"><span style="font-size: 10pt;">i) +effectively disclaims on behalf of all Contributors all warranties and +conditions, express and implied, including warranties or conditions of title +and non-infringement, and implied warranties or conditions of merchantability +and fitness for a particular purpose; </span></p> + +<p class="MsoNormal" style="margin-left: 0.5in;"><span style="font-size: 10pt;">ii) +effectively excludes on behalf of all Contributors all liability for damages, +including direct, indirect, special, incidental and consequential damages, such +as lost profits; </span></p> + +<p class="MsoNormal" style="margin-left: 0.5in;"><span style="font-size: 10pt;">iii) +states that any provisions which differ from this Agreement are offered by that +Contributor alone and not by any other party; and</span></p> + +<p class="MsoNormal" style="margin-left: 0.5in;"><span style="font-size: 10pt;">iv) +states that source code for the Program is available from such Contributor, and +informs licensees how to obtain it in a reasonable manner on or through a +medium customarily used for software exchange.<span style="color: blue;"> </span></span></p> + +<p><span style="font-size: 10pt;">When the Program is made available in source +code form:</span> </p> + +<p class="MsoNormal" style="margin-left: 0.5in;"><span style="font-size: 10pt;">a) +it must be made available under this Agreement; and </span></p> + +<p class="MsoNormal" style="margin-left: 0.5in;"><span style="font-size: 10pt;">b) a +copy of this Agreement must be included with each copy of the Program. </span></p> + +<p><span style="font-size: 10pt;">Contributors may not remove or alter any +copyright notices contained within the Program. </span></p> + +<p><span style="font-size: 10pt;">Each Contributor must identify itself as the +originator of its Contribution, if any, in a manner that reasonably allows +subsequent Recipients to identify the originator of the Contribution. </span></p> + +<p><b><span style="font-size: 10pt;">4. COMMERCIAL DISTRIBUTION</span></b> </p> + +<p><span style="font-size: 10pt;">Commercial distributors of software may +accept certain responsibilities with respect to end users, business partners +and the like. While this license is intended to facilitate the commercial use +of the Program, the Contributor who includes the Program in a commercial +product offering should do so in a manner which does not create potential +liability for other Contributors. Therefore, if a Contributor includes the +Program in a commercial product offering, such Contributor ("Commercial +Contributor") hereby agrees to defend and indemnify every other +Contributor ("Indemnified Contributor") against any losses, damages and +costs (collectively "Losses") arising from claims, lawsuits and other +legal actions brought by a third party against the Indemnified Contributor to +the extent caused by the acts or omissions of such Commercial Contributor in +connection with its distribution of the Program in a commercial product +offering. The obligations in this section do not apply to any claims or Losses +relating to any actual or alleged intellectual property infringement. In order +to qualify, an Indemnified Contributor must: a) promptly notify the Commercial +Contributor in writing of such claim, and b) allow the Commercial Contributor +to control, and cooperate with the Commercial Contributor in, the defense and +any related settlement negotiations. The Indemnified Contributor may participate +in any such claim at its own expense.</span> </p> + +<p><span style="font-size: 10pt;">For example, a Contributor might include the +Program in a commercial product offering, Product X. That Contributor is then a +Commercial Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance claims and +warranties are such Commercial Contributor's responsibility alone. Under this +section, the Commercial Contributor would have to defend claims against the +other Contributors related to those performance claims and warranties, and if a +court requires any other Contributor to pay any damages as a result, the +Commercial Contributor must pay those damages.</span> </p> + +<p><b><span style="font-size: 10pt;">5. NO WARRANTY</span></b> </p> + +<p><span style="font-size: 10pt;">EXCEPT AS EXPRESSLY SET FORTH IN THIS +AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, +WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, +MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely +responsible for determining the appropriateness of using and distributing the +Program and assumes all risks associated with its exercise of rights under this +Agreement , including but not limited to the risks and costs of program errors, +compliance with applicable laws, damage to or loss of data, programs or +equipment, and unavailability or interruption of operations. </span></p> + +<p><b><span style="font-size: 10pt;">6. DISCLAIMER OF LIABILITY</span></b> </p> + +<p><span style="font-size: 10pt;">EXCEPT AS EXPRESSLY SET FORTH IN THIS +AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF +THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGES.</span> </p> + +<p><b><span style="font-size: 10pt;">7. GENERAL</span></b> </p> + +<p><span style="font-size: 10pt;">If any provision of this Agreement is invalid +or unenforceable under applicable law, it shall not affect the validity or +enforceability of the remainder of the terms of this Agreement, and without +further action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable.</span> </p> + +<p><span style="font-size: 10pt;">If Recipient institutes patent litigation +against any entity (including a cross-claim or counterclaim in a lawsuit) +alleging that the Program itself (excluding combinations of the Program with +other software or hardware) infringes such Recipient's patent(s), then such +Recipient's rights granted under Section 2(b) shall terminate as of the date +such litigation is filed. </span></p> + +<p><span style="font-size: 10pt;">All Recipient's rights under this Agreement +shall terminate if it fails to comply with any of the material terms or +conditions of this Agreement and does not cure such failure in a reasonable +period of time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use and +distribution of the Program as soon as reasonably practicable. However, +Recipient's obligations under this Agreement and any licenses granted by +Recipient relating to the Program shall continue and survive. </span></p> + +<p><span style="font-size: 10pt;">Everyone is permitted to copy and distribute +copies of this Agreement, but in order to avoid inconsistency the Agreement is +copyrighted and may only be modified in the following manner. The Agreement +Steward reserves the right to publish new versions (including revisions) of +this Agreement from time to time. No one other than the Agreement Steward has +the right to modify this Agreement. The Eclipse Foundation is the initial +Agreement Steward. The Eclipse Foundation may assign the responsibility to +serve as the Agreement Steward to a suitable separate entity. Each new version +of the Agreement will be given a distinguishing version number. The Program +(including Contributions) may always be distributed subject to the version of +the Agreement under which it was received. In addition, after a new version of +the Agreement is published, Contributor may elect to distribute the Program +(including its Contributions) under the new version. Except as expressly stated +in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to +the intellectual property of any Contributor under this Agreement, whether +expressly, by implication, estoppel or otherwise. All rights in the Program not +expressly granted under this Agreement are reserved.</span> </p> + +<p><span style="font-size: 10pt;">This Agreement is governed by the laws of the +State of New York and the intellectual property laws of the United States of +America. No party to this Agreement will bring a legal action under this +Agreement more than one year after the cause of action arose. Each party waives +its rights to a jury trial in any resulting litigation.</span> </p> + +<p class="MsoNormal"><!--[if !supportEmptyParas]--> <!--[endif]--><o:p></o:p></p> + +</div> + +</body></html> \ No newline at end of file diff --git a/licenses/NOTICE-Jetty.html b/licenses/NOTICE-Jetty.html new file mode 100644 index 0000000000000000000000000000000000000000..e9461a8e86ed02db02b7639f9a45fd90eef96885 --- /dev/null +++ b/licenses/NOTICE-Jetty.html @@ -0,0 +1,111 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> +<html><head> + + +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>Eclipse.org Software User Agreement</title> +</head><body lang="EN-US" link="blue" vlink="purple"> +<h2>Eclipse Foundation Software User Agreement</h2> +<p>March 17, 2005</p> + +<h3>Usage Of Content</h3> + +<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS + (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND + CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE + OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR + NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND + CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p> + +<h3>Applicable Licenses</h3> + +<p>Unless otherwise indicated, all Content made available by the +Eclipse Foundation is provided to you under the terms and conditions of +the Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is +provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>. + For purposes of the EPL, "Program" will mean the Content.</p> + +<p>Content includes, but is not limited to, source code, object code, +documentation and other files maintained in the Eclipse.org CVS +repository ("Repository") in CVS modules ("Modules") and made available +as downloadable archives ("Downloads").</p> + +<ul> + <li>Content may be structured and packaged into modules to +facilitate delivering, extending, and upgrading the Content. Typical +modules may include plug-ins ("Plug-ins"), plug-in fragments +("Fragments"), and features ("Features").</li> + <li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".</li> + <li>A +Feature is a bundle of one or more Plug-ins and/or Fragments and +associated material. Each Feature may be packaged as a sub-directory in +a directory named "features". Within a Feature, files named +"feature.xml" may contain a list of the names and version numbers of +the Plug-ins and/or Fragments associated with that Feature.</li> + <li>Features +may also include other Features ("Included Features"). Within a +Feature, files named "feature.xml" may contain a list of the names and +version numbers of Included Features.</li> +</ul> + +<p>The terms and conditions governing Plug-ins and Fragments should be +contained in files named "about.html" ("Abouts"). The terms and +conditions governing Features and +Included Features should be contained in files named "license.html" +("Feature Licenses"). Abouts and Feature Licenses may be located in any +directory of a Download or Module +including, but not limited to the following locations:</p> + +<ul> + <li>The top-level (root) directory</li> + <li>Plug-in and Fragment directories</li> + <li>Inside Plug-ins and Fragments packaged as JARs</li> + <li>Sub-directories of the directory named "src" of certain Plug-ins</li> + <li>Feature directories</li> +</ul> + +<p>Note: if a Feature made available by the Eclipse Foundation is +installed using the Eclipse Update Manager, you must agree to a license +("Feature Update License") during the +installation process. If the Feature contains Included Features, the +Feature Update License should either provide you with the terms and +conditions governing the Included Features or +inform you where you can locate them. Feature Update Licenses may be +found in the "license" property of files named "feature.properties" +found within a Feature. +Such Abouts, Feature Licenses, and Feature Update Licenses contain the +terms and conditions (or references to such terms and conditions) that +govern your use of the associated Content in +that directory.</p> + +<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER +TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND +CONDITIONS. SOME OF THESE +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p> + +<ul> + <li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li> + <li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li> + <li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li> + <li>IBM Public License 1.0 (available at <a href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</a>)</li> + <li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li> + <li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li> +</ul> + +<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND +CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, +or Feature Update License is provided, please +contact the Eclipse Foundation to determine what terms and conditions +govern that particular Content.</p> + +<h3>Cryptography</h3> + +<p>Content may contain encryption software. The country in which you +are currently may have restrictions on the import, possession, and use, +and/or re-export to another country, of encryption software. BEFORE +using any encryption software, please check the country's laws, +regulations and policies concerning the import, possession, or use, and +re-export of encryption software, to see if this is permitted.</p> + +<small>Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.</small> +</body></html> \ No newline at end of file diff --git a/licenses/NOTICE-Jetty.txt b/licenses/NOTICE-Jetty.txt deleted file mode 100644 index 21d4ed3d0ee3a1cbaf494b4017837e79ca84356d..0000000000000000000000000000000000000000 --- a/licenses/NOTICE-Jetty.txt +++ /dev/null @@ -1,36 +0,0 @@ -============================================================== - Jetty Web Container - Copyright 1995-2009 Mort Bay Consulting Pty Ltd -============================================================== - -The Jetty Web Container is Copyright Mort Bay Consulting Pty Ltd -unless otherwise noted. It is licensed under the apache 2.0 -license. - -The javax.servlet package used by Jetty is copyright -Sun Microsystems, Inc and Apache Software Foundation. It is -distributed under the Common Development and Distribution License. -You can obtain a copy of the license at -https://glassfish.dev.java.net/public/CDDLv1.0.html. - -The UnixCrypt.java code ~Implements the one way cryptography used by -Unix systems for simple password protection. Copyright 1996 Aki Yoshida, -modified April 2001 by Iris Van den Broeke, Daniel Deville. -Permission to use, copy, modify and distribute UnixCrypt -for non-commercial or commercial purposes and without fee is -granted provided that the copyright notice appears in all copies. - -The default JSP implementation is provided by the Glassfish JSP engine -from project Glassfish http://glassfish.dev.java.net. Copyright 2005 -Sun Microsystems, Inc. and portions Copyright Apache Software Foundation. - -Some portions of the code are Copyright: - 2006 Tim Vernum - 1999 Jason Gilbert. - -The jboss integration module contains some LGPL code. - -The win32 Java Service Wrapper (v3.2.3) is Copyright (c) 1999, 2006 -Tanuki Software, Inc. and 2001 Silver Egg Technology. It is -covered by an open license which is viewable at -http://svn.codehaus.org/jetty/jetty/branches/jetty-6.1/extras/win32service/LICENSE.txt diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index 725ca2779b9b8223291c3f90743141631137458b..125d2e075c83b1dab67467cffe1aeb5da6050471 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -128,7 +128,8 @@ public class Router implements RouterClock.ClockShiftListener { // Fixed in Jetty 5.1.15 but we are running 5.1.12 // The default is true, unfortunately it was previously // set to false in wrapper.config thru 0.7.10 so we must set it back here. - System.setProperty("org.mortbay.util.FileResource.checkAliases", "true"); + // Not in Jetty 7 + //System.setProperty("org.mortbay.util.FileResource.checkAliases", "true"); } /** diff --git a/router/java/src/net/i2p/router/startup/MigrateJetty.java b/router/java/src/net/i2p/router/startup/MigrateJetty.java index b78331284c1ca7839feb70ca31c11a7cf09aa0dc..3b197f9de6022bd3cb4cb2b3a4c30e86da326949 100644 --- a/router/java/src/net/i2p/router/startup/MigrateJetty.java +++ b/router/java/src/net/i2p/router/startup/MigrateJetty.java @@ -35,13 +35,15 @@ import net.i2p.router.RouterContext; */ abstract class MigrateJetty { private static boolean _wasChecked; - private static boolean _hasJetty6; + private static boolean _hasLatestJetty; private static final String OLD_CLASS = "org.mortbay.jetty.Server"; - private static final String NEW_CLASS = "org.mortbay.start.Main"; - private static final String BACKUP = "jetty5.xml"; - private static final String JETTY6_TEMPLATE_DIR = "eepsite-jetty6"; - private static final String JETTY6_TEMPLATE_PKGDIR = "eepsite"; + private static final String OLD_CLASS_6 = "org.mortbay.start.Main"; + private static final String NEW_CLASS = "net.i2p.jetty.JettyStart"; + private static final String TEST_CLASS = "org.eclipse.jetty.server.Server"; + private static final String BACKUP = "jetty6.xml"; + private static final String JETTY_TEMPLATE_DIR = "eepsite-jetty7"; + private static final String JETTY_TEMPLATE_PKGDIR = "eepsite"; private static final String BASE_CONTEXT = "contexts/base-context.xml"; private static final String CGI_CONTEXT = "contexts/cgi-context.xml"; @@ -49,13 +51,13 @@ abstract class MigrateJetty { boolean shouldSave = false; for (int i = 0; i < apps.size(); i++) { ClientAppConfig app = apps.get(i); - if (!app.className.equals(OLD_CLASS)) + if (!(app.className.equals(OLD_CLASS) || app.className.equals(OLD_CLASS_6))) continue; String client = "client application " + i + " [" + app.clientName + - "] from Jetty 5 " + OLD_CLASS + - " to Jetty 6 " + NEW_CLASS; - if (!hasJetty6()) { - System.err.println("WARNING: Jetty 6 unavailable, cannot migrate " + client); + "] from Jetty 5/6 " + app.className + + " to Jetty 7 " + NEW_CLASS; + if (!hasLatestJetty()) { + System.err.println("WARNING: Jetty 7 unavailable, cannot migrate " + client); continue; } if (app.args == null) @@ -83,10 +85,10 @@ abstract class MigrateJetty { ", cannot migrate " + client); continue; } - File baseEep = new File(ctx.getBaseDir(), JETTY6_TEMPLATE_DIR); + File baseEep = new File(ctx.getBaseDir(), JETTY_TEMPLATE_DIR); // in packages, or perhaps on an uninstall/reinstall, the files are in eepsite/ if (!baseEep.exists()) - baseEep = new File(ctx.getBaseDir(), JETTY6_TEMPLATE_PKGDIR); + baseEep = new File(ctx.getBaseDir(), JETTY_TEMPLATE_PKGDIR); if (baseEep.equals(eepsite)) { // non-split directory yet not an upgrade? shouldn't happen System.err.println("Eepsite in non-split directory " + eepsite + @@ -132,28 +134,29 @@ abstract class MigrateJetty { } if (shouldSave) { File cfgFile = ClientAppConfig.configFile(ctx); - File backup = new File(cfgFile.getAbsolutePath() + ".jetty5"); + File backup = new File(cfgFile.getAbsolutePath() + ".jetty6"); if (backup.exists()) backup = new File(cfgFile.getAbsolutePath() + ctx.random().nextInt()); boolean ok = WorkingDir.copyFile(cfgFile, backup); if (ok) { ClientAppConfig.writeClientAppConfig(ctx, apps); System.err.println("WARNING: Migrated clients config file " + cfgFile + - " from Jetty 5 " + OLD_CLASS + - " to Jetty 6 " + NEW_CLASS + "\n" + + " from Jetty 5/6 " + OLD_CLASS + '/' + OLD_CLASS_6 + + " to Jetty 7 " + NEW_CLASS + "\n" + "Your old clients config file was saved as " + backup); } } } - private static boolean hasJetty6() { + /** do we have Jetty 7? */ + private static boolean hasLatestJetty() { if (!_wasChecked) { try { - LoadClientAppsJob.testClient(NEW_CLASS, null); - _hasJetty6 = true; + LoadClientAppsJob.testClient(TEST_CLASS, null); + _hasLatestJetty = true; } catch (ClassNotFoundException cnfe) {} _wasChecked = true; } - return _hasJetty6; + return _hasLatestJetty; } }