forked from I2P_Developers/i2p.i2p
propagate from branch 'i2p.i2p' (head 156f8e6137be3c25aa70176fe0a78218b898a684)
to branch 'i2p.i2p.zzz.jetty6' (head 960f416b20e26662b1b5b30468a85dbb25f09ffd)
This commit is contained in:
15
LICENSE.txt
15
LICENSE.txt
@ -172,8 +172,9 @@ Applications:
|
||||
By welterde.
|
||||
See licenses/LICENSE-GPLv2.txt
|
||||
|
||||
Jetty 5.1.15:
|
||||
Copyright 2000-2004 Mort Bay Consulting Pty. Ltd.
|
||||
Jetty 6.1.26:
|
||||
Copyright 1995-2009 Mort Bay Consulting Pty Ltd
|
||||
See licenses/LICENSE-Jetty.txt
|
||||
See licenses/LICENSE-Apache2.0.txt
|
||||
See licenses/NOTICE-Commons-Logging.txt
|
||||
|
||||
@ -215,8 +216,10 @@ Applications:
|
||||
Copyright (C) 2005 <susi23@mail.i2p>
|
||||
GPLv2 (or any later version)
|
||||
See licenses/LICENSE-GPLv2.txt
|
||||
Uses Apache Jakarta Standard Tag Library 1.1.2:
|
||||
See licenses/LICENSE-Apache2.0.txt
|
||||
Uses Glassfish Standard Tag Library (JSTL) 1.2:
|
||||
Common Development and Distribution License (CDDL) version 1.0 + GNU General Public License (GPL) version 2
|
||||
See https://glassfish.dev.java.net/public/CDDL+GPL.html
|
||||
See licenses/LICENSE-GPLv2.txt
|
||||
|
||||
SusiMail:
|
||||
Copyright (C) 2004-2005 <susi23@mail.i2p>
|
||||
@ -228,6 +231,10 @@ Applications:
|
||||
Bundles systray4j-2.4.1:
|
||||
See licenses/LICENSE-LGPLv2.1.txt
|
||||
|
||||
Tomcat 6.0.35:
|
||||
Copyright 1999-2011 The Apache Software Foundation
|
||||
See licenses/LICENSE-Apache2.0.txt
|
||||
See licenses/NOTICE-Tomcat.txt
|
||||
|
||||
|
||||
Other Applications and Libraries
|
||||
|
@ -84,7 +84,7 @@ public class Servlet extends HttpServlet {
|
||||
this.thread.setDaemon(true);
|
||||
this.thread.setName("Addressbook");
|
||||
this.thread.start();
|
||||
System.out.println("INFO: Starting Addressbook " + Daemon.VERSION);
|
||||
//System.out.println("INFO: Starting Addressbook " + Daemon.VERSION);
|
||||
//System.out.println("INFO: config root under " + args[0]);
|
||||
}
|
||||
|
||||
|
@ -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-util.jar" />
|
||||
</classpath>
|
||||
</depend>
|
||||
</target>
|
||||
@ -34,7 +35,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:../../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-util.jar:../../ministreaming/java/build/mstreaming.jar" >
|
||||
<compilerarg line="${javac.compilerargs}" />
|
||||
</javac>
|
||||
</target>
|
||||
|
@ -43,17 +43,16 @@ import org.klomp.snark.SnarkManager;
|
||||
import org.klomp.snark.Storage;
|
||||
import org.klomp.snark.TrackerClient;
|
||||
|
||||
import org.mortbay.http.HttpResponse;
|
||||
import org.mortbay.jetty.servlet.Default;
|
||||
import org.mortbay.util.Resource;
|
||||
import org.mortbay.util.URI;
|
||||
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://
|
||||
*/
|
||||
public class I2PSnarkServlet extends Default {
|
||||
public class I2PSnarkServlet extends DefaultServlet {
|
||||
private I2PAppContext _context;
|
||||
private Log _log;
|
||||
private SnarkManager _manager;
|
||||
@ -99,13 +98,17 @@ public class I2PSnarkServlet extends Default {
|
||||
* and we can't get any resources (like icons) out of the .war
|
||||
*/
|
||||
@Override
|
||||
protected Resource getResource(String pathInContext) throws IOException
|
||||
public Resource 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
|
||||
return _resourceBase.addPath(pathInContext);
|
||||
try {
|
||||
return _resourceBase.addPath(pathInContext);
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,10 +116,11 @@ public class I2PSnarkServlet extends Default {
|
||||
* @since 0.8.3
|
||||
*/
|
||||
@Override
|
||||
public void handleGet(HttpServletRequest request, HttpServletResponse response, String pathInContext, Resource resource, boolean endsWithSlash) throws ServletException, IOException {
|
||||
if (resource.getName().startsWith("jar:file:"))
|
||||
response.setHeader("Cache-Control", "max-age=86400"); // cache for a day
|
||||
super.handleGet(request, response, pathInContext, resource, endsWithSlash);
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
////////////////////////////////////
|
||||
//if (resource.getName().startsWith("jar:file:"))
|
||||
// response.setHeader("Cache-Control", "max-age=86400"); // cache for a day
|
||||
super.doGet(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,7 +148,7 @@ public class I2PSnarkServlet extends Default {
|
||||
// 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(HttpResponse.__405_Method_Not_Allowed);
|
||||
resp.sendError(405);
|
||||
return;
|
||||
}
|
||||
_themePath = "/themes/snark/" + _manager.getTheme() + '/';
|
||||
@ -157,20 +161,20 @@ public class I2PSnarkServlet extends Default {
|
||||
if (path.endsWith("/")) {
|
||||
// bypass the horrid Resource.getListHTML()
|
||||
String pathInfo = req.getPathInfo();
|
||||
String pathInContext = URI.addPaths(path, pathInfo);
|
||||
String pathInContext = URIUtil.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())) {
|
||||
resp.sendError(HttpResponse.__404_Not_Found);
|
||||
resp.sendError(404);
|
||||
} else {
|
||||
String base = URI.addPaths(req.getRequestURI(), "/");
|
||||
String base = URIUtil.addPaths(req.getRequestURI(), "/");
|
||||
String listing = getListHTML(resource, base, true, method.equals("POST") ? req.getParameterMap() : null);
|
||||
if (listing != null)
|
||||
resp.getWriter().write(listing);
|
||||
else // shouldn't happen
|
||||
resp.sendError(HttpResponse.__404_Not_Found);
|
||||
resp.sendError(404);
|
||||
}
|
||||
} else {
|
||||
super.service(req, resp);
|
||||
@ -1680,7 +1684,7 @@ public class I2PSnarkServlet extends Default {
|
||||
|
||||
StringBuilder buf=new StringBuilder(4096);
|
||||
buf.append(DOCTYPE + "<HTML><HEAD><TITLE>");
|
||||
String title = URI.decodePath(base);
|
||||
String title = URIUtil.decodePath(base);
|
||||
if (title.startsWith("/i2psnark/"))
|
||||
title = title.substring("/i2psnark/".length());
|
||||
|
||||
@ -1783,7 +1787,7 @@ public class I2PSnarkServlet extends Default {
|
||||
.append(_("Priority")).append("</th>");
|
||||
buf.append("</tr></thead>\n");
|
||||
buf.append("<tr><td colspan=\"" + (showPriority ? '4' : '3') + "\" class=\"ParentDir\"><A HREF=\"");
|
||||
buf.append(URI.addPaths(base,"../"));
|
||||
buf.append(URIUtil.addPaths(base,"../"));
|
||||
buf.append("\"><img alt=\"\" border=\"0\" src=\"" + _imgPath + "up.png\"> ")
|
||||
.append(_("Up to higher level directory")).append("</A></td></tr>\n");
|
||||
|
||||
@ -1793,7 +1797,7 @@ public class I2PSnarkServlet extends Default {
|
||||
boolean showSaveButton = false;
|
||||
for (int i=0 ; i< ls.length ; i++)
|
||||
{
|
||||
String encoded=URI.encodePath(ls[i]);
|
||||
String encoded=URIUtil.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
|
||||
@ -1849,9 +1853,9 @@ public class I2PSnarkServlet extends Default {
|
||||
}
|
||||
}
|
||||
|
||||
String path=URI.addPaths(base,encoded);
|
||||
String path=URIUtil.addPaths(base,encoded);
|
||||
if (item.isDirectory() && !path.endsWith("/"))
|
||||
path=URI.addPaths(path,"/");
|
||||
path=URIUtil.addPaths(path,"/");
|
||||
String icon = toIcon(item);
|
||||
|
||||
if (complete) {
|
||||
|
@ -31,6 +31,8 @@ public class RunStandalone {
|
||||
if (!workDirCreated)
|
||||
System.err.println("ERROR: Unable to create Jetty temporary work directory");
|
||||
|
||||
throw new RuntimeException("unsupported");
|
||||
/****
|
||||
try {
|
||||
_server = new Server("jetty-i2psnark.xml");
|
||||
// just blow up NPE if we don't have a context
|
||||
@ -39,13 +41,17 @@ public class RunStandalone {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
****/
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
throw new RuntimeException("unsupported");
|
||||
/****
|
||||
try {
|
||||
_server.stop();
|
||||
} catch (InterruptedException ie) {
|
||||
ie.printStackTrace();
|
||||
}
|
||||
****/
|
||||
}
|
||||
}
|
||||
|
@ -52,13 +52,11 @@
|
||||
</target>
|
||||
|
||||
|
||||
<!-- TODO: Move the web classes from the jar to the war - they are not part of the API
|
||||
- This will require sponge to rewrite some seedless stuff that uses it.
|
||||
-->
|
||||
<!-- The web classes are now in the war not the jar - they are not part of the API -->
|
||||
<target name="jar" depends="builddep, compile, jarUpToDate, listChangedFiles" unless="jar.uptodate" >
|
||||
<!-- set if unset -->
|
||||
<property name="workspace.changes.j.tr" value="" />
|
||||
<jar destfile="./build/i2ptunnel.jar" basedir="./build/obj" includes="**/*.class">
|
||||
<jar destfile="./build/i2ptunnel.jar" basedir="./build/obj" includes="**/*.class" excludes="**/EditBean.class **/IndexBean.class" >
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="net.i2p.i2ptunnel.I2PTunnel" />
|
||||
<attribute name="Class-Path" value="i2p.jar mstreaming.jar" />
|
||||
@ -68,6 +66,7 @@
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.j.tr}" />
|
||||
</manifest>
|
||||
</jar>
|
||||
<jar destfile="./build/temp-beans.jar" basedir="./build/obj" includes="**/EditBean.class **/IndexBean.class" />
|
||||
</target>
|
||||
|
||||
<target name="jarUpToDate">
|
||||
@ -129,9 +128,12 @@
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<!-- The web classes are now in the war not the jar - they are not part of the API -->
|
||||
<target name="war" depends="precompilejsp, bundle, warUpToDate, listChangedFiles2" unless="war.uptodate" >
|
||||
<!-- set if unset -->
|
||||
<property name="workspace.changes.w.tr" value="" />
|
||||
<copy file="build/obj/net/i2p/i2ptunnel/web/EditBean.class" todir="../jsp/WEB-INF/classes/net/i2p/i2ptunnel/web" />
|
||||
<copy file="build/obj/net/i2p/i2ptunnel/web/IndexBean.class" todir="../jsp/WEB-INF/classes/net/i2p/i2ptunnel/web" />
|
||||
<war destfile="build/i2ptunnel.war" webxml="../jsp/web-out.xml"
|
||||
basedir="../jsp/" excludes="web.xml, web-fragment.xml, web-out.xml, **/*.java, *.jsp">
|
||||
<manifest>
|
||||
@ -171,11 +173,14 @@
|
||||
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
|
||||
<pathelement location="../../jetty/jettylib/commons-logging.jar" />
|
||||
<pathelement location="../../jetty/jettylib/commons-el.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
|
||||
<pathelement location="../../jetty/jettylib/ant.jar" />
|
||||
<pathelement location="build/i2ptunnel.jar" />
|
||||
<pathelement location="build/temp-beans.jar" />
|
||||
</classpath>
|
||||
<arg value="-d" />
|
||||
<arg value="../jsp/WEB-INF/classes" />
|
||||
<arg value="-v" />
|
||||
<arg value="-p" />
|
||||
<arg value="net.i2p.i2ptunnel.jsp" />
|
||||
<arg value="-webinc" />
|
||||
@ -192,7 +197,9 @@
|
||||
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
|
||||
<pathelement location="../../jetty/jettylib/commons-logging.jar" />
|
||||
<pathelement location="../../jetty/jettylib/commons-el.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
|
||||
<pathelement location="build/i2ptunnel.jar" />
|
||||
<pathelement location="build/temp-beans.jar" />
|
||||
</classpath>
|
||||
</javac>
|
||||
<copy file="../jsp/web.xml" tofile="../jsp/web-out.xml" />
|
||||
|
@ -2,6 +2,7 @@
|
||||
// NOTE: Do the header carefully so there is no whitespace before the <?xml... line
|
||||
|
||||
%><%@page pageEncoding="UTF-8"
|
||||
%><%@page trimDirectiveWhitespaces="true"
|
||||
%><%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"
|
||||
%><%
|
||||
String tun = request.getParameter("tunnel");
|
||||
|
@ -1,4 +1,6 @@
|
||||
<%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"%><?xml version="1.0" encoding="UTF-8"?>
|
||||
<%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"
|
||||
%><%@page trimDirectiveWhitespaces="true"
|
||||
%><?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.EditBean" id="editBean" scope="request" />
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.Messages" id="intl" scope="request" />
|
||||
|
@ -1,4 +1,6 @@
|
||||
<%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"%><?xml version="1.0" encoding="UTF-8"?>
|
||||
<%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"
|
||||
%><%@page trimDirectiveWhitespaces="true"
|
||||
%><?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.EditBean" id="editBean" scope="request" />
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.Messages" id="intl" scope="request" />
|
||||
|
@ -6,6 +6,7 @@
|
||||
request.setCharacterEncoding("UTF-8");
|
||||
|
||||
%><%@page pageEncoding="UTF-8"
|
||||
%><%@page trimDirectiveWhitespaces="true"
|
||||
%><%@page contentType="text/html" import="net.i2p.i2ptunnel.web.IndexBean"
|
||||
%><?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
16
apps/jetty/apache-tomcat-deployer/NOTICE
Normal file
16
apps/jetty/apache-tomcat-deployer/NOTICE
Normal file
@ -0,0 +1,16 @@
|
||||
Apache Tomcat
|
||||
Copyright 1999-2011 The Apache Software Foundation
|
||||
|
||||
This product includes software developed by
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
The Windows Installer is built with the Nullsoft
|
||||
Scriptable Install Sysem (NSIS), which is
|
||||
open source software. The original software and
|
||||
related information is available at
|
||||
http://nsis.sourceforge.net.
|
||||
|
||||
Java compilation software for JSP pages is provided by Eclipse,
|
||||
which is open source software. The original software and
|
||||
related information is available at
|
||||
http://www.eclipse.org.
|
14
apps/jetty/apache-tomcat-deployer/README-i2p.txt
Normal file
14
apps/jetty/apache-tomcat-deployer/README-i2p.txt
Normal file
@ -0,0 +1,14 @@
|
||||
This is Apache Tomcat 6.x, supporting Servlet 2.5 and JSP 2.1.
|
||||
The Glassfish JSP 2.1 bundled in Jetty 6 is way too old.
|
||||
|
||||
Retrieved from the file
|
||||
apache-tomcat-6.0.35-deployer.tar.gz
|
||||
|
||||
minus the following files and directores:
|
||||
|
||||
build.xml
|
||||
deployer-howto.html
|
||||
images/*
|
||||
lib/catalina*
|
||||
LICENSE (see ../../../licenses/LICENSE-Apache2.0.txt, it's also inside every jar)
|
||||
RELEASE-NOTES
|
BIN
apps/jetty/apache-tomcat-deployer/lib/el-api.jar
Normal file
BIN
apps/jetty/apache-tomcat-deployer/lib/el-api.jar
Normal file
Binary file not shown.
BIN
apps/jetty/apache-tomcat-deployer/lib/jasper-el.jar
Normal file
BIN
apps/jetty/apache-tomcat-deployer/lib/jasper-el.jar
Normal file
Binary file not shown.
BIN
apps/jetty/apache-tomcat-deployer/lib/jasper.jar
Normal file
BIN
apps/jetty/apache-tomcat-deployer/lib/jasper.jar
Normal file
Binary file not shown.
BIN
apps/jetty/apache-tomcat-deployer/lib/jsp-api.jar
Normal file
BIN
apps/jetty/apache-tomcat-deployer/lib/jsp-api.jar
Normal file
Binary file not shown.
BIN
apps/jetty/apache-tomcat-deployer/lib/servlet-api.jar
Normal file
BIN
apps/jetty/apache-tomcat-deployer/lib/servlet-api.jar
Normal file
Binary file not shown.
BIN
apps/jetty/apache-tomcat-deployer/lib/tomcat-juli.jar
Normal file
BIN
apps/jetty/apache-tomcat-deployer/lib/tomcat-juli.jar
Normal file
Binary file not shown.
@ -1,12 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project basedir="." default="all" name="jetty">
|
||||
|
||||
<property name="jetty.base" value="jetty-5.1.15" />
|
||||
<property name="jetty.sha1" value="3a7a3de50f86f0cdb23c33aec632ea7f44132c5e" />
|
||||
<property name="jetty.filename" value="${jetty.base}.tgz" />
|
||||
<property name="jetty.url" value="http://dist.codehaus.org/jetty/jetty-5.1.x/${jetty.filename}" />
|
||||
<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.filename" value="${jetty.base}.zip" />
|
||||
<property name="jetty.url" value="http://dist.codehaus.org/jetty/${jetty.base}/${jetty.filename}" />
|
||||
<property name="verified.filename" value="verified.txt" />
|
||||
<property name="javac.compilerargs" value="" />
|
||||
<property name="tomcat.lib" value="apache-tomcat-deployer/lib" />
|
||||
|
||||
<target name="all" depends="build" />
|
||||
|
||||
@ -64,26 +66,76 @@
|
||||
</target>
|
||||
|
||||
<target name="extractJettylib" unless="jetty.zip.extracted" >
|
||||
<!-- for .tgz -->
|
||||
<!--
|
||||
<gunzip src="${jetty.filename}" dest="jetty.tar" />
|
||||
<untar src="jetty.tar" dest="." />
|
||||
-->
|
||||
<!-- for .zip -->
|
||||
<unzip src="${jetty.filename}" dest="." />
|
||||
<mkdir dir="jettylib" />
|
||||
<copy todir="jettylib" preservelastmodified="true" >
|
||||
<fileset dir="${jetty.base}/lib">
|
||||
<include name="*.jar" />
|
||||
</fileset>
|
||||
<fileset dir="${jetty.base}/ext">
|
||||
<include name="ant.jar" />
|
||||
<include name="commons-el.jar" />
|
||||
<include name="commons-logging.jar" />
|
||||
<include name="jasper-compiler.jar" />
|
||||
<include name="jasper-runtime.jar" />
|
||||
</fileset>
|
||||
</copy>
|
||||
<!-- We copy everything to names without the version numbers so we
|
||||
can update them later. Where there was something similar in Jetty 5,
|
||||
we use the same names so they will overwrite the Jetty 5 jar on upgrade.
|
||||
Otherwise we use the same name as the symlink in Ubuntu /usr/share/java.
|
||||
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
|
||||
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 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 file="${jetty.base}/lib/jsp-2.1/ant-1.6.5.jar" tofile="jettylib/ant.jar" />
|
||||
<delete file="jetty.tar" />
|
||||
<delete dir="${jetty.base}" />
|
||||
<!-- commons-logging.jar not in Jetty 6 but we have it in launch4j so copy it over, we need it
|
||||
for org.apache.jasper.JspC compiler
|
||||
-->
|
||||
<copy preservelastmodified="true" file="../../installer/lib/launch4j/lib/commons-logging.jar" todir="jettylib/" />
|
||||
<ant target="copyTomcatLib" />
|
||||
</target>
|
||||
|
||||
<!-- Tomcat.
|
||||
The glassfish jars bundled in Jetty 6 are way too old.
|
||||
For compatibility with very old I2P installations where the classpath
|
||||
was set individually in wrapper.config, we rename and combine the jars as follows:
|
||||
jasper.jar : jasper-runtime.jar
|
||||
jasper-el.jar + el-api.jar : commons-el.jar
|
||||
servlet-api.jar + jsp-api.jar : javax.servlet.jar
|
||||
tomcat-juli.jar : commons-logging.jar
|
||||
empty jar : jasper-compiler.jar
|
||||
Also, take NOTICE and LICENSE out of each one, we bundle those separately.
|
||||
-->
|
||||
<target name="copyTomcatLib" >
|
||||
<jar destfile="jettylib/jasper-runtime.jar" >
|
||||
<zipfileset excludes="META-INF/LICENSE META-INF/NOTICE" src="${tomcat.lib}/jasper.jar" />
|
||||
</jar>
|
||||
<jar destfile="jettylib/commons-el.jar" duplicate="preserve" >
|
||||
<zipfileset excludes="META-INF/LICENSE META-INF/NOTICE" src="${tomcat.lib}/jasper-el.jar" />
|
||||
<zipfileset excludes="META-INF/**/*" src="${tomcat.lib}/el-api.jar" />
|
||||
</jar>
|
||||
<jar destfile="jettylib/javax.servlet.jar" duplicate="preserve" >
|
||||
<zipfileset excludes="META-INF/LICENSE META-INF/NOTICE" src="${tomcat.lib}/servlet-api.jar" />
|
||||
<zipfileset excludes="META-INF/**/*" src="${tomcat.lib}/jsp-api.jar" />
|
||||
</jar>
|
||||
<jar destfile="jettylib/commons-logging.jar" >
|
||||
<zipfileset excludes="META-INF/LICENSE META-INF/NOTICE" src="${tomcat.lib}/tomcat-juli.jar" />
|
||||
</jar>
|
||||
<jar destfile="jettylib/jasper-compiler.jar" />
|
||||
</target>
|
||||
|
||||
<target name="build" depends="jar" />
|
||||
|
||||
<target name="builddep" />
|
||||
<target name="compile" depends="builddep, ensureJettylib" >
|
||||
<mkdir dir="./build" />
|
||||
@ -93,7 +145,7 @@
|
||||
debug="true" source="1.5" target="1.5"
|
||||
destdir="./build/obj"
|
||||
includeAntRuntime="false"
|
||||
classpath="./jettylib/commons-logging.jar:./jettylib/javax.servlet.jar:./jettylib/org.mortbay.jetty.jar" >
|
||||
classpath="../../core/java/build/i2p.jar:./jettylib/commons-logging.jar:./jettylib/javax.servlet.jar:./jettylib/org.mortbay.jetty.jar:./jettylib/jetty-util.jar" >
|
||||
<compilerarg line="${javac.compilerargs}" />
|
||||
</javac>
|
||||
</target>
|
||||
@ -112,10 +164,14 @@
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<!-- With Jetty 5 we replaced classes in the jar, but with Jetty 6 we
|
||||
put our stuff in its own jar so we can work with standard Jetty 6 packages
|
||||
-->
|
||||
<target name="jar" depends="compile, jarUpToDate, listChangedFiles" unless="jar.uptodate" >
|
||||
<!-- set if unset -->
|
||||
<property name="workspace.changes.tr" value="" />
|
||||
<jar destfile="./jettylib/org.mortbay.jetty.jar" basedir="./build/obj" includes="**/*.class" update="true" >
|
||||
<copy todir="build/obj" file="resources/log4j.properties" />
|
||||
<jar destfile="./jettylib/jetty-i2p.jar" basedir="./build/obj" includes="**/*.class log4j.properties" >
|
||||
<manifest>
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
@ -125,7 +181,7 @@
|
||||
</target>
|
||||
|
||||
<target name="jarUpToDate">
|
||||
<uptodate property="jar.uptodate" targetfile="jettylib/org.mortbay.jetty.jar" >
|
||||
<uptodate property="jar.uptodate" targetfile="jettylib/jetty-i2p.jar" >
|
||||
<srcfiles dir= "build/obj" includes="**/*.class" />
|
||||
</uptodate>
|
||||
<condition property="shouldListChanges" >
|
||||
|
175
apps/jetty/java/src/net/i2p/jetty/I2PLogger.java
Normal file
175
apps/jetty/java/src/net/i2p/jetty/I2PLogger.java
Normal file
@ -0,0 +1,175 @@
|
||||
// ========================================================================
|
||||
// Copyright 2004-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 net.i2p.jetty;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.log.Logger;
|
||||
|
||||
/**
|
||||
* Modified from Jetty 6.1.26 StdErrLog.java and Slf4jLog.java
|
||||
*
|
||||
* Usage: org.mortbay.log.Log.setLog(new I2PLogger(ctx));
|
||||
*
|
||||
* @since Jetty 6
|
||||
*/
|
||||
public class I2PLogger implements Logger
|
||||
{
|
||||
private final Log _log;
|
||||
|
||||
StringBuilder _buffer = new StringBuilder();
|
||||
|
||||
public I2PLogger()
|
||||
{
|
||||
this(I2PAppContext.getGlobalContext());
|
||||
}
|
||||
|
||||
public I2PLogger(I2PAppContext ctx)
|
||||
{
|
||||
_log = ctx.logManager().getLog(Server.class);
|
||||
if (System.getProperty("DEBUG") != null)
|
||||
setDebugEnabled(true);
|
||||
}
|
||||
|
||||
public boolean isDebugEnabled()
|
||||
{
|
||||
return _log.shouldLog(Log.DEBUG);
|
||||
}
|
||||
|
||||
public void setDebugEnabled(boolean enabled)
|
||||
{
|
||||
if (enabled)
|
||||
_log.setMinimumPriority(Log.DEBUG);
|
||||
else
|
||||
// LogManager.getDefaultLimit() returns a String, not worth it
|
||||
_log.setMinimumPriority(Log.ERROR);
|
||||
}
|
||||
|
||||
public void info(String msg,Object arg0, Object arg1)
|
||||
{
|
||||
if (arg0 == null && arg1 == null) {
|
||||
_log.info(msg);
|
||||
} else if (_log.shouldLog(Log.INFO)) {
|
||||
synchronized(_buffer) {
|
||||
format(msg,arg0,arg1);
|
||||
_log.info(_buffer.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void debug(String msg,Throwable th)
|
||||
{
|
||||
_log.debug(msg,th);
|
||||
}
|
||||
|
||||
public void debug(String msg,Object arg0, Object arg1)
|
||||
{
|
||||
if (arg0 == null && arg1 == null) {
|
||||
_log.debug(msg);
|
||||
} else if (_log.shouldLog(Log.DEBUG)) {
|
||||
synchronized(_buffer) {
|
||||
format(msg,arg0,arg1);
|
||||
_log.debug(_buffer.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void warn(String msg,Object arg0, Object arg1)
|
||||
{
|
||||
if (arg0 == null && arg1 == null) {
|
||||
_log.warn(msg);
|
||||
} else if (_log.shouldLog(Log.WARN)) {
|
||||
synchronized(_buffer) {
|
||||
format(msg,arg0,arg1);
|
||||
_log.warn(_buffer.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void warn(String msg, Throwable th)
|
||||
{
|
||||
// This doesn't cover ClassNotFoundException, etc.
|
||||
//if (th instanceof RuntimeException || th instanceof Error)
|
||||
_log.error(msg, th);
|
||||
//else
|
||||
// _log.warn(msg,th);
|
||||
}
|
||||
|
||||
private void format(String msg, Object arg0, Object arg1)
|
||||
{
|
||||
_buffer.setLength(0);
|
||||
int i0=msg==null?-1:msg.indexOf("{}");
|
||||
int i1=i0<0?-1:msg.indexOf("{}",i0+2);
|
||||
|
||||
if (i0>=0)
|
||||
{
|
||||
format(msg.substring(0,i0));
|
||||
format(String.valueOf(arg0==null?"null":arg0));
|
||||
|
||||
if (i1>=0)
|
||||
{
|
||||
format(msg.substring(i0+2,i1));
|
||||
format(String.valueOf(arg1==null?"null":arg1));
|
||||
format(msg.substring(i1+2));
|
||||
}
|
||||
else
|
||||
{
|
||||
format(msg.substring(i0+2));
|
||||
if (arg1!=null)
|
||||
{
|
||||
_buffer.append(' ');
|
||||
format(String.valueOf(arg1));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
format(msg);
|
||||
if (arg0!=null)
|
||||
{
|
||||
_buffer.append(' ');
|
||||
format(String.valueOf(arg0));
|
||||
}
|
||||
if (arg1!=null)
|
||||
{
|
||||
_buffer.append(' ');
|
||||
format(String.valueOf(arg1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void format(String msg)
|
||||
{
|
||||
if (msg == null)
|
||||
_buffer.append("null");
|
||||
else
|
||||
_buffer.append(msg);
|
||||
}
|
||||
|
||||
public Logger getLogger(String name)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "I2PLogger";
|
||||
}
|
||||
|
||||
|
||||
}
|
513
apps/jetty/java/src/net/i2p/jetty/I2PRequestLog.java
Normal file
513
apps/jetty/java/src/net/i2p/jetty/I2PRequestLog.java
Normal file
@ -0,0 +1,513 @@
|
||||
//========================================================================
|
||||
//Copyright 1997-2006 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 net.i2p.jetty;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
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;
|
||||
|
||||
/**
|
||||
* This {@link RequestLog} implementation outputs logs in the pseudo-standard NCSA common log format.
|
||||
* Configuration options allow a choice between the standard Common Log Format (as used in the 3 log format)
|
||||
* and the Combined Log Format (single log format).
|
||||
* This log format can be output by most web servers, and almost all web log analysis software can understand
|
||||
* these formats.
|
||||
*
|
||||
* ** I2P Mods **
|
||||
*
|
||||
* For Jetty 5, this extended NCSARequestLog to
|
||||
* override log() to put in the requestor's destination hash,
|
||||
* instead of 127.0.0.1,
|
||||
* which is placed in the X-I2P-DestHash field in the request headers
|
||||
* by I2PTunnelHTTPServer.
|
||||
* But we also had to modify NCSARequestLog to do so, to change private
|
||||
* fields to protected.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
|
||||
{
|
||||
private String _filename;
|
||||
private boolean _extended;
|
||||
private boolean _append;
|
||||
private int _retainDays;
|
||||
private boolean _closeOut;
|
||||
private boolean _preferProxiedForAddress;
|
||||
private String _logDateFormat="dd/MMM/yyyy:HH:mm:ss Z";
|
||||
private String _filenameDateFormat = null;
|
||||
private Locale _logLocale = Locale.getDefault();
|
||||
private String _logTimeZone = "GMT";
|
||||
private String[] _ignorePaths;
|
||||
private boolean _logLatency = false;
|
||||
private boolean _logCookies = false;
|
||||
private boolean _logServer = false;
|
||||
|
||||
private transient OutputStream _out;
|
||||
private transient OutputStream _fileOut;
|
||||
private transient DateCache _logDateCache;
|
||||
private transient PathMap _ignorePathMap;
|
||||
private transient Writer _writer;
|
||||
private transient ArrayList _buffers;
|
||||
private transient char[] _copy;
|
||||
|
||||
|
||||
public I2PRequestLog()
|
||||
{
|
||||
_extended = true;
|
||||
_append = true;
|
||||
_retainDays = 31;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param filename The filename for the request log. This may be in the format expected by {@link RolloverFileOutputStream}
|
||||
*/
|
||||
public I2PRequestLog(String filename)
|
||||
{
|
||||
_extended = true;
|
||||
_append = true;
|
||||
_retainDays = 31;
|
||||
setFilename(filename);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param filename The filename for the request log. This may be in the format expected by {@link RolloverFileOutputStream}
|
||||
*/
|
||||
public void setFilename(String filename)
|
||||
{
|
||||
if (filename != null)
|
||||
{
|
||||
filename = filename.trim();
|
||||
if (filename.length() == 0)
|
||||
filename = null;
|
||||
}
|
||||
_filename = filename;
|
||||
}
|
||||
|
||||
public String getFilename()
|
||||
{
|
||||
return _filename;
|
||||
}
|
||||
|
||||
public String getDatedFilename()
|
||||
{
|
||||
if (_fileOut instanceof RolloverFileOutputStream)
|
||||
return ((RolloverFileOutputStream)_fileOut).getDatedFilename();
|
||||
return null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param format Format for the timestamps in the log file. If not set,
|
||||
* the pre-formated request timestamp is used.
|
||||
*/
|
||||
public void setLogDateFormat(String format)
|
||||
{
|
||||
_logDateFormat = format;
|
||||
}
|
||||
|
||||
public String getLogDateFormat()
|
||||
{
|
||||
return _logDateFormat;
|
||||
}
|
||||
|
||||
public void setLogLocale(Locale logLocale)
|
||||
{
|
||||
_logLocale = logLocale;
|
||||
}
|
||||
|
||||
public Locale getLogLocale()
|
||||
{
|
||||
return _logLocale;
|
||||
}
|
||||
|
||||
public void setLogTimeZone(String tz)
|
||||
{
|
||||
_logTimeZone = tz;
|
||||
}
|
||||
|
||||
public String getLogTimeZone()
|
||||
{
|
||||
return _logTimeZone;
|
||||
}
|
||||
|
||||
public void setRetainDays(int retainDays)
|
||||
{
|
||||
_retainDays = retainDays;
|
||||
}
|
||||
|
||||
public int getRetainDays()
|
||||
{
|
||||
return _retainDays;
|
||||
}
|
||||
|
||||
public void setExtended(boolean extended)
|
||||
{
|
||||
_extended = extended;
|
||||
}
|
||||
|
||||
public boolean isExtended()
|
||||
{
|
||||
return _extended;
|
||||
}
|
||||
|
||||
public void setAppend(boolean append)
|
||||
{
|
||||
_append = append;
|
||||
}
|
||||
|
||||
public boolean isAppend()
|
||||
{
|
||||
return _append;
|
||||
}
|
||||
|
||||
public void setIgnorePaths(String[] ignorePaths)
|
||||
{
|
||||
_ignorePaths = ignorePaths;
|
||||
}
|
||||
|
||||
public String[] getIgnorePaths()
|
||||
{
|
||||
return _ignorePaths;
|
||||
}
|
||||
|
||||
public void setLogCookies(boolean logCookies)
|
||||
{
|
||||
_logCookies = logCookies;
|
||||
}
|
||||
|
||||
public boolean getLogCookies()
|
||||
{
|
||||
return _logCookies;
|
||||
}
|
||||
|
||||
public boolean getLogServer()
|
||||
{
|
||||
return _logServer;
|
||||
}
|
||||
|
||||
public void setLogServer(boolean logServer)
|
||||
{
|
||||
_logServer=logServer;
|
||||
}
|
||||
|
||||
public void setLogLatency(boolean logLatency)
|
||||
{
|
||||
_logLatency = logLatency;
|
||||
}
|
||||
|
||||
public boolean getLogLatency()
|
||||
{
|
||||
return _logLatency;
|
||||
}
|
||||
|
||||
public void setPreferProxiedForAddress(boolean preferProxiedForAddress)
|
||||
{
|
||||
_preferProxiedForAddress = preferProxiedForAddress;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void log(Request request, Response response)
|
||||
{
|
||||
if (!isStarted())
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
if (_ignorePathMap != null && _ignorePathMap.getMatch(request.getRequestURI()) != null)
|
||||
return;
|
||||
|
||||
if (_fileOut == null)
|
||||
return;
|
||||
|
||||
Utf8StringBuffer u8buf;
|
||||
StringBuffer buf;
|
||||
synchronized(_writer)
|
||||
{
|
||||
int size=_buffers.size();
|
||||
u8buf = size==0?new Utf8StringBuffer(160):(Utf8StringBuffer)_buffers.remove(size-1);
|
||||
buf = u8buf.getStringBuffer();
|
||||
}
|
||||
|
||||
synchronized(buf) // for efficiency until we can use StringBuilder
|
||||
{
|
||||
if (_logServer)
|
||||
{
|
||||
buf.append(request.getServerName());
|
||||
buf.append(' ');
|
||||
}
|
||||
|
||||
String addr = null;
|
||||
if (_preferProxiedForAddress)
|
||||
{
|
||||
addr = request.getHeader(HttpHeaders.X_FORWARDED_FOR);
|
||||
}
|
||||
|
||||
if (addr == null) {
|
||||
// TODO offer B32 option
|
||||
addr = request.getHeader("X-I2P-DestHash");
|
||||
if(addr != null)
|
||||
addr += ".i2p";
|
||||
else
|
||||
addr = request.getRemoteAddr();
|
||||
}
|
||||
|
||||
buf.append(addr);
|
||||
buf.append(" - ");
|
||||
String user = request.getRemoteUser();
|
||||
buf.append((user == null)? " - " : user);
|
||||
buf.append(" [");
|
||||
if (_logDateCache!=null)
|
||||
buf.append(_logDateCache.format(request.getTimeStamp()));
|
||||
else
|
||||
buf.append(request.getTimeStampBuffer().toString());
|
||||
|
||||
buf.append("] \"");
|
||||
buf.append(request.getMethod());
|
||||
buf.append(' ');
|
||||
|
||||
request.getUri().writeTo(u8buf);
|
||||
|
||||
buf.append(' ');
|
||||
buf.append(request.getProtocol());
|
||||
buf.append("\" ");
|
||||
int status = response.getStatus();
|
||||
if (status<=0)
|
||||
status=404;
|
||||
buf.append((char)('0'+((status/100)%10)));
|
||||
buf.append((char)('0'+((status/10)%10)));
|
||||
buf.append((char)('0'+(status%10)));
|
||||
|
||||
|
||||
long responseLength=response.getContentCount();
|
||||
if (responseLength >=0)
|
||||
{
|
||||
buf.append(' ');
|
||||
if (responseLength > 99999)
|
||||
buf.append(Long.toString(responseLength));
|
||||
else
|
||||
{
|
||||
if (responseLength > 9999)
|
||||
buf.append((char)('0' + ((responseLength / 10000)%10)));
|
||||
if (responseLength > 999)
|
||||
buf.append((char)('0' + ((responseLength /1000)%10)));
|
||||
if (responseLength > 99)
|
||||
buf.append((char)('0' + ((responseLength / 100)%10)));
|
||||
if (responseLength > 9)
|
||||
buf.append((char)('0' + ((responseLength / 10)%10)));
|
||||
buf.append((char)('0' + (responseLength)%10));
|
||||
}
|
||||
buf.append(' ');
|
||||
}
|
||||
else
|
||||
buf.append(" - ");
|
||||
|
||||
}
|
||||
|
||||
if (!_extended && !_logCookies && !_logLatency)
|
||||
{
|
||||
synchronized(_writer)
|
||||
{
|
||||
buf.append(StringUtil.__LINE_SEPARATOR);
|
||||
int l=buf.length();
|
||||
if (l>_copy.length)
|
||||
l=_copy.length;
|
||||
buf.getChars(0,l,_copy,0);
|
||||
_writer.write(_copy,0,l);
|
||||
_writer.flush();
|
||||
u8buf.reset();
|
||||
_buffers.add(u8buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
synchronized(_writer)
|
||||
{
|
||||
int l=buf.length();
|
||||
if (l>_copy.length)
|
||||
l=_copy.length;
|
||||
buf.getChars(0,l,_copy,0);
|
||||
_writer.write(_copy,0,l);
|
||||
u8buf.reset();
|
||||
_buffers.add(u8buf);
|
||||
|
||||
// TODO do outside synchronized scope
|
||||
if (_extended)
|
||||
logExtended(request, response, _writer);
|
||||
|
||||
// TODO do outside synchronized scope
|
||||
if (_logCookies)
|
||||
{
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if (cookies == null || cookies.length == 0)
|
||||
_writer.write(" -");
|
||||
else
|
||||
{
|
||||
_writer.write(" \"");
|
||||
for (int i = 0; i < cookies.length; i++)
|
||||
{
|
||||
if (i != 0)
|
||||
_writer.write(';');
|
||||
_writer.write(cookies[i].getName());
|
||||
_writer.write('=');
|
||||
_writer.write(cookies[i].getValue());
|
||||
}
|
||||
_writer.write('\"');
|
||||
}
|
||||
}
|
||||
|
||||
if (_logLatency)
|
||||
{
|
||||
_writer.write(' ');
|
||||
_writer.write(TypeUtil.toString(System.currentTimeMillis() - request.getTimeStamp()));
|
||||
}
|
||||
|
||||
_writer.write(StringUtil.__LINE_SEPARATOR);
|
||||
_writer.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
Log.warn(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected void logExtended(Request request,
|
||||
Response response,
|
||||
Writer writer) throws IOException
|
||||
{
|
||||
String referer = request.getHeader(HttpHeaders.REFERER);
|
||||
if (referer == null)
|
||||
writer.write("\"-\" ");
|
||||
else
|
||||
{
|
||||
writer.write('"');
|
||||
writer.write(referer);
|
||||
writer.write("\" ");
|
||||
}
|
||||
|
||||
String agent = request.getHeader(HttpHeaders.USER_AGENT);
|
||||
if (agent == null)
|
||||
writer.write("\"-\" ");
|
||||
else
|
||||
{
|
||||
writer.write('"');
|
||||
writer.write(agent);
|
||||
writer.write('"');
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
if (_logDateFormat!=null)
|
||||
{
|
||||
_logDateCache = new DateCache(_logDateFormat, _logLocale);
|
||||
_logDateCache.setTimeZoneID(_logTimeZone);
|
||||
}
|
||||
|
||||
if (_filename != null)
|
||||
{
|
||||
_fileOut = new RolloverFileOutputStream(_filename,_append,_retainDays,TimeZone.getTimeZone(_logTimeZone),_filenameDateFormat,null);
|
||||
_closeOut = true;
|
||||
Log.info("Opened "+getDatedFilename());
|
||||
}
|
||||
else
|
||||
_fileOut = System.err;
|
||||
|
||||
_out = _fileOut;
|
||||
|
||||
if (_ignorePaths != null && _ignorePaths.length > 0)
|
||||
{
|
||||
_ignorePathMap = new PathMap();
|
||||
for (int i = 0; i < _ignorePaths.length; i++)
|
||||
_ignorePathMap.put(_ignorePaths[i], _ignorePaths[i]);
|
||||
}
|
||||
else
|
||||
_ignorePathMap = null;
|
||||
|
||||
_writer = new OutputStreamWriter(_out);
|
||||
_buffers = new ArrayList();
|
||||
_copy = new char[1024];
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
super.doStop();
|
||||
try {if (_writer != null) _writer.flush();} catch (IOException e) {Log.ignore(e);}
|
||||
if (_out != null && _closeOut)
|
||||
try {_out.close();} catch (IOException e) {Log.ignore(e);}
|
||||
|
||||
_out = null;
|
||||
_fileOut = null;
|
||||
_closeOut = false;
|
||||
_logDateCache = null;
|
||||
_writer = null;
|
||||
_buffers = null;
|
||||
_copy = null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return the log File Date Format
|
||||
*/
|
||||
public String getFilenameDateFormat()
|
||||
{
|
||||
return _filenameDateFormat;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the log file date format.
|
||||
* see RolloverFileOutputStream(String, boolean, int, TimeZone, String, String)
|
||||
* @param logFileDateFormat the logFileDateFormat to pass to RolloverFileOutputStream
|
||||
*/
|
||||
public void setFilenameDateFormat(String logFileDateFormat)
|
||||
{
|
||||
_filenameDateFormat=logFileDateFormat;
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,182 +0,0 @@
|
||||
// ========================================================================
|
||||
// $Id: NCSARequestLog.java,v 1.35 2005/08/13 00:01:24 gregwilkins Exp $
|
||||
// Copyright 2000-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.mortbay.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.mortbay.log.LogFactory;
|
||||
import org.mortbay.util.DateCache;
|
||||
import org.mortbay.util.LogSupport;
|
||||
import org.mortbay.util.RolloverFileOutputStream;
|
||||
import org.mortbay.util.StringUtil;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** NCSA HTTP Request Log.
|
||||
*
|
||||
* Override log() to put in the requestor's destination hash,
|
||||
* instead of 127.0.0.1,
|
||||
* which is placed in the X-I2P-DestHash field in the request headers
|
||||
* by I2PTunnelHTTPServer.
|
||||
*
|
||||
* NCSA common or NCSA extended (combined) request log.
|
||||
* @version $Id: NCSARequestLog.java,v 1.35 2005/08/13 00:01:24 gregwilkins Exp $
|
||||
* @author Tony Thompson
|
||||
* @author Greg Wilkins
|
||||
*/
|
||||
public class I2PRequestLog extends NCSARequestLog
|
||||
{
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
*/
|
||||
public I2PRequestLog()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param filename Filename, which can be in
|
||||
* rolloverFileOutputStream format
|
||||
* @see org.mortbay.util.RolloverFileOutputStream
|
||||
* @exception IOException
|
||||
*/
|
||||
public I2PRequestLog(String filename)
|
||||
throws IOException
|
||||
{
|
||||
super(filename);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Log a request.
|
||||
* @param request The request
|
||||
* @param response The response to this request.
|
||||
* @param responseLength The bytes written to the response.
|
||||
*/
|
||||
public void log(HttpRequest request,
|
||||
HttpResponse response,
|
||||
int responseLength)
|
||||
{
|
||||
try{
|
||||
// ignore ignorables
|
||||
if (_ignorePathMap != null &&
|
||||
_ignorePathMap.getMatch(request.getPath()) != null)
|
||||
return;
|
||||
|
||||
// log the rest
|
||||
if (_fileOut==null)
|
||||
return;
|
||||
|
||||
StringBuilder buf = new StringBuilder(160);
|
||||
|
||||
String addr = request.getField("X-I2P-DestHash");
|
||||
if(addr != null)
|
||||
buf.append(addr).append(".i2p");
|
||||
else
|
||||
buf.append(request.getRemoteAddr());
|
||||
|
||||
buf.append(" - ");
|
||||
String user = request.getAuthUser();
|
||||
buf.append((user==null)?"-":user);
|
||||
buf.append(" [");
|
||||
buf.append(_logDateCache.format(request.getTimeStamp()));
|
||||
buf.append("] \"");
|
||||
buf.append(request.getMethod());
|
||||
buf.append(' ');
|
||||
buf.append(request.getURI());
|
||||
buf.append(' ');
|
||||
buf.append(request.getVersion());
|
||||
buf.append("\" ");
|
||||
int status=response.getStatus();
|
||||
buf.append((char)('0'+((status/100)%10)));
|
||||
buf.append((char)('0'+((status/10)%10)));
|
||||
buf.append((char)('0'+(status%10)));
|
||||
if (responseLength>=0)
|
||||
{
|
||||
buf.append(' ');
|
||||
if (responseLength>99999)
|
||||
buf.append(Integer.toString(responseLength));
|
||||
else
|
||||
{
|
||||
if (responseLength>9999)
|
||||
buf.append((char)('0'+((responseLength/10000)%10)));
|
||||
if (responseLength>999)
|
||||
buf.append((char)('0'+((responseLength/1000)%10)));
|
||||
if (responseLength>99)
|
||||
buf.append((char)('0'+((responseLength/100)%10)));
|
||||
if (responseLength>9)
|
||||
buf.append((char)('0'+((responseLength/10)%10)));
|
||||
buf.append((char)('0'+(responseLength%10)));
|
||||
}
|
||||
buf.append(' ');
|
||||
}
|
||||
else
|
||||
buf.append(" - ");
|
||||
|
||||
String log =buf.toString();
|
||||
synchronized(_writer)
|
||||
{
|
||||
_writer.write(log);
|
||||
if (isExtended())
|
||||
{
|
||||
logExtended(request,response,_writer);
|
||||
if (!getLogCookies())
|
||||
_writer.write(" -");
|
||||
}
|
||||
|
||||
if (getLogCookies())
|
||||
{
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if (cookies==null || cookies.length==0)
|
||||
_writer.write(" -");
|
||||
else
|
||||
{
|
||||
_writer.write(" \"");
|
||||
for (int i=0;i<cookies.length;i++)
|
||||
{
|
||||
if (i!=0)
|
||||
_writer.write(';');
|
||||
_writer.write(cookies[i].getName());
|
||||
_writer.write('=');
|
||||
_writer.write(cookies[i].getValue());
|
||||
}
|
||||
_writer.write("\"");
|
||||
}
|
||||
}
|
||||
|
||||
if (getLogLatency())
|
||||
_writer.write(" "+(System.currentTimeMillis()-request.getTimeStamp()));
|
||||
|
||||
_writer.write(StringUtil.__LINE_SEPARATOR);
|
||||
_writer.flush();
|
||||
}
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,505 +0,0 @@
|
||||
// ========================================================================
|
||||
// $Id: NCSARequestLog.java,v 1.35 2005/08/13 00:01:24 gregwilkins Exp $
|
||||
// Copyright 2000-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.mortbay.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.mortbay.log.LogFactory;
|
||||
import org.mortbay.util.DateCache;
|
||||
import org.mortbay.util.LogSupport;
|
||||
import org.mortbay.util.RolloverFileOutputStream;
|
||||
import org.mortbay.util.StringUtil;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** NCSA HTTP Request Log.
|
||||
* NCSA common or NCSA extended (combined) request log.
|
||||
*
|
||||
* Taken from 5.1.12 source and modded to change some private vars to protected
|
||||
* so we can extend it for I2P.
|
||||
*
|
||||
* @version $Id: NCSARequestLog.java,v 1.35 2005/08/13 00:01:24 gregwilkins Exp $
|
||||
* @author Tony Thompson
|
||||
* @author Greg Wilkins
|
||||
*/
|
||||
public class NCSARequestLog implements RequestLog
|
||||
{
|
||||
protected static Log log = LogFactory.getLog(NCSARequestLog.class);
|
||||
|
||||
private String _filename;
|
||||
private boolean _extended;
|
||||
private boolean _append;
|
||||
private int _retainDays;
|
||||
private boolean _closeOut;
|
||||
private boolean _preferProxiedForAddress;
|
||||
private String _logDateFormat="dd/MMM/yyyy:HH:mm:ss ZZZ";
|
||||
private Locale _logLocale=Locale.getDefault();
|
||||
private String _logTimeZone=TimeZone.getDefault().getID();
|
||||
private String[] _ignorePaths;
|
||||
private boolean _logLatency=false;
|
||||
private boolean _logCookies=false;
|
||||
|
||||
protected transient OutputStream _out;
|
||||
protected transient OutputStream _fileOut;
|
||||
protected transient DateCache _logDateCache;
|
||||
protected transient PathMap _ignorePathMap;
|
||||
protected transient Writer _writer;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
*/
|
||||
public NCSARequestLog()
|
||||
{
|
||||
_extended=true;
|
||||
_append=true;
|
||||
_retainDays=31;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param filename Filename, which can be in
|
||||
* rolloverFileOutputStream format
|
||||
* @see org.mortbay.util.RolloverFileOutputStream
|
||||
* @exception IOException
|
||||
*/
|
||||
public NCSARequestLog(String filename)
|
||||
throws IOException
|
||||
{
|
||||
_extended=true;
|
||||
_append=true;
|
||||
_retainDays=31;
|
||||
setFilename(filename);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the log filename.
|
||||
* @see NCSARequestLog#setRetainDays(int)
|
||||
* @param filename The filename to use. If the filename contains the
|
||||
* string "yyyy_mm_dd", then a RolloverFileOutputStream is used and the
|
||||
* log is rolled over nightly and aged according setRetainDays. If no
|
||||
* filename is set or a null filename
|
||||
* passed, then requests are logged to System.err.
|
||||
*/
|
||||
public void setFilename(String filename)
|
||||
{
|
||||
if (filename!=null)
|
||||
{
|
||||
filename=filename.trim();
|
||||
if (filename.length()==0)
|
||||
filename=null;
|
||||
}
|
||||
_filename=filename;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the log filename.
|
||||
* @see NCSARequestLog#getDatedFilename()
|
||||
* @return The log filename without any date expansion.
|
||||
*/
|
||||
public String getFilename()
|
||||
{
|
||||
return _filename;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the dated log filename.
|
||||
* @see NCSARequestLog#getFilename()
|
||||
* @return The log filename with any date encoding expanded.
|
||||
*/
|
||||
public String getDatedFilename()
|
||||
{
|
||||
if (_fileOut instanceof RolloverFileOutputStream)
|
||||
return ((RolloverFileOutputStream)_fileOut).getDatedFilename();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param format The date format to use within the log file.
|
||||
*/
|
||||
public void setLogDateFormat(String format)
|
||||
{
|
||||
_logDateFormat=format;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The date format to use within the log file.
|
||||
*/
|
||||
public String getLogDateFormat()
|
||||
{
|
||||
return _logDateFormat;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param tz The date format timezone to use within the log file.
|
||||
*/
|
||||
public void setLogTimeZone(String tz)
|
||||
{
|
||||
_logTimeZone=tz;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The date format timezone to use within the log file.
|
||||
*/
|
||||
public String getLogTimeZone()
|
||||
{
|
||||
return _logTimeZone;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The number of days to retain rollovered log files.
|
||||
*/
|
||||
public int getRetainDays()
|
||||
{
|
||||
return _retainDays;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param retainDays The number of days to retain rollovered log files.
|
||||
*/
|
||||
public void setRetainDays(int retainDays)
|
||||
{
|
||||
_retainDays = retainDays;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return True if NCSA extended format is to be used.
|
||||
*/
|
||||
public boolean isExtended()
|
||||
{
|
||||
return _extended;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param e True if NCSA extended format is to be used.
|
||||
*/
|
||||
public void setExtended(boolean e)
|
||||
{
|
||||
_extended=e;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return True if logs are appended to existing log files.
|
||||
*/
|
||||
public boolean isAppend()
|
||||
{
|
||||
return _append;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param a True if logs are appended to existing log files.
|
||||
*/
|
||||
public void setAppend(boolean a)
|
||||
{
|
||||
_append=a;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @deprecated ignored
|
||||
*/
|
||||
public void setBuffered(boolean b)
|
||||
{}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set which paths to ignore.
|
||||
*
|
||||
* @param ignorePaths Array of path specifications to ignore
|
||||
*/
|
||||
public void setIgnorePaths(String[] ignorePaths)
|
||||
{
|
||||
// Contributed by Martin Vilcans (martin@jadestone.se)
|
||||
_ignorePaths = ignorePaths;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String[] getIgnorePaths()
|
||||
{
|
||||
return _ignorePaths;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return Returns the logCookies.
|
||||
*/
|
||||
public boolean getLogCookies()
|
||||
{
|
||||
return _logCookies;
|
||||
}
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param logCookies The logCookies to set.
|
||||
*/
|
||||
public void setLogCookies(boolean logCookies)
|
||||
{
|
||||
_logCookies = logCookies;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return Returns true if logging latency
|
||||
*/
|
||||
public boolean getLogLatency()
|
||||
{
|
||||
return _logLatency;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param logLatency If true, latency is logged at the end of the log line
|
||||
*/
|
||||
public void setLogLatency(boolean logLatency)
|
||||
{
|
||||
_logLatency = logLatency;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Prefer to log the proxied-for IP address (if present in
|
||||
* the request header) over the native requester IP address.
|
||||
* Useful in reverse-proxy situations when you'd rather see
|
||||
* the IP address of the host before the most recent proxy
|
||||
* server, as opposed to your own proxy server(s) every time.
|
||||
*
|
||||
* jlrobins@socialserve.com, March 2004.
|
||||
**/
|
||||
public void setPreferProxiedForAddress(boolean value)
|
||||
{
|
||||
_preferProxiedForAddress = value;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void start()
|
||||
throws Exception
|
||||
{
|
||||
_logDateCache=new DateCache(_logDateFormat,_logLocale);
|
||||
_logDateCache.setTimeZoneID(_logTimeZone);
|
||||
|
||||
if (_filename != null)
|
||||
{
|
||||
_fileOut=new RolloverFileOutputStream(_filename,_append,_retainDays);
|
||||
_closeOut=true;
|
||||
}
|
||||
else
|
||||
_fileOut=System.err;
|
||||
|
||||
_out=_fileOut;
|
||||
|
||||
if (_ignorePaths!=null && _ignorePaths.length>0)
|
||||
{
|
||||
_ignorePathMap=new PathMap();
|
||||
for (int i=0;i<_ignorePaths.length;i++)
|
||||
_ignorePathMap.put(_ignorePaths[i],_ignorePaths[i]);
|
||||
}
|
||||
else
|
||||
_ignorePathMap=null;
|
||||
|
||||
_writer=new OutputStreamWriter(_out);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isStarted()
|
||||
{
|
||||
return _fileOut!=null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void stop()
|
||||
{
|
||||
try{if (_writer!=null)_writer.flush();} catch (IOException e){LogSupport.ignore(log,e);}
|
||||
if (_out!=null && _closeOut)
|
||||
try{_out.close();}catch(IOException e){LogSupport.ignore(log,e);}
|
||||
_out=null;
|
||||
_fileOut=null;
|
||||
_closeOut=false;
|
||||
_logDateCache=null;
|
||||
_writer=null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Log a request.
|
||||
* @param request The request
|
||||
* @param response The response to this request.
|
||||
* @param responseLength The bytes written to the response.
|
||||
*/
|
||||
public void log(HttpRequest request,
|
||||
HttpResponse response,
|
||||
int responseLength)
|
||||
{
|
||||
try{
|
||||
// ignore ignorables
|
||||
if (_ignorePathMap != null &&
|
||||
_ignorePathMap.getMatch(request.getPath()) != null)
|
||||
return;
|
||||
|
||||
// log the rest
|
||||
if (_fileOut==null)
|
||||
return;
|
||||
|
||||
StringBuffer buf = new StringBuffer(160);
|
||||
|
||||
String addr = null;
|
||||
if(_preferProxiedForAddress)
|
||||
{
|
||||
// If header is not present, addr will remain null ...
|
||||
addr = request.getField(HttpFields.__XForwardedFor);
|
||||
}
|
||||
if(addr == null)
|
||||
addr = request.getRemoteAddr();
|
||||
buf.append(addr);
|
||||
|
||||
buf.append(" - ");
|
||||
String user = request.getAuthUser();
|
||||
buf.append((user==null)?"-":user);
|
||||
buf.append(" [");
|
||||
buf.append(_logDateCache.format(request.getTimeStamp()));
|
||||
buf.append("] \"");
|
||||
buf.append(request.getMethod());
|
||||
buf.append(' ');
|
||||
buf.append(request.getURI());
|
||||
buf.append(' ');
|
||||
buf.append(request.getVersion());
|
||||
buf.append("\" ");
|
||||
int status=response.getStatus();
|
||||
buf.append((char)('0'+((status/100)%10)));
|
||||
buf.append((char)('0'+((status/10)%10)));
|
||||
buf.append((char)('0'+(status%10)));
|
||||
if (responseLength>=0)
|
||||
{
|
||||
buf.append(' ');
|
||||
if (responseLength>99999)
|
||||
buf.append(Integer.toString(responseLength));
|
||||
else
|
||||
{
|
||||
if (responseLength>9999)
|
||||
buf.append((char)('0'+((responseLength/10000)%10)));
|
||||
if (responseLength>999)
|
||||
buf.append((char)('0'+((responseLength/1000)%10)));
|
||||
if (responseLength>99)
|
||||
buf.append((char)('0'+((responseLength/100)%10)));
|
||||
if (responseLength>9)
|
||||
buf.append((char)('0'+((responseLength/10)%10)));
|
||||
buf.append((char)('0'+(responseLength%10)));
|
||||
}
|
||||
buf.append(' ');
|
||||
}
|
||||
else
|
||||
buf.append(" - ");
|
||||
|
||||
String log =buf.toString();
|
||||
synchronized(_writer)
|
||||
{
|
||||
_writer.write(log);
|
||||
if (_extended)
|
||||
{
|
||||
logExtended(request,response,_writer);
|
||||
if (!_logCookies)
|
||||
_writer.write(" -");
|
||||
}
|
||||
|
||||
if (_logCookies)
|
||||
{
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if (cookies==null || cookies.length==0)
|
||||
_writer.write(" -");
|
||||
else
|
||||
{
|
||||
_writer.write(" \"");
|
||||
for (int i=0;i<cookies.length;i++)
|
||||
{
|
||||
if (i!=0)
|
||||
_writer.write(';');
|
||||
_writer.write(cookies[i].getName());
|
||||
_writer.write('=');
|
||||
_writer.write(cookies[i].getValue());
|
||||
}
|
||||
_writer.write("\"");
|
||||
}
|
||||
}
|
||||
|
||||
if (_logLatency)
|
||||
_writer.write(" "+(System.currentTimeMillis()-request.getTimeStamp()));
|
||||
|
||||
_writer.write(StringUtil.__LINE_SEPARATOR);
|
||||
_writer.flush();
|
||||
}
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,e);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Log Extended fields.
|
||||
* This method can be extended by a derived class to add extened fields to
|
||||
* each log entry. It is called by the log method after all standard
|
||||
* fields have been added, but before the line terminator.
|
||||
* Derived implementations should write extra fields to the Writer
|
||||
* provided.
|
||||
* The default implementation writes the referer and user agent.
|
||||
* @param request The request to log.
|
||||
* @param response The response to log.
|
||||
* @param log The writer to write the extra fields to.
|
||||
* @exception IOException Problem writing log
|
||||
*/
|
||||
protected void logExtended(HttpRequest request,
|
||||
HttpResponse response,
|
||||
Writer log)
|
||||
throws IOException
|
||||
{
|
||||
String referer = request.getField(HttpFields.__Referer);
|
||||
if(referer==null)
|
||||
log.write("\"-\" ");
|
||||
else
|
||||
{
|
||||
log.write('"');
|
||||
log.write(referer);
|
||||
log.write("\" ");
|
||||
}
|
||||
|
||||
String agent = request.getField(HttpFields.__UserAgent);
|
||||
if(agent==null)
|
||||
log.write("\"-\"");
|
||||
else
|
||||
{
|
||||
log.write('"');
|
||||
log.write(agent);
|
||||
log.write('"');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,809 +0,0 @@
|
||||
// ========================================================================
|
||||
// $Id: ResourceHandler.java,v 1.66 2005/08/24 08:18:17 gregwilkins Exp $
|
||||
// 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.mortbay.http.handler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.mortbay.log.LogFactory;
|
||||
import org.mortbay.http.HttpException;
|
||||
import org.mortbay.http.HttpFields;
|
||||
import org.mortbay.http.HttpRequest;
|
||||
import org.mortbay.http.HttpResponse;
|
||||
import org.mortbay.http.InclusiveByteRange;
|
||||
import org.mortbay.http.MultiPartResponse;
|
||||
import org.mortbay.http.ResourceCache;
|
||||
import org.mortbay.util.CachedResource;
|
||||
import org.mortbay.util.IO;
|
||||
import org.mortbay.util.LogSupport;
|
||||
import org.mortbay.util.Resource;
|
||||
import org.mortbay.util.StringMap;
|
||||
import org.mortbay.util.TypeUtil;
|
||||
import org.mortbay.util.URI;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Handler to serve files and resources.
|
||||
* Serves files from a given resource URL base and implements
|
||||
* the GET, HEAD, DELETE, OPTIONS, PUT, MOVE methods and the
|
||||
* IfModifiedSince and IfUnmodifiedSince header fields.
|
||||
* A simple memory cache is also provided to reduce file I/O.
|
||||
* HTTP/1.1 ranges are supported.
|
||||
*
|
||||
* @version $Id: ResourceHandler.java,v 1.66 2005/08/24 08:18:17 gregwilkins Exp $
|
||||
* @author Nuno Pregui?a (sorry, wasn't UTF-8)
|
||||
* @author Greg Wilkins
|
||||
*/
|
||||
public class ResourceHandler extends AbstractHttpHandler
|
||||
{
|
||||
private static Log log = LogFactory.getLog(ResourceHandler.class);
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
private boolean _acceptRanges=true;
|
||||
private boolean _redirectWelcomeFiles ;
|
||||
private String[] _methods=null;
|
||||
private String _allowed;
|
||||
private boolean _dirAllowed=true;
|
||||
private int _minGzipLength =-1;
|
||||
private StringMap _methodMap = new StringMap();
|
||||
{
|
||||
setAllowedMethods(new String[]
|
||||
{
|
||||
HttpRequest.__GET,
|
||||
HttpRequest.__POST,
|
||||
HttpRequest.__HEAD,
|
||||
HttpRequest.__OPTIONS,
|
||||
HttpRequest.__TRACE
|
||||
});
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/** Construct a ResourceHandler.
|
||||
*/
|
||||
public ResourceHandler()
|
||||
{}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
public synchronized void start()
|
||||
throws Exception
|
||||
{
|
||||
super.start();
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
public void stop()
|
||||
throws InterruptedException
|
||||
{
|
||||
super.stop();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String[] getAllowedMethods()
|
||||
{
|
||||
return _methods;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setAllowedMethods(String[] methods)
|
||||
{
|
||||
StringBuffer b = new StringBuffer();
|
||||
_methods=methods;
|
||||
_methodMap.clear();
|
||||
for (int i=0;i<methods.length;i++)
|
||||
{
|
||||
_methodMap.put(methods[i],methods[i]);
|
||||
if (i>0)
|
||||
b.append(',');
|
||||
b.append(methods[i]);
|
||||
}
|
||||
_allowed=b.toString();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isMethodAllowed(String method)
|
||||
{
|
||||
return _methodMap.get(method)!=null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String getAllowedString()
|
||||
{
|
||||
return _allowed;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isDirAllowed()
|
||||
{
|
||||
return _dirAllowed;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setDirAllowed(boolean dirAllowed)
|
||||
{
|
||||
_dirAllowed = dirAllowed;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isAcceptRanges()
|
||||
{
|
||||
return _acceptRanges;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return True if welcome files are redirected to. False if forward is used.
|
||||
*/
|
||||
public boolean getRedirectWelcome()
|
||||
{
|
||||
return _redirectWelcomeFiles;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param redirectWelcome True if welcome files are redirected to. False
|
||||
* if forward is used.
|
||||
*/
|
||||
public void setRedirectWelcome(boolean redirectWelcome)
|
||||
{
|
||||
_redirectWelcomeFiles = redirectWelcome;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set if the handler accepts range requests.
|
||||
* Default is false;
|
||||
* @param ar True if the handler should accept ranges
|
||||
*/
|
||||
public void setAcceptRanges(boolean ar)
|
||||
{
|
||||
_acceptRanges=ar;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get minimum content length for GZIP encoding.
|
||||
* @return Minimum length of content for gzip encoding or -1 if disabled.
|
||||
*/
|
||||
public int getMinGzipLength()
|
||||
{
|
||||
return _minGzipLength;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set minimum content length for GZIP encoding.
|
||||
* @param minGzipLength If set to a positive integer, then static content
|
||||
* larger than this will be served as gzip content encoded
|
||||
* if a matching resource is found ending with ".gz"
|
||||
*/
|
||||
public void setMinGzipLength(int minGzipLength)
|
||||
{
|
||||
_minGzipLength = minGzipLength;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** get Resource to serve.
|
||||
* Map a path to a resource. The default implementation calls
|
||||
* HttpContext.getResource but derived handers may provide
|
||||
* their own mapping.
|
||||
* @param pathInContext The path to find a resource for.
|
||||
* @return The resource to serve.
|
||||
*/
|
||||
protected Resource getResource(String pathInContext)
|
||||
throws IOException
|
||||
{
|
||||
return getHttpContext().getResource(pathInContext);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void handle(String pathInContext,
|
||||
String pathParams,
|
||||
HttpRequest request,
|
||||
HttpResponse response)
|
||||
throws HttpException, IOException
|
||||
{
|
||||
Resource resource = getResource(pathInContext);
|
||||
if (resource==null)
|
||||
return;
|
||||
|
||||
// Is the method allowed?
|
||||
if (!isMethodAllowed(request.getMethod()))
|
||||
{
|
||||
if(log.isDebugEnabled())log.debug("Method not allowed: "+request.getMethod());
|
||||
if (resource.exists())
|
||||
{
|
||||
setAllowHeader(response);
|
||||
response.sendError(HttpResponse.__405_Method_Not_Allowed);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle the request
|
||||
try
|
||||
{
|
||||
if(log.isDebugEnabled())log.debug("PATH="+pathInContext+" RESOURCE="+resource);
|
||||
|
||||
// check filename
|
||||
String method=request.getMethod();
|
||||
if (method.equals(HttpRequest.__GET) ||
|
||||
method.equals(HttpRequest.__POST) ||
|
||||
method.equals(HttpRequest.__HEAD))
|
||||
handleGet(request, response, pathInContext, pathParams, resource);
|
||||
else if (method.equals(HttpRequest.__PUT))
|
||||
handlePut(request, response, pathInContext, resource);
|
||||
else if (method.equals(HttpRequest.__DELETE))
|
||||
handleDelete(request, response, pathInContext, resource);
|
||||
else if (method.equals(HttpRequest.__OPTIONS))
|
||||
handleOptions(response, pathInContext);
|
||||
else if (method.equals(HttpRequest.__MOVE))
|
||||
handleMove(request, response, pathInContext, resource);
|
||||
else if (method.equals(HttpRequest.__TRACE))
|
||||
handleTrace(request, response);
|
||||
else
|
||||
{
|
||||
if(log.isDebugEnabled())log.debug("Unknown action:"+method);
|
||||
// anything else...
|
||||
try{
|
||||
if (resource.exists())
|
||||
response.sendError(HttpResponse.__501_Not_Implemented);
|
||||
}
|
||||
catch(Exception e) {LogSupport.ignore(log,e);}
|
||||
}
|
||||
}
|
||||
catch(IllegalArgumentException e)
|
||||
{
|
||||
LogSupport.ignore(log,e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (resource!=null && !(resource instanceof CachedResource))
|
||||
resource.release();
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
public void handleGet(HttpRequest request,
|
||||
HttpResponse response,
|
||||
String pathInContext,
|
||||
String pathParams,
|
||||
Resource resource)
|
||||
throws IOException
|
||||
{
|
||||
if(log.isDebugEnabled())log.debug("Looking for "+resource);
|
||||
|
||||
if (resource!=null && resource.exists())
|
||||
{
|
||||
// check if directory
|
||||
if (resource.isDirectory())
|
||||
{
|
||||
if (!pathInContext.endsWith("/") && !pathInContext.equals("/"))
|
||||
{
|
||||
log.debug("Redirect to directory/");
|
||||
|
||||
String q=request.getQuery();
|
||||
|
||||
// Properly fix URI
|
||||
URI urifix = new URI(request.getRequestURL().toString());
|
||||
urifix.setPath(urifix.getPath());
|
||||
StringBuffer buf = new StringBuffer(urifix.toString());
|
||||
urifix = null;
|
||||
|
||||
if (q!=null&&q.length()!=0)
|
||||
{
|
||||
buf.append('?');
|
||||
buf.append(q);
|
||||
}
|
||||
response.setField(HttpFields.__Location, URI.addPaths(buf.toString(),"/"));
|
||||
response.setStatus(302);
|
||||
request.setHandled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// See if index file exists
|
||||
String welcome=getHttpContext().getWelcomeFile(resource);
|
||||
if (welcome!=null)
|
||||
{
|
||||
// Forward to the index
|
||||
String ipath=URI.addPaths(pathInContext,welcome);
|
||||
if (_redirectWelcomeFiles)
|
||||
{
|
||||
// Redirect to the index
|
||||
ipath=URI.addPaths(getHttpContext().getContextPath(),ipath);
|
||||
response.setContentLength(0);
|
||||
response.sendRedirect(ipath);
|
||||
}
|
||||
else
|
||||
{
|
||||
URI uri=request.getURI();
|
||||
uri.setPath(URI.addPaths(uri.getPath(),welcome));
|
||||
getHttpContext().handle(ipath,pathParams,request,response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Check modified dates
|
||||
if (!passConditionalHeaders(request,response,resource))
|
||||
return;
|
||||
// If we got here, no forward to index took place
|
||||
sendDirectory(request,response,resource,pathInContext.length()>1);
|
||||
}
|
||||
// check if it is a file
|
||||
else if (resource.exists())
|
||||
{
|
||||
// Check modified dates
|
||||
if (!passConditionalHeaders(request,response,resource))
|
||||
return;
|
||||
sendData(request,response,pathInContext,resource,true);
|
||||
}
|
||||
else
|
||||
// don't know what it is
|
||||
log.warn("Unknown file type");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* Check modification date headers.
|
||||
*/
|
||||
private boolean passConditionalHeaders(HttpRequest request,
|
||||
HttpResponse response,
|
||||
Resource resource)
|
||||
throws IOException
|
||||
{
|
||||
if (!request.getMethod().equals(HttpRequest.__HEAD))
|
||||
{
|
||||
// If we have meta data for the file
|
||||
// Try a direct match for most common requests. Avoids
|
||||
// parsing the date.
|
||||
ResourceCache.ResourceMetaData metaData =
|
||||
(ResourceCache.ResourceMetaData)resource.getAssociate();
|
||||
if (metaData!=null)
|
||||
{
|
||||
String ifms=request.getField(HttpFields.__IfModifiedSince);
|
||||
String mdlm=metaData.getLastModified();
|
||||
if (ifms!=null && mdlm!=null && ifms.equals(mdlm))
|
||||
{
|
||||
response.setStatus(HttpResponse.__304_Not_Modified);
|
||||
request.setHandled(true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
long date=0;
|
||||
// Parse the if[un]modified dates and compare to resource
|
||||
|
||||
if ((date=request.getDateField(HttpFields.__IfUnmodifiedSince))>0)
|
||||
{
|
||||
if (resource.lastModified()/1000 > date/1000)
|
||||
{
|
||||
response.sendError(HttpResponse.__412_Precondition_Failed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((date=request.getDateField(HttpFields.__IfModifiedSince))>0)
|
||||
{
|
||||
|
||||
if (resource.lastModified()/1000 <= date/1000)
|
||||
{
|
||||
response.setStatus(HttpResponse.__304_Not_Modified);
|
||||
request.setHandled(true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
void handlePut(HttpRequest request,
|
||||
HttpResponse response,
|
||||
String pathInContext,
|
||||
Resource resource)
|
||||
throws IOException
|
||||
{
|
||||
if(log.isDebugEnabled())log.debug("PUT "+pathInContext+" in "+resource);
|
||||
|
||||
boolean exists=resource!=null && resource.exists();
|
||||
if (exists &&
|
||||
!passConditionalHeaders(request,response,resource))
|
||||
return;
|
||||
|
||||
if (pathInContext.endsWith("/"))
|
||||
{
|
||||
if (!exists)
|
||||
{
|
||||
if (!resource.getFile().mkdirs())
|
||||
response.sendError(HttpResponse.__403_Forbidden, "Directories could not be created");
|
||||
else
|
||||
{
|
||||
request.setHandled(true);
|
||||
response.setStatus(HttpResponse.__201_Created);
|
||||
response.commit();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
request.setHandled(true);
|
||||
response.setStatus(HttpResponse.__200_OK);
|
||||
response.commit();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
int toRead = request.getContentLength();
|
||||
InputStream in = request.getInputStream();
|
||||
OutputStream out = resource.getOutputStream();
|
||||
if (toRead>=0)
|
||||
IO.copy(in,out,toRead);
|
||||
else
|
||||
IO.copy(in,out);
|
||||
out.close();
|
||||
request.setHandled(true);
|
||||
response.setStatus(exists
|
||||
?HttpResponse.__200_OK
|
||||
:HttpResponse.__201_Created);
|
||||
response.commit();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,ex);
|
||||
response.sendError(HttpResponse.__403_Forbidden,
|
||||
ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
void handleDelete(HttpRequest request,
|
||||
HttpResponse response,
|
||||
String pathInContext,
|
||||
Resource resource)
|
||||
throws IOException
|
||||
{
|
||||
if(log.isDebugEnabled())log.debug("DELETE "+pathInContext+" from "+resource);
|
||||
|
||||
if (!resource.exists() ||
|
||||
!passConditionalHeaders(request,response,resource))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
// delete the file
|
||||
if (resource.delete())
|
||||
response.setStatus(HttpResponse.__204_No_Content);
|
||||
else
|
||||
response.sendError(HttpResponse.__403_Forbidden);
|
||||
|
||||
// Send response
|
||||
request.setHandled(true);
|
||||
}
|
||||
catch (SecurityException sex)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,sex);
|
||||
response.sendError(HttpResponse.__403_Forbidden, sex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
void handleMove(HttpRequest request,
|
||||
HttpResponse response,
|
||||
String pathInContext,
|
||||
Resource resource)
|
||||
throws IOException
|
||||
{
|
||||
if (!resource.exists() || !passConditionalHeaders(request,response,resource))
|
||||
return;
|
||||
|
||||
|
||||
String newPath = URI.canonicalPath(request.getField("New-uri"));
|
||||
if (newPath==null)
|
||||
{
|
||||
response.sendError(HttpResponse.__405_Method_Not_Allowed,
|
||||
"Bad new uri");
|
||||
return;
|
||||
}
|
||||
|
||||
String contextPath = getHttpContext().getContextPath();
|
||||
if (contextPath!=null && !newPath.startsWith(contextPath))
|
||||
{
|
||||
response.sendError(HttpResponse.__405_Method_Not_Allowed,
|
||||
"Not in context");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Find path
|
||||
try
|
||||
{
|
||||
// TODO - Check this
|
||||
String newInfo=newPath;
|
||||
if (contextPath!=null)
|
||||
newInfo=newInfo.substring(contextPath.length());
|
||||
Resource newFile = getHttpContext().getBaseResource().addPath(newInfo);
|
||||
|
||||
if(log.isDebugEnabled())log.debug("Moving "+resource+" to "+newFile);
|
||||
resource.renameTo(newFile);
|
||||
|
||||
response.setStatus(HttpResponse.__204_No_Content);
|
||||
request.setHandled(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,ex);
|
||||
setAllowHeader(response);
|
||||
response.sendError(HttpResponse.__405_Method_Not_Allowed,
|
||||
"Error:"+ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
void handleOptions(HttpResponse response, String pathInContext)
|
||||
throws IOException
|
||||
{
|
||||
if ("*".equals(pathInContext))
|
||||
return;
|
||||
setAllowHeader(response);
|
||||
response.commit();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
void setAllowHeader(HttpResponse response)
|
||||
{
|
||||
response.setField(HttpFields.__Allow, getAllowedString());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void writeHeaders(HttpResponse response,Resource resource, long count)
|
||||
throws IOException
|
||||
{
|
||||
ResourceCache.ResourceMetaData metaData =
|
||||
(ResourceCache.ResourceMetaData)resource.getAssociate();
|
||||
|
||||
response.setContentType(metaData.getMimeType());
|
||||
if (count != -1)
|
||||
{
|
||||
if (count==resource.length())
|
||||
response.setField(HttpFields.__ContentLength,metaData.getLength());
|
||||
else
|
||||
response.setContentLength((int)count);
|
||||
}
|
||||
|
||||
response.setField(HttpFields.__LastModified,metaData.getLastModified());
|
||||
|
||||
if (_acceptRanges && response.getHttpRequest().getDotVersion()>0)
|
||||
response.setField(HttpFields.__AcceptRanges,"bytes");
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void sendData(HttpRequest request,
|
||||
HttpResponse response,
|
||||
String pathInContext,
|
||||
Resource resource,
|
||||
boolean writeHeaders)
|
||||
throws IOException
|
||||
{
|
||||
long resLength=resource.length();
|
||||
|
||||
// see if there are any range headers
|
||||
Enumeration reqRanges =
|
||||
request.getDotVersion()>0
|
||||
?request.getFieldValues(HttpFields.__Range)
|
||||
:null;
|
||||
|
||||
if (!writeHeaders || reqRanges == null || !reqRanges.hasMoreElements())
|
||||
{
|
||||
// look for a gziped content.
|
||||
Resource data=resource;
|
||||
if (_minGzipLength>0)
|
||||
{
|
||||
String accept=request.getField(HttpFields.__AcceptEncoding);
|
||||
if (accept!=null && resLength>_minGzipLength &&
|
||||
!pathInContext.endsWith(".gz"))
|
||||
{
|
||||
Resource gz = getHttpContext().getResource(pathInContext+".gz");
|
||||
if (gz.exists() && accept.indexOf("gzip")>=0)
|
||||
{
|
||||
if(log.isDebugEnabled())log.debug("gzip="+gz);
|
||||
response.setField(HttpFields.__ContentEncoding,"gzip");
|
||||
data=gz;
|
||||
resLength=data.length();
|
||||
}
|
||||
}
|
||||
}
|
||||
writeHeaders(response,resource,resLength);
|
||||
|
||||
request.setHandled(true);
|
||||
OutputStream out = response.getOutputStream();
|
||||
data.writeTo(out,0,resLength);
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the satisfiable ranges
|
||||
List ranges =InclusiveByteRange.satisfiableRanges(reqRanges,resLength);
|
||||
if(log.isDebugEnabled())log.debug("ranges: " + reqRanges + " == " + ranges);
|
||||
|
||||
// if there are no satisfiable ranges, send 416 response
|
||||
if (ranges==null || ranges.size()==0)
|
||||
{
|
||||
log.debug("no satisfiable ranges");
|
||||
writeHeaders(response, resource, resLength);
|
||||
response.setStatus(HttpResponse.__416_Requested_Range_Not_Satisfiable);
|
||||
response.setReason((String)HttpResponse.__statusMsg
|
||||
.get(TypeUtil.newInteger(HttpResponse.__416_Requested_Range_Not_Satisfiable)));
|
||||
|
||||
response.setField(HttpFields.__ContentRange,
|
||||
InclusiveByteRange.to416HeaderRangeString(resLength));
|
||||
|
||||
OutputStream out = response.getOutputStream();
|
||||
resource.writeTo(out,0,resLength);
|
||||
request.setHandled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// if there is only a single valid range (must be satisfiable
|
||||
// since were here now), send that range with a 216 response
|
||||
if ( ranges.size()== 1)
|
||||
{
|
||||
InclusiveByteRange singleSatisfiableRange =
|
||||
(InclusiveByteRange)ranges.get(0);
|
||||
if(log.isDebugEnabled())log.debug("single satisfiable range: " + singleSatisfiableRange);
|
||||
long singleLength = singleSatisfiableRange.getSize(resLength);
|
||||
writeHeaders(response,resource,singleLength);
|
||||
response.setStatus(HttpResponse.__206_Partial_Content);
|
||||
response.setReason((String)HttpResponse.__statusMsg
|
||||
.get(TypeUtil.newInteger(HttpResponse.__206_Partial_Content)));
|
||||
response.setField(HttpFields.__ContentRange,
|
||||
singleSatisfiableRange.toHeaderRangeString(resLength));
|
||||
OutputStream out = response.getOutputStream();
|
||||
resource.writeTo(out,
|
||||
singleSatisfiableRange.getFirst(resLength),
|
||||
singleLength);
|
||||
request.setHandled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// multiple non-overlapping valid ranges cause a multipart
|
||||
// 216 response which does not require an overall
|
||||
// content-length header
|
||||
//
|
||||
ResourceCache.ResourceMetaData metaData =
|
||||
(ResourceCache.ResourceMetaData)resource.getAssociate();
|
||||
String encoding = metaData.getMimeType();
|
||||
MultiPartResponse multi = new MultiPartResponse(response);
|
||||
response.setStatus(HttpResponse.__206_Partial_Content);
|
||||
response.setReason((String)HttpResponse.__statusMsg
|
||||
.get(TypeUtil.newInteger(HttpResponse.__206_Partial_Content)));
|
||||
|
||||
// If the request has a "Request-Range" header then we need to
|
||||
// send an old style multipart/x-byteranges Content-Type. This
|
||||
// keeps Netscape and acrobat happy. This is what Apache does.
|
||||
String ctp;
|
||||
if (request.containsField(HttpFields.__RequestRange))
|
||||
ctp = "multipart/x-byteranges; boundary=";
|
||||
else
|
||||
ctp = "multipart/byteranges; boundary=";
|
||||
response.setContentType(ctp+multi.getBoundary());
|
||||
|
||||
InputStream in=(resource instanceof CachedResource)
|
||||
?null:resource.getInputStream();
|
||||
OutputStream out = response.getOutputStream();
|
||||
long pos=0;
|
||||
|
||||
for (int i=0;i<ranges.size();i++)
|
||||
{
|
||||
InclusiveByteRange ibr = (InclusiveByteRange) ranges.get(i);
|
||||
String header=HttpFields.__ContentRange+": "+
|
||||
ibr.toHeaderRangeString(resLength);
|
||||
if(log.isDebugEnabled())log.debug("multi range: "+encoding+" "+header);
|
||||
multi.startPart(encoding,new String[]{header});
|
||||
|
||||
long start=ibr.getFirst(resLength);
|
||||
long size=ibr.getSize(resLength);
|
||||
if (in!=null)
|
||||
{
|
||||
// Handle non cached resource
|
||||
if (start<pos)
|
||||
{
|
||||
in.close();
|
||||
in=resource.getInputStream();
|
||||
pos=0;
|
||||
}
|
||||
if (pos<start)
|
||||
{
|
||||
in.skip(start-pos);
|
||||
pos=start;
|
||||
}
|
||||
IO.copy(in,out,size);
|
||||
pos+=size;
|
||||
}
|
||||
else
|
||||
// Handle cached resource
|
||||
resource.writeTo(out,start,size);
|
||||
|
||||
}
|
||||
if (in!=null)
|
||||
in.close();
|
||||
multi.close();
|
||||
|
||||
request.setHandled(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
void sendDirectory(HttpRequest request,
|
||||
HttpResponse response,
|
||||
Resource resource,
|
||||
boolean parent)
|
||||
throws IOException
|
||||
{
|
||||
if (!_dirAllowed)
|
||||
{
|
||||
response.sendError(HttpResponse.__403_Forbidden);
|
||||
return;
|
||||
}
|
||||
|
||||
request.setHandled(true);
|
||||
|
||||
if(log.isDebugEnabled())log.debug("sendDirectory: "+resource);
|
||||
byte[] data=null;
|
||||
if (resource instanceof CachedResource)
|
||||
data=((CachedResource)resource).getCachedData();
|
||||
|
||||
if (data==null)
|
||||
{
|
||||
String base = URI.addPaths(request.getPath(),"/");
|
||||
String dir = resource.getListHTML(URI.encodePath(base),parent);
|
||||
if (dir==null)
|
||||
{
|
||||
response.sendError(HttpResponse.__403_Forbidden,
|
||||
"No directory");
|
||||
return;
|
||||
}
|
||||
data=dir.getBytes("UTF8");
|
||||
if (resource instanceof CachedResource)
|
||||
((CachedResource)resource).setCachedData(data);
|
||||
}
|
||||
|
||||
response.setContentType("text/html; charset=UTF8");
|
||||
response.setContentLength(data.length);
|
||||
|
||||
if (request.getMethod().equals(HttpRequest.__HEAD))
|
||||
{
|
||||
response.commit();
|
||||
return;
|
||||
}
|
||||
|
||||
response.getOutputStream().write(data,0,data.length);
|
||||
response.commit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,617 +0,0 @@
|
||||
// ========================================================================
|
||||
// $Id: Server.java,v 1.40 2005/10/21 13:52:11 gregwilkins Exp $
|
||||
// Copyright 2002-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.mortbay.jetty;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.mortbay.log.LogFactory;
|
||||
import org.mortbay.http.HttpContext;
|
||||
import org.mortbay.http.HttpServer;
|
||||
import org.mortbay.jetty.servlet.ServletHttpContext;
|
||||
import org.mortbay.jetty.servlet.WebApplicationContext;
|
||||
import org.mortbay.util.LogSupport;
|
||||
import org.mortbay.util.Resource;
|
||||
import org.mortbay.xml.XmlConfiguration;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** The Jetty HttpServer.
|
||||
*
|
||||
* This specialization of org.mortbay.http.HttpServer adds knowledge
|
||||
* about servlets and their specialized contexts. It also included
|
||||
* support for initialization from xml configuration files
|
||||
* that follow the XmlConfiguration dtd.
|
||||
*
|
||||
* HttpContexts created by Server are of the type
|
||||
* org.mortbay.jetty.servlet.ServletHttpContext unless otherwise
|
||||
* specified.
|
||||
*
|
||||
* This class also provides a main() method which starts a server for
|
||||
* each config file passed on the command line. If the system
|
||||
* property JETTY_NO_SHUTDOWN_HOOK is not set to true, then a shutdown
|
||||
* hook is thread is registered to stop these servers.
|
||||
*
|
||||
* @see org.mortbay.xml.XmlConfiguration
|
||||
* @see org.mortbay.jetty.servlet.ServletHttpContext
|
||||
* @version $Revision: 1.40 $
|
||||
* @author Greg Wilkins (gregw)
|
||||
*/
|
||||
public class Server extends HttpServer
|
||||
{
|
||||
static Log log = LogFactory.getLog(Server.class);
|
||||
private String[] _webAppConfigurationClassNames =
|
||||
new String[]{"org.mortbay.jetty.servlet.XMLConfiguration", "org.mortbay.jetty.servlet.JettyWebConfiguration"};
|
||||
private String _configuration;
|
||||
private String _rootWebApp;
|
||||
private static ShutdownHookThread hookThread = new ShutdownHookThread();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
*/
|
||||
public Server()
|
||||
{
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param configuration The filename or URL of the XML
|
||||
* configuration file.
|
||||
*/
|
||||
public Server(String configuration)
|
||||
throws IOException
|
||||
{
|
||||
this(Resource.newResource(configuration).getURL());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param configuration The filename or URL of the XML
|
||||
* configuration file.
|
||||
*/
|
||||
public Server(Resource configuration)
|
||||
throws IOException
|
||||
{
|
||||
this(configuration.getURL());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param configuration The filename or URL of the XML
|
||||
* configuration file.
|
||||
*/
|
||||
public Server(URL configuration)
|
||||
throws IOException
|
||||
{
|
||||
_configuration=configuration.toString();
|
||||
Server.hookThread.add(this);
|
||||
try
|
||||
{
|
||||
XmlConfiguration config=new XmlConfiguration(configuration);
|
||||
config.configure(this);
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch(InvocationTargetException e)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,e.getTargetException());
|
||||
throw new IOException("Jetty configuration problem: "+e.getTargetException());
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,e);
|
||||
throw new IOException("Jetty configuration problem: "+e);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean getStopAtShutdown()
|
||||
{
|
||||
return hookThread.contains(this);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setStopAtShutdown(boolean stop)
|
||||
{
|
||||
if (stop)
|
||||
hookThread.add(this);
|
||||
else
|
||||
hookThread.remove(this);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the root webapp name.
|
||||
* @return The name of the root webapp (eg. "root" for root.war).
|
||||
*/
|
||||
public String getRootWebApp()
|
||||
{
|
||||
return _rootWebApp;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the root webapp name.
|
||||
* @param rootWebApp The name of the root webapp (eg. "root" for root.war).
|
||||
*/
|
||||
public void setRootWebApp(String rootWebApp)
|
||||
{
|
||||
_rootWebApp = rootWebApp;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Configure the server from an XML file.
|
||||
* @param configuration The filename or URL of the XML
|
||||
* configuration file.
|
||||
*/
|
||||
public void configure(String configuration)
|
||||
throws IOException
|
||||
{
|
||||
|
||||
URL url=Resource.newResource(configuration).getURL();
|
||||
if (_configuration!=null && _configuration.equals(url.toString()))
|
||||
return;
|
||||
if (_configuration!=null)
|
||||
throw new IllegalStateException("Already configured with "+_configuration);
|
||||
try
|
||||
{
|
||||
XmlConfiguration config=new XmlConfiguration(url);
|
||||
_configuration=url.toString();
|
||||
config.configure(this);
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,e);
|
||||
throw new IOException("Jetty configuration problem: "+e);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String getConfiguration()
|
||||
{
|
||||
return _configuration;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Create a new ServletHttpContext.
|
||||
* Ths method is called by HttpServer to creat new contexts. Thus
|
||||
* calls to addContext or getContext that result in a new Context
|
||||
* being created will return an
|
||||
* org.mortbay.jetty.servlet.ServletHttpContext instance.
|
||||
* @return ServletHttpContext
|
||||
*/
|
||||
protected HttpContext newHttpContext()
|
||||
{
|
||||
return new ServletHttpContext();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Create a new WebApplicationContext.
|
||||
* Ths method is called by Server to creat new contexts for web
|
||||
* applications. Thus calls to addWebApplication that result in
|
||||
* a new Context being created will return an correct class instance.
|
||||
* Derived class can override this method to create instance of its
|
||||
* own class derived from WebApplicationContext in case it needs more
|
||||
* functionality.
|
||||
* @param webApp The Web application directory or WAR file.
|
||||
* @return WebApplicationContext
|
||||
*/
|
||||
protected WebApplicationContext newWebApplicationContext(
|
||||
String webApp
|
||||
)
|
||||
{
|
||||
return new WebApplicationContext(webApp);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add Web Application.
|
||||
* @param contextPathSpec The context path spec. Which must be of
|
||||
* the form / or /path/*
|
||||
* @param webApp The Web application directory or WAR file.
|
||||
* @return The WebApplicationContext
|
||||
* @exception IOException
|
||||
*/
|
||||
public WebApplicationContext addWebApplication(String contextPathSpec,
|
||||
String webApp)
|
||||
throws IOException
|
||||
{
|
||||
return addWebApplication(null,contextPathSpec,webApp);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add Web Application.
|
||||
* @param virtualHost Virtual host name or null
|
||||
* @param contextPathSpec The context path spec. Which must be of
|
||||
* the form / or /path/*
|
||||
* @param webApp The Web application directory or WAR file.
|
||||
* @return The WebApplicationContext
|
||||
* @exception IOException
|
||||
*/
|
||||
public WebApplicationContext addWebApplication(String virtualHost,
|
||||
String contextPathSpec,
|
||||
String webApp)
|
||||
throws IOException
|
||||
{
|
||||
WebApplicationContext appContext =
|
||||
newWebApplicationContext(webApp);
|
||||
appContext.setContextPath(contextPathSpec);
|
||||
addContext(virtualHost,appContext);
|
||||
if(log.isDebugEnabled())log.debug("Web Application "+appContext+" added");
|
||||
return appContext;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add Web Applications.
|
||||
* Add auto webapplications to the server. The name of the
|
||||
* webapp directory or war is used as the context name. If a
|
||||
* webapp is called "root" it is added at "/".
|
||||
* @param webapps Directory file name or URL to look for auto webapplication.
|
||||
* @exception IOException
|
||||
*/
|
||||
public WebApplicationContext[] addWebApplications(String webapps)
|
||||
throws IOException
|
||||
{
|
||||
return addWebApplications(null,webapps,null,false);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add Web Applications.
|
||||
* Add auto webapplications to the server. The name of the
|
||||
* webapp directory or war is used as the context name. If the
|
||||
* webapp matches the rootWebApp it is added as the "/" context.
|
||||
* @param host Virtual host name or null
|
||||
* @param webapps Directory file name or URL to look for auto webapplication.
|
||||
* @exception IOException
|
||||
*/
|
||||
public WebApplicationContext[] addWebApplications(String host,
|
||||
String webapps)
|
||||
throws IOException
|
||||
{
|
||||
return addWebApplications(host,webapps,null,false);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add Web Applications.
|
||||
* Add auto webapplications to the server. The name of the
|
||||
* webapp directory or war is used as the context name. If the
|
||||
* webapp matches the rootWebApp it is added as the "/" context.
|
||||
* @param host Virtual host name or null
|
||||
* @param webapps Directory file name or URL to look for auto
|
||||
* webapplication.
|
||||
* @param extract If true, extract war files
|
||||
* @exception IOException
|
||||
*/
|
||||
public WebApplicationContext[] addWebApplications(String host,
|
||||
String webapps,
|
||||
boolean extract)
|
||||
throws IOException
|
||||
{
|
||||
return addWebApplications(host,webapps,null,extract);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add Web Applications.
|
||||
* Add auto webapplications to the server. The name of the
|
||||
* webapp directory or war is used as the context name. If the
|
||||
* webapp matches the rootWebApp it is added as the "/" context.
|
||||
* @param host Virtual host name or null
|
||||
* @param webapps Directory file name or URL to look for auto
|
||||
* webapplication.
|
||||
* @param defaults The defaults xml filename or URL which is
|
||||
* loaded before any in the web app. Must respect the web.dtd.
|
||||
* If null the default defaults file is used. If the empty string, then
|
||||
* no defaults file is used.
|
||||
* @param extract If true, extract war files
|
||||
* @exception IOException
|
||||
*/
|
||||
public WebApplicationContext[] addWebApplications(String host,
|
||||
String webapps,
|
||||
String defaults,
|
||||
boolean extract)
|
||||
throws IOException
|
||||
{
|
||||
return addWebApplications(host,webapps,defaults,extract,true,null);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add Web Applications.
|
||||
* Add auto webapplications to the server. The name of the
|
||||
* webapp directory or war is used as the context name. If the
|
||||
* webapp matches the rootWebApp it is added as the "/" context.
|
||||
* @param host Virtual host name or null
|
||||
* @param webapps Directory file name or URL to look for auto
|
||||
* webapplication.
|
||||
* @param defaults The defaults xml filename or URL which is
|
||||
* loaded before any in the web app. Must respect the web.dtd.
|
||||
* If null the default defaults file is used. If the empty string, then
|
||||
* no defaults file is used.
|
||||
* @param extract If true, extract war files
|
||||
* @param java2CompliantClassLoader True if java2 compliance is applied to all webapplications
|
||||
* @exception IOException
|
||||
*/
|
||||
public WebApplicationContext[] addWebApplications(String host,
|
||||
String webapps,
|
||||
String defaults,
|
||||
boolean extract,
|
||||
boolean java2CompliantClassLoader)
|
||||
throws IOException
|
||||
{
|
||||
return addWebApplications(host,webapps,defaults,extract,java2CompliantClassLoader,null);
|
||||
|
||||
}
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add Web Applications.
|
||||
* Add auto webapplications to the server. The name of the
|
||||
* webapp directory or war is used as the context name. If the
|
||||
* webapp matches the rootWebApp it is added as the "/" context.
|
||||
* @param host Virtual host name or null
|
||||
* @param webapps Directory file name or URL to look for auto
|
||||
* webapplication.
|
||||
* @param defaults The defaults xml filename or URL which is
|
||||
* loaded before any in the web app. Must respect the web.dtd.
|
||||
* If null the default defaults file is used. If the empty string, then
|
||||
* no defaults file is used.
|
||||
* @param extract If true, extract war files
|
||||
* @param java2CompliantClassLoader True if java2 compliance is applied to all webapplications
|
||||
* @param Attributes[] A set of attributes to pass to setAttribute, format is first item is the key, second item is the value.
|
||||
* @exception IOException
|
||||
*/
|
||||
public WebApplicationContext[] addWebApplications(String host,
|
||||
String webapps,
|
||||
String defaults,
|
||||
boolean extract,
|
||||
boolean java2CompliantClassLoader,
|
||||
String Attributes[])
|
||||
throws IOException
|
||||
{
|
||||
ArrayList wacs = new ArrayList();
|
||||
Resource r=Resource.newResource(webapps);
|
||||
if (!r.exists())
|
||||
throw new IllegalArgumentException("No such webapps resource "+r);
|
||||
|
||||
if (!r.isDirectory())
|
||||
throw new IllegalArgumentException("Not directory webapps resource "+r);
|
||||
if(Attributes != null) {
|
||||
if(((Attributes.length / 2) * 2) != Attributes.length) {
|
||||
throw new IllegalArgumentException("Attributes must be in pairs of key,value.");
|
||||
}
|
||||
}
|
||||
String[] files=r.list();
|
||||
|
||||
for (int f=0;files!=null && f<files.length;f++)
|
||||
{
|
||||
String context=files[f];
|
||||
|
||||
if (context.equalsIgnoreCase("CVS/") ||
|
||||
context.equalsIgnoreCase("CVS") ||
|
||||
context.startsWith("."))
|
||||
continue;
|
||||
|
||||
|
||||
String app = r.addPath(r.encode(files[f])).toString();
|
||||
if (context.toLowerCase().endsWith(".war") ||
|
||||
context.toLowerCase().endsWith(".jar"))
|
||||
{
|
||||
context=context.substring(0,context.length()-4);
|
||||
Resource unpacked=r.addPath(context);
|
||||
if (unpacked!=null && unpacked.exists() && unpacked.isDirectory())
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_rootWebApp!=null && (context.equals(_rootWebApp)||context.equals(_rootWebApp+"/")))
|
||||
context="/";
|
||||
else
|
||||
context="/"+context;
|
||||
|
||||
WebApplicationContext wac= addWebApplication(host,
|
||||
context,
|
||||
app);
|
||||
wac.setExtractWAR(extract);
|
||||
wac.setClassLoaderJava2Compliant(java2CompliantClassLoader);
|
||||
if (defaults!=null)
|
||||
{
|
||||
if (defaults.length()==0)
|
||||
wac.setDefaultsDescriptor(null);
|
||||
else
|
||||
wac.setDefaultsDescriptor(defaults);
|
||||
}
|
||||
if(Attributes != null) {
|
||||
for(int i = 0; i < Attributes.length; i++, i++) {
|
||||
wac.setAttribute(Attributes[i],Attributes[i + 1]);
|
||||
}
|
||||
}
|
||||
wacs.add(wac);
|
||||
}
|
||||
|
||||
return (WebApplicationContext[])wacs.toArray(new WebApplicationContext[wacs.size()]);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** setWebApplicationConfigurationClasses
|
||||
* Set up the list of classnames of WebApplicationContext.Configuration
|
||||
* implementations that will be applied to configure every webapp.
|
||||
* The list can be overridden by individual WebApplicationContexts.
|
||||
* @param configurationClasses
|
||||
*/
|
||||
public void setWebApplicationConfigurationClassNames (String[] configurationClassNames)
|
||||
{
|
||||
if (configurationClassNames != null)
|
||||
{
|
||||
_webAppConfigurationClassNames = new String[configurationClassNames.length];
|
||||
System.arraycopy(configurationClassNames, 0, _webAppConfigurationClassNames, 0, configurationClassNames.length);
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getWebApplicationConfigurationClassNames ()
|
||||
{
|
||||
return _webAppConfigurationClassNames;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
public static void main(String[] arg)
|
||||
{
|
||||
String[] dftConfig={"etc/jetty.xml"};
|
||||
|
||||
if (arg.length==0)
|
||||
{
|
||||
log.info("Using default configuration: etc/jetty.xml");
|
||||
arg=dftConfig;
|
||||
}
|
||||
|
||||
final Server[] servers=new Server[arg.length];
|
||||
|
||||
// create and start the servers.
|
||||
for (int i=0;i<arg.length;i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
servers[i] = new Server(arg[i]);
|
||||
servers[i].setStopAtShutdown(true);
|
||||
servers[i].start();
|
||||
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,e);
|
||||
}
|
||||
}
|
||||
|
||||
// create and start the servers.
|
||||
for (int i=0;i<arg.length;i++)
|
||||
{
|
||||
try{servers[i].join();}
|
||||
catch (Exception e){LogSupport.ignore(log,e);}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ShutdownHook thread for stopping all servers.
|
||||
*
|
||||
* Thread is hooked first time list of servers is changed.
|
||||
*/
|
||||
private static class ShutdownHookThread extends Thread {
|
||||
private boolean hooked = false;
|
||||
private ArrayList servers = new ArrayList();
|
||||
|
||||
/**
|
||||
* Hooks this thread for shutdown.
|
||||
* @see java.lang.Runtime#addShutdownHook(java.lang.Thread)
|
||||
*/
|
||||
private void createShutdownHook() {
|
||||
if (!Boolean.getBoolean("JETTY_NO_SHUTDOWN_HOOK") && !hooked) {
|
||||
try {
|
||||
Method shutdownHook = java.lang.Runtime.class.getMethod("addShutdownHook",
|
||||
new Class[] { java.lang.Thread.class });
|
||||
shutdownHook.invoke(Runtime.getRuntime(), new Object[] { this });
|
||||
this.hooked = true;
|
||||
} catch (Exception e) {
|
||||
if (log.isDebugEnabled()) log.debug("No shutdown hook in JVM ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Server to servers list.
|
||||
*/
|
||||
public boolean add(Server server) {
|
||||
createShutdownHook();
|
||||
return this.servers.add(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains Server in servers list?
|
||||
*/
|
||||
public boolean contains(Server server) {
|
||||
return this.servers.contains(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append all Servers from Collection
|
||||
*/
|
||||
public boolean addAll(Collection c) {
|
||||
createShutdownHook();
|
||||
return this.servers.addAll(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear list of Servers.
|
||||
*/
|
||||
public void clear() {
|
||||
createShutdownHook();
|
||||
this.servers.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove Server from list.
|
||||
*/
|
||||
public boolean remove(Server server) {
|
||||
createShutdownHook();
|
||||
return this.servers.remove(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all Servers in Collection from list.
|
||||
*/
|
||||
public boolean removeAll(Collection c) {
|
||||
createShutdownHook();
|
||||
return this.servers.removeAll(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop all Servers in list.
|
||||
*/
|
||||
public void run() {
|
||||
setName("Shutdown");
|
||||
log.info("Shutdown hook executing");
|
||||
Iterator it = servers.iterator();
|
||||
while (it.hasNext()) {
|
||||
Server svr = (Server) it.next();
|
||||
if (svr == null) continue;
|
||||
try {
|
||||
svr.stop();
|
||||
} catch (Exception e) {
|
||||
log.warn(LogSupport.EXCEPTION, e);
|
||||
}
|
||||
log.info("Shutdown hook complete");
|
||||
|
||||
// Try to avoid JVM crash
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (Exception e) {
|
||||
log.warn(LogSupport.EXCEPTION, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,352 +0,0 @@
|
||||
// ========================================================================
|
||||
// $Id: FileResource.java,v 1.31 2006/01/04 13:55:31 gregwilkins Exp $
|
||||
// Copyright 1996-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.mortbay.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
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 java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.security.Permission;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.mortbay.log.LogFactory;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** File Resource.
|
||||
*
|
||||
* Handle resources of implied or explicit file type.
|
||||
* This class can check for aliasing in the filesystem (eg case
|
||||
* insensitivity). By default this is turned on if the platform does
|
||||
* not have the "/" path separator, or it can be controlled with the
|
||||
* "org.mortbay.util.FileResource.checkAliases" system parameter.
|
||||
*
|
||||
* If alias checking is turned on, then aliased resources are
|
||||
* treated as if they do not exist, nor can they be created.
|
||||
*
|
||||
* @version $Revision: 1.31 $
|
||||
* @author Greg Wilkins (gregw)
|
||||
*/
|
||||
public class FileResource extends URLResource
|
||||
{
|
||||
private static Log log = LogFactory.getLog(Credential.class);
|
||||
private static boolean __checkAliases;
|
||||
static
|
||||
{
|
||||
__checkAliases=
|
||||
"true".equalsIgnoreCase
|
||||
(System.getProperty("org.mortbay.util.FileResource.checkAliases","true"));
|
||||
|
||||
if (__checkAliases)
|
||||
log.info("Checking Resource aliases");
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private File _file;
|
||||
private transient URL _alias=null;
|
||||
private transient boolean _aliasChecked=false;
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/** setCheckAliases.
|
||||
* @param checkAliases True of resource aliases are to be checked for (eg case insensitivity or 8.3 short names) and treated as not found.
|
||||
*/
|
||||
public static void setCheckAliases(boolean checkAliases)
|
||||
{
|
||||
__checkAliases=checkAliases;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/** getCheckAliases.
|
||||
* @return True of resource aliases are to be checked for (eg case insensitivity or 8.3 short names) and treated as not found.
|
||||
*/
|
||||
public static boolean getCheckAliases()
|
||||
{
|
||||
return __checkAliases;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
FileResource(URL url)
|
||||
throws IOException, URISyntaxException
|
||||
{
|
||||
super(url,null);
|
||||
|
||||
try
|
||||
{
|
||||
// Try standard API to convert URL to file.
|
||||
_file =new File(new URI(url.toString()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogSupport.ignore(log,e);
|
||||
try
|
||||
{
|
||||
// Assume that File.toURL produced unencoded chars. So try
|
||||
// encoding them.
|
||||
String urls=
|
||||
"file:"+org.mortbay.util.URI.encodePath(url.toString().substring(5));
|
||||
_file =new File(new URI(urls));
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
LogSupport.ignore(log,e2);
|
||||
|
||||
// Still can't get the file. Doh! try good old hack!
|
||||
checkConnection();
|
||||
Permission perm = _connection.getPermission();
|
||||
_file = new File(perm==null?url.getFile():perm.getName());
|
||||
}
|
||||
}
|
||||
|
||||
if (_file.isDirectory() && !_urlString.endsWith("/"))
|
||||
_urlString=_urlString+"/";
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
FileResource(URL url, URLConnection connection, File file)
|
||||
{
|
||||
super(url,connection);
|
||||
_file=file;
|
||||
if (_file.isDirectory() && !_urlString.endsWith("/"))
|
||||
_urlString=_urlString+"/";
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
public Resource addPath(String path)
|
||||
throws IOException,MalformedURLException
|
||||
{
|
||||
FileResource r=null;
|
||||
|
||||
if (!isDirectory())
|
||||
{
|
||||
r=(FileResource)super.addPath(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
path = org.mortbay.util.URI.canonicalPath(path);
|
||||
|
||||
// treat all paths being added as relative
|
||||
String rel=path;
|
||||
if (path.startsWith("/"))
|
||||
rel = path.substring(1);
|
||||
|
||||
File newFile = new File(_file,rel.replace('/', File.separatorChar));
|
||||
r=new FileResource(newFile.toURI().toURL(),null,newFile);
|
||||
}
|
||||
|
||||
String encoded=org.mortbay.util.URI.encodePath(path);
|
||||
int expected=r._urlString.length()-encoded.length();
|
||||
int index = r._urlString.lastIndexOf(encoded, expected);
|
||||
|
||||
if (expected!=index && ((expected-1)!=index || path.endsWith("/") || !r.isDirectory()))
|
||||
{
|
||||
r._alias=r._url;
|
||||
r._aliasChecked=true;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public URL getAlias()
|
||||
{
|
||||
if (__checkAliases) {
|
||||
if (!_aliasChecked)
|
||||
{
|
||||
try
|
||||
{
|
||||
String abs=_file.getAbsolutePath();
|
||||
String can=_file.getCanonicalPath();
|
||||
|
||||
if (abs.length()!=can.length() || !abs.equals(can))
|
||||
_alias=new File(can).toURI().toURL();
|
||||
|
||||
_aliasChecked=true;
|
||||
|
||||
if (_alias!=null && log.isDebugEnabled())
|
||||
{
|
||||
log.debug("ALIAS abs="+abs);
|
||||
log.debug("ALIAS can="+can);
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,e);
|
||||
return getURL();
|
||||
}
|
||||
}
|
||||
} else return null;
|
||||
return _alias;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
/**
|
||||
* Returns true if the resource exists.
|
||||
*/
|
||||
public boolean exists()
|
||||
{
|
||||
return _file.exists();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
/**
|
||||
* Returns the last modified time
|
||||
*/
|
||||
public long lastModified()
|
||||
{
|
||||
return _file.lastModified();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
/**
|
||||
* Returns true if the respresenetd resource is a container/directory.
|
||||
*/
|
||||
public boolean isDirectory()
|
||||
{
|
||||
return _file.isDirectory();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/**
|
||||
* Return the length of the resource
|
||||
*/
|
||||
public long length()
|
||||
{
|
||||
return _file.length();
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/**
|
||||
* Returns the name of the resource
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return _file.getAbsolutePath();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns an File representing the given resource or NULL if this
|
||||
* is not possible.
|
||||
*/
|
||||
public File getFile()
|
||||
{
|
||||
return _file;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/**
|
||||
* Returns an input stream to the resource
|
||||
*/
|
||||
public InputStream getInputStream() throws IOException
|
||||
{
|
||||
return new FileInputStream(_file);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/**
|
||||
* Returns an output stream to the resource
|
||||
*/
|
||||
public OutputStream getOutputStream()
|
||||
throws java.io.IOException, SecurityException
|
||||
{
|
||||
return new FileOutputStream(_file);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/**
|
||||
* Deletes the given resource
|
||||
*/
|
||||
public boolean delete()
|
||||
throws SecurityException
|
||||
{
|
||||
return _file.delete();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/**
|
||||
* Rename the given resource
|
||||
*/
|
||||
public boolean renameTo( Resource dest)
|
||||
throws SecurityException
|
||||
{
|
||||
if( dest instanceof FileResource)
|
||||
return _file.renameTo( ((FileResource)dest)._file);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/**
|
||||
* Returns a list of resources contained in the given resource
|
||||
*/
|
||||
public String[] list()
|
||||
{
|
||||
String[] list =_file.list();
|
||||
if (list==null)
|
||||
return null;
|
||||
for (int i=list.length;i-->0;)
|
||||
{
|
||||
if (new File(_file,list[i]).isDirectory() &&
|
||||
!list[i].endsWith("/"))
|
||||
list[i]+="/";
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Encode according to this resource type.
|
||||
* File URIs are encoded.
|
||||
* @param uri URI to encode.
|
||||
* @return The uri unchanged.
|
||||
*/
|
||||
public String encode(String uri)
|
||||
{
|
||||
return uri;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public boolean equals( Object o)
|
||||
{
|
||||
if (this == o)
|
||||
return true;
|
||||
|
||||
if (null == o || ! (o instanceof FileResource))
|
||||
return false;
|
||||
|
||||
FileResource f=(FileResource)o;
|
||||
return f._file == _file || (null != _file && _file.equals(f._file));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return the hashcode.
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
return null == _file ? super.hashCode() : _file.hashCode();
|
||||
}
|
||||
}
|
@ -1,253 +0,0 @@
|
||||
// ========================================================================
|
||||
// $Id: InetAddrPort.java,v 1.7 2004/10/23 09:03:22 gregwilkins Exp $
|
||||
// Copyright 1996-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.mortbay.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.InetAddress;
|
||||
|
||||
/* ======================================================================== */
|
||||
/** InetAddress and Port.
|
||||
*/
|
||||
public class InetAddrPort implements Serializable
|
||||
{
|
||||
/* ------------------------------------------------------------ */
|
||||
public final static String __0_0_0_0 = "0.0.0.0";
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private InetAddress _addr=null;
|
||||
private boolean _addrIsHost=false;
|
||||
private int _port=0;
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
public InetAddrPort()
|
||||
{}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor for a port on all local host address.
|
||||
* @param port
|
||||
*/
|
||||
public InetAddrPort(int port)
|
||||
{
|
||||
_port=port;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param addr
|
||||
* @param port
|
||||
*/
|
||||
public InetAddrPort(InetAddress addr, int port)
|
||||
{
|
||||
_addr=addr;
|
||||
_port=port;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param host
|
||||
* @param port
|
||||
*/
|
||||
public InetAddrPort(String host, int port)
|
||||
throws java.net.UnknownHostException
|
||||
{
|
||||
setHost(host);
|
||||
setPort(port);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* Patched to support [::1]:port for I2P
|
||||
*
|
||||
* @param inetAddrPort String of the form "addr:port"
|
||||
*/
|
||||
public InetAddrPort(String inetAddrPort)
|
||||
throws java.net.UnknownHostException
|
||||
{
|
||||
int b = inetAddrPort.indexOf('[');
|
||||
if (b>0)
|
||||
throw new java.net.UnknownHostException("Bad [] syntax");
|
||||
if (b==0) // IPV6
|
||||
{
|
||||
int b2 = inetAddrPort.indexOf(']');
|
||||
if (b2<2)
|
||||
throw new java.net.UnknownHostException("Bad [] syntax");
|
||||
String addr=inetAddrPort.substring(1,b2);
|
||||
if (addr.indexOf('/')>0)
|
||||
addr=addr.substring(addr.indexOf('/')+1);
|
||||
inetAddrPort=inetAddrPort.substring(b2+1);
|
||||
int c = inetAddrPort.indexOf(':');
|
||||
if (c>0)
|
||||
throw new java.net.UnknownHostException("Bad [] syntax");
|
||||
if (c==0)
|
||||
inetAddrPort=inetAddrPort.substring(1);
|
||||
|
||||
if (addr.length()>0 && ! __0_0_0_0.equals(addr))
|
||||
{
|
||||
_addrIsHost=!Character.isDigit((addr.charAt(0)));
|
||||
this._addr=InetAddress.getByName(addr);
|
||||
}
|
||||
} else { // IPV4
|
||||
int c = inetAddrPort.indexOf(':');
|
||||
if (c>=0)
|
||||
{
|
||||
String addr=inetAddrPort.substring(0,c);
|
||||
if (addr.indexOf('/')>0)
|
||||
addr=addr.substring(addr.indexOf('/')+1);
|
||||
inetAddrPort=inetAddrPort.substring(c+1);
|
||||
|
||||
if (addr.length()>0 && ! __0_0_0_0.equals(addr))
|
||||
{
|
||||
_addrIsHost=!Character.isDigit((addr.charAt(0)));
|
||||
this._addr=InetAddress.getByName(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_port = Integer.parseInt(inetAddrPort);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param address InetAddrPort top copy.
|
||||
*/
|
||||
public InetAddrPort(InetAddrPort address)
|
||||
{
|
||||
if (address!=null)
|
||||
{
|
||||
_addr=address._addr;
|
||||
_port=address._port;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the Host.
|
||||
* @return The IP address
|
||||
*/
|
||||
public String getHost()
|
||||
{
|
||||
if (_addr==null)
|
||||
return __0_0_0_0;
|
||||
|
||||
return _addrIsHost?_addr.getHostName():_addr.getHostAddress();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the Host.
|
||||
* @param host
|
||||
* @exception java.net.UnknownHostException
|
||||
*/
|
||||
public void setHost(String host)
|
||||
throws java.net.UnknownHostException
|
||||
{
|
||||
_addr=null;
|
||||
if (host!=null)
|
||||
{
|
||||
if (host.indexOf('/')>0)
|
||||
host=host.substring(0,host.indexOf('/'));
|
||||
_addrIsHost=!Character.isDigit((host.charAt(0)));
|
||||
_addr=InetAddress.getByName(host);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the IP address.
|
||||
* @return The IP address
|
||||
*/
|
||||
public InetAddress getInetAddress()
|
||||
{
|
||||
return _addr;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the IP address.
|
||||
* @param addr The IP address
|
||||
*/
|
||||
public void setInetAddress(InetAddress addr)
|
||||
{
|
||||
_addrIsHost=false;
|
||||
_addr=addr;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the port.
|
||||
* @return The port number
|
||||
*/
|
||||
public int getPort()
|
||||
{
|
||||
return _port;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the port.
|
||||
* @param port The port number
|
||||
*/
|
||||
public void setPort(int port)
|
||||
{
|
||||
_port=port;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
public String toString()
|
||||
{
|
||||
return getHost()+':'+_port;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Clone the InetAddrPort.
|
||||
* @return A new instance.
|
||||
*/
|
||||
public Object clone()
|
||||
{
|
||||
return new InetAddrPort(this);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Hash Code.
|
||||
* @return hash Code.
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
return _port+((_addr==null)?0:_addr.hashCode());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Equals.
|
||||
* @param o
|
||||
* @return True if is the same address and port.
|
||||
*/
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (o==null)
|
||||
return false;
|
||||
if (o==this)
|
||||
return true;
|
||||
if (o instanceof InetAddrPort)
|
||||
{
|
||||
InetAddrPort addr=(InetAddrPort)o;
|
||||
return addr._port==_port &&
|
||||
( addr._addr==_addr ||
|
||||
addr._addr!=null && addr._addr.equals(_addr));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,431 +0,0 @@
|
||||
// ========================================================================
|
||||
// $Id: Resource.java,v 1.32 2009/05/16 01:53:36 gregwilkins Exp $
|
||||
// Copyright 1996-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.mortbay.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.mortbay.log.LogFactory;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Abstract resource class.
|
||||
*
|
||||
* @version $Id: Resource.java,v 1.32 2009/05/16 01:53:36 gregwilkins Exp $
|
||||
* @author Nuno Preguica
|
||||
* @author Greg Wilkins (gregw)
|
||||
*/
|
||||
public abstract class Resource implements Serializable
|
||||
{
|
||||
private static Log log = LogFactory.getLog(Resource.class);
|
||||
|
||||
Object _associate;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Construct a resource from a url.
|
||||
* @param url A URL.
|
||||
* @return A Resource object.
|
||||
*/
|
||||
public static Resource newResource(URL url)
|
||||
throws IOException
|
||||
{
|
||||
if (url==null)
|
||||
return null;
|
||||
|
||||
String urls=url.toExternalForm();
|
||||
if( urls.startsWith( "file:"))
|
||||
{
|
||||
try
|
||||
{
|
||||
FileResource fileResource= new FileResource(url);
|
||||
return fileResource;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
log.debug(LogSupport.EXCEPTION,e);
|
||||
return new BadResource(url,e.toString());
|
||||
}
|
||||
}
|
||||
else if( urls.startsWith( "jar:file:"))
|
||||
{
|
||||
return new JarFileResource(url);
|
||||
}
|
||||
else if( urls.startsWith( "jar:"))
|
||||
{
|
||||
return new JarResource(url);
|
||||
}
|
||||
|
||||
return new URLResource(url,null);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Construct a resource from a string.
|
||||
* @param resource A URL or filename.
|
||||
* @return A Resource object.
|
||||
*/
|
||||
public static Resource newResource(String resource)
|
||||
throws MalformedURLException, IOException
|
||||
{
|
||||
URL url=null;
|
||||
try
|
||||
{
|
||||
// Try to format as a URL?
|
||||
url = new URL(resource);
|
||||
}
|
||||
catch(MalformedURLException e)
|
||||
{
|
||||
if(!resource.startsWith("ftp:") &&
|
||||
!resource.startsWith("file:") &&
|
||||
!resource.startsWith("jar:"))
|
||||
{
|
||||
try
|
||||
{
|
||||
// It's a file.
|
||||
if (resource.startsWith("./"))
|
||||
resource=resource.substring(2);
|
||||
|
||||
File file=new File(resource).getCanonicalFile();
|
||||
url=file.toURI().toURL();
|
||||
|
||||
URLConnection connection=url.openConnection();
|
||||
FileResource fileResource= new FileResource(url,connection,file);
|
||||
return fileResource;
|
||||
}
|
||||
catch(Exception e2)
|
||||
{
|
||||
log.debug(LogSupport.EXCEPTION,e2);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log.warn("Bad Resource: "+resource);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
String nurl=url.toString();
|
||||
if (nurl.length()>0 &&
|
||||
nurl.charAt(nurl.length()-1)!=
|
||||
resource.charAt(resource.length()-1))
|
||||
{
|
||||
if ((nurl.charAt(nurl.length()-1)!='/' ||
|
||||
nurl.charAt(nurl.length()-2)!=resource.charAt(resource.length()-1))
|
||||
&&
|
||||
(resource.charAt(resource.length()-1)!='/' ||
|
||||
resource.charAt(resource.length()-2)!=nurl.charAt(nurl.length()-1)
|
||||
))
|
||||
{
|
||||
return new BadResource(url,"Trailing special characters stripped by URL in "+resource);
|
||||
}
|
||||
}
|
||||
return newResource(url);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Construct a system resource from a string.
|
||||
* The resource is tried as classloader resource before being
|
||||
* treated as a normal resource.
|
||||
*/
|
||||
public static Resource newSystemResource(String resource)
|
||||
throws IOException
|
||||
{
|
||||
URL url=null;
|
||||
// Try to format as a URL?
|
||||
ClassLoader
|
||||
loader=Thread.currentThread().getContextClassLoader();
|
||||
if (loader!=null)
|
||||
{
|
||||
url=loader.getResource(resource);
|
||||
if (url==null && resource.startsWith("/"))
|
||||
url=loader.getResource(resource.substring(1));
|
||||
}
|
||||
if (url==null)
|
||||
{
|
||||
loader=Resource.class.getClassLoader();
|
||||
if (loader!=null)
|
||||
{
|
||||
url=loader.getResource(resource);
|
||||
if (url==null && resource.startsWith("/"))
|
||||
url=loader.getResource(resource.substring(1));
|
||||
}
|
||||
}
|
||||
|
||||
if (url==null)
|
||||
{
|
||||
url=ClassLoader.getSystemResource(resource);
|
||||
if (url==null && resource.startsWith("/"))
|
||||
url=loader.getResource(resource.substring(1));
|
||||
}
|
||||
|
||||
if (url==null)
|
||||
return null;
|
||||
|
||||
return newResource(url);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected void finalize()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Release any resources held by the resource.
|
||||
*/
|
||||
public abstract void release();
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns true if the respresened resource exists.
|
||||
*/
|
||||
public abstract boolean exists();
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns true if the respresenetd resource is a container/directory.
|
||||
* If the resource is not a file, resources ending with "/" are
|
||||
* considered directories.
|
||||
*/
|
||||
public abstract boolean isDirectory();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns the last modified time
|
||||
*/
|
||||
public abstract long lastModified();
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Return the length of the resource
|
||||
*/
|
||||
public abstract long length();
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns an URL representing the given resource
|
||||
*/
|
||||
public abstract URL getURL();
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns an File representing the given resource or NULL if this
|
||||
* is not possible.
|
||||
*/
|
||||
public abstract File getFile()
|
||||
throws IOException;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns the name of the resource
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns an input stream to the resource
|
||||
*/
|
||||
public abstract InputStream getInputStream()
|
||||
throws java.io.IOException;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns an output stream to the resource
|
||||
*/
|
||||
public abstract OutputStream getOutputStream()
|
||||
throws java.io.IOException, SecurityException;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Deletes the given resource
|
||||
*/
|
||||
public abstract boolean delete()
|
||||
throws SecurityException;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Rename the given resource
|
||||
*/
|
||||
public abstract boolean renameTo( Resource dest)
|
||||
throws SecurityException;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns a list of resource names contained in the given resource
|
||||
* The resource names are not URL encoded.
|
||||
*/
|
||||
public abstract String[] list();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns the resource contained inside the current resource with the
|
||||
* given name.
|
||||
* @param path The path segment to add, which should be encoded by the
|
||||
* encode method.
|
||||
*/
|
||||
public abstract Resource addPath(String path)
|
||||
throws IOException,MalformedURLException;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Encode according to this resource type.
|
||||
* The default implementation calls URI.encodePath(uri)
|
||||
* @param uri
|
||||
* @return String encoded for this resource type.
|
||||
*/
|
||||
public String encode(String uri)
|
||||
{
|
||||
return URI.encodePath(uri);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Object getAssociate()
|
||||
{
|
||||
return _associate;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setAssociate(Object o)
|
||||
{
|
||||
_associate=o;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The canonical Alias of this resource or null if none.
|
||||
*/
|
||||
public URL getAlias()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public CachedResource cache()
|
||||
throws IOException
|
||||
{
|
||||
return new CachedResource(this);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the resource list as a HTML directory listing.
|
||||
* @param base The base URL
|
||||
* @param parent True if the parent directory should be included
|
||||
* @return String of HTML
|
||||
*/
|
||||
public String getListHTML(String base,
|
||||
boolean parent)
|
||||
throws IOException
|
||||
{
|
||||
if (!isDirectory())
|
||||
return null;
|
||||
|
||||
|
||||
String[] ls = list();
|
||||
if (ls==null)
|
||||
return null;
|
||||
Arrays.sort(ls);
|
||||
|
||||
String title = "Directory: "+URI.decodePath(base);
|
||||
title=StringUtil.replace(StringUtil.replace(title,"<","<"),">",">");
|
||||
StringBuffer buf=new StringBuffer(4096);
|
||||
buf.append("<HTML><HEAD><TITLE>");
|
||||
buf.append(title);
|
||||
buf.append("</TITLE></HEAD><BODY>\n<H1>");
|
||||
buf.append(title);
|
||||
buf.append("</H1><TABLE BORDER=0>");
|
||||
|
||||
if (parent)
|
||||
{
|
||||
buf.append("<TR><TD><A HREF=");
|
||||
buf.append(URI.encodePath(URI.addPaths(base,"../")));
|
||||
buf.append(">Parent Directory</A></TD><TD></TD><TD></TD></TR>\n");
|
||||
}
|
||||
|
||||
DateFormat dfmt=DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
|
||||
DateFormat.MEDIUM);
|
||||
for (int i=0 ; i< ls.length ; i++)
|
||||
{
|
||||
String encoded=URI.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 = addPath(ls[i]);
|
||||
|
||||
buf.append("<TR><TD><A HREF=\"");
|
||||
|
||||
String path=URI.addPaths(base,encoded);
|
||||
|
||||
if (item.isDirectory() && !path.endsWith("/"))
|
||||
path=URI.addPaths(path,"/");
|
||||
buf.append(path);
|
||||
buf.append("\">");
|
||||
buf.append(StringUtil.replace(StringUtil.replace(ls[i],"<","<"),">",">"));
|
||||
buf.append("</A> ");
|
||||
buf.append("</TD><TD ALIGN=right>");
|
||||
buf.append(item.length());
|
||||
buf.append(" bytes </TD><TD>");
|
||||
buf.append(dfmt.format(new Date(item.lastModified())));
|
||||
buf.append("</TD></TR>\n");
|
||||
}
|
||||
buf.append("</TABLE>\n");
|
||||
buf.append("</BODY></HTML>\n");
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param out
|
||||
* @param start First byte to write
|
||||
* @param count Bytes to write or -1 for all of them.
|
||||
*/
|
||||
public void writeTo(OutputStream out,long start,long count)
|
||||
throws IOException
|
||||
{
|
||||
InputStream in = getInputStream();
|
||||
try
|
||||
{
|
||||
in.skip(start);
|
||||
if (count<0)
|
||||
IO.copy(in,out);
|
||||
else
|
||||
IO.copy(in,out,(int)count);
|
||||
}
|
||||
finally
|
||||
{
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
9
apps/jetty/resources/log4j.properties
Normal file
9
apps/jetty/resources/log4j.properties
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
# This is not needed by Jetty - but it helps with many web apps.
|
||||
|
||||
log4j.rootLogger=INFO, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
|
||||
|
@ -21,7 +21,12 @@
|
||||
<pathelement location="../../../core/java/build/obj" />
|
||||
<pathelement location="../../../router/java/build/obj" />
|
||||
<pathelement location="../../jetty/jettylib/org.mortbay.jetty.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/javax.servlet.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-i2p.jar" />
|
||||
<pathelement location="../../systray/java/build/obj" />
|
||||
<pathelement location="../../systray/java/lib/systray4j.jar" />
|
||||
<pathelement location="../../desktopgui/build" />
|
||||
@ -54,7 +59,12 @@
|
||||
<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-util.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-sslengine.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-java5-threadpool.jar" />
|
||||
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-i2p.jar" />
|
||||
<pathelement location="../../systray/java/build/systray.jar" />
|
||||
<pathelement location="../../systray/java/lib/systray4j.jar" />
|
||||
<pathelement location="../../desktopgui/dist/desktopgui.jar" />
|
||||
@ -236,7 +246,9 @@
|
||||
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
|
||||
<pathelement location="../../jetty/jettylib/commons-logging.jar" />
|
||||
<pathelement location="../../jetty/jettylib/commons-el.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
|
||||
<pathelement location="../../jetty/jettylib/ant.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-i2p.jar" />
|
||||
<pathelement location="../../systray/java/build/obj" />
|
||||
<pathelement location="../../systray/java/lib/systray4j.jar" />
|
||||
<pathelement location="../../desktopgui/dist/desktopgui.jar" />
|
||||
@ -269,6 +281,11 @@
|
||||
<pathelement location="../../jetty/jettylib/commons-logging.jar" />
|
||||
<pathelement location="../../jetty/jettylib/commons-el.jar" />
|
||||
<pathelement location="../../jetty/jettylib/org.mortbay.jetty.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/jsp-api.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-i2p.jar" />
|
||||
<pathelement location="../../systray/java/build/obj" />
|
||||
<pathelement location="../../systray/java/lib/systray4j.jar" />
|
||||
<pathelement location="../../desktopgui/dist/desktopgui.jar" />
|
||||
|
@ -14,7 +14,7 @@ import net.i2p.router.client.ClientManagerFacadeImpl;
|
||||
import net.i2p.router.startup.ClientAppConfig;
|
||||
import net.i2p.router.startup.LoadClientAppsJob;
|
||||
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.handler.ContextHandlerCollection;
|
||||
|
||||
/**
|
||||
* Saves changes to clients.config or webapps.config
|
||||
@ -290,7 +290,7 @@ public class ConfigClientsHandler extends FormHandler {
|
||||
* requested and add the .war to that one
|
||||
*/
|
||||
private void startWebApp(String app) {
|
||||
Server s = WebAppStarter.getConsoleServer();
|
||||
ContextHandlerCollection s = WebAppStarter.getConsoleServer();
|
||||
if (s != null) {
|
||||
try {
|
||||
File path = new File(_context.getBaseDir(), "webapps");
|
||||
|
@ -4,11 +4,13 @@ import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
|
||||
import org.mortbay.http.HttpRequest;
|
||||
import org.mortbay.http.HttpResponse;
|
||||
import org.mortbay.jetty.servlet.WebApplicationHandler;
|
||||
import org.mortbay.jetty.webapp.WebAppContext;
|
||||
|
||||
/**
|
||||
* Convert foo.jsp to foo_xx.jsp for language xx.
|
||||
@ -19,12 +21,12 @@ import org.mortbay.jetty.servlet.WebApplicationHandler;
|
||||
*
|
||||
* @author zzz
|
||||
*/
|
||||
public class LocaleWebAppHandler extends WebApplicationHandler
|
||||
public class LocaleWebAppHandler extends WebAppContext
|
||||
{
|
||||
private final I2PAppContext _context;
|
||||
|
||||
public LocaleWebAppHandler(I2PAppContext ctx) {
|
||||
super();
|
||||
public LocaleWebAppHandler(I2PAppContext ctx, String path, String warPath) {
|
||||
super(warPath, path);
|
||||
_context = ctx;
|
||||
}
|
||||
|
||||
@ -36,13 +38,13 @@ public class LocaleWebAppHandler extends WebApplicationHandler
|
||||
*/
|
||||
@Override
|
||||
public void handle(String pathInContext,
|
||||
String pathParams,
|
||||
HttpRequest httpRequest,
|
||||
HttpResponse httpResponse)
|
||||
throws IOException
|
||||
HttpServletRequest httpRequest,
|
||||
HttpServletResponse httpResponse,
|
||||
int dispatch)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
// Handle OPTIONS (nothing to override)
|
||||
if (HttpRequest.__OPTIONS.equals(httpRequest.getMethod()))
|
||||
if ("OPTIONS".equals(httpRequest.getMethod()))
|
||||
{
|
||||
handleOptions(httpRequest, httpResponse);
|
||||
return;
|
||||
@ -74,7 +76,7 @@ public class LocaleWebAppHandler extends WebApplicationHandler
|
||||
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 = getHolderEntry(testPath);
|
||||
Map.Entry servlet = getServletHandler().getHolderEntry(testPath);
|
||||
if (servlet != null) {
|
||||
String servletPath = (String) servlet.getKey();
|
||||
if (servletPath != null && !servletPath.startsWith("*")) {
|
||||
@ -87,7 +89,7 @@ public class LocaleWebAppHandler extends WebApplicationHandler
|
||||
}
|
||||
}
|
||||
//System.err.println("New path: " + newPath);
|
||||
super.handle(newPath, pathParams, httpRequest, httpResponse);
|
||||
super.handle(newPath, httpRequest, httpResponse, dispatch);
|
||||
//System.err.println("Was handled? " + httpRequest.isHandled());
|
||||
}
|
||||
|
||||
@ -95,22 +97,24 @@ public class LocaleWebAppHandler extends WebApplicationHandler
|
||||
* Overrides method in ServletHandler
|
||||
* @since 0.8
|
||||
*/
|
||||
/**** not in Jetty 6
|
||||
@Override
|
||||
public void handleTrace(HttpRequest request,
|
||||
HttpResponse response)
|
||||
public void handleTrace(HttpServletRequest request,
|
||||
HttpServletResponse response)
|
||||
throws IOException
|
||||
{
|
||||
response.sendError(HttpResponse.__405_Method_Not_Allowed);
|
||||
response.sendError(405);
|
||||
}
|
||||
****/
|
||||
|
||||
/**
|
||||
* Not an override
|
||||
* @since 0.8
|
||||
*/
|
||||
public void handleOptions(HttpRequest request,
|
||||
HttpResponse response)
|
||||
public void handleOptions(HttpServletRequest request,
|
||||
HttpServletResponse response)
|
||||
throws IOException
|
||||
{
|
||||
response.sendError(HttpResponse.__405_Method_Not_Allowed);
|
||||
response.sendError(405);
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import java.util.List;
|
||||
import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.VersionComparator;
|
||||
|
||||
import org.mortbay.http.Version;
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.tanukisoftware.wrapper.WrapperManager;
|
||||
|
||||
public class LogsHelper extends HelperBase {
|
||||
@ -15,19 +15,12 @@ public class LogsHelper extends HelperBase {
|
||||
|
||||
/** @since 0.8.12 */
|
||||
public String getJettyVersion() {
|
||||
return jettyVersion();
|
||||
return Server.getVersion();
|
||||
}
|
||||
|
||||
|
||||
/** @since 0.8.13 */
|
||||
static String jettyVersion() {
|
||||
try {
|
||||
String rv = Version.getImplVersion();
|
||||
if (rv.startsWith("Jetty/"))
|
||||
rv = rv.substring(6);
|
||||
return rv;
|
||||
} catch (Throwable t) {
|
||||
return "unknown";
|
||||
}
|
||||
return Server.getVersion();
|
||||
}
|
||||
|
||||
public String getLogs() {
|
||||
|
@ -32,7 +32,7 @@ import net.i2p.util.Log;
|
||||
import net.i2p.util.Translate;
|
||||
import net.i2p.util.VersionComparator;
|
||||
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.handler.ContextHandlerCollection;
|
||||
|
||||
|
||||
/**
|
||||
@ -254,7 +254,7 @@ public class PluginStarter implements Runnable {
|
||||
}
|
||||
|
||||
// start console webapps in console/webapps
|
||||
Server server = WebAppStarter.getConsoleServer();
|
||||
ContextHandlerCollection server = WebAppStarter.getConsoleServer();
|
||||
if (server != null) {
|
||||
File consoleDir = new File(pluginDir, "console");
|
||||
Properties wprops = RouterConsoleRunner.webAppProperties(consoleDir.getAbsolutePath());
|
||||
@ -354,8 +354,8 @@ public class PluginStarter implements Runnable {
|
||||
}
|
||||
|
||||
// stop console webapps in console/webapps
|
||||
Server server = WebAppStarter.getConsoleServer();
|
||||
if (server != null) {
|
||||
//ContextHandlerCollection server = WebAppStarter.getConsoleServer();
|
||||
//if (server != null) {
|
||||
/*
|
||||
File consoleDir = new File(pluginDir, "console");
|
||||
Properties props = RouterConsoleRunner.webAppProperties(consoleDir.getAbsolutePath());
|
||||
@ -375,11 +375,11 @@ public class PluginStarter implements Runnable {
|
||||
Iterator <String> wars = pluginWars.get(appName).iterator();
|
||||
while (wars.hasNext()) {
|
||||
String warName = wars.next();
|
||||
WebAppStarter.stopWebApp(server, warName);
|
||||
WebAppStarter.stopWebApp(warName);
|
||||
}
|
||||
pluginWars.get(appName).clear();
|
||||
}
|
||||
}
|
||||
//}
|
||||
|
||||
// remove summary bar link
|
||||
Properties props = pluginProperties(ctx, appName);
|
||||
|
@ -11,12 +11,18 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.apps.systray.SysTray;
|
||||
import net.i2p.data.Base32;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.desktopgui.Main;
|
||||
import net.i2p.jetty.I2PLogger;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
@ -26,25 +32,41 @@ import net.i2p.util.SecureFileOutputStream;
|
||||
import net.i2p.util.ShellCommand;
|
||||
import net.i2p.util.VersionComparator;
|
||||
|
||||
import org.mortbay.http.DigestAuthenticator;
|
||||
import org.mortbay.http.HashUserRealm;
|
||||
import org.mortbay.http.NCSARequestLog;
|
||||
import org.mortbay.http.SecurityConstraint;
|
||||
import org.mortbay.http.SocketListener;
|
||||
import org.mortbay.http.SslListener;
|
||||
import org.mortbay.http.handler.SecurityHandler;
|
||||
import org.mortbay.jetty.AbstractConnector;
|
||||
import org.mortbay.jetty.Connector;
|
||||
import org.mortbay.jetty.Handler;
|
||||
import org.mortbay.jetty.NCSARequestLog;
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.servlet.WebApplicationContext;
|
||||
import org.mortbay.jetty.servlet.WebApplicationHandler;
|
||||
import org.mortbay.util.InetAddrPort;
|
||||
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.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.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.log.Log;
|
||||
import org.mortbay.thread.QueuedThreadPool;
|
||||
import org.mortbay.thread.concurrent.ThreadPool;
|
||||
|
||||
/**
|
||||
* Start the router console.
|
||||
*/
|
||||
public class RouterConsoleRunner {
|
||||
private Server _server;
|
||||
private static Server _server;
|
||||
private String _listenPort;
|
||||
private String _listenHost;
|
||||
private String _sslListenPort;
|
||||
private String _sslListenHost;
|
||||
private String _webAppsDir;
|
||||
|
||||
private static final String PROP_WEBAPP_CONFIG_FILENAME = "router.webappsConfigFile";
|
||||
private static final String DEFAULT_WEBAPP_CONFIG_FILENAME = "webapps.config";
|
||||
private static final DigestAuthenticator authenticator = new DigestAuthenticator();
|
||||
@ -59,6 +81,11 @@ public class RouterConsoleRunner {
|
||||
private static final String DEFAULT_WEBAPPS_DIR = "./webapps/";
|
||||
private static final String USAGE = "Bad RouterConsoleRunner arguments, check clientApp.0.args in your clients.config file! " +
|
||||
"Usage: [[port host[,host]] [-s sslPort [host[,host]]] [webAppsDir]]";
|
||||
|
||||
private static final int MIN_THREADS = 1;
|
||||
private static final int MAX_THREADS = 24;
|
||||
private static final int MAX_IDLE_TIME = 90*1000;
|
||||
private static final String THREAD_NAME = "RouterConsole Jetty";
|
||||
|
||||
static {
|
||||
System.setProperty("org.mortbay.http.Version.paranoid", "true");
|
||||
@ -137,6 +164,15 @@ public class RouterConsoleRunner {
|
||||
runner.startConsole();
|
||||
}
|
||||
|
||||
/**
|
||||
* SInce _server is now static
|
||||
* @return may be null or stopped perhaps
|
||||
* @since Jetty 6 since it doesn't have Server.getServers()
|
||||
*/
|
||||
static Server getConsoleServer() {
|
||||
return _server;
|
||||
}
|
||||
|
||||
private static void startTrayApp() {
|
||||
try {
|
||||
//TODO: move away from routerconsole into a separate application.
|
||||
@ -160,6 +196,24 @@ public class RouterConsoleRunner {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* http://irc.codehaus.org/display/JETTY/Porting+to+jetty6
|
||||
*
|
||||
*<pre>
|
||||
* Server
|
||||
* HandlerCollection
|
||||
* ContextHandlerCollection
|
||||
* WebAppContext (i.e. ContextHandler)
|
||||
* SessionHandler
|
||||
* SecurityHandler
|
||||
* ServletHandler
|
||||
* servlets...
|
||||
* WebAppContext
|
||||
* ...
|
||||
* DefaultHandler
|
||||
* RequestLogHandler (opt)
|
||||
*</pre>
|
||||
*/
|
||||
public void startConsole() {
|
||||
File workDir = new SecureDirectory(I2PAppContext.getGlobalContext().getTempDir(), "jetty-work");
|
||||
boolean workDirRemoved = FileUtil.rmdir(workDir, false);
|
||||
@ -169,9 +223,37 @@ public class RouterConsoleRunner {
|
||||
if (!workDirCreated)
|
||||
System.err.println("ERROR: Unable to create Jetty temporary work directory");
|
||||
|
||||
//try {
|
||||
// Log.setLog(new I2PLogger(I2PAppContext.getGlobalContext()));
|
||||
//} catch (Throwable t) {
|
||||
// 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");
|
||||
|
||||
// so Jetty can find WebAppConfiguration
|
||||
System.setProperty("jetty.class.path", I2PAppContext.getGlobalContext().getBaseDir() + "/lib/routerconsole.jar");
|
||||
_server = new Server();
|
||||
_server.setGracefulShutdown(1000);
|
||||
|
||||
try {
|
||||
ThreadPool ctp = new CustomThreadPoolExecutor();
|
||||
ctp.prestartAllCoreThreads();
|
||||
_server.setThreadPool(ctp);
|
||||
} catch (Throwable t) {
|
||||
// class not found...
|
||||
System.out.println("INFO: Jetty concurrent ThreadPool unavailable, using QueuedThreadPool");
|
||||
QueuedThreadPool qtp = new QueuedThreadPool(MAX_THREADS);
|
||||
qtp.setMinThreads(MIN_THREADS);
|
||||
qtp.setMaxIdleTimeMs(MAX_IDLE_TIME);
|
||||
_server.setThreadPool(qtp);
|
||||
}
|
||||
|
||||
HandlerCollection hColl = new HandlerCollection();
|
||||
ContextHandlerCollection chColl = new ContextHandlerCollection();
|
||||
_server.addHandler(hColl);
|
||||
hColl.addHandler(chColl);
|
||||
hColl.addHandler(new DefaultHandler());
|
||||
|
||||
String log = I2PAppContext.getGlobalContext().getProperty("routerconsole.log");
|
||||
if (log != null) {
|
||||
@ -179,8 +261,10 @@ public class RouterConsoleRunner {
|
||||
if (!logFile.isAbsolute())
|
||||
logFile = new File(I2PAppContext.getGlobalContext().getLogDir(), "logs/" + log);
|
||||
try {
|
||||
_server.setRequestLog(new NCSARequestLog(logFile.getAbsolutePath()));
|
||||
} catch (IOException ioe) {
|
||||
RequestLogHandler rhl = new RequestLogHandler();
|
||||
rhl.setRequestLog(new NCSARequestLog(logFile.getAbsolutePath()));
|
||||
hColl.addHandler(rhl);
|
||||
} catch (Exception ioe) {
|
||||
System.err.println("ERROR: Unable to create Jetty log: " + ioe);
|
||||
}
|
||||
}
|
||||
@ -203,8 +287,8 @@ public class RouterConsoleRunner {
|
||||
if (!_webAppsDir.endsWith("/"))
|
||||
_webAppsDir += '/';
|
||||
|
||||
List<String> notStarted = new ArrayList();
|
||||
WebApplicationHandler baseHandler = null;
|
||||
WebAppContext rootWebApp = null;
|
||||
ServletHandler rootServletHandler = null;
|
||||
try {
|
||||
int boundAddresses = 0;
|
||||
|
||||
@ -219,17 +303,17 @@ public class RouterConsoleRunner {
|
||||
// _server.addListener('[' + host + "]:" + _listenPort);
|
||||
//else
|
||||
// _server.addListener(host + ':' + _listenPort);
|
||||
InetAddrPort iap = new InetAddrPort(host, lport);
|
||||
SocketListener lsnr = new SocketListener(iap);
|
||||
lsnr.setMinThreads(1); // default 2
|
||||
lsnr.setMaxThreads(24); // default 256
|
||||
lsnr.setMaxIdleTimeMs(90*1000); // default 10 sec
|
||||
// Use AbstractConnector instead of Connector so we can do setName()
|
||||
AbstractConnector lsnr = new SelectChannelConnector();
|
||||
lsnr.setHost(host);
|
||||
lsnr.setPort(lport);
|
||||
lsnr.setMaxIdleTime(90*1000); // default 10 sec
|
||||
lsnr.setName("ConsoleSocket"); // all with same name will use the same thread pool
|
||||
_server.addListener(lsnr);
|
||||
_server.addConnector(lsnr);
|
||||
boundAddresses++;
|
||||
} catch (NumberFormatException nfe) {
|
||||
System.err.println("Unable to bind routerconsole to " + host + " port " + _listenPort + ' ' + nfe);
|
||||
} catch (IOException ioe) { // this doesn't seem to work, exceptions don't happen until start() below
|
||||
} catch (Exception ioe) { // this doesn't seem to work, exceptions don't happen until start() below
|
||||
System.err.println("Unable to bind routerconsole to " + host + " port " + _listenPort + ' ' + ioe);
|
||||
}
|
||||
}
|
||||
@ -254,19 +338,20 @@ public class RouterConsoleRunner {
|
||||
while (tok.hasMoreTokens()) {
|
||||
String host = tok.nextToken().trim();
|
||||
// doing it this way means we don't have to escape an IPv6 host with []
|
||||
InetAddrPort iap = new InetAddrPort(host, sslPort);
|
||||
try {
|
||||
SslListener ssll = new SslListener(iap);
|
||||
// TODO if class not found use SslChannelConnector
|
||||
// Sadly there's no common base class with the ssl methods in it
|
||||
SslSelectChannelConnector ssll = new SslSelectChannelConnector();
|
||||
ssll.setHost(host);
|
||||
ssll.setPort(sslPort);
|
||||
// the keystore path and password
|
||||
ssll.setKeystore(keyStore.getAbsolutePath());
|
||||
ssll.setPassword(ctx.getProperty(PROP_KEYSTORE_PASSWORD, DEFAULT_KEYSTORE_PASSWORD));
|
||||
// the X.509 cert password (if not present, verifyKeyStore() returned false)
|
||||
ssll.setKeyPassword(ctx.getProperty(PROP_KEY_PASSWORD, "thisWontWork"));
|
||||
ssll.setMinThreads(1); // default 2
|
||||
ssll.setMaxThreads(24); // default 256
|
||||
ssll.setMaxIdleTimeMs(90*1000); // default 10 sec
|
||||
ssll.setMaxIdleTime(90*1000); // default 10 sec
|
||||
ssll.setName("ConsoleSocket"); // all with same name will use the same thread pool
|
||||
_server.addListener(ssll);
|
||||
_server.addConnector(ssll);
|
||||
boundAddresses++;
|
||||
} catch (Exception e) { // probably no exceptions at this point
|
||||
System.err.println("Unable to bind routerconsole to " + host + " port " + sslPort + " for SSL: " + e);
|
||||
@ -282,47 +367,25 @@ public class RouterConsoleRunner {
|
||||
System.err.println("Unable to bind routerconsole to any address on port " + _listenPort + (sslPort > 0 ? (" or SSL port " + sslPort) : ""));
|
||||
return;
|
||||
}
|
||||
_server.setRootWebApp(ROUTERCONSOLE);
|
||||
WebApplicationContext wac = _server.addWebApplication("/", _webAppsDir + ROUTERCONSOLE + ".war");
|
||||
|
||||
rootWebApp = new LocaleWebAppHandler(I2PAppContext.getGlobalContext(),
|
||||
"/", _webAppsDir + ROUTERCONSOLE + ".war");
|
||||
File tmpdir = new SecureDirectory(workDir, ROUTERCONSOLE + "-" +
|
||||
(_listenPort != null ? _listenPort : _sslListenPort));
|
||||
tmpdir.mkdir();
|
||||
wac.setTempDirectory(tmpdir);
|
||||
baseHandler = new LocaleWebAppHandler(I2PAppContext.getGlobalContext());
|
||||
wac.addHandler(0, baseHandler);
|
||||
initialize(wac);
|
||||
File dir = new File(_webAppsDir);
|
||||
String fileNames[] = dir.list(WarFilenameFilter.instance());
|
||||
if (fileNames != null) {
|
||||
for (int i = 0; i < fileNames.length; i++) {
|
||||
try {
|
||||
String appName = fileNames[i].substring(0, fileNames[i].lastIndexOf(".war"));
|
||||
String enabled = props.getProperty(PREFIX + appName + ENABLED);
|
||||
if (! "false".equals(enabled)) {
|
||||
String path = new File(dir, fileNames[i]).getCanonicalPath();
|
||||
tmpdir = new SecureDirectory(workDir, appName + "-" +
|
||||
(_listenPort != null ? _listenPort : _sslListenPort));
|
||||
WebAppStarter.addWebApp(I2PAppContext.getGlobalContext(), _server, appName, path, tmpdir);
|
||||
rootWebApp.setTempDirectory(tmpdir);
|
||||
rootWebApp.setSessionHandler(new SessionHandler());
|
||||
rootServletHandler = new ServletHandler();
|
||||
rootWebApp.setServletHandler(rootServletHandler);
|
||||
initialize(rootWebApp);
|
||||
chColl.addHandler(rootWebApp);
|
||||
|
||||
if (enabled == null) {
|
||||
// do this so configclients.jsp knows about all apps from reading the config
|
||||
props.setProperty(PREFIX + appName + ENABLED, "true");
|
||||
rewrite = true;
|
||||
}
|
||||
} else {
|
||||
notStarted.add(appName);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
System.err.println("Error resolving '" + fileNames[i] + "' in '" + dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
} catch (Exception ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
if (rewrite)
|
||||
storeWebAppProperties(props);
|
||||
|
||||
try {
|
||||
// start does a mapContexts()
|
||||
_server.start();
|
||||
} catch (Throwable me) {
|
||||
// NoClassFoundDefError from a webapp is a throwable, not an exception
|
||||
@ -335,14 +398,61 @@ public class RouterConsoleRunner {
|
||||
me.printStackTrace();
|
||||
}
|
||||
|
||||
if (baseHandler != null) {
|
||||
// Start all the other webapps after the server is up,
|
||||
// so things start faster.
|
||||
// Jetty 6 starts the connector before the router console is ready
|
||||
// This also prevents one webapp from breaking the whole thing
|
||||
List<String> notStarted = new ArrayList();
|
||||
if (_server.isRunning()) {
|
||||
File dir = new File(_webAppsDir);
|
||||
String fileNames[] = dir.list(WarFilenameFilter.instance());
|
||||
if (fileNames != null) {
|
||||
for (int i = 0; i < fileNames.length; i++) {
|
||||
String appName = fileNames[i].substring(0, fileNames[i].lastIndexOf(".war"));
|
||||
String enabled = props.getProperty(PREFIX + appName + ENABLED);
|
||||
if (! "false".equals(enabled)) {
|
||||
try {
|
||||
String path = new File(dir, fileNames[i]).getCanonicalPath();
|
||||
WebAppStarter.startWebApp(I2PAppContext.getGlobalContext(), chColl, appName, path);
|
||||
if (enabled == null) {
|
||||
// do this so configclients.jsp knows about all apps from reading the config
|
||||
props.setProperty(PREFIX + appName + ENABLED, "true");
|
||||
rewrite = true;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
System.err.println("ERROR: Failed to start " + appName + ' ' + t);
|
||||
t.printStackTrace();
|
||||
notStarted.add(appName);
|
||||
}
|
||||
} else {
|
||||
notStarted.add(appName);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
System.err.println("ERROR: Router console did not start, not starting webapps");
|
||||
}
|
||||
|
||||
if (rewrite)
|
||||
storeWebAppProperties(props);
|
||||
|
||||
if (rootServletHandler != null && notStarted.size() > 0) {
|
||||
// map each not-started webapp to the error page
|
||||
ServletHolder noWebApp = rootServletHandler.getServlet("net.i2p.router.web.jsp.nowebapp_jsp");
|
||||
for (int i = 0; i < notStarted.size(); i++) {
|
||||
// we want a new handler for each one since if the webapp is started we remove the handler???
|
||||
try {
|
||||
baseHandler.mapPathToServlet('/' + notStarted.get(i) + "/*",
|
||||
"net.i2p.router.web.jsp.nowebapp_jsp");
|
||||
if (noWebApp != null) {
|
||||
String path = '/' + notStarted.get(i);
|
||||
// LocaleWebAppsHandler adds a .jsp
|
||||
rootServletHandler.addServletWithMapping(noWebApp, path + ".jsp");
|
||||
rootServletHandler.addServletWithMapping(noWebApp, path + "/*");
|
||||
} else {
|
||||
System.err.println("Can't find nowebapp.jsp?");
|
||||
}
|
||||
} catch (Throwable me) {
|
||||
System.err.println(me);
|
||||
me.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -458,18 +568,22 @@ public class RouterConsoleRunner {
|
||||
return success;
|
||||
}
|
||||
|
||||
static void initialize(WebApplicationContext context) {
|
||||
static void initialize(WebAppContext context) {
|
||||
SecurityHandler sec = new SecurityHandler();
|
||||
List<ConstraintMapping> constraints = new ArrayList(4);
|
||||
String password = getPassword();
|
||||
if (password != null) {
|
||||
HashUserRealm realm = new HashUserRealm("i2prouter");
|
||||
realm.put("admin", password);
|
||||
realm.addUserToRole("admin", "routerAdmin");
|
||||
context.setRealm(realm);
|
||||
context.setAuthenticator(authenticator);
|
||||
context.addHandler(0, new SecurityHandler());
|
||||
SecurityConstraint constraint = new SecurityConstraint("admin", "routerAdmin");
|
||||
sec.setUserRealm(realm);
|
||||
sec.setAuthenticator(authenticator);
|
||||
Constraint constraint = new Constraint("admin", "routerAdmin");
|
||||
constraint.setAuthenticate(true);
|
||||
context.addSecurityConstraint("/", constraint);
|
||||
ConstraintMapping cm = new ConstraintMapping();
|
||||
cm.setConstraint(constraint);
|
||||
cm.setPathSpec("/");
|
||||
constraints.add(cm);
|
||||
}
|
||||
|
||||
// This forces a '403 Forbidden' response for TRACE and OPTIONS unless the
|
||||
@ -481,12 +595,27 @@ public class RouterConsoleRunner {
|
||||
// The other strange methods - PUT, DELETE, MOVE - are disabled by default
|
||||
// See also:
|
||||
// http://old.nabble.com/Disable-HTTP-TRACE-in-Jetty-5.x-td12412607.html
|
||||
SecurityConstraint sc = new SecurityConstraint();
|
||||
sc.setName("No trace or options");
|
||||
sc.addMethod("TRACE");
|
||||
sc.addMethod("OPTIONS");
|
||||
sc.setAuthenticate(true);
|
||||
context.addSecurityConstraint("/*", sc) ;
|
||||
|
||||
Constraint sc = new Constraint();
|
||||
sc.setName("No trace");
|
||||
ConstraintMapping cm = new ConstraintMapping();
|
||||
cm.setMethod("TRACE");
|
||||
cm.setConstraint(sc);
|
||||
cm.setPathSpec("/");
|
||||
constraints.add(cm);
|
||||
|
||||
sc = new Constraint();
|
||||
sc.setName("No options");
|
||||
cm = new ConstraintMapping();
|
||||
cm.setMethod("OPTIONS");
|
||||
cm.setConstraint(sc);
|
||||
cm.setPathSpec("/");
|
||||
constraints.add(cm);
|
||||
|
||||
ConstraintMapping cmarr[] = constraints.toArray(new ConstraintMapping[constraints.size()]);
|
||||
sec.setConstraintMappings(cmarr);
|
||||
|
||||
context.setSecurityHandler(sec);
|
||||
}
|
||||
|
||||
static String getPassword() {
|
||||
@ -511,11 +640,11 @@ public class RouterConsoleRunner {
|
||||
}
|
||||
|
||||
/** @since 0.8.8 */
|
||||
private class ServerShutdown implements Runnable {
|
||||
private static class ServerShutdown implements Runnable {
|
||||
public void run() {
|
||||
try {
|
||||
_server.stop();
|
||||
} catch (InterruptedException ie) {}
|
||||
} catch (Exception ie) {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -574,4 +703,31 @@ public class RouterConsoleRunner {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Just to set the name and set Daemon
|
||||
* @since Jetty 6
|
||||
*/
|
||||
private static class CustomThreadPoolExecutor extends ThreadPool {
|
||||
public CustomThreadPoolExecutor() {
|
||||
super(MIN_THREADS, MAX_THREADS, MAX_IDLE_TIME, TimeUnit.MILLISECONDS,
|
||||
new SynchronousQueue(), new CustomThreadFactory(),
|
||||
new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Just to set the name and set Daemon
|
||||
* @since Jetty 6
|
||||
*/
|
||||
private static class CustomThreadFactory implements ThreadFactory {
|
||||
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread rv = Executors.defaultThreadFactory().newThread(r);
|
||||
rv.setName(THREAD_NAME);
|
||||
rv.setDaemon(true);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,8 @@ import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
|
||||
import org.mortbay.jetty.servlet.WebApplicationContext;
|
||||
import org.mortbay.jetty.webapp.Configuration;
|
||||
import org.mortbay.jetty.webapp.WebAppContext;
|
||||
|
||||
|
||||
/**
|
||||
@ -31,16 +32,16 @@ import org.mortbay.jetty.servlet.WebApplicationContext;
|
||||
* @since 0.7.12
|
||||
* @author zzz
|
||||
*/
|
||||
public class WebAppConfiguration implements WebApplicationContext.Configuration {
|
||||
private WebApplicationContext _wac;
|
||||
public class WebAppConfiguration implements Configuration {
|
||||
private WebAppContext _wac;
|
||||
|
||||
private static final String CLASSPATH = ".classpath";
|
||||
|
||||
public void setWebApplicationContext(WebApplicationContext context) {
|
||||
public void setWebAppContext(WebAppContext context) {
|
||||
_wac = context;
|
||||
}
|
||||
|
||||
public WebApplicationContext getWebApplicationContext() {
|
||||
public WebAppContext getWebAppContext() {
|
||||
return _wac;
|
||||
}
|
||||
|
||||
@ -87,10 +88,16 @@ public class WebAppConfiguration implements WebApplicationContext.Configuration
|
||||
else
|
||||
path = dir.getAbsolutePath() + '/' + elem;
|
||||
System.err.println("Adding " + path + " to classpath for " + appName);
|
||||
_wac.addClassPath(path);
|
||||
_wac.setExtraClasspath(path);
|
||||
}
|
||||
}
|
||||
|
||||
public void configureDefaults() {}
|
||||
public void configureWebApp() {}
|
||||
|
||||
/** @since Jetty 6 */
|
||||
public void deconfigureWebApp() {}
|
||||
|
||||
/** @since Jetty 6 */
|
||||
public void configureClassLoader() {}
|
||||
}
|
||||
|
@ -14,10 +14,12 @@ import net.i2p.util.Log;
|
||||
import net.i2p.util.SecureDirectory;
|
||||
import net.i2p.util.PortMapper;
|
||||
|
||||
import org.mortbay.http.HttpContext;
|
||||
import org.mortbay.http.HttpListener;
|
||||
import org.mortbay.jetty.Connector;
|
||||
import org.mortbay.jetty.Handler;
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.servlet.WebApplicationContext;
|
||||
import org.mortbay.jetty.webapp.WebAppContext;
|
||||
import org.mortbay.jetty.handler.ContextHandler;
|
||||
import org.mortbay.jetty.handler.ContextHandlerCollection;
|
||||
|
||||
|
||||
/**
|
||||
@ -49,9 +51,10 @@ public class WebAppStarter {
|
||||
* adds and starts
|
||||
* @throws just about anything, caller would be wise to catch Throwable
|
||||
*/
|
||||
static void startWebApp(I2PAppContext ctx, Server server, String appName, String warPath) throws Exception {
|
||||
static void startWebApp(I2PAppContext ctx, ContextHandlerCollection server,
|
||||
String appName, String warPath) throws Exception {
|
||||
File tmpdir = new SecureDirectory(ctx.getTempDir(), "jetty-work-" + appName + ctx.random().nextInt());
|
||||
WebApplicationContext wac = addWebApp(ctx, server, appName, warPath, tmpdir);
|
||||
WebAppContext wac = addWebApp(ctx, server, appName, warPath, tmpdir);
|
||||
_log.debug("Loading war from: " + warPath);
|
||||
wac.start();
|
||||
}
|
||||
@ -61,12 +64,13 @@ public class WebAppStarter {
|
||||
* This is used only by RouterConsoleRunner, which adds all the webapps first
|
||||
* and then starts all at once.
|
||||
*/
|
||||
static WebApplicationContext addWebApp(I2PAppContext ctx, Server server, String appName, String warPath, File tmpdir) throws IOException {
|
||||
static WebAppContext addWebApp(I2PAppContext ctx, ContextHandlerCollection server,
|
||||
String appName, String warPath, File tmpdir) throws IOException {
|
||||
|
||||
// Jetty will happily load one context on top of another without stopping
|
||||
// the first one, so we remove any previous one here
|
||||
try {
|
||||
stopWebApp(server, appName);
|
||||
stopWebApp(appName);
|
||||
} catch (Throwable t) {}
|
||||
|
||||
// To avoid ZipErrors from JarURLConnetion caching,
|
||||
@ -91,7 +95,7 @@ public class WebAppStarter {
|
||||
warPath = tmpPath;
|
||||
}
|
||||
|
||||
WebApplicationContext wac = server.addWebApplication("/"+ appName, warPath);
|
||||
WebAppContext wac = new WebAppContext(warPath, "/"+ appName);
|
||||
tmpdir.mkdir();
|
||||
wac.setTempDirectory(tmpdir);
|
||||
|
||||
@ -101,12 +105,14 @@ public class WebAppStarter {
|
||||
|
||||
|
||||
// see WebAppConfiguration for info
|
||||
String[] classNames = server.getWebApplicationConfigurationClassNames();
|
||||
String[] classNames = wac.getConfigurationClasses();
|
||||
String[] newClassNames = new String[classNames.length + 1];
|
||||
for (int j = 0; j < classNames.length; j++)
|
||||
newClassNames[j] = classNames[j];
|
||||
newClassNames[classNames.length] = WebAppConfiguration.class.getName();
|
||||
wac.setConfigurationClassNames(newClassNames);
|
||||
wac.setConfigurationClasses(newClassNames);
|
||||
server.addHandler(wac);
|
||||
server.mapContexts();
|
||||
return wac;
|
||||
}
|
||||
|
||||
@ -114,42 +120,55 @@ public class WebAppStarter {
|
||||
* stop it and remove the context
|
||||
* @throws just about anything, caller would be wise to catch Throwable
|
||||
*/
|
||||
static void stopWebApp(Server server, String appName) {
|
||||
// this will return a new context if one does not exist
|
||||
HttpContext wac = server.getContext('/' + appName);
|
||||
static void stopWebApp(String appName) {
|
||||
ContextHandler wac = getWebApp(appName);
|
||||
if (wac == null)
|
||||
return;
|
||||
try {
|
||||
// false -> not graceful
|
||||
wac.stop(false);
|
||||
} catch (InterruptedException ie) {}
|
||||
// not graceful is default in Jetty 6?
|
||||
wac.stop();
|
||||
} catch (Exception ie) {}
|
||||
ContextHandlerCollection server = getConsoleServer();
|
||||
if (server == null)
|
||||
return;
|
||||
try {
|
||||
server.removeContext(wac);
|
||||
server.removeHandler(wac);
|
||||
server.mapContexts();
|
||||
} catch (IllegalStateException ise) {}
|
||||
}
|
||||
|
||||
static boolean isWebAppRunning(String appName) {
|
||||
Server server = WebAppStarter.getConsoleServer();
|
||||
if (server == null)
|
||||
ContextHandler wac = getWebApp(appName);
|
||||
if (wac == null)
|
||||
return false;
|
||||
// this will return a new context if one does not exist
|
||||
HttpContext wac = server.getContext('/' + appName);
|
||||
return wac.isStarted();
|
||||
}
|
||||
|
||||
/** see comments in ConfigClientsHandler */
|
||||
static Server getConsoleServer() {
|
||||
PortMapper pm = I2PAppContext.getGlobalContext().portMapper();
|
||||
int p1 = pm.getPort(PortMapper.SVC_CONSOLE);
|
||||
int p2 = pm.getPort(PortMapper.SVC_HTTPS_CONSOLE);
|
||||
Collection c = Server.getHttpServers();
|
||||
for (int i = 0; i < c.size(); i++) {
|
||||
Server s = (Server) c.toArray()[i];
|
||||
HttpListener[] hl = s.getListeners();
|
||||
for (int j = 0; j < hl.length; j++) {
|
||||
int port = hl[j].getPort();
|
||||
if (port == p1 || port == p2)
|
||||
return s;
|
||||
}
|
||||
/** @since Jetty 6 */
|
||||
static ContextHandler getWebApp(String appName) {
|
||||
ContextHandlerCollection server = getConsoleServer();
|
||||
if (server == null)
|
||||
return null;
|
||||
Handler handlers[] = server.getHandlers();
|
||||
if (handlers == null)
|
||||
return null;
|
||||
String path = '/'+ appName;
|
||||
for (int i = 0; i < handlers.length; i++) {
|
||||
ContextHandler ch = (ContextHandler) handlers[i];
|
||||
if (path.equals(ch.getContextPath()))
|
||||
return ch;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** see comments in ConfigClientsHandler */
|
||||
static ContextHandlerCollection getConsoleServer() {
|
||||
Server s = RouterConsoleRunner.getConsoleServer();
|
||||
if (s == null)
|
||||
return null;
|
||||
Handler h = s.getChildHandlerByClass(ContextHandlerCollection.class);
|
||||
if (h == null)
|
||||
return null;
|
||||
return (ContextHandlerCollection) h;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html" %>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -10,7 +11,7 @@
|
||||
<%@include file="summary.jsi" %>
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigNetHelper" id="nethelper" scope="request" />
|
||||
<jsp:setProperty name="nethelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="nethelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<h1><%=intl._("I2P Bandwidth Configuration")%></h1>
|
||||
<div class="main" id="main">
|
||||
<%@include file="confignav.jsi" %>
|
||||
@ -18,7 +19,7 @@
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigNetHandler" id="formhandler" scope="request" />
|
||||
<% formhandler.storeMethod(request.getMethod()); %>
|
||||
<jsp:setProperty name="formhandler" property="*" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:getProperty name="formhandler" property="allMessages" />
|
||||
<div class="configure">
|
||||
<form action="" method="POST">
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -10,7 +11,7 @@
|
||||
<%@include file="summary.jsi" %>
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigAdvancedHelper" id="advancedhelper" scope="request" />
|
||||
<jsp:setProperty name="advancedhelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="advancedhelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
|
||||
<h1><%=intl._("I2P Advanced Configuration")%></h1>
|
||||
<div class="main" id="main">
|
||||
@ -20,7 +21,7 @@
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigAdvancedHandler" id="formhandler" scope="request" />
|
||||
<% formhandler.storeMethod(request.getMethod()); %>
|
||||
<jsp:setProperty name="formhandler" property="*" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:getProperty name="formhandler" property="allMessages" />
|
||||
<div class="configure">
|
||||
<div class="wideload">
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -14,17 +15,17 @@ button span.hide{
|
||||
<%@include file="summary.jsi" %>
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigClientsHelper" id="clientshelper" scope="request" />
|
||||
<jsp:setProperty name="clientshelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="clientshelper" property="edit" value="<%=request.getParameter("edit")%>" />
|
||||
<jsp:setProperty name="clientshelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:setProperty name="clientshelper" property="edit" value="<%=request.getParameter(\"edit\")%>" />
|
||||
<h1><%=intl._("I2P Client Configuration")%></h1>
|
||||
<div class="main" id="main">
|
||||
<%@include file="confignav.jsi" %>
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigClientsHandler" id="formhandler" scope="request" />
|
||||
<% formhandler.storeMethod(request.getMethod()); %>
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="formhandler" property="action" value="<%=request.getParameter("action")%>" />
|
||||
<jsp:setProperty name="formhandler" property="nonce" value="<%=request.getParameter("nonce")%>" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:setProperty name="formhandler" property="action" value="<%=request.getParameter(\"action\")%>" />
|
||||
<jsp:setProperty name="formhandler" property="nonce" value="<%=request.getParameter(\"nonce\")%>" />
|
||||
<jsp:setProperty name="formhandler" property="settings" value="<%=request.getParameterMap()%>" />
|
||||
<jsp:getProperty name="formhandler" property="allMessages" />
|
||||
<div class="configure">
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -15,10 +16,10 @@
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigKeyringHandler" id="formhandler" scope="request" />
|
||||
<% formhandler.storeMethod(request.getMethod()); %>
|
||||
<jsp:setProperty name="formhandler" property="*" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:getProperty name="formhandler" property="allMessages" />
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigKeyringHelper" id="keyringhelper" scope="request" />
|
||||
<jsp:setProperty name="keyringhelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="keyringhelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<div class="configure"><h2><%=intl._("Keyring")%></h2><p>
|
||||
<%=intl._("The router keyring is used to decrypt encrypted leaseSets.")%>
|
||||
<%=intl._("The keyring may contain keys for local or remote encrypted destinations.")%></p>
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -7,7 +8,7 @@
|
||||
<%=intl.title("config logging")%>
|
||||
</head><body>
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigLoggingHelper" id="logginghelper" scope="request" />
|
||||
<jsp:setProperty name="logginghelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="logginghelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
|
||||
<%@include file="summary.jsi" %>
|
||||
<h1><%=intl._("I2P Logging Configuration")%></h1>
|
||||
@ -17,7 +18,7 @@
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigLoggingHandler" id="formhandler" scope="request" />
|
||||
<% formhandler.storeMethod(request.getMethod()); %>
|
||||
<jsp:setProperty name="formhandler" property="*" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:getProperty name="formhandler" property="allMessages" />
|
||||
<div class="configure">
|
||||
<form action="" method="POST">
|
||||
|
@ -4,7 +4,7 @@
|
||||
*/
|
||||
%>
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigNavHelper" id="navHelper" scope="request" />
|
||||
<jsp:setProperty name="navHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="navHelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<% navHelper.storeWriter(out); %>
|
||||
<div class="confignav" id="confignav">
|
||||
<%
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html" %>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -10,7 +11,7 @@
|
||||
<%@include file="summary.jsi" %>
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigNetHelper" id="nethelper" scope="request" />
|
||||
<jsp:setProperty name="nethelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="nethelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<h1><%=intl._("I2P Network Configuration")%></h1>
|
||||
<div class="main" id="main">
|
||||
<%@include file="confignav.jsi" %>
|
||||
@ -18,7 +19,7 @@
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigNetHandler" id="formhandler" scope="request" />
|
||||
<% formhandler.storeMethod(request.getMethod()); %>
|
||||
<jsp:setProperty name="formhandler" property="*" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:getProperty name="formhandler" property="allMessages" />
|
||||
<div class="configure">
|
||||
<form action="" method="POST">
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -15,13 +16,13 @@
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigPeerHandler" id="formhandler" scope="request" />
|
||||
<% formhandler.storeMethod(request.getMethod()); %>
|
||||
<jsp:setProperty name="formhandler" property="*" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:getProperty name="formhandler" property="allMessages" />
|
||||
|
||||
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigPeerHelper" id="peerhelper" scope="request" />
|
||||
<jsp:setProperty name="peerhelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="peerhelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
|
||||
<% String peer = "";
|
||||
if (request.getParameter("peer") != null)
|
||||
@ -61,7 +62,7 @@
|
||||
</form>
|
||||
<a name="shitlist"> </a><h2><%=intl._("Banned Peers")%></h2>
|
||||
<jsp:useBean class="net.i2p.router.web.ProfilesHelper" id="profilesHelper" scope="request" />
|
||||
<jsp:setProperty name="profilesHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="profilesHelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<% profilesHelper.storeWriter(out); %>
|
||||
<jsp:getProperty name="profilesHelper" property="shitlistSummary" />
|
||||
<div class="wideload"><h2><%=intl._("Banned IPs")%></h2>
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -10,16 +11,16 @@
|
||||
<%@include file="summary.jsi" %>
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigReseedHelper" id="reseedHelper" scope="request" />
|
||||
<jsp:setProperty name="reseedHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="reseedHelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<h1><%=intl._("I2P Reseeding Configuration")%></h1>
|
||||
<div class="main" id="main">
|
||||
<%@include file="confignav.jsi" %>
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigReseedHandler" id="formhandler" scope="request" />
|
||||
<% formhandler.storeMethod(request.getMethod()); %>
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="formhandler" property="action" value="<%=request.getParameter("action")%>" />
|
||||
<jsp:setProperty name="formhandler" property="nonce" value="<%=request.getParameter("nonce")%>" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:setProperty name="formhandler" property="action" value="<%=request.getParameter(\"action\")%>" />
|
||||
<jsp:setProperty name="formhandler" property="nonce" value="<%=request.getParameter(\"nonce\")%>" />
|
||||
<jsp:setProperty name="formhandler" property="settings" value="<%=request.getParameterMap()%>" />
|
||||
<jsp:getProperty name="formhandler" property="allMessages" />
|
||||
<div class="configure"><form action="" method="POST">
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -15,7 +16,7 @@
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigServiceHandler" id="formhandler" scope="request" />
|
||||
<% formhandler.storeMethod(request.getMethod()); %>
|
||||
<jsp:setProperty name="formhandler" property="*" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:getProperty name="formhandler" property="allMessages" />
|
||||
<div class="configure">
|
||||
<form action="" method="POST">
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -64,11 +65,11 @@ function toggleAll(category)
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigStatsHandler" id="formhandler" scope="request" />
|
||||
<% formhandler.storeMethod(request.getMethod()); %>
|
||||
<jsp:setProperty name="formhandler" property="*" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:getProperty name="formhandler" property="allMessages" />
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigStatsHelper" id="statshelper" scope="request" />
|
||||
<jsp:setProperty name="statshelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="statshelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<div class="configure">
|
||||
<form id="statsForm" name="statsForm" action="" method="POST">
|
||||
<input type="hidden" name="action" value="foo" >
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -10,16 +11,16 @@
|
||||
<%@include file="summary.jsi" %>
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigTunnelsHelper" id="tunnelshelper" scope="request" />
|
||||
<jsp:setProperty name="tunnelshelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="tunnelshelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<h1><%=intl._("I2P Tunnel Configuration")%></h1>
|
||||
<div class="main" id="main">
|
||||
<%@include file="confignav.jsi" %>
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigTunnelsHandler" id="formhandler" scope="request" />
|
||||
<% formhandler.storeMethod(request.getMethod()); %>
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="formhandler" property="shouldsave" value="<%=request.getParameter("shouldsave")%>" />
|
||||
<jsp:setProperty name="formhandler" property="action" value="<%=request.getParameter("action")%>" />
|
||||
<jsp:setProperty name="formhandler" property="nonce" value="<%=request.getParameter("nonce")%>" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:setProperty name="formhandler" property="shouldsave" value="<%=request.getParameter(\"shouldsave\")%>" />
|
||||
<jsp:setProperty name="formhandler" property="action" value="<%=request.getParameter(\"action\")%>" />
|
||||
<jsp:setProperty name="formhandler" property="nonce" value="<%=request.getParameter(\"nonce\")%>" />
|
||||
<jsp:setProperty name="formhandler" property="settings" value="<%=request.getParameterMap()%>" />
|
||||
<jsp:getProperty name="formhandler" property="allMessages" />
|
||||
<div class="configure"><p>
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -10,7 +11,7 @@
|
||||
<%@include file="summary.jsi" %>
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigUIHelper" id="uihelper" scope="request" />
|
||||
<jsp:setProperty name="uihelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="uihelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
|
||||
<h1><%=uihelper._("I2P UI Configuration")%></h1>
|
||||
<div class="main" id="main">
|
||||
@ -20,7 +21,7 @@
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigUIHandler" id="formhandler" scope="request" />
|
||||
<% formhandler.storeMethod(request.getMethod()); %>
|
||||
<jsp:setProperty name="formhandler" property="*" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:getProperty name="formhandler" property="allMessages" />
|
||||
<div class="configure"><div class="topshimten"><h3><%=uihelper._("Router Console Theme")%></h3></div>
|
||||
<form action="" method="POST">
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -15,10 +16,10 @@
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigUpdateHandler" id="formhandler" scope="request" />
|
||||
<% formhandler.storeMethod(request.getMethod()); %>
|
||||
<jsp:setProperty name="formhandler" property="*" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:getProperty name="formhandler" property="allMessages" />
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigUpdateHelper" id="updatehelper" scope="request" />
|
||||
<jsp:setProperty name="updatehelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="updatehelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<div class="messages">
|
||||
<jsp:getProperty name="updatehelper" property="newsStatus" /></div>
|
||||
<div class="configure">
|
||||
|
@ -27,7 +27,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="shortcut icon" href="/themes/console/images/favicon.ico">
|
||||
<jsp:useBean class="net.i2p.router.web.CSSHelper" id="intl" scope="request" />
|
||||
<jsp:setProperty name="intl" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="intl" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<%
|
||||
String conNonceParam = request.getParameter("consoleNonce");
|
||||
if (conNonceParam != null && conNonceParam.equals(System.getProperty("router.consoleNonce"))) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<%
|
||||
|
@ -1,6 +1,6 @@
|
||||
<%@page contentType="text/plain"
|
||||
%><jsp:useBean id="helper" class="net.i2p.router.web.StatHelper"
|
||||
/><jsp:setProperty name="helper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>"
|
||||
/><jsp:setProperty name="helper" property="peer" value="<%=net.i2p.data.DataHelper.stripHTML(request.getParameter("peer"))%>"
|
||||
/><jsp:setProperty name="helper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>"
|
||||
/><jsp:setProperty name="helper" property="peer" value="<%=net.i2p.data.DataHelper.stripHTML(request.getParameter(\"peer\"))%>"
|
||||
/><% helper.storeWriter(out);
|
||||
%><jsp:getProperty name="helper" property="profile" />
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<%
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<%
|
||||
@ -57,7 +58,7 @@
|
||||
<b>Java version:</b> <%=System.getProperty("java.vendor")%> <%=System.getProperty("java.version")%> (<%=System.getProperty("java.runtime.name")%> <%=System.getProperty("java.runtime.version")%>)<br>
|
||||
<b>Wrapper version:</b> <%=System.getProperty("wrapper.version", "none")%><br>
|
||||
<jsp:useBean class="net.i2p.router.web.LogsHelper" id="logsHelper" scope="request" />
|
||||
<jsp:setProperty name="logsHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="logsHelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<b>Server version:</b> <jsp:getProperty name="logsHelper" property="jettyVersion" /><br>
|
||||
<b>Platform:</b> <%=System.getProperty("os.name")%> <%=System.getProperty("os.arch")%> <%=System.getProperty("os.version")%><br>
|
||||
<b>Processor:</b> <%=net.i2p.util.NativeBigInteger.cpuModel()%> (<%=net.i2p.util.NativeBigInteger.cpuType()%>)<br>
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -7,7 +8,7 @@
|
||||
<%=intl.title("graphs")%>
|
||||
<jsp:useBean class="net.i2p.router.web.GraphHelper" id="graphHelper" scope="request" />
|
||||
<% graphHelper.storeMethod(request.getMethod()); %>
|
||||
<jsp:setProperty name="graphHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="graphHelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<% /* GraphHelper sets the defaults in setContextId, so setting the properties must be after the context */ %>
|
||||
<jsp:setProperty name="graphHelper" property="*" />
|
||||
<%
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<%
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<%
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<%
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<%
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<%
|
||||
|
@ -1,8 +0,0 @@
|
||||
<html><head><title>I2PSnark Anonymous BitTorrent Client Disabled</title>
|
||||
<meta http-equiv="cache-control" content="no-cache" />
|
||||
<meta http-equiv="pragma" content="no-cache" />
|
||||
</head>
|
||||
<body>
|
||||
The I2PSnark Anonymous BitTorrent Client is not running. Please visit the <a href="/configclients#webapp">config clients page</a>
|
||||
to start it.
|
||||
</body></html>
|
@ -1,7 +0,0 @@
|
||||
<html><head><title>I2P Tunnel Manager Not Running</title>
|
||||
<meta http-equiv="cache-control" content="no-cache" />
|
||||
<meta http-equiv="pragma" content="no-cache" />
|
||||
</head>
|
||||
<body>
|
||||
The I2P Tunnel Manager is not currently running. Please visit the <a href="/configclients#webapp">Client Configuration</a> page to start it.
|
||||
</body></html>
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -17,7 +18,7 @@
|
||||
<%@include file="summary.jsi" %><h1><%=intl._("I2P Router Console")%></h1>
|
||||
<div class="news" id="news">
|
||||
<jsp:useBean class="net.i2p.router.web.NewsHelper" id="newshelper" scope="request" />
|
||||
<jsp:setProperty name="newshelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="newshelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<%
|
||||
if (newshelper.shouldShowNews()) {
|
||||
java.io.File fpath = new java.io.File(net.i2p.I2PAppContext.getGlobalContext().getRouterDir(), "docs/news.xml");
|
||||
@ -30,7 +31,7 @@
|
||||
} // shouldShowNews()
|
||||
%>
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigUpdateHelper" id="updatehelper" scope="request" />
|
||||
<jsp:setProperty name="updatehelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="updatehelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:getProperty name="updatehelper" property="newsStatus" /><br>
|
||||
</div><div class="main" id="main">
|
||||
<jsp:useBean class="net.i2p.router.web.ContentHelper" id="contenthelper" scope="request" />
|
||||
@ -60,6 +61,6 @@
|
||||
<% java.io.File fpath = new java.io.File(net.i2p.I2PAppContext.getGlobalContext().getBaseDir(), "docs/readme.html"); %>
|
||||
<jsp:setProperty name="contenthelper" property="page" value="<%=fpath.getAbsolutePath()%>" />
|
||||
<jsp:setProperty name="contenthelper" property="maxLines" value="300" />
|
||||
<jsp:setProperty name="contenthelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="contenthelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:getProperty name="contenthelper" property="content" />
|
||||
</div></body></html>
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -9,7 +10,7 @@
|
||||
<%@include file="summary.jsi" %><h1><%=intl._("I2P Router Job Queue")%></h1>
|
||||
<div class="main" id="main">
|
||||
<jsp:useBean class="net.i2p.router.web.JobQueueHelper" id="jobQueueHelper" scope="request" />
|
||||
<jsp:setProperty name="jobQueueHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="jobQueueHelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<% jobQueueHelper.storeWriter(out); %>
|
||||
<jsp:getProperty name="jobQueueHelper" property="jobQueueSummary" />
|
||||
<hr></div></body></html>
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -22,7 +23,7 @@
|
||||
<b>Java version:</b> <%=System.getProperty("java.vendor")%> <%=System.getProperty("java.version")%> (<%=System.getProperty("java.runtime.name")%> <%=System.getProperty("java.runtime.version")%>)<br>
|
||||
<b>Wrapper version:</b> <%=System.getProperty("wrapper.version", "none")%><br>
|
||||
<jsp:useBean class="net.i2p.router.web.LogsHelper" id="logsHelper" scope="request" />
|
||||
<jsp:setProperty name="logsHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="logsHelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<b>Server version:</b> <jsp:getProperty name="logsHelper" property="jettyVersion" /><br>
|
||||
<b>Platform:</b> <%=System.getProperty("os.name")%> <%=System.getProperty("os.arch")%> <%=System.getProperty("os.version")%><br>
|
||||
<b>Processor:</b> <%=net.i2p.util.NativeBigInteger.cpuModel()%> (<%=net.i2p.util.NativeBigInteger.cpuType()%>)<br>
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -11,10 +12,10 @@
|
||||
<div class="main" id="main">
|
||||
<div class="wideload">
|
||||
<jsp:useBean class="net.i2p.router.web.NetDbHelper" id="netdbHelper" scope="request" />
|
||||
<jsp:setProperty name="netdbHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="netdbHelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<% netdbHelper.storeWriter(out); %>
|
||||
<jsp:setProperty name="netdbHelper" property="full" value="<%=request.getParameter("f")%>" />
|
||||
<jsp:setProperty name="netdbHelper" property="router" value="<%=request.getParameter("r")%>" />
|
||||
<jsp:setProperty name="netdbHelper" property="lease" value="<%=request.getParameter("l")%>" />
|
||||
<jsp:setProperty name="netdbHelper" property="full" value="<%=request.getParameter(\"f\")%>" />
|
||||
<jsp:setProperty name="netdbHelper" property="router" value="<%=request.getParameter(\"r\")%>" />
|
||||
<jsp:setProperty name="netdbHelper" property="lease" value="<%=request.getParameter(\"l\")%>" />
|
||||
<jsp:getProperty name="netdbHelper" property="netDbSummary" />
|
||||
</div></div></body></html>
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<%
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<%
|
||||
@ -11,7 +12,7 @@
|
||||
</head><body>
|
||||
<%@include file="summary.jsi" %>
|
||||
<jsp:useBean class="net.i2p.router.web.OldConsoleHelper" id="conhelper" scope="request" />
|
||||
<jsp:setProperty name="conhelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="conhelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<% conhelper.storeWriter(out); %>
|
||||
<h1>I2P Router » Old Console</h1>
|
||||
<div class="main" id="main">
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -10,9 +11,9 @@
|
||||
<h1><%=intl._("I2P Network Peers")%></h1>
|
||||
<div class="main" id="main"><div class="wideload">
|
||||
<jsp:useBean class="net.i2p.router.web.PeerHelper" id="peerHelper" scope="request" />
|
||||
<jsp:setProperty name="peerHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="peerHelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<% peerHelper.storeWriter(out); %>
|
||||
<jsp:setProperty name="peerHelper" property="urlBase" value="peers.jsp" />
|
||||
<jsp:setProperty name="peerHelper" property="sort" value="<%=request.getParameter("sort") != null ? request.getParameter("sort") : ""%>" />
|
||||
<jsp:setProperty name="peerHelper" property="sort" value="<%=request.getParameter(\"sort\") != null ? request.getParameter(\"sort\") : \"\"%>" />
|
||||
<jsp:getProperty name="peerHelper" property="peerSummary" />
|
||||
</div></div></body></html>
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -9,9 +10,9 @@
|
||||
<h1><%=intl._("I2P Network Peer Profiles")%></h1>
|
||||
<div class="main" id="main"><div class="wideload">
|
||||
<jsp:useBean class="net.i2p.router.web.ProfilesHelper" id="profilesHelper" scope="request" />
|
||||
<jsp:setProperty name="profilesHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="profilesHelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<% profilesHelper.storeWriter(out); %>
|
||||
<jsp:setProperty name="profilesHelper" property="full" value="<%=request.getParameter("f")%>" />
|
||||
<jsp:setProperty name="profilesHelper" property="full" value="<%=request.getParameter(\"f\")%>" />
|
||||
<jsp:getProperty name="profilesHelper" property="profileSummary" />
|
||||
<a name="shitlist"> </a><h2><%=intl._("Banned Peers")%></h2>
|
||||
<jsp:getProperty name="profilesHelper" property="shitlistSummary" />
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -8,9 +9,9 @@
|
||||
</head><body>
|
||||
<%@include file="summary.jsi" %>
|
||||
<jsp:useBean class="net.i2p.router.web.OldConsoleHelper" id="oldhelper" scope="request" />
|
||||
<jsp:setProperty name="oldhelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="oldhelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<% oldhelper.storeWriter(out); %>
|
||||
<jsp:setProperty name="oldhelper" property="full" value="<%=request.getParameter("f")%>" />
|
||||
<jsp:setProperty name="oldhelper" property="full" value="<%=request.getParameter(\"f\")%>" />
|
||||
<h1><%=intl._("I2P Router Statistics")%></h1>
|
||||
<div class="main" id="main">
|
||||
<jsp:getProperty name="oldhelper" property="stats" />
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<%
|
||||
|
@ -6,10 +6,10 @@
|
||||
*/
|
||||
%>
|
||||
<jsp:useBean class="net.i2p.router.web.SummaryHelper" id="helper" scope="request" />
|
||||
<jsp:setProperty name="helper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="helper" property="action" value="<%=request.getParameter("action")%>" />
|
||||
<jsp:setProperty name="helper" property="updateNonce" value="<%=request.getParameter("updateNonce")%>" />
|
||||
<jsp:setProperty name="helper" property="consoleNonce" value="<%=request.getParameter("consoleNonce")%>" />
|
||||
<jsp:setProperty name="helper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:setProperty name="helper" property="action" value="<%=request.getParameter(\"action\")%>" />
|
||||
<jsp:setProperty name="helper" property="updateNonce" value="<%=request.getParameter(\"updateNonce\")%>" />
|
||||
<jsp:setProperty name="helper" property="consoleNonce" value="<%=request.getParameter(\"consoleNonce\")%>" />
|
||||
<jsp:setProperty name="helper" property="requestURI" value="<%=request.getRequestURI()%>" />
|
||||
<% helper.storeWriter(out); %>
|
||||
<%
|
||||
@ -28,7 +28,7 @@
|
||||
%>
|
||||
<jsp:useBean class="net.i2p.router.web.UpdateHandler" id="update" scope="request" />
|
||||
<jsp:setProperty name="update" property="*" />
|
||||
<jsp:setProperty name="update" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="update" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<%
|
||||
// moved to java for ease of translation and to avoid 30 copies
|
||||
helper.renderSummaryBar();
|
||||
|
@ -1,8 +0,0 @@
|
||||
<html><head><title>SusiDNS Disabled</title>
|
||||
<meta http-equiv="cache-control" content="no-cache" />
|
||||
<meta http-equiv="pragma" content="no-cache" />
|
||||
</head>
|
||||
<body>
|
||||
SusiDNS is not running. Go to <a href="/configclients#webapp">the config clients page</a>
|
||||
to start it.
|
||||
</body></html>
|
@ -1,8 +0,0 @@
|
||||
<html><head><title>SusiMail Disabled</title>
|
||||
<meta http-equiv="cache-control" content="no-cache" />
|
||||
<meta http-equiv="pragma" content="no-cache" />
|
||||
</head>
|
||||
<body>
|
||||
SusiMail is not running. Go to <a href="/configclients#webapp">the config clients page</a>
|
||||
to start it.
|
||||
</body></html>
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -9,7 +10,7 @@
|
||||
<%@include file="summary.jsi" %><h1><%=intl._("I2P Tunnel Summary")%></h1>
|
||||
<div class="main" id="main">
|
||||
<jsp:useBean class="net.i2p.router.web.TunnelHelper" id="tunnelHelper" scope="request" />
|
||||
<jsp:setProperty name="tunnelHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="tunnelHelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<% tunnelHelper.storeWriter(out); %>
|
||||
<jsp:getProperty name="tunnelHelper" property="tunnelSummary" />
|
||||
</div></body></html>
|
||||
|
@ -1,4 +1,5 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
@ -17,7 +18,7 @@
|
||||
peerB64 = net.i2p.data.DataHelper.stripHTML(peerB64); // XSS
|
||||
%>
|
||||
<jsp:useBean id="stathelper" class="net.i2p.router.web.StatHelper" />
|
||||
<jsp:setProperty name="stathelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="stathelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<jsp:setProperty name="stathelper" property="peer" value="<%=peerB64%>" />
|
||||
<% stathelper.storeWriter(out); %>
|
||||
<h2><%=intl._("Profile for peer {0}", peerB64)%></h2>
|
||||
|
12
apps/susidns/src/WEB-INF/lib/README.txt
Normal file
12
apps/susidns/src/WEB-INF/lib/README.txt
Normal file
@ -0,0 +1,12 @@
|
||||
These are 1.2 libs downloaded from http://jstl.java.net/download.html
|
||||
Licenses: Common Development and Distribution License (CDDL) version 1.0 + GNU General Public License (GPL) version 2
|
||||
https://glassfish.dev.java.net/public/CDDL+GPL.html
|
||||
|
||||
1.2 libs are compatible with JSP 2.1 containers.
|
||||
See http://www.coderanch.com/how-to/java/JstlTagLibDefinitions for more info.
|
||||
|
||||
The previous files were version 1.1.2 for JSP 2.0.
|
||||
Old names kept so they are overwritten in the update and are in the classpath.
|
||||
|
||||
jstl-api-1.2.jar -> jstl.jar
|
||||
jstl-impl-1.2.jar -> standard.jar
|
Binary file not shown.
Binary file not shown.
@ -17,6 +17,7 @@
|
||||
<pathelement location="${lib}/jasper-compiler.jar" />
|
||||
<pathelement location="${lib}/jasper-runtime.jar" />
|
||||
<pathelement location="${lib}/javax.servlet.jar" />
|
||||
<pathelement location="${lib}/jsp-api.jar" />
|
||||
<pathelement location="${lib}/commons-logging.jar" />
|
||||
<pathelement location="${lib}/commons-el.jar" />
|
||||
<pathelement location="${lib}/ant.jar" />
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@ page contentType="text/html"%>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<jsp:useBean id="version" class="i2p.susi.dns.VersionBean" scope="application" />
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@ page contentType="text/html" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<jsp:useBean id="version" class="i2p.susi.dns.VersionBean" scope="application"/>
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@ page contentType="text/html"%>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<jsp:useBean id="version" class="i2p.susi.dns.VersionBean" scope="application" />
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@ page contentType="text/html"%>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<jsp:useBean id="version" class="i2p.susi.dns.VersionBean" scope="application" />
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<%@page trimDirectiveWhitespaces="true"%>
|
||||
<%@ page contentType="text/html"%>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<jsp:useBean id="version" class="i2p.susi.dns.VersionBean" scope="application" />
|
||||
|
@ -19,6 +19,7 @@
|
||||
<classpath>
|
||||
<pathelement location="../jetty/jettylib/javax.servlet.jar" />
|
||||
<pathelement location="../jetty/jettylib/org.mortbay.jetty.jar" />
|
||||
<pathelement location="../jetty/jettylib/jetty-util.jar" />
|
||||
<pathelement location="../../core/java/build/i2p.jar" />
|
||||
</classpath>
|
||||
</javac>
|
||||
|
@ -15,4 +15,26 @@
|
||||
<session-config>
|
||||
<session-timeout>15</session-timeout>
|
||||
</session-config>
|
||||
</web-app>
|
||||
|
||||
<!--
|
||||
Jetty 6 mulipart form handling
|
||||
See http://docs.codehaus.org/display/JETTY/File+Upload+in+jetty6
|
||||
and RequestWrapper.java.
|
||||
Unused because it doesn't support content-type until Jetty 8.
|
||||
|
||||
<filter>
|
||||
<filter-name>fileuploadfilter</filter-name>
|
||||
<filter-class>org.mortbay.servlet.MultiPartFilter</filter-class>
|
||||
<init-param>
|
||||
<param-name>deleteFiles</param-name>
|
||||
<param-value>true</param-value>
|
||||
</init-param>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>fileuploadfilter</filter-name>
|
||||
<url-pattern>/susimail</url-pattern>
|
||||
</filter-mapping>
|
||||
-->
|
||||
|
||||
-</web-app>
|
||||
|
@ -35,6 +35,19 @@ import javax.servlet.http.HttpSession;
|
||||
import org.mortbay.servlet.MultiPartRequest;
|
||||
|
||||
/**
|
||||
* Required major changes for Jetty 6
|
||||
* to support change from MultiPartRequest to MultiPartFilter.
|
||||
* See http://docs.codehaus.org/display/JETTY/File+Upload+in+jetty6
|
||||
* Unfortunately, Content-type not available until Jetty 8
|
||||
* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=349110
|
||||
*
|
||||
* So we could either extend and fix MultiPartFilter, and rewrite everything here,
|
||||
* or copy MultiParRequest into our war and fix it so it compiles with Jetty 6.
|
||||
* We do the latter.
|
||||
*
|
||||
* The filter would have been added in web.xml,
|
||||
* see that file, where it's commented out.
|
||||
*
|
||||
* @author user
|
||||
*/
|
||||
public class RequestWrapper {
|
||||
|
447
apps/susimail/src/src/org/mortbay/servlet/MultiPartRequest.java
Normal file
447
apps/susimail/src/src/org/mortbay/servlet/MultiPartRequest.java
Normal file
@ -0,0 +1,447 @@
|
||||
// ========================================================================
|
||||
// $Id: MultiPartRequest.java,v 1.16 2005/12/02 20:13:52 gregwilkins Exp $
|
||||
// Copyright 1996-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.mortbay.servlet;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
//import org.apache.commons.logging.Log;
|
||||
//import org.mortbay.log.LogFactory;
|
||||
import org.mortbay.jetty.HttpHeaders;
|
||||
import org.mortbay.util.LineInput;
|
||||
import org.mortbay.util.MultiMap;
|
||||
import org.mortbay.util.StringUtil;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Multipart Form Data request.
|
||||
* <p>
|
||||
* This class decodes the multipart/form-data stream sent by
|
||||
* a HTML form that uses a file input item.
|
||||
*
|
||||
* <p><h4>Usage</h4>
|
||||
* Each part of the form data is named from the HTML form and
|
||||
* is available either via getString(name) or getInputStream(name).
|
||||
* Furthermore the MIME parameters and filename can be requested for
|
||||
* each part.
|
||||
* <pre>
|
||||
* </pre>
|
||||
*
|
||||
* Modded to compile with Jetty 6 for I2P
|
||||
*
|
||||
* @version $Id: MultiPartRequest.java,v 1.16 2005/12/02 20:13:52 gregwilkins Exp $
|
||||
* @author Greg Wilkins
|
||||
* @author Jim Crossley
|
||||
*/
|
||||
public class MultiPartRequest
|
||||
{
|
||||
//private static Log log = LogFactory.getLog(MultiPartRequest.class);
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
HttpServletRequest _request;
|
||||
LineInput _in;
|
||||
String _boundary;
|
||||
String _encoding;
|
||||
byte[] _byteBoundary;
|
||||
MultiMap _partMap = new MultiMap(10);
|
||||
int _char=-2;
|
||||
boolean _lastPart=false;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param request The request containing a multipart/form-data
|
||||
* request
|
||||
* @exception IOException IOException
|
||||
*/
|
||||
public MultiPartRequest(HttpServletRequest request)
|
||||
throws IOException
|
||||
{
|
||||
_request=request;
|
||||
String content_type = request.getHeader(HttpHeaders.CONTENT_TYPE);
|
||||
if (!content_type.startsWith("multipart/form-data"))
|
||||
throw new IOException("Not multipart/form-data request");
|
||||
|
||||
//if(log.isDebugEnabled())log.debug("Multipart content type = "+content_type);
|
||||
_encoding = request.getCharacterEncoding();
|
||||
if (_encoding != null)
|
||||
_in = new LineInput(request.getInputStream(), 2048, _encoding);
|
||||
else
|
||||
_in = new LineInput(request.getInputStream());
|
||||
|
||||
// Extract boundary string
|
||||
_boundary="--"+
|
||||
value(content_type.substring(content_type.indexOf("boundary=")));
|
||||
|
||||
//if(log.isDebugEnabled())log.debug("Boundary="+_boundary);
|
||||
_byteBoundary= (_boundary+"--").getBytes(StringUtil.__ISO_8859_1);
|
||||
|
||||
loadAllParts();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the part names.
|
||||
* @return an array of part names
|
||||
*/
|
||||
public String[] getPartNames()
|
||||
{
|
||||
Set s = _partMap.keySet();
|
||||
return (String[]) s.toArray(new String[s.size()]);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Check if a named part is present
|
||||
* @param name The part
|
||||
* @return true if it was included
|
||||
*/
|
||||
public boolean contains(String name)
|
||||
{
|
||||
Part part = (Part)_partMap.get(name);
|
||||
return (part!=null);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the data of a part as a string.
|
||||
* @param name The part name
|
||||
* @return The part data
|
||||
*/
|
||||
public String getString(String name)
|
||||
{
|
||||
List part = _partMap.getValues(name);
|
||||
if (part==null)
|
||||
return null;
|
||||
if (_encoding != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new String(((Part)part.get(0))._data, _encoding);
|
||||
}
|
||||
catch (UnsupportedEncodingException uee)
|
||||
{
|
||||
//if (log.isDebugEnabled())log.debug("Invalid character set: " + uee);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
return new String(((Part)part.get(0))._data);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param name The part name
|
||||
* @return The parts data
|
||||
*/
|
||||
public String[] getStrings(String name)
|
||||
{
|
||||
List parts = _partMap.getValues(name);
|
||||
if (parts==null)
|
||||
return null;
|
||||
String[] strings = new String[parts.size()];
|
||||
|
||||
if (_encoding == null)
|
||||
{
|
||||
for (int i=0; i<strings.length; i++)
|
||||
strings[i] = new String(((Part)parts.get(i))._data);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
for (int i=0; i<strings.length; i++)
|
||||
strings[i] = new String(((Part)parts.get(i))._data, _encoding);
|
||||
}
|
||||
catch (UnsupportedEncodingException uee)
|
||||
{
|
||||
//if (log.isDebugEnabled())log.debug("Invalid character set: " + uee);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return strings;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the data of a part as a stream.
|
||||
* @param name The part name
|
||||
* @return Stream providing the part data
|
||||
*/
|
||||
public InputStream getInputStream(String name)
|
||||
{
|
||||
List part = (List)_partMap.getValues(name);
|
||||
if (part==null)
|
||||
return null;
|
||||
return new ByteArrayInputStream(((Part)part.get(0))._data);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public InputStream[] getInputStreams(String name)
|
||||
{
|
||||
List parts = (List)_partMap.getValues(name);
|
||||
if (parts==null)
|
||||
return null;
|
||||
InputStream[] streams = new InputStream[parts.size()];
|
||||
for (int i=0; i<streams.length; i++) {
|
||||
streams[i] = new ByteArrayInputStream(((Part)parts.get(i))._data);
|
||||
}
|
||||
return streams;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the MIME parameters associated with a part.
|
||||
* @param name The part name
|
||||
* @return Hashtable of parameters
|
||||
*/
|
||||
public Hashtable getParams(String name)
|
||||
{
|
||||
List part = (List)_partMap.getValues(name);
|
||||
if (part==null)
|
||||
return null;
|
||||
return ((Part)part.get(0))._headers;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Hashtable[] getMultipleParams(String name)
|
||||
{
|
||||
List parts = (List)_partMap.getValues(name);
|
||||
if (parts==null)
|
||||
return null;
|
||||
Hashtable[] params = new Hashtable[parts.size()];
|
||||
for (int i=0; i<params.length; i++) {
|
||||
params[i] = ((Part)parts.get(i))._headers;
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get any file name associated with a part.
|
||||
* @param name The part name
|
||||
* @return The filename
|
||||
*/
|
||||
public String getFilename(String name)
|
||||
{
|
||||
List part = (List)_partMap.getValues(name);
|
||||
if (part==null)
|
||||
return null;
|
||||
return ((Part)part.get(0))._filename;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String[] getFilenames(String name)
|
||||
{
|
||||
List parts = (List)_partMap.getValues(name);
|
||||
if (parts==null)
|
||||
return null;
|
||||
String[] filenames = new String[parts.size()];
|
||||
for (int i=0; i<filenames.length; i++) {
|
||||
filenames[i] = ((Part)parts.get(i))._filename;
|
||||
}
|
||||
return filenames;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private void loadAllParts()
|
||||
throws IOException
|
||||
{
|
||||
// Get first boundary
|
||||
String line = _in.readLine();
|
||||
if (!line.equals(_boundary))
|
||||
{
|
||||
//log.warn(line);
|
||||
throw new IOException("Missing initial multi part boundary");
|
||||
}
|
||||
|
||||
// Read each part
|
||||
while (!_lastPart)
|
||||
{
|
||||
// Read Part headers
|
||||
Part part = new Part();
|
||||
|
||||
String content_disposition=null;
|
||||
while ((line=_in.readLine())!=null)
|
||||
{
|
||||
// If blank line, end of part headers
|
||||
if (line.length()==0)
|
||||
break;
|
||||
|
||||
//if(log.isDebugEnabled())log.debug("LINE="+line);
|
||||
|
||||
// place part header key and value in map
|
||||
int c = line.indexOf(':',0);
|
||||
if (c>0)
|
||||
{
|
||||
String key = line.substring(0,c).trim().toLowerCase();
|
||||
String value = line.substring(c+1,line.length()).trim();
|
||||
String ev = (String) part._headers.get(key);
|
||||
part._headers.put(key,(ev!=null)?(ev+';'+value):value);
|
||||
//if(log.isDebugEnabled())log.debug(key+": "+value);
|
||||
if (key.equals("content-disposition"))
|
||||
content_disposition=value;
|
||||
}
|
||||
}
|
||||
|
||||
// Extract content-disposition
|
||||
boolean form_data=false;
|
||||
if (content_disposition==null)
|
||||
{
|
||||
throw new IOException("Missing content-disposition");
|
||||
}
|
||||
|
||||
StringTokenizer tok =
|
||||
new StringTokenizer(content_disposition,";");
|
||||
while (tok.hasMoreTokens())
|
||||
{
|
||||
String t = tok.nextToken().trim();
|
||||
String tl = t.toLowerCase();
|
||||
if (t.startsWith("form-data"))
|
||||
form_data=true;
|
||||
else if (tl.startsWith("name="))
|
||||
part._name=value(t);
|
||||
else if (tl.startsWith("filename="))
|
||||
part._filename=value(t);
|
||||
}
|
||||
|
||||
// Check disposition
|
||||
if (!form_data)
|
||||
{
|
||||
//log.warn("Non form-data part in multipart/form-data");
|
||||
continue;
|
||||
}
|
||||
if (part._name==null || part._name.length()==0)
|
||||
{
|
||||
//log.warn("Part with no name in multipart/form-data");
|
||||
continue;
|
||||
}
|
||||
//if(log.isDebugEnabled())log.debug("name="+part._name);
|
||||
//if(log.isDebugEnabled())log.debug("filename="+part._filename);
|
||||
_partMap.add(part._name,part);
|
||||
part._data=readBytes();
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private byte[] readBytes()
|
||||
throws IOException
|
||||
{
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
int c;
|
||||
boolean cr=false;
|
||||
boolean lf=false;
|
||||
|
||||
// loop for all lines`
|
||||
while (true)
|
||||
{
|
||||
int b=0;
|
||||
while ((c=(_char!=-2)?_char:_in.read())!=-1)
|
||||
{
|
||||
_char=-2;
|
||||
|
||||
// look for CR and/or LF
|
||||
if (c==13 || c==10)
|
||||
{
|
||||
if (c==13) _char=_in.read();
|
||||
break;
|
||||
}
|
||||
|
||||
// look for boundary
|
||||
if (b>=0 && b<_byteBoundary.length && c==_byteBoundary[b])
|
||||
b++;
|
||||
else
|
||||
{
|
||||
// this is not a boundary
|
||||
if (cr) baos.write(13);
|
||||
if (lf) baos.write(10);
|
||||
cr=lf=false;
|
||||
|
||||
if (b>0)
|
||||
baos.write(_byteBoundary,0,b);
|
||||
b=-1;
|
||||
|
||||
baos.write(c);
|
||||
}
|
||||
}
|
||||
|
||||
// check partial boundary
|
||||
if ((b>0 && b<_byteBoundary.length-2) ||
|
||||
(b==_byteBoundary.length-1))
|
||||
{
|
||||
if (cr) baos.write(13);
|
||||
if (lf) baos.write(10);
|
||||
cr=lf=false;
|
||||
baos.write(_byteBoundary,0,b);
|
||||
b=-1;
|
||||
}
|
||||
|
||||
// boundary match
|
||||
if (b>0 || c==-1)
|
||||
{
|
||||
if (b==_byteBoundary.length)
|
||||
_lastPart=true;
|
||||
if (_char==10) _char=-2;
|
||||
break;
|
||||
}
|
||||
|
||||
// handle CR LF
|
||||
if (cr) baos.write(13);
|
||||
if (lf) baos.write(10);
|
||||
cr=(c==13);
|
||||
lf=(c==10 || _char==10);
|
||||
if (_char==10) _char=-2;
|
||||
}
|
||||
//if(log.isTraceEnabled())log.trace(baos.toString());
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private String value(String nameEqualsValue)
|
||||
{
|
||||
String value =
|
||||
nameEqualsValue.substring(nameEqualsValue.indexOf('=')+1).trim();
|
||||
|
||||
int i=value.indexOf(';');
|
||||
if (i>0)
|
||||
value=value.substring(0,i);
|
||||
if (value.startsWith("\""))
|
||||
{
|
||||
value=value.substring(1,value.indexOf('"',1));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
i=value.indexOf(' ');
|
||||
if (i>0)
|
||||
value=value.substring(0,i);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private class Part
|
||||
{
|
||||
String _name=null;
|
||||
String _filename=null;
|
||||
Hashtable _headers= new Hashtable(10);
|
||||
byte[] _data=null;
|
||||
}
|
||||
};
|
112
apps/susimail/src/src/org/mortbay/util/ByteArrayPool.java
Normal file
112
apps/susimail/src/src/org/mortbay/util/ByteArrayPool.java
Normal file
@ -0,0 +1,112 @@
|
||||
// ========================================================================
|
||||
// $Id: ByteArrayPool.java,v 1.9 2004/05/09 20:32:49 gregwilkins Exp $
|
||||
// Copyright 2002-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.mortbay.util;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Byte Array Pool
|
||||
* Simple pool for recycling byte arrays of a fixed size.
|
||||
*
|
||||
* @version $Id: ByteArrayPool.java,v 1.9 2004/05/09 20:32:49 gregwilkins Exp $
|
||||
* @author Greg Wilkins (gregw)
|
||||
*/
|
||||
public class ByteArrayPool
|
||||
{
|
||||
public static final int __POOL_SIZE=
|
||||
Integer.getInteger("org.mortbay.util.ByteArrayPool.pool_size",8).intValue();
|
||||
|
||||
public static final ThreadLocal __pools=new BAThreadLocal();
|
||||
public static int __slot;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get a byte array from the pool of known size.
|
||||
* @param size Size of the byte array.
|
||||
* @return Byte array of known size.
|
||||
*/
|
||||
public static byte[] getByteArray(int size)
|
||||
{
|
||||
byte[][] pool = (byte[][])__pools.get();
|
||||
boolean full=true;
|
||||
for (int i=pool.length;i-->0;)
|
||||
{
|
||||
if (pool[i]!=null && pool[i].length==size)
|
||||
{
|
||||
byte[]b = pool[i];
|
||||
pool[i]=null;
|
||||
return b;
|
||||
}
|
||||
else
|
||||
full=false;
|
||||
}
|
||||
|
||||
if (full)
|
||||
for (int i=pool.length;i-->0;)
|
||||
pool[i]=null;
|
||||
|
||||
return new byte[size];
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static byte[] getByteArrayAtLeast(int minSize)
|
||||
{
|
||||
byte[][] pool = (byte[][])__pools.get();
|
||||
for (int i=pool.length;i-->0;)
|
||||
{
|
||||
if (pool[i]!=null && pool[i].length>=minSize)
|
||||
{
|
||||
byte[]b = pool[i];
|
||||
pool[i]=null;
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
return new byte[minSize];
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static void returnByteArray(final byte[] b)
|
||||
{
|
||||
if (b==null)
|
||||
return;
|
||||
|
||||
byte[][] pool = (byte[][])__pools.get();
|
||||
for (int i=pool.length;i-->0;)
|
||||
{
|
||||
if (pool[i]==null)
|
||||
{
|
||||
pool[i]=b;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// slot.
|
||||
int s = __slot++;
|
||||
if (s<0)s=-s;
|
||||
pool[s%pool.length]=b;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
private static final class BAThreadLocal extends ThreadLocal
|
||||
{
|
||||
protected Object initialValue()
|
||||
{
|
||||
return new byte[__POOL_SIZE][];
|
||||
}
|
||||
}
|
||||
}
|
719
apps/susimail/src/src/org/mortbay/util/LineInput.java
Normal file
719
apps/susimail/src/src/org/mortbay/util/LineInput.java
Normal file
@ -0,0 +1,719 @@
|
||||
// ========================================================================
|
||||
// $Id: LineInput.java,v 1.17 2005/10/05 11:32:40 gregwilkins Exp $
|
||||
// Copyright 1996-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.mortbay.util;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
//import org.apache.commons.logging.Log;
|
||||
//import org.mortbay.log.LogFactory;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Fast LineInput InputStream.
|
||||
* This buffered InputStream provides methods for reading lines
|
||||
* of bytes. The lines can be converted to String or character
|
||||
* arrays either using the default encoding or a user supplied
|
||||
* encoding.
|
||||
*
|
||||
* Buffering and data copying are highly optimized, making this
|
||||
* an ideal class for protocols that mix character encoding lines
|
||||
* with arbitrary byte data (eg HTTP).
|
||||
*
|
||||
* The buffer size is also the maximum line length in bytes and/or
|
||||
* characters. If the byte length of a line is less than the max,
|
||||
* but the character length is greater, than then trailing characters
|
||||
* are lost.
|
||||
*
|
||||
* Line termination is forgiving and accepts CR, LF, CRLF or EOF.
|
||||
* Line input uses the mark/reset mechanism, so any marks set
|
||||
* prior to a readLine call are lost.
|
||||
*
|
||||
* @version $Id: LineInput.java,v 1.17 2005/10/05 11:32:40 gregwilkins Exp $
|
||||
* @author Greg Wilkins (gregw)
|
||||
*/
|
||||
public class LineInput extends FilterInputStream
|
||||
{
|
||||
//private static Log log = LogFactory.getLog(LineInput.class);
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private byte _buf[];
|
||||
private ByteBuffer _byteBuffer;
|
||||
private InputStreamReader _reader;
|
||||
private int _mark=-1; // reset marker
|
||||
private int _pos; // Start marker
|
||||
private int _avail; // Available back marker, may be byte limited
|
||||
private int _contents; // Absolute back marker of buffer
|
||||
private int _byteLimit=-1;
|
||||
private boolean _newByteLimit;
|
||||
private LineBuffer _lineBuffer;
|
||||
private String _encoding;
|
||||
private boolean _eof=false;
|
||||
private boolean _lastCr=false;
|
||||
private boolean _seenCrLf=false;
|
||||
|
||||
private final static int LF=10;
|
||||
private final static int CR=13;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* Default buffer and maximum line size is 2048.
|
||||
* @param in The underlying input stream.
|
||||
*/
|
||||
public LineInput(InputStream in)
|
||||
{
|
||||
this(in,0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param in The underlying input stream.
|
||||
* @param bufferSize The buffer size and maximum line length.
|
||||
*/
|
||||
public LineInput(InputStream in, int bufferSize)
|
||||
{
|
||||
super(in);
|
||||
_mark=-1;
|
||||
if (bufferSize==0)
|
||||
bufferSize=8192;
|
||||
_buf=ByteArrayPool.getByteArray(bufferSize);
|
||||
_byteBuffer=new ByteBuffer(_buf);
|
||||
_lineBuffer=new LineBuffer(bufferSize);
|
||||
|
||||
try
|
||||
{
|
||||
_reader=new InputStreamReader(_byteBuffer,"UTF-8");
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
_reader=new InputStreamReader(_byteBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param in The underlying input stream.
|
||||
* @param bufferSize The buffer size and maximum line length.
|
||||
* @param encoding the character encoding to use for readLine methods.
|
||||
* @exception UnsupportedEncodingException
|
||||
*/
|
||||
public LineInput(InputStream in, int bufferSize, String encoding)
|
||||
throws UnsupportedEncodingException
|
||||
{
|
||||
super(in);
|
||||
_mark=-1;
|
||||
if (bufferSize==0)
|
||||
bufferSize=2048;
|
||||
_buf=ByteArrayPool.getByteArray(bufferSize);
|
||||
_byteBuffer=new ByteBuffer(_buf);
|
||||
_lineBuffer=new LineBuffer(bufferSize);
|
||||
_reader=new InputStreamReader(_byteBuffer,encoding);
|
||||
_encoding=encoding;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public InputStream getInputStream()
|
||||
{
|
||||
return in;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the byte limit.
|
||||
* If set, only this number of bytes are read before EOF.
|
||||
* @param bytes Limit number of bytes, or -1 for no limit.
|
||||
*/
|
||||
public void setByteLimit(int bytes)
|
||||
{
|
||||
_byteLimit=bytes;
|
||||
|
||||
if (bytes>=0)
|
||||
{
|
||||
_newByteLimit=true;
|
||||
_byteLimit-=_contents-_pos;
|
||||
if (_byteLimit<0)
|
||||
{
|
||||
_avail+=_byteLimit;
|
||||
_byteLimit=0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_newByteLimit=false;
|
||||
_avail=_contents;
|
||||
_eof=false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the byte limit.
|
||||
* @return Number of bytes until EOF is returned or -1 for no limit.
|
||||
*/
|
||||
public int getByteLimit()
|
||||
{
|
||||
if (_byteLimit<0)
|
||||
return _byteLimit;
|
||||
|
||||
return _byteLimit+_avail-_pos;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Read a line ended by CR, LF or CRLF.
|
||||
* The default or supplied encoding is used to convert bytes to
|
||||
* characters.
|
||||
* @return The line as a String or null for EOF.
|
||||
* @exception IOException
|
||||
*/
|
||||
public synchronized String readLine()
|
||||
throws IOException
|
||||
{
|
||||
int len=fillLine(_buf.length);
|
||||
|
||||
if (len<0)
|
||||
return null;
|
||||
|
||||
String s=null;
|
||||
if (_encoding==null)
|
||||
s=new String(_buf,_mark,len);
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
s=new String(_buf,_mark,len,_encoding);
|
||||
}
|
||||
catch(UnsupportedEncodingException e)
|
||||
{
|
||||
//log.warn(LogSupport.EXCEPTION,e);
|
||||
}
|
||||
}
|
||||
_mark=-1;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Read a line ended by CR, LF or CRLF.
|
||||
* The default or supplied encoding is used to convert bytes to
|
||||
* characters.
|
||||
* @param c Character buffer to place the line into.
|
||||
* @param off Offset into the buffer.
|
||||
* @param len Maximum length of line.
|
||||
* @return The length of the line or -1 for EOF.
|
||||
* @exception IOException
|
||||
*/
|
||||
public int readLine(char[] c,int off,int len)
|
||||
throws IOException
|
||||
{
|
||||
int blen=fillLine(len);
|
||||
|
||||
if (blen<0)
|
||||
return -1;
|
||||
if (blen==0)
|
||||
return 0;
|
||||
|
||||
_byteBuffer.setStream(_mark,blen);
|
||||
|
||||
int read=0;
|
||||
while(read<len && _reader.ready())
|
||||
{
|
||||
int r = _reader.read(c,off+read,len-read);
|
||||
if (r<=0)
|
||||
break;
|
||||
read+=r;
|
||||
}
|
||||
|
||||
_mark=-1;
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Read a line ended by CR, LF or CRLF.
|
||||
* @param b Byte array to place the line into.
|
||||
* @param off Offset into the buffer.
|
||||
* @param len Maximum length of line.
|
||||
* @return The length of the line or -1 for EOF.
|
||||
* @exception IOException
|
||||
*/
|
||||
public int readLine(byte[] b,int off,int len)
|
||||
throws IOException
|
||||
{
|
||||
len=fillLine(len);
|
||||
|
||||
if (len<0)
|
||||
return -1;
|
||||
if (len==0)
|
||||
return 0;
|
||||
|
||||
System.arraycopy(_buf,_mark, b, off, len);
|
||||
_mark=-1;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Read a Line ended by CR, LF or CRLF.
|
||||
* Read a line into a shared LineBuffer instance. The LineBuffer is
|
||||
* resused between calls and should not be held by the caller.
|
||||
* The default or supplied encoding is used to convert bytes to
|
||||
* characters.
|
||||
* @return LineBuffer instance or null for EOF.
|
||||
* @exception IOException
|
||||
*/
|
||||
public LineBuffer readLineBuffer()
|
||||
throws IOException
|
||||
{
|
||||
return readLineBuffer(_buf.length);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Read a Line ended by CR, LF or CRLF.
|
||||
* Read a line into a shared LineBuffer instance. The LineBuffer is
|
||||
* resused between calls and should not be held by the caller.
|
||||
* The default or supplied encoding is used to convert bytes to
|
||||
* characters.
|
||||
* @param len Maximum length of a line, or 0 for default
|
||||
* @return LineBuffer instance or null for EOF.
|
||||
* @exception IOException
|
||||
*/
|
||||
public LineBuffer readLineBuffer(int len)
|
||||
throws IOException
|
||||
{
|
||||
len=fillLine(len>0?len:_buf.length);
|
||||
|
||||
if (len<0)
|
||||
return null;
|
||||
|
||||
if (len==0)
|
||||
{
|
||||
_lineBuffer.size=0;
|
||||
return _lineBuffer;
|
||||
}
|
||||
|
||||
_byteBuffer.setStream(_mark,len);
|
||||
|
||||
_lineBuffer.size=0;
|
||||
int read=0;
|
||||
while(read<len && _reader.ready())
|
||||
{
|
||||
int r = _reader.read(_lineBuffer.buffer,
|
||||
read,
|
||||
len-read);
|
||||
if (r<=0)
|
||||
break;
|
||||
read+=r;
|
||||
}
|
||||
_lineBuffer.size=read;
|
||||
_mark=-1;
|
||||
|
||||
return _lineBuffer;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public synchronized int read() throws IOException
|
||||
{
|
||||
int b;
|
||||
if (_pos >=_avail)
|
||||
fill();
|
||||
if (_pos >=_avail)
|
||||
b=-1;
|
||||
else
|
||||
b=_buf[_pos++]&255;
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public synchronized int read(byte b[], int off, int len) throws IOException
|
||||
{
|
||||
int avail=_avail-_pos;
|
||||
if (avail <=0)
|
||||
{
|
||||
fill();
|
||||
avail=_avail-_pos;
|
||||
}
|
||||
|
||||
if (avail <=0)
|
||||
len=-1;
|
||||
else
|
||||
{
|
||||
len=(avail < len) ? avail : len;
|
||||
System.arraycopy(_buf,_pos,b,off,len);
|
||||
_pos +=len;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public long skip(long n) throws IOException
|
||||
{
|
||||
int avail=_avail-_pos;
|
||||
if (avail <=0)
|
||||
{
|
||||
fill();
|
||||
avail=_avail-_pos;
|
||||
}
|
||||
|
||||
if (avail <=0)
|
||||
n=0;
|
||||
else
|
||||
{
|
||||
n=(avail < n) ? avail : n;
|
||||
_pos +=n;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public synchronized int available()
|
||||
throws IOException
|
||||
{
|
||||
int in_stream=in.available();
|
||||
if (_byteLimit>=0 && in_stream>_byteLimit)
|
||||
in_stream=_byteLimit;
|
||||
|
||||
return _avail - _pos + in_stream;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public synchronized void mark(int limit)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
if (limit>_buf.length)
|
||||
{
|
||||
byte[] new_buf=new byte[limit];
|
||||
System.arraycopy(_buf,_pos,new_buf,_pos,_avail-_pos);
|
||||
_buf=new_buf;
|
||||
if (_byteBuffer!=null)
|
||||
_byteBuffer.setBuffer(_buf);
|
||||
}
|
||||
_mark=_pos;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public synchronized void reset()
|
||||
throws IOException
|
||||
{
|
||||
if (_mark < 0)
|
||||
throw new IOException("Resetting to invalid mark");
|
||||
_pos=_mark;
|
||||
_mark=-1;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean markSupported()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private void fill()
|
||||
throws IOException
|
||||
{
|
||||
// if the mark is in the middle of the buffer
|
||||
if (_mark > 0)
|
||||
{
|
||||
// moved saved bytes to start of buffer
|
||||
int saved=_contents - _mark;
|
||||
System.arraycopy(_buf, _mark, _buf, 0, saved);
|
||||
_pos-=_mark;
|
||||
_avail-=_mark;
|
||||
_contents=saved;
|
||||
_mark=0;
|
||||
}
|
||||
else if (_mark<0 && _pos>0)
|
||||
{
|
||||
// move remaining bytes to start of buffer
|
||||
int saved=_contents-_pos;
|
||||
System.arraycopy(_buf,_pos, _buf, 0, saved);
|
||||
_avail-=_pos;
|
||||
_contents=saved;
|
||||
_pos=0;
|
||||
}
|
||||
else if (_mark==0 && _pos>0 && _contents==_buf.length)
|
||||
{
|
||||
// Discard the mark as we need the space.
|
||||
_mark=-1;
|
||||
fill();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get ready to top up the buffer
|
||||
int n=0;
|
||||
_eof=false;
|
||||
|
||||
// Handle byte limited EOF
|
||||
if (_byteLimit==0)
|
||||
_eof=true;
|
||||
// else loop until something is read.
|
||||
else while (!_eof && n==0 && _buf.length>_contents)
|
||||
{
|
||||
// try to read as much as will fit.
|
||||
int space=_buf.length-_contents;
|
||||
|
||||
n=in.read(_buf,_contents,space);
|
||||
|
||||
if (n<=0)
|
||||
{
|
||||
// If no bytes - we could be NBIO, so we want to avoid
|
||||
// a busy loop.
|
||||
if (n==0)
|
||||
{
|
||||
// Yield to give a chance for some bytes to turn up
|
||||
Thread.yield();
|
||||
|
||||
// Do a byte read as that is blocking
|
||||
int b = in.read();
|
||||
if (b>=0)
|
||||
{
|
||||
n=1;
|
||||
_buf[_contents++]=(byte)b;
|
||||
}
|
||||
else
|
||||
_eof=true;
|
||||
}
|
||||
else
|
||||
_eof=true;
|
||||
}
|
||||
else
|
||||
_contents+=n;
|
||||
_avail=_contents;
|
||||
|
||||
// If we have a byte limit
|
||||
if (_byteLimit>0)
|
||||
{
|
||||
// adjust the bytes available
|
||||
if (_contents-_pos >=_byteLimit)
|
||||
_avail=_byteLimit+_pos;
|
||||
|
||||
if (n>_byteLimit)
|
||||
_byteLimit=0;
|
||||
else if (n>=0)
|
||||
_byteLimit-=n;
|
||||
else if (n==-1)
|
||||
throw new IOException("Premature EOF");
|
||||
}
|
||||
}
|
||||
|
||||
// If we have some characters and the last read was a CR and
|
||||
// the first char is a LF, skip it
|
||||
if (_avail-_pos>0 && _lastCr && _buf[_pos]==LF)
|
||||
{
|
||||
_seenCrLf=true;
|
||||
_pos++;
|
||||
if (_mark>=0)
|
||||
_mark++;
|
||||
_lastCr=false;
|
||||
|
||||
// If the byte limit has just been imposed, dont count
|
||||
// LF as content.
|
||||
if(_byteLimit>=0 && _newByteLimit)
|
||||
{
|
||||
if (_avail<_contents)
|
||||
_avail++;
|
||||
else
|
||||
_byteLimit++;
|
||||
}
|
||||
// If we ate all that ws filled, fill some more
|
||||
if (_pos==_avail)
|
||||
fill();
|
||||
}
|
||||
_newByteLimit=false;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private int fillLine(int maxLen)
|
||||
throws IOException
|
||||
{
|
||||
_mark=_pos;
|
||||
|
||||
if (_pos>=_avail)
|
||||
fill();
|
||||
if (_pos>=_avail)
|
||||
return -1;
|
||||
|
||||
byte b;
|
||||
boolean cr=_lastCr;
|
||||
boolean lf=false;
|
||||
_lastCr=false;
|
||||
int len=0;
|
||||
|
||||
LineLoop:
|
||||
while (_pos<=_avail)
|
||||
{
|
||||
// if we have gone past the end of the buffer
|
||||
while (_pos==_avail)
|
||||
{
|
||||
// If EOF or no more space in the buffer,
|
||||
// return a line.
|
||||
if (_eof || (_mark==0 && _contents==_buf.length))
|
||||
{
|
||||
_lastCr=!_eof && _buf[_avail-1]==CR;
|
||||
|
||||
cr=true;
|
||||
lf=true;
|
||||
break LineLoop;
|
||||
}
|
||||
|
||||
// If we have a CR and no more characters are available
|
||||
if (cr && in.available()==0 && !_seenCrLf)
|
||||
{
|
||||
_lastCr=true;
|
||||
cr=true;
|
||||
lf=true;
|
||||
break LineLoop;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Else just wait for more...
|
||||
_pos=_mark;
|
||||
fill();
|
||||
_pos=len;
|
||||
cr=false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the byte
|
||||
b=_buf[_pos++];
|
||||
|
||||
switch(b)
|
||||
{
|
||||
case LF:
|
||||
if (cr) _seenCrLf=true;
|
||||
lf=true;
|
||||
break LineLoop;
|
||||
|
||||
case CR:
|
||||
if (cr)
|
||||
{
|
||||
// Double CR
|
||||
if (_pos>1)
|
||||
{
|
||||
_pos--;
|
||||
break LineLoop;
|
||||
}
|
||||
}
|
||||
cr=true;
|
||||
break;
|
||||
|
||||
default:
|
||||
if(cr)
|
||||
{
|
||||
if (_pos==1)
|
||||
cr=false;
|
||||
else
|
||||
{
|
||||
_pos--;
|
||||
break LineLoop;
|
||||
}
|
||||
}
|
||||
|
||||
len++;
|
||||
if (len==maxLen)
|
||||
{
|
||||
// look for EOL
|
||||
if (_mark!=0 && _pos+2>=_avail && _avail<_buf.length)
|
||||
fill();
|
||||
|
||||
if (_pos<_avail && _buf[_pos]==CR)
|
||||
{
|
||||
cr=true;
|
||||
_pos++;
|
||||
}
|
||||
if (_pos<_avail && _buf[_pos]==LF)
|
||||
{
|
||||
lf=true;
|
||||
_pos++;
|
||||
}
|
||||
|
||||
if (!cr && !lf)
|
||||
{
|
||||
// fake EOL
|
||||
lf=true;
|
||||
cr=true;
|
||||
}
|
||||
break LineLoop;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cr && !lf && len==0)
|
||||
len=-1;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private static class ByteBuffer extends ByteArrayInputStream
|
||||
{
|
||||
ByteBuffer(byte[] buffer)
|
||||
{
|
||||
super(buffer);
|
||||
}
|
||||
|
||||
void setBuffer(byte[] buffer)
|
||||
{
|
||||
buf=buffer;
|
||||
}
|
||||
|
||||
void setStream(int offset,int length)
|
||||
{
|
||||
pos=offset;
|
||||
count=offset+length;
|
||||
mark=-1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Reusable LineBuffer.
|
||||
* Externalized LineBuffer for fast line parsing.
|
||||
*/
|
||||
public static class LineBuffer
|
||||
{
|
||||
public char[] buffer;
|
||||
public int size;
|
||||
public LineBuffer(int maxLineLength)
|
||||
{buffer=new char[maxLineLength];}
|
||||
|
||||
public String toString(){return new String(buffer,0,size);}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void destroy()
|
||||
{
|
||||
ByteArrayPool.returnByteArray(_buf);
|
||||
_byteBuffer=null;
|
||||
_reader=null;
|
||||
_lineBuffer=null;
|
||||
_encoding=null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -77,6 +77,11 @@ public class UrlLauncher {
|
||||
try {
|
||||
test.close();
|
||||
} catch (IOException ioe) {}
|
||||
// Jetty 6 seems to start the Connector before the
|
||||
// webapp is completely ready
|
||||
try {
|
||||
Thread.sleep(2*1000);
|
||||
} catch (InterruptedException ie) {}
|
||||
return true;
|
||||
} catch (Exception e) {}
|
||||
if (System.currentTimeMillis() > done)
|
||||
|
@ -10,6 +10,6 @@
|
||||
# Javadocs
|
||||
# Note: Include the trailing slash! Don't surround the URL in quotes!
|
||||
javasedocs.url=http://docs.oracle.com/javase/6/docs/api/
|
||||
jettydocs.url=http://docs.i2p2.de/jetty/javadoc/
|
||||
jettydocs.url=http://jetty.codehaus.org/jetty/jetty-6/apidocs/
|
||||
jrobindocs.url=http://docs.i2p-projekt.de/jrobin/javadoc/
|
||||
wrapperdocs.url=http://wrapper.tanukisoftware.com/jdoc/
|
||||
|
157
build.xml
157
build.xml
@ -36,6 +36,7 @@
|
||||
<echo message=" updaterWithJavadoc: updater including the javadocs, for display in the console" />
|
||||
<echo message=" updater200WithJavadoc: updater including the javadocs, for display in the console (creates i2pupdate200.zip)" />
|
||||
<echo message=" updaterWithJetty: Updater including Jetty" />
|
||||
<echo message=" updater200withJetty: Updater including Jetty" />
|
||||
<echo message=" updaterWithJettyFixes: updater including local jetty patches" />
|
||||
<echo message=" updaterWithGeoIP: updater including GeoIP Files" />
|
||||
<echo message=" updaterWithJettyFixesAndGeoIP" />
|
||||
@ -50,26 +51,28 @@
|
||||
<echo message=" javadoc: generate javadoc for the entire project into ./build/javadoc" />
|
||||
<echo message=" slackpkg: generate Slackware packages in ./Slackware/i2p and ./Slackware/i2p-base" />
|
||||
<echo message=" debianhowto: instructions on building Debian packages" />
|
||||
<echo message=" debian: generate Debian packages in ../" />
|
||||
<echo message=" run "ant debianhowto" for instructions" />
|
||||
<echo message=" debian-clean: rollback debian specific patches and run the "distclean" target (done automatically at the end of the "debian" target)" />
|
||||
<!-- <echo message=" debianrepo: build a Debian repository (reprepro required)" /> -->
|
||||
<echo message=" debian: generate Debian packages in ../" />
|
||||
<echo message=" run "ant debianhowto" for instructions" />
|
||||
<echo message=" debian-clean: rollback debian specific patches and run the "distclean" target (done automatically at the end of the "debian" target)" />
|
||||
<!-- <echo message=" debianrepo: build a Debian repository (reprepro required)" /> -->
|
||||
<echo message=" poupdate: update the .po files for translators" />
|
||||
<echo message=" pkg-portable-win32: build a minimum portable version for win32" />
|
||||
</target>
|
||||
<target name="debianhowto">
|
||||
<echo message="To build debian packages, you must make sure that you have" />
|
||||
<echo message="the necessary build-dependencies installed." />
|
||||
<echo message="The packages required to build can be found in the file "/>
|
||||
<echo message=""debian/control" in both the Build-Depends and Build-Depends-Indep fields."/>
|
||||
<echo message="In addition to those packages, be sure to install "fakeroot","/>
|
||||
<echo message=""quilt" and "build-essential"!" />
|
||||
<echo message="" />
|
||||
<echo message="The following command will install all dependencies for you:" />
|
||||
<echo message="apt-get install debhelper ant debconf default-jdk gettext libgmp3-dev po-debconf fakeroot build-essential quilt" />
|
||||
<echo message=" " />
|
||||
<echo message="Once the dependencies are installed, run "ant debian""/>
|
||||
<echo message="to patch the source and build the packages." />
|
||||
<echo message="To build debian packages, you must make sure that you have" />
|
||||
<echo message="the necessary build-dependencies installed." />
|
||||
<echo message="The packages required to build can be found in the file "/>
|
||||
<echo message=""debian/control" in the "Build-Depends" field."/>
|
||||
<echo message="In addition to those packages, be sure to install "fakeroot","/>
|
||||
<echo message=""quilt" and "build-essential"!" />
|
||||
<echo message="" />
|
||||
<echo message="The following command will install all of the dependencies for you:" />
|
||||
<echo message=" " />
|
||||
<echo message="apt-get install debhelper ant debconf default-jdk gettext libgmp3-dev po-debconf fakeroot build-essential \" />
|
||||
<echo message=" quilt libcommons-el-java libcommons-logging-java libjetty-extra-java libjetty-java" />
|
||||
<echo message=" " />
|
||||
<echo message="Once the dependencies are installed, run "ant debian""/>
|
||||
<echo message="to patch the source and build the packages." />
|
||||
</target>
|
||||
<target name="dist" depends="pkg, javadoc">
|
||||
</target>
|
||||
@ -132,7 +135,7 @@
|
||||
<ant dir="apps/routerconsole/java/" target="jar" />
|
||||
</target>
|
||||
|
||||
<target name="buildJetty" depends="buildProperties" >
|
||||
<target name="buildJetty" depends="buildCore" >
|
||||
<ant dir="apps/jetty" target="build" />
|
||||
</target>
|
||||
|
||||
@ -197,12 +200,9 @@
|
||||
<target name="buildWEB" depends="buildRouterConsole" >
|
||||
<copy file="apps/routerconsole/java/build/routerconsole.jar" todir="build/" />
|
||||
<copy file="apps/routerconsole/java/build/routerconsole.war" todir="build/" />
|
||||
<copy file="apps/jetty/jettylib/org.mortbay.jetty.jar" todir="build/" />
|
||||
<copy file="apps/jetty/jettylib/jasper-compiler.jar" todir="build/" />
|
||||
<copy file="apps/jetty/jettylib/jasper-runtime.jar" todir="build/" />
|
||||
<copy file="apps/jetty/jettylib/commons-logging.jar" todir="build/" />
|
||||
<copy file="apps/jetty/jettylib/commons-el.jar" todir="build/" />
|
||||
<copy file="apps/jetty/jettylib/javax.servlet.jar" todir="build/" />
|
||||
<copy todir="build/" >
|
||||
<fileset dir="apps/jetty/jettylib" excludes="ant.jar" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="buildexe">
|
||||
@ -402,9 +402,10 @@
|
||||
<group title="Desktopgui Application" packages="net.i2p.desktopgui:net.i2p.desktopgui.*" />
|
||||
<group title="I2PSnark Application" packages="org.klomp.snark:org.klomp.snark.*" />
|
||||
<group title="I2PTunnel Application" packages="net.i2p.i2ptunnel:net.i2p.i2ptunnel.*" />
|
||||
<group title="Jetty Logging" packages="net.i2p.jetty" />
|
||||
<group title="SAM Bridge" packages="net.i2p.sam:net.i2p.sam.client" />
|
||||
<group title="SusiDNS Application" packages="i2p.susi.dns" />
|
||||
<group title="SusiMail Application" packages="i2p.susi.webmail:i2p.susi.webmail.*:i2p.susi.debug:i2p.susi.util" />
|
||||
<group title="SusiMail Application" packages="i2p.susi.webmail:i2p.susi.webmail.*:i2p.susi.debug:i2p.susi.util:org.mortbay.servlet:org.mortbay.util" />
|
||||
<group title="Systray Application" packages="net.i2p.apps.systray" />
|
||||
<sourcepath>
|
||||
<pathelement location="core/java/src" />
|
||||
@ -423,10 +424,16 @@
|
||||
<pathelement location="apps/BOB/src" />
|
||||
<pathelement location="apps/susidns/src/java/src" />
|
||||
<pathelement location="apps/susimail/src/src" />
|
||||
<pathelement location="apps/jetty/java/src" />
|
||||
</sourcepath>
|
||||
<classpath>
|
||||
<pathelement location="apps/jetty/jettylib/org.mortbay.jetty.jar" />
|
||||
<pathelement location="apps/jetty/jettylib/javax.servlet.jar" />
|
||||
<pathelement location="apps/jetty/jettylib/jetty-sslengine.jar" />
|
||||
<pathelement location="apps/jetty/jettylib/jetty-start.jar" />
|
||||
<pathelement location="apps/jetty/jettylib/jetty-java5-threadpool.jar" />
|
||||
<pathelement location="apps/jetty/jettylib/jetty-util.jar" />
|
||||
<pathelement location="apps/jetty/jettylib/jsp-api.jar" />
|
||||
<pathelement location="apps/systray/java/lib/systray4j.jar" />
|
||||
<pathelement location="apps/jrobin/jrobin-1.5.9.1.jar" />
|
||||
<pathelement location="installer/lib/wrapper/all/wrapper.jar" />
|
||||
@ -603,6 +610,15 @@
|
||||
<defaultexcludes default="true"/>
|
||||
</target>
|
||||
|
||||
<target name="webappDistclean">
|
||||
<ant dir="apps/i2ptunnel/java/" target="distclean" />
|
||||
<ant dir="apps/routerconsole/java/" target="distclean" />
|
||||
<ant dir="apps/addressbook/" target="distclean" />
|
||||
<ant dir="apps/susimail/" target="distclean" />
|
||||
<ant dir="apps/susidns/src/" target="distclean" />
|
||||
<ant dir="apps/i2psnark/java/" target="distclean" />
|
||||
</target>
|
||||
|
||||
<target name="pkg" depends="distclean, updater, preppkg, installer" />
|
||||
|
||||
<target name="pkgclean" depends="deletepkg-temp">
|
||||
@ -722,14 +738,12 @@
|
||||
</delete>
|
||||
<copy file="build/i2p.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/i2ptunnel.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/jasper-compiler.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/jasper-runtime.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/commons-logging.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/commons-el.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/javax.servlet.jar" todir="pkg-temp/lib/" />
|
||||
<!-- all jetty stuff -->
|
||||
<copy todir="pkg-temp/lib" >
|
||||
<fileset dir="build" includes="commons*.jar jasper*.jar javax*.jar jetty*.jar jsp*.jar org.mortbay.*.jar" />
|
||||
</copy>
|
||||
<copy file="build/mstreaming.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/streaming.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/org.mortbay.jetty.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/router.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/desktopgui.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/routerconsole.jar" todir="pkg-temp/lib/" />
|
||||
@ -776,20 +790,13 @@
|
||||
<copy file="installer/resources/uninstall.ico" todir="pkg-temp/docs/" />
|
||||
<!-- Eepsite stuff here -->
|
||||
<mkdir dir="pkg-temp/eepsite" />
|
||||
<mkdir dir="pkg-temp/eepsite/webapps" />
|
||||
<mkdir dir="pkg-temp/eepsite/logs" />
|
||||
<mkdir dir="pkg-temp/eepsite/cgi-bin" />
|
||||
<mkdir dir="pkg-temp/eepsite/docroot" />
|
||||
<mkdir dir="pkg-temp/eepsite/docroot/help" />
|
||||
<mkdir dir="pkg-temp/eepsite/docroot/help/lib" />
|
||||
<copy todir="pkg-temp/eepsite/docroot/" >
|
||||
<fileset dir="installer/resources/eepsite.help/" />
|
||||
<copy todir="pkg-temp/eepsite/" >
|
||||
<fileset dir="installer/resources/eepsite/" />
|
||||
</copy>
|
||||
<copy todir="pkg-temp/eepsite/docroot/help/lib/" >
|
||||
<fileset dir="installer/resources/icons/flags/" includes="cn.png de.png es.png fr.png ir.png it.png jp.png nl.png ru.png se.png us.png" />
|
||||
</copy>
|
||||
<copy file="installer/resources/themes/console/images/favicon.ico" tofile="pkg-temp/eepsite/docroot/favicon.ico" />
|
||||
<copy file="installer/resources/jetty.xml" tofile="pkg-temp/eepsite/jetty.xml" />
|
||||
</target>
|
||||
|
||||
<target name="preplicenses">
|
||||
@ -803,6 +810,7 @@
|
||||
So we include the MIT one in our binary package
|
||||
-->
|
||||
<copy file="installer/lib/launch4j/head/LICENSE.txt" tofile="pkg-temp/licenses/LICENSE-Launch4j.txt" />
|
||||
<copy file="apps/jetty/apache-tomcat-deployer/NOTICE" tofile="pkg-temp/licenses/NOTICE-Tomcat.txt" />
|
||||
<!-- Not sure if these are used or should be included -->
|
||||
<copy file="installer/lib/launch4j/lib/foxtrot.LICENSE.txt" tofile="pkg-temp/licenses/LICENSE-Foxtrot.txt" />
|
||||
<copy file="installer/lib/launch4j/lib/JGoodies.Forms.LICENSE.txt" tofile="pkg-temp/licenses/LICENSE-JGoodies-Forms.txt" />
|
||||
@ -869,6 +877,7 @@
|
||||
<target name="updater200WithJavadoc" depends="prepupdate, preplicenses, copyJavadoc, pack200, zipit200" />
|
||||
<target name="updaterWithGeoIP" depends="prepupdate, prepgeoupdate, preplicenses, zipit" />
|
||||
<target name="updaterWithJetty" depends="prepjupdate, preplicenses, zipit" />
|
||||
<target name="updater200WithJetty" depends="prepjupdate, preplicenses, pack200, zipit200" />
|
||||
<target name="updaterWithJettyFixes" depends="prepjupdatefixes, preplicenses, zipit" />
|
||||
<target name="updaterWithJettyFixesAndJbigi" depends="prepjupdatefixes, prepjbigiupdate, preplicenses, zipit" />
|
||||
<target name="updaterWithJettyFixesAndGeoIP" depends="prepjupdatefixes, prepgeoupdate, preplicenses, zipit" />
|
||||
@ -985,16 +994,26 @@
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<!-- All jetty jars required for update.
|
||||
We don't need commons-el or commons-logging, they haven't changed.
|
||||
TODO do we need to bother updating jasper?
|
||||
TODO where is JMX? We don't need it I hope.
|
||||
-->
|
||||
<target name="prepjupdate" depends="prepupdate, buildWEB">
|
||||
<copy file="build/jasper-compiler.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/jasper-runtime.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/commons-logging.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/commons-el.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/javax.servlet.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/org.mortbay.jetty.jar" todir="pkg-temp/lib/" />
|
||||
<copy todir="pkg-temp/lib" >
|
||||
<fileset dir="build" includes="commons*.jar jasper*.jar javax*.jar jetty*.jar jsp*.jar org.mortbay.*.jar" />
|
||||
</copy>
|
||||
<!-- 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" >
|
||||
<fileset dir="installer/resources/eepsite" includes="*.xml contexts/* etc/*" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<!-- Jetty 6 I2P logging addons, not really fixes -->
|
||||
<target name="prepjupdatefixes" depends="prepupdate, buildWEB">
|
||||
<copy file="build/org.mortbay.jetty.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/jetty-i2p.jar" todir="pkg-temp/lib/" />
|
||||
</target>
|
||||
|
||||
<target name="util-list-changes" depends="checkForMtn" if="mtn.available" >
|
||||
@ -1426,33 +1445,33 @@
|
||||
|
||||
<target name="debian-binary" >
|
||||
<echo message="Did you update the version using dch -i?" />
|
||||
<echo message=" " />
|
||||
<echo message="If the changelog was not updated with dch -i, press" />
|
||||
<echo message="press CTRL+C to abort building this Debian package." />
|
||||
<echo message="" />
|
||||
<echo message="Pausing build for ten seconds to give enough time to read this notice." />
|
||||
<exec executable="sleep" failonerror="true">
|
||||
<arg value="10" />
|
||||
</exec>
|
||||
<echo message="====================" />
|
||||
<!-- bundle the jetty 5 lib since there isn't a deb for it -->
|
||||
<ant dir="apps/jetty" target="ensureJettylib" />
|
||||
|
||||
<exec executable="fakeroot" failonerror="true">
|
||||
<arg value="debian/rules" />
|
||||
<arg value="patch" />
|
||||
<arg value="binary" />
|
||||
<arg value="clean" />
|
||||
<echo message=" " />
|
||||
<echo message="If the changelog was not updated with dch -i, press" />
|
||||
<echo message="press CTRL+C to abort building this Debian package." />
|
||||
<echo message="" />
|
||||
<echo message="Pausing build for ten seconds to give enough time to read this notice." />
|
||||
<exec executable="sleep" failonerror="true">
|
||||
<arg value="10" />
|
||||
</exec>
|
||||
<delete dir=".pc" />
|
||||
<echo message="====================" />
|
||||
|
||||
<exec executable="fakeroot" failonerror="true">
|
||||
<arg value="debian/rules" />
|
||||
<arg value="patch" />
|
||||
<arg value="binary" />
|
||||
<arg value="clean" />
|
||||
</exec>
|
||||
<delete dir=".pc" />
|
||||
</target>
|
||||
|
||||
<target name="debian-clean" depends="buildProperties" >
|
||||
<exec executable="fakeroot" failonerror="true">
|
||||
<arg value="debian/rules" />
|
||||
<arg value="clean" />
|
||||
<arg value="debian/rules" />
|
||||
<arg value="clean" />
|
||||
</exec>
|
||||
<delete dir="./.pc" />
|
||||
<delete dir="./.pc" />
|
||||
</target>
|
||||
|
||||
<target name="debian-patch" depends="buildProperties" >
|
||||
<exec executable="quilt" failonerror="true">
|
||||
<arg value="-a" />
|
||||
@ -1462,8 +1481,8 @@
|
||||
</target>
|
||||
<target name="debian-unpatch" depends="buildProperties">
|
||||
<exec executable="quilt" failonerror="false">
|
||||
<arg value="-a" />
|
||||
<arg value="pop" />
|
||||
<arg value="-a" />
|
||||
<arg value="pop" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
|
11
debian/control
vendored
11
debian/control
vendored
@ -10,9 +10,12 @@ Build-Depends: debhelper (>= 7.0.50~),
|
||||
debconf,
|
||||
default-jdk,
|
||||
gettext,
|
||||
libcommons-el-java,
|
||||
libcommons-logging-java,
|
||||
libgmp3-dev,
|
||||
libjetty-extra-java,
|
||||
libjetty-java,
|
||||
po-debconf
|
||||
##Build-Depends-Indep: tor-geoipdb
|
||||
|
||||
Package: i2p
|
||||
Architecture: all
|
||||
@ -65,7 +68,11 @@ Package: i2p-router
|
||||
Architecture: all
|
||||
Section: net
|
||||
Priority: optional
|
||||
Depends: ${misc:Depends}, ${java:Depends}, ${shlibs:Depends}, default-jre-headless | java5-runtime-headless | java6-runtime-headless
|
||||
Depends: ${misc:Depends}, ${java:Depends}, ${shlibs:Depends},
|
||||
default-jre-headless | java5-runtime-headless | java6-runtime-headless,
|
||||
libcommons-logging-java,
|
||||
libjetty-java,
|
||||
libtomcat6-java
|
||||
Replaces: i2p ( << 0.8.6-5)
|
||||
Breaks: i2p (<< 0.8.6-5)
|
||||
Recommends: libjbigi-jni (>= ${source:Version}), libjbigi-jni (<< ${source:Version}.1~), ttf-dejavu
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user