forked from I2P_Developers/i2p.i2p
Conversion to Jetty 12 / Java 17
Some checks failed
Java CI / build (push) Has been cancelled
Java CI / javadoc-latest (push) Has been cancelled
Java CI / build-java7 (push) Has been cancelled
Java with IzPack Snapshot Setup / setup (push) Has been cancelled
Sync Primary Repository to GitHub Mirror / sync (push) Has been cancelled
Some checks failed
Java CI / build (push) Has been cancelled
Java CI / javadoc-latest (push) Has been cancelled
Java CI / build-java7 (push) Has been cancelled
Java with IzPack Snapshot Setup / setup (push) Has been cancelled
Sync Primary Repository to GitHub Mirror / sync (push) Has been cancelled
- Basic console (tested) - SSL console (tested) - Auth (tested) - Debug logging (tested) - Console request log (tested) - I2PControl separate port (untested) - Eepsite request log (untested) TODO: - Eepsites + migration - Debian with or without Jetty 12 - Snark standalone - Tomcat upgrade - Checkin jetty jars - Cleanups
This commit is contained in:
@ -21,6 +21,9 @@
|
||||
<pathelement location="${jettylib}/org.mortbay.jetty.jar" />
|
||||
<pathelement location="${jettylib}/javax.servlet.jar" />
|
||||
<pathelement location="${jettylib}/jetty-servlet.jar" />
|
||||
<pathelement location="${jettylib}/jetty-http.jar" />
|
||||
<pathelement location="${jettylib}/jetty-io.jar" />
|
||||
<pathelement location="${jettylib}/jetty-webapp.jar" />
|
||||
<pathelement location="${wrapperlib}/wrapper.jar" />
|
||||
<!-- following jar only present for debian builds -->
|
||||
<pathelement location="../../core/java/build/json-simple.jar" />
|
||||
|
@ -14,8 +14,10 @@ import net.i2p.util.Log;
|
||||
|
||||
import net.i2p.apache.http.conn.util.InetAddressUtils;
|
||||
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
||||
/**
|
||||
* Block certain Host headers to prevent DNS rebinding attacks.
|
||||
@ -28,7 +30,7 @@ import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
*
|
||||
* @since 0.12 copied from routerconsole
|
||||
*/
|
||||
public class HostCheckHandler extends HandlerWrapper
|
||||
public class HostCheckHandler extends Handler.Wrapper
|
||||
{
|
||||
private final I2PAppContext _context;
|
||||
private final Set<String> _listenHosts;
|
||||
@ -57,14 +59,13 @@ public class HostCheckHandler extends HandlerWrapper
|
||||
/**
|
||||
* Block by Host header, pass everything else to the delegate.
|
||||
*/
|
||||
public void handle(String pathInContext,
|
||||
Request baseRequest,
|
||||
HttpServletRequest httpRequest,
|
||||
HttpServletResponse httpResponse)
|
||||
throws IOException, ServletException
|
||||
@Override
|
||||
public boolean handle(Request request,
|
||||
Response response,
|
||||
Callback callback)
|
||||
throws Exception
|
||||
{
|
||||
|
||||
String host = httpRequest.getHeader("Host");
|
||||
String host = request.getHeaders().get("Host");
|
||||
if (!allowHost(host)) {
|
||||
Log log = _context.logManager().getLog(HostCheckHandler.class);
|
||||
host = DataHelper.stripHTML(getHost(host));
|
||||
@ -73,11 +74,12 @@ public class HostCheckHandler extends HandlerWrapper
|
||||
I2PControlController.PROP_ALLOWED_HOSTS + '=' + host +
|
||||
"\" to I2PControl.conf and restart.";
|
||||
log.logAlways(Log.WARN, s);
|
||||
httpResponse.sendError(403, s);
|
||||
return;
|
||||
Response.writeError(request, response, callback, 403, s);
|
||||
callback.succeeded();
|
||||
return true;
|
||||
}
|
||||
|
||||
super.handle(pathInContext, baseRequest, httpRequest, httpResponse);
|
||||
return super.handle(request, response, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -31,6 +31,8 @@ import net.i2p.i2pcontrol.security.SecurityManager;
|
||||
import net.i2p.i2pcontrol.servlets.JSONRPC2Servlet;
|
||||
import net.i2p.i2pcontrol.servlets.configuration.ConfigurationManager;
|
||||
|
||||
import org.eclipse.jetty.ee8.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.ee8.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||
@ -38,8 +40,6 @@ import org.eclipse.jetty.server.SecureRequestCustomizer;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.SslConnectionFactory;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
|
||||
import java.io.File;
|
||||
@ -238,8 +238,8 @@ public class I2PControlController implements RouterApp {
|
||||
Connector ssl = buildDefaultListener(server);
|
||||
server.addConnector(ssl);
|
||||
|
||||
ServletHandler sh = new ServletHandler();
|
||||
sh.addServletWithMapping(new ServletHolder(new JSONRPC2Servlet(_context, _secMan)), "/");
|
||||
ServletContextHandler sch = new ServletContextHandler();
|
||||
sch.addServlet(new ServletHolder(new JSONRPC2Servlet(_context, _secMan)), "/");
|
||||
HostCheckHandler hch = new HostCheckHandler(_appContext);
|
||||
Set<String> listenHosts = new HashSet<String>(8);
|
||||
// fix up the allowed hosts set (see HostCheckHandler)
|
||||
@ -261,8 +261,8 @@ public class I2PControlController implements RouterApp {
|
||||
}
|
||||
}
|
||||
hch.setListenHosts(listenHosts);
|
||||
hch.setHandler(sh);
|
||||
server.getServer().setHandler(hch);
|
||||
hch.setHandler(sch);
|
||||
server.setHandler(hch);
|
||||
|
||||
_conf.writeConfFile();
|
||||
return server;
|
||||
@ -282,7 +282,8 @@ public class I2PControlController implements RouterApp {
|
||||
}
|
||||
|
||||
// the keystore path and password
|
||||
SslContextFactory sslFactory = new SslContextFactory(_ksp.getKeyStoreLocation());
|
||||
SslContextFactory.Server sslFactory = new SslContextFactory.Server();
|
||||
sslFactory.setKeyStorePath(_ksp.getKeyStoreLocation());
|
||||
sslFactory.setKeyStorePassword(KeyStoreProvider.DEFAULT_KEYSTORE_PASSWORD);
|
||||
// the X.509 cert password (if not present, verifyKeyStore() returned false)
|
||||
sslFactory.setKeyManagerPassword(KeyStoreProvider.DEFAULT_CERTIFICATE_PASSWORD);
|
||||
|
@ -62,6 +62,8 @@
|
||||
<pathelement location="../../systray/java/build/systray.jar" />
|
||||
<pathelement location="../../jetty/jettylib/org.mortbay.jetty.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-util.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-http.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-io.jar" />
|
||||
<pathelement location="../../desktopgui/dist/desktopgui.jar" />
|
||||
</classpath>
|
||||
</javac>
|
||||
|
@ -13,8 +13,10 @@ import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.Addresses;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
||||
/**
|
||||
* Block certain Host headers to prevent DNS rebinding attacks.
|
||||
@ -23,7 +25,7 @@ import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
*
|
||||
* @since 0.9.34 adapted from router console
|
||||
*/
|
||||
public class HostCheckHandler extends AbstractHandler {
|
||||
public class HostCheckHandler extends Handler.Abstract {
|
||||
private final I2PAppContext _context;
|
||||
private final Set<String> _listenHosts;
|
||||
private static final String PROP_ALLOWED_HOSTS = "i2psnark.allowedHosts";
|
||||
@ -63,14 +65,13 @@ public class HostCheckHandler extends AbstractHandler {
|
||||
* redirect HTTP to HTTPS,
|
||||
* pass everything else to the delegate.
|
||||
*/
|
||||
public void handle(String pathInContext,
|
||||
Request baseRequest,
|
||||
HttpServletRequest httpRequest,
|
||||
HttpServletResponse httpResponse)
|
||||
throws IOException, ServletException
|
||||
@Override
|
||||
public boolean handle(Request request,
|
||||
Response response,
|
||||
Callback callback)
|
||||
throws Exception
|
||||
{
|
||||
|
||||
String host = httpRequest.getHeader("Host");
|
||||
String host = request.getHeaders().get("Host");
|
||||
if (!allowHost(host)) {
|
||||
Log log = _context.logManager().getLog(HostCheckHandler.class);
|
||||
host = getHost(host);
|
||||
@ -79,10 +80,11 @@ public class HostCheckHandler extends AbstractHandler {
|
||||
PROP_ALLOWED_HOSTS + '=' + host +
|
||||
"\" in the file " + RunStandalone.APP_CONFIG_FILE.getAbsolutePath() + " and restart.";
|
||||
log.logAlways(Log.WARN, s);
|
||||
httpResponse.sendError(403, s);
|
||||
baseRequest.setHandled(true);
|
||||
return;
|
||||
Response.writeError(request, response, callback, 403, s);
|
||||
callback.succeeded();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,8 +5,6 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.app.MenuCallback;
|
||||
import net.i2p.app.MenuHandle;
|
||||
@ -44,11 +42,8 @@ public class RunStandalone {
|
||||
_context = new I2PAppContext(p);
|
||||
// Do this after we have a context
|
||||
// To take effect, must be set before any Jetty classes are loaded
|
||||
try {
|
||||
Log.setLog(new I2PLogger(_context));
|
||||
} catch (Throwable t) {
|
||||
System.err.println("INFO: I2P Jetty logging class not found, logging to stdout");
|
||||
}
|
||||
// https://slf4j.org/faq.html
|
||||
System.setProperty("slf4j.provider", "net.i2p.jetty.I2PLoggingServiceProvider");
|
||||
File base = _context.getBaseDir();
|
||||
File xml = new File(base, "jetty-i2psnark.xml");
|
||||
_jettyStart = new JettyStart(_context, null, new String[] { xml.getAbsolutePath() } );
|
||||
|
@ -16,10 +16,10 @@
|
||||
<!-- Note: Change version numbers in top-level build.xml if you update to a new Tomcat or Jetty! -->
|
||||
|
||||
<property name="jetty.branch" value="stable-9" />
|
||||
<property name="jetty.base" value="jetty-distribution-${jetty.ver}" />
|
||||
<property name="jetty.sha1" value="e9f176730aea36a69c24eeba77dd0880a30492dc" />
|
||||
<property name="jetty.base" value="jetty-home-${jetty.ver}" />
|
||||
<property name="jetty.sha1" value="6c8b834d313bcac2e6a2e42ebaf34a249887162a" />
|
||||
<property name="jetty.filename" value="${jetty.base}.zip" />
|
||||
<property name="jetty.url" value="https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-distribution/${jetty.ver}/${jetty.filename}" />
|
||||
<property name="jetty.url" value="https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-home/${jetty.ver}/${jetty.filename}" />
|
||||
<property name="verified.filename" value="verified.txt" />
|
||||
<property name="javac.compilerargs" value="" />
|
||||
<property name="javac.version" value="1.8" />
|
||||
@ -154,44 +154,44 @@
|
||||
start.jar: Needed for clients.config startup of eepsites
|
||||
jetty-util-xxx.jar: LifeCycle (base class for stuff), URIUtil (used in i2psnark)
|
||||
jetty-deploy, -http, -io, -security, -servlet, -webapp: All split out from main server jar in Jetty 7
|
||||
jetty-continuation-xxx.jar: Needed? Useful?
|
||||
jetty-continuation-xxx.jar: Old Jetty 9, now a dummy
|
||||
jetty-servlets-xxx.jar: Needed for CGI for eepsite
|
||||
jetty-sslengine-xxx.jar: Old Jetty 6, now a dummy
|
||||
jetty-java5-threadpool-xxx.jar: Old Jetty 6, now a dummy
|
||||
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
|
||||
javax.servlet.jsp-2.2.0.v201112011158.jar: Required API
|
||||
servlet-api-3.0.jar: Required API
|
||||
jetty-management: No longer included
|
||||
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-server-${jetty.ver}.jar" tofile="jettylib/org.mortbay.jetty.jar" />
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-continuation-${jetty.ver}.jar" tofile="jettylib/jetty-continuation.jar" />
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-deploy-${jetty.ver}.jar" tofile="jettylib/jetty-deploy.jar" />
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-http-${jetty.ver}.jar" tofile="jettylib/jetty-http.jar" />
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-io-${jetty.ver}.jar" tofile="jettylib/jetty-io.jar" />
|
||||
<!-- comment out above line and uncomment below and the patches section further down if we need patches -->
|
||||
<!--
|
||||
<jar destfile="jettylib/jetty-io.jar" manifest="${jetty.base}/lib/jetty-io-${jetty.ver}.jar" filesetmanifest="mergewithoutmain" >
|
||||
<zipfileset excludes="**/SslConnection*.class" src="${jetty.base}/lib/jetty-io-${jetty.ver}.jar" />
|
||||
<zipfileset src="build/jetty-io-patch.jar" />
|
||||
</jar>
|
||||
-->
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-jmx-${jetty.ver}.jar" tofile="jettylib/org.mortbay.jmx.jar" />
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-rewrite-${jetty.ver}.jar" tofile="jettylib/jetty-rewrite-handler.jar" />
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-security-${jetty.ver}.jar" tofile="jettylib/jetty-security.jar" />
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-servlet-${jetty.ver}.jar" tofile="jettylib/jetty-servlet.jar" />
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-servlets-${jetty.ver}.jar" tofile="jettylib/jetty-servlets.jar" />
|
||||
<!--
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-util-${jetty.ver}.jar" tofile="jettylib/jetty-util.jar" />
|
||||
-->
|
||||
<!-- comment out above line and uncomment below and the patches section further down if we need patches -->
|
||||
|
||||
<!--
|
||||
TODO move out of here
|
||||
Debian libjetty12-java does NOT include the ee8 jars,
|
||||
so we keep them all together here, for ease in
|
||||
handling both the Debian and non-Debian build cases.
|
||||
-->
|
||||
<jar destfile="jettylib/jetty-webapp.jar" manifest="${jetty.base}/lib/jetty-ee8-webapp-${jetty.ver}.jar" filesetmanifest="mergewithoutmain" >
|
||||
<zipfileset src="${jetty.base}/lib/jetty-ee8-nested-${jetty.ver}.jar" />
|
||||
<zipfileset src="${jetty.base}/lib/jetty-ee8-security-${jetty.ver}.jar" />
|
||||
<zipfileset src="${jetty.base}/lib/jetty-ee8-webapp-${jetty.ver}.jar" />
|
||||
</jar>
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-ee8-servlet-${jetty.ver}.jar" tofile="jettylib/jetty-servlet.jar" />
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-ee8-servlets-${jetty.ver}.jar" tofile="jettylib/jetty-servlets.jar" />
|
||||
|
||||
<jar destfile="jettylib/jetty-util.jar" manifest="${jetty.base}/lib/jetty-util-${jetty.ver}.jar" filesetmanifest="mergewithoutmain" >
|
||||
<zipfileset excludes="**/JavaVersion.class" src="${jetty.base}/lib/jetty-util-${jetty.ver}.jar" />
|
||||
<zipfileset src="build/jetty-util-patch.jar" />
|
||||
<zipfileset src="${jetty.base}/lib/jetty-ee-${jetty.ver}.jar" />
|
||||
<zipfileset src="${jetty.base}/lib/jetty-session-${jetty.ver}.jar" />
|
||||
<zipfileset src="${jetty.base}/lib/jetty-util-${jetty.ver}.jar" />
|
||||
<zipfileset src="${jetty.base}/lib/logging/slf4j-api-2.0.17.jar" />
|
||||
</jar>
|
||||
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-webapp-${jetty.ver}.jar" tofile="jettylib/jetty-webapp.jar" />
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-xml-${jetty.ver}.jar" tofile="jettylib/jetty-xml.jar" />
|
||||
<jar destfile="jettylib/jetty-java5-threadpool.jar" >
|
||||
<manifest>
|
||||
@ -203,6 +203,11 @@
|
||||
<attribute name="Note" value="Intentionally empty" />
|
||||
</manifest>
|
||||
</jar>
|
||||
<jar destfile="jettylib/jetty-continuation.jar" >
|
||||
<manifest>
|
||||
<attribute name="Note" value="Intentionally empty" />
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<!--
|
||||
@ -228,7 +233,7 @@
|
||||
<!-- In Debian packages they are found in /usr/share/java/tomcat8-servlet-api.jar in the libtomcat8-java package -->
|
||||
<!-- javax/servlet/jsp/resources are dups of those in apache-jsp jar -->
|
||||
<!--
|
||||
<zipfileset includes="javax/**/*" src="${jetty.base}/lib/apache-jsp/org.mortbay.jasper.apache-jsp-8.0.33.jar"/>
|
||||
<zipfileset includes="javax/**/*" src="${jetty.base}/lib/ee8-apache-jsp/org.mortbay.jasper.apache-jsp-9.0.96.jar"/>
|
||||
<zipfileset excludes="about.html about_files about_files/* META-INF/ECLIPSEF.* META-INF/eclipse.inf plugin.properties javax/servlet/jsp/resources/*" src="${jetty.base}/lib/jetty-schemas-3.1.jar" />
|
||||
-->
|
||||
|
||||
@ -248,7 +253,7 @@
|
||||
<!-- ONLY if with-libtomcat8-java but NOT with-libjetty9-java (wheezy/jessie configuration) -->
|
||||
<!-- If neither with-libtomcat8-java nor with-libjetty9-java, it's merged into jasper-runtime.jar in the copyTomcatLib2 target below -->
|
||||
<target name="copyJettylib3" depends="extractJettylib, copyTomcatLib1" if="${with-libtomcat-without-libjetty}" >
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/apache-jsp/org.eclipse.jetty.apache-jsp-${jetty.ver}.jar" tofile="jettylib/jetty-apache-jsp.jar" />
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-ee8-apache-jsp-${jetty.ver}.jar" tofile="jettylib/jetty-apache-jsp.jar" />
|
||||
</target>
|
||||
|
||||
<!-- Tomcat.
|
||||
@ -330,7 +335,7 @@
|
||||
|
||||
<!-- For both Apache in Jetty package and Apache package versions -->
|
||||
<!-- required Jetty initializer (see RouterConsoleRunner) -->
|
||||
<zipfileset src="${jetty.base}/lib/apache-jsp/org.eclipse.jetty.apache-jsp-${jetty.ver}.jar"/>
|
||||
<zipfileset src="${jetty.base}/lib/jetty-ee8-apache-jsp-${jetty.ver}.jar"/>
|
||||
|
||||
<!-- Apache in Jetty package version -->
|
||||
<!-- Also includes javax.servlet.jsp.*, this is copied into javax.servlet.jar above -->
|
||||
@ -485,11 +490,11 @@
|
||||
</target>
|
||||
|
||||
<!-- empty, uncomment below if needed -->
|
||||
<!--
|
||||
<target name="buildPatches" unless="${with-libjetty9-java}" />
|
||||
-->
|
||||
|
||||
<!--
|
||||
<target name="buildPatches" depends="jarPatches" unless="${with-libjetty9-java}" />
|
||||
-->
|
||||
|
||||
<target name="compilePatches" unless="${with-libjetty9-java}" >
|
||||
<mkdir dir="./build" />
|
||||
|
@ -19,8 +19,10 @@ import java.nio.channels.ClosedChannelException;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.Marker;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
/**
|
||||
* Modified from Jetty 6.1.26 StdErrLog.java and Slf4jLog.java
|
||||
@ -281,4 +283,106 @@ public class I2PLogger implements Logger
|
||||
public void debug(String msg, long arg) {
|
||||
debug(msg, Long.valueOf(arg), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* All of the following
|
||||
* @since Jetty 12
|
||||
*/
|
||||
public void debug(Marker marker, String msg) { debug(msg); }
|
||||
public void debug(Marker marker, String format, Object arg) { debug(format, arg); }
|
||||
public void debug(Marker marker, String format, Object... arguments) { debug(format, arguments); }
|
||||
public void debug(Marker marker, String format, Object arg1, Object arg2) { debug(format, arg1, arg2); }
|
||||
public void debug(Marker marker, String msg, Throwable t) { debug(msg, t); }
|
||||
|
||||
public void error(Marker marker, String msg) { error(msg); }
|
||||
public void error(Marker marker, String format, Object arg) { error(format, arg); }
|
||||
public void error(Marker marker, String format, Object... arguments) { error(format, arguments); }
|
||||
public void error(Marker marker, String format, Object arg1, Object arg2) { error(format, arg1, arg2); }
|
||||
public void error(Marker marker, String msg, Throwable t) { error(msg, t); }
|
||||
|
||||
public void info(Marker marker, String msg) { info(msg); }
|
||||
public void info(Marker marker, String format, Object arg) { info(format, arg); }
|
||||
public void info(Marker marker, String format, Object... arguments) { info(format, arguments); }
|
||||
public void info(Marker marker, String format, Object arg1, Object arg2) { info(format, arg1, arg2); }
|
||||
public void info(Marker marker, String msg, Throwable t) { info(msg, t); }
|
||||
|
||||
public void trace(Marker marker, String msg) { trace(msg); }
|
||||
public void trace(Marker marker, String format, Object arg) { trace(format, arg); }
|
||||
public void trace(Marker marker, String format, Object... arguments) { trace(format, arguments); }
|
||||
public void trace(Marker marker, String format, Object arg1, Object arg2) { trace(format, arg1, arg2); }
|
||||
public void trace(Marker marker, String msg, Throwable t) { trace(msg, t); }
|
||||
|
||||
public void warn(Marker marker, String msg) { warn(msg); }
|
||||
public void warn(Marker marker, String format, Object arg) { warn(format, arg); }
|
||||
public void warn(Marker marker, String format, Object... arguments) { warn(format, arguments); }
|
||||
public void warn(Marker marker, String format, Object arg1, Object arg2) { warn(format, arg1, arg2); }
|
||||
public void warn(Marker marker, String msg, Throwable t) { warn(msg, t); }
|
||||
|
||||
public boolean isDebugEnabled(Marker marker) { return isDebugEnabled(); }
|
||||
public boolean isErrorEnabled(Marker marker) { return isErrorEnabled(); }
|
||||
public boolean isInfoEnabled(Marker marker) { return isInfoEnabled(); }
|
||||
public boolean isTraceEnabled(Marker marker) { return isTraceEnabled(); }
|
||||
public boolean isWarnEnabled(Marker marker) { return isWarnEnabled(); }
|
||||
|
||||
public boolean isErrorEnabled() { return _log.shouldError(); }
|
||||
public boolean isInfoEnabled() { return _log.shouldInfo(); }
|
||||
public boolean isTraceEnabled() { return _log.shouldDebug(); }
|
||||
public boolean isWarnEnabled() { return _log.shouldWarn(); }
|
||||
|
||||
public void trace(String msg) { debug(msg); }
|
||||
public void trace(String format, Object arg) { debug(format, arg); }
|
||||
public void trace(String format, Object... arguments) { debug(format, arguments); }
|
||||
public void trace(String format, Object arg1, Object arg2) { debug(format, arg1, arg2); }
|
||||
public void trace(String msg, Throwable t) { debug(msg, t); }
|
||||
|
||||
public void debug(String msg, Object arg) { debug(msg, arg, null); }
|
||||
public void info(String msg, Object arg) { info(msg, arg, null); }
|
||||
public void warn(String msg, Object arg) { warn(msg, arg, null); }
|
||||
|
||||
public void debug(String msg) { debug(msg, null, null); }
|
||||
public void info(String msg) { info(msg, null, null); }
|
||||
public void warn(String msg) { warn(msg, null, null); }
|
||||
|
||||
|
||||
public void error(String msg,Object arg0, Object arg1)
|
||||
{
|
||||
if (arg0 == null && arg1 == null) {
|
||||
_log.error(msg);
|
||||
} else if (arg0 != null && arg1 == null && arg0 instanceof Throwable) {
|
||||
error(msg, (Throwable) arg0);
|
||||
} else {
|
||||
format(msg,arg0,arg1);
|
||||
if (arg1 != null && arg1 instanceof Throwable)
|
||||
_log.error(_buffer.toString(), (Throwable) arg1);
|
||||
else
|
||||
_log.error(_buffer.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void error(String msg)
|
||||
{
|
||||
_log.error(msg);
|
||||
}
|
||||
|
||||
public void error(String msg, Throwable th)
|
||||
{
|
||||
_log.error(msg, th);
|
||||
}
|
||||
|
||||
public void error(Throwable thrown)
|
||||
{
|
||||
error("", thrown);
|
||||
}
|
||||
|
||||
public void error(String msg, Object arg)
|
||||
{
|
||||
error(msg, arg, null);
|
||||
}
|
||||
|
||||
public void error(String msg, Object... args)
|
||||
{
|
||||
Object a1 = args.length > 0 ? args[0] : null;
|
||||
Object a2 = args.length > 1 ? args[1] : null;
|
||||
error(msg, a1, a2);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,60 @@
|
||||
package net.i2p.jetty;
|
||||
|
||||
import org.slf4j.ILoggerFactory;
|
||||
import org.slf4j.IMarkerFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.helpers.BasicMarkerFactory;
|
||||
import org.slf4j.helpers.BasicMDCAdapter;
|
||||
import org.slf4j.spi.SLF4JServiceProvider;
|
||||
import org.slf4j.spi.MDCAdapter;
|
||||
|
||||
/**
|
||||
* An SLF4J Service Provider logging to router log with levels,
|
||||
* replacing Jetty's Service Provider that logs to stderr
|
||||
* (wrapper log).
|
||||
*
|
||||
* @since Jetty 12
|
||||
*/
|
||||
public class I2PLoggingServiceProvider implements SLF4JServiceProvider {
|
||||
private final ILoggerFactory lf;
|
||||
private final IMarkerFactory mf;
|
||||
private final MDCAdapter md;
|
||||
|
||||
public I2PLoggingServiceProvider() {
|
||||
lf = new LoggerFactory();
|
||||
mf = new BasicMarkerFactory();
|
||||
md = new BasicMDCAdapter();
|
||||
}
|
||||
|
||||
public ILoggerFactory getLoggerFactory() {
|
||||
return lf;
|
||||
}
|
||||
|
||||
public IMarkerFactory getMarkerFactory() {
|
||||
return mf;
|
||||
}
|
||||
|
||||
public MDCAdapter getMDCAdapter() {
|
||||
return md;
|
||||
}
|
||||
|
||||
public String getRequestedApiVersion() {
|
||||
return "2.0.999";
|
||||
}
|
||||
|
||||
public void initialize() {}
|
||||
|
||||
private static class LoggerFactory implements ILoggerFactory {
|
||||
private final Logger logger;
|
||||
|
||||
public LoggerFactory() {
|
||||
logger = new I2PLogger();
|
||||
logger.error("I2PLogger initialized");
|
||||
}
|
||||
|
||||
public Logger getLogger(String name) {
|
||||
return logger;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -17,23 +17,19 @@ package net.i2p.jetty;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
//import java.io.Writer; // As of Jetty 9.4.15, RequestLog interface has a Writer subinterface
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.eclipse.jetty.http.PathMap;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.RequestLog;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
import org.eclipse.jetty.util.DateCache;
|
||||
import org.eclipse.jetty.util.RolloverFileOutputStream;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.Utf8StringBuilder;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
||||
/**
|
||||
* This {@link RequestLog} implementation outputs logs in the pseudo-standard NCSA common log format.
|
||||
@ -80,10 +76,7 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
|
||||
private transient OutputStream _out;
|
||||
private transient OutputStream _fileOut;
|
||||
private transient DateCache _logDateCache;
|
||||
private transient PathMap<String> _ignorePathMap;
|
||||
private transient java.io.Writer _writer;
|
||||
private transient ArrayList<Utf8StringBuilder> _buffers;
|
||||
private transient char[] _copy;
|
||||
|
||||
|
||||
public I2PRequestLog()
|
||||
@ -259,68 +252,56 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
|
||||
|
||||
try
|
||||
{
|
||||
if (_ignorePathMap != null && _ignorePathMap.getMatch(request.getRequestURI()) != null)
|
||||
return;
|
||||
|
||||
if (_fileOut == null)
|
||||
return;
|
||||
|
||||
Utf8StringBuilder u8buf;
|
||||
StringBuilder buf;
|
||||
synchronized(_writer)
|
||||
{
|
||||
int size=_buffers.size();
|
||||
u8buf = size==0?new Utf8StringBuilder(160):_buffers.remove(size-1);
|
||||
buf = u8buf.getStringBuilder();
|
||||
}
|
||||
StringBuilder buf = new StringBuilder(160);
|
||||
|
||||
synchronized(buf) // for efficiency until we can use StringBuilder
|
||||
{
|
||||
if (_logServer)
|
||||
{
|
||||
buf.append(request.getServerName());
|
||||
buf.append(Request.getServerName(request));
|
||||
buf.append(' ');
|
||||
}
|
||||
|
||||
String addr = null;
|
||||
if (_preferProxiedForAddress)
|
||||
{
|
||||
addr = request.getHeader("X-Forwarded-For");
|
||||
addr = request.getHeaders().get("X-Forwarded-For");
|
||||
}
|
||||
|
||||
if (addr == null) {
|
||||
if (_b64) {
|
||||
addr = request.getHeader("X-I2P-DestHash");
|
||||
addr = request.getHeaders().get("X-I2P-DestHash");
|
||||
if (addr != null)
|
||||
addr += ".i2p";
|
||||
} else {
|
||||
// 52chars.b32.i2p
|
||||
addr = request.getHeader("X-I2P-DestB32");
|
||||
addr = request.getHeaders().get("X-I2P-DestB32");
|
||||
}
|
||||
if (addr == null)
|
||||
addr = request.getRemoteAddr();
|
||||
addr = Request.getRemoteAddr(request);
|
||||
}
|
||||
|
||||
buf.append(addr);
|
||||
buf.append(" - ");
|
||||
String user = request.getRemoteUser();
|
||||
String user = request.getHttpURI().getUser();
|
||||
buf.append((user == null)? " - " : user);
|
||||
buf.append(" [");
|
||||
if (_logDateCache!=null)
|
||||
buf.append(_logDateCache.format(request.getTimeStamp()));
|
||||
buf.append(_logDateCache.format(Request.getTimeStamp(request)));
|
||||
else
|
||||
//buf.append(request.getTimeStampBuffer().toString());
|
||||
// TODO SimpleDateFormat or something
|
||||
buf.append(request.getTimeStamp());
|
||||
buf.append(Request.getTimeStamp(request));
|
||||
|
||||
buf.append("] \"");
|
||||
buf.append(request.getMethod());
|
||||
buf.append(' ');
|
||||
|
||||
u8buf.append(request.getRequestURI());
|
||||
buf.append(request.getHttpURI().getPathQuery());
|
||||
|
||||
buf.append(' ');
|
||||
buf.append(request.getProtocol());
|
||||
buf.append(request.getConnectionMetaData().getProtocol());
|
||||
buf.append("\" ");
|
||||
int status = response.getStatus();
|
||||
if (status<=0)
|
||||
@ -330,18 +311,7 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
|
||||
buf.append((char)('0'+(status%10)));
|
||||
|
||||
|
||||
long responseLength=response.getContentCount();
|
||||
// The above is what Jetty used before 9, but now
|
||||
// it often (for large content?) returns 0 for non-cgi responses.
|
||||
// Now, Jetty uses getLongContentLength(), but according to
|
||||
// these threads it returns 0 for streaming (cgi) responses.
|
||||
// So we take whichever one is nonzero, if the result was 200.
|
||||
// See:
|
||||
// https://dev.eclipse.org/mhonarc/lists/jetty-dev/msg02261.html
|
||||
// and followups including this workaround:
|
||||
// https://dev.eclipse.org/mhonarc/lists/jetty-dev/msg02267.html
|
||||
if (responseLength == 0 && status == 200 && !"HEAD".equals(request.getMethod()))
|
||||
responseLength = response.getLongContentLength();
|
||||
long responseLength = Response.getContentBytesWritten(response);
|
||||
if (responseLength >=0)
|
||||
{
|
||||
buf.append(' ');
|
||||
@ -364,64 +334,30 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
|
||||
else
|
||||
buf.append(" - ");
|
||||
|
||||
}
|
||||
|
||||
if (!_extended && !_logCookies && !_logLatency)
|
||||
{
|
||||
synchronized(_writer)
|
||||
{
|
||||
buf.append(System.getProperty("line.separator", "\n"));
|
||||
int l=buf.length();
|
||||
if (l>_copy.length)
|
||||
l=_copy.length;
|
||||
buf.getChars(0,l,_copy,0);
|
||||
_writer.write(_copy,0,l);
|
||||
_writer.write(buf.toString());
|
||||
_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);
|
||||
_writer.write(buf.toString());
|
||||
|
||||
// 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(Long.toString(System.currentTimeMillis() - request.getTimeStamp()));
|
||||
_writer.write(Long.toString(System.currentTimeMillis() - Request.getTimeStamp(request)));
|
||||
}
|
||||
|
||||
_writer.write(System.getProperty("line.separator", "\n"));
|
||||
@ -431,7 +367,8 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
Log.getLogger((String)null).warn(e);
|
||||
System.out.println(e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
@ -441,7 +378,7 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
|
||||
Response response,
|
||||
java.io.Writer writer) throws IOException
|
||||
{
|
||||
String referer = request.getHeader("Referer");
|
||||
String referer = request.getHeaders().get("Referer");
|
||||
if (referer == null)
|
||||
writer.write("\"-\" ");
|
||||
else
|
||||
@ -451,7 +388,7 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
|
||||
writer.write("\" ");
|
||||
}
|
||||
|
||||
String agent = request.getHeader("User-Agent");
|
||||
String agent = request.getHeaders().get("User-Agent");
|
||||
if (agent == null)
|
||||
writer.write("\"-\" ");
|
||||
else
|
||||
@ -474,25 +411,13 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
|
||||
{
|
||||
_fileOut = new RolloverFileOutputStream(_filename,_append,_retainDays,TimeZone.getTimeZone(_logTimeZone),_filenameDateFormat,null);
|
||||
_closeOut = true;
|
||||
Log.getLogger((String)null).info("Opened "+getDatedFilename());
|
||||
}
|
||||
else
|
||||
_fileOut = System.err;
|
||||
|
||||
_out = _fileOut;
|
||||
|
||||
if (_ignorePaths != null && _ignorePaths.length > 0)
|
||||
{
|
||||
_ignorePathMap = new PathMap<String>();
|
||||
for (int i = 0; i < _ignorePaths.length; i++)
|
||||
_ignorePathMap.put(_ignorePaths[i], _ignorePaths[i]);
|
||||
}
|
||||
else
|
||||
_ignorePathMap = null;
|
||||
|
||||
_writer = new OutputStreamWriter(_out, "UTF-8");
|
||||
_buffers = new ArrayList<Utf8StringBuilder>();
|
||||
_copy = new char[1024];
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
@ -500,17 +425,15 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
super.doStop();
|
||||
try {if (_writer != null) _writer.flush();} catch (IOException e) {Log.getLogger((String)null).ignore(e);}
|
||||
try {if (_writer != null) _writer.flush();} catch (IOException e) {}
|
||||
if (_out != null && _closeOut)
|
||||
try {_out.close();} catch (IOException e) {Log.getLogger((String)null).ignore(e);}
|
||||
try {_out.close();} catch (IOException e) {}
|
||||
|
||||
_out = null;
|
||||
_fileOut = null;
|
||||
_closeOut = false;
|
||||
_logDateCache = null;
|
||||
_writer = null;
|
||||
_buffers = null;
|
||||
_copy = null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -40,8 +40,10 @@ import net.i2p.util.VersionComparator;
|
||||
import org.eclipse.jetty.server.AbstractNetworkConnector;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.ConnectionFactory;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
|
||||
/**
|
||||
@ -141,7 +143,7 @@ public class JettyStart implements ClientApp {
|
||||
}
|
||||
} else {
|
||||
URL configUrl = f.toURI().toURL();
|
||||
XmlConfiguration configuration = new XmlConfiguration(configUrl);
|
||||
XmlConfiguration configuration = new XmlConfiguration(ResourceFactory.root().newResource(configUrl));
|
||||
if (last!=null)
|
||||
configuration.getIdMap().putAll(last.getIdMap());
|
||||
if (properties.size()>0) {
|
||||
@ -181,7 +183,8 @@ public class JettyStart implements ClientApp {
|
||||
if (!lc.isRunning()) {
|
||||
if (lc instanceof Server) {
|
||||
Server server = (Server) lc;
|
||||
server.insertHandler(new XI2PLocationFilter());
|
||||
// FIXME
|
||||
//server.insertHandler(new XI2PLocationFilter());
|
||||
}
|
||||
try {
|
||||
lc.start();
|
||||
|
@ -43,25 +43,6 @@ public class JettyXmlConfigurationParser
|
||||
private static XmlParser initParser()
|
||||
{
|
||||
XmlParser parser = new XmlParser();
|
||||
URL config60 = Loader.getResource(XmlConfiguration.class, "org/eclipse/jetty/xml/configure_6_0.dtd");
|
||||
URL config76 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_7_6.dtd");
|
||||
URL config90 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_9_0.dtd");
|
||||
parser.redirectEntity("configure.dtd",config90);
|
||||
parser.redirectEntity("configure_1_0.dtd",config60);
|
||||
parser.redirectEntity("configure_1_1.dtd",config60);
|
||||
parser.redirectEntity("configure_1_2.dtd",config60);
|
||||
parser.redirectEntity("configure_1_3.dtd",config60);
|
||||
parser.redirectEntity("configure_6_0.dtd",config60);
|
||||
parser.redirectEntity("configure_7_6.dtd",config76);
|
||||
parser.redirectEntity("configure_9_0.dtd",config90);
|
||||
|
||||
parser.redirectEntity("http://jetty.mortbay.org/configure.dtd",config90);
|
||||
parser.redirectEntity("http://jetty.eclipse.org/configure.dtd",config90);
|
||||
parser.redirectEntity("http://www.eclipse.org/jetty/configure.dtd",config90);
|
||||
|
||||
parser.redirectEntity("-//Mort Bay Consulting//DTD Configure//EN",config90);
|
||||
parser.redirectEntity("-//Jetty//Configure//EN",config90);
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
@ -35,12 +36,13 @@ import javax.servlet.UnavailableException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.servlet.DefaultServlet;
|
||||
import org.eclipse.jetty.ee8.nested.ContextHandler;
|
||||
import org.eclipse.jetty.ee8.servlet.DefaultServlet;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.resource.CombinedResource;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
|
||||
@ -76,7 +78,7 @@ public class I2PDefaultServlet extends DefaultServlet
|
||||
String rb=getInitParameter("resourceBase");
|
||||
if (rb!=null)
|
||||
{
|
||||
try{_resourceBase=_contextHandler.newResource(rb);}
|
||||
try{_resourceBase = ResourceFactory.root().newResource(rb);}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new UnavailableException(e.toString());
|
||||
@ -88,7 +90,7 @@ public class I2PDefaultServlet extends DefaultServlet
|
||||
{
|
||||
if(css!=null)
|
||||
{
|
||||
_stylesheet = Resource.newResource(css);
|
||||
_stylesheet = ResourceFactory.root().newResource(css);
|
||||
if(!_stylesheet.exists())
|
||||
{
|
||||
_stylesheet = null;
|
||||
@ -96,7 +98,7 @@ public class I2PDefaultServlet extends DefaultServlet
|
||||
}
|
||||
if(_stylesheet == null)
|
||||
{
|
||||
_stylesheet = Resource.newResource(this.getClass().getResource("/jetty-dir.css"));
|
||||
_stylesheet = ResourceFactory.root().newResource(this.getClass().getResource("/jetty-dir.css"));
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
@ -135,7 +137,6 @@ public class I2PDefaultServlet extends DefaultServlet
|
||||
*
|
||||
* Get the resource list as a HTML directory listing.
|
||||
*/
|
||||
@Override
|
||||
protected void sendDirectory(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
Resource resource,
|
||||
@ -149,18 +150,18 @@ public class I2PDefaultServlet extends DefaultServlet
|
||||
}
|
||||
|
||||
byte[] data=null;
|
||||
String base = URIUtil.addPaths(request.getRequestURI(),URIUtil.SLASH);
|
||||
String base = URIUtil.addPaths(request.getRequestURI(), "/");
|
||||
|
||||
//If the DefaultServlet has a resource base set, use it
|
||||
if (_resourceBase != null)
|
||||
{
|
||||
// handle ResourceCollection
|
||||
if (_resourceBase instanceof ResourceCollection)
|
||||
resource=_resourceBase.addPath(pathInContext);
|
||||
if (_resourceBase instanceof CombinedResource)
|
||||
resource=_resourceBase.resolve(pathInContext);
|
||||
}
|
||||
//Otherwise, try using the resource base of its enclosing context handler
|
||||
else if (_contextHandler.getBaseResource() instanceof ResourceCollection)
|
||||
resource=_contextHandler.getBaseResource().addPath(pathInContext);
|
||||
else if (_contextHandler.getBaseResource() instanceof CombinedResource)
|
||||
resource=_contextHandler.getBaseResource().resolve(pathInContext);
|
||||
|
||||
String dir = getListHTML(resource, base, pathInContext.length()>1);
|
||||
if (dir==null)
|
||||
@ -192,7 +193,7 @@ public class I2PDefaultServlet extends DefaultServlet
|
||||
if (base==null || !res.isDirectory())
|
||||
return null;
|
||||
|
||||
String[] ls = res.list();
|
||||
List<Resource> ls = res.list();
|
||||
if (ls==null)
|
||||
return null;
|
||||
DataHelper.sort(ls, new FileComparator(res));
|
||||
@ -220,11 +221,11 @@ public class I2PDefaultServlet extends DefaultServlet
|
||||
DateFormat dfmt = new SimpleDateFormat(FORMAT, Locale.UK);
|
||||
TimeZone utc = TimeZone.getTimeZone("GMT");
|
||||
dfmt.setTimeZone(utc);
|
||||
for (int i=0 ; i< ls.length ; i++)
|
||||
for (Resource item : ls)
|
||||
{
|
||||
Resource item;
|
||||
/* FIXME still needed?
|
||||
try {
|
||||
item = res.addPath(ls[i]);
|
||||
item = res.resolve(r);
|
||||
} catch (IOException ioe) {
|
||||
System.out.println("Skipping file in directory listing: " + ioe.getMessage());
|
||||
continue;
|
||||
@ -243,18 +244,19 @@ public class I2PDefaultServlet extends DefaultServlet
|
||||
System.out.println("Skipping file in directory listing: " + re.getMessage());
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
buf.append("\n<TR><TD><A HREF=\"");
|
||||
String path=URIUtil.addPaths(encodedBase,URIUtil.encodePath(ls[i]));
|
||||
String path=URIUtil.addPaths(encodedBase,URIUtil.encodePath(item.toString()));
|
||||
|
||||
buf.append(path);
|
||||
|
||||
boolean isDir = item.isDirectory();
|
||||
if (isDir && !path.endsWith("/"))
|
||||
buf.append(URIUtil.SLASH);
|
||||
buf.append('/');
|
||||
|
||||
buf.append("\">");
|
||||
buf.append(deTag(ls[i]));
|
||||
buf.append(deTag(item.toString()));
|
||||
buf.append("</A></TD><TD ALIGN=right>");
|
||||
if (!isDir) {
|
||||
buf.append(item.length());
|
||||
@ -262,7 +264,7 @@ public class I2PDefaultServlet extends DefaultServlet
|
||||
}
|
||||
buf.append("</TD><TD>");
|
||||
if (!isDir) {
|
||||
buf.append(dfmt.format(new Date(item.lastModified())));
|
||||
buf.append(dfmt.format(new Date(item.lastModified().toEpochMilli())));
|
||||
buf.append(" UTC");
|
||||
}
|
||||
buf.append("</TD></TR>");
|
||||
@ -278,7 +280,7 @@ public class I2PDefaultServlet extends DefaultServlet
|
||||
*
|
||||
* @since 0.9.51
|
||||
*/
|
||||
private static class FileComparator implements Comparator<String> {
|
||||
private static class FileComparator implements Comparator<Resource> {
|
||||
private final Comparator<Object> _coll;
|
||||
private final Resource _base;
|
||||
|
||||
@ -287,10 +289,8 @@ public class I2PDefaultServlet extends DefaultServlet
|
||||
_coll = Collator.getInstance(Locale.US);
|
||||
}
|
||||
|
||||
public int compare(String a, String b) {
|
||||
public int compare(Resource ra, Resource rb) {
|
||||
try {
|
||||
Resource ra = _base.addPath(a);
|
||||
Resource rb = _base.addPath(b);
|
||||
boolean da = ra.isDirectory();
|
||||
boolean db = rb.isDirectory();
|
||||
if (da && !db) return -1;
|
||||
@ -298,7 +298,7 @@ public class I2PDefaultServlet extends DefaultServlet
|
||||
} catch (Exception e) {
|
||||
// see above
|
||||
}
|
||||
return _coll.compare(a, b);
|
||||
return _coll.compare(ra.toString(), rb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
package net.i2p.servlet;
|
||||
|
||||
import org.apache.tomcat.SimpleInstanceManager;
|
||||
import org.eclipse.jetty.deploy.providers.WebAppProvider;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.deploy.providers.ContextProvider;
|
||||
import org.eclipse.jetty.ee8.webapp.Configuration;
|
||||
import org.eclipse.jetty.ee8.webapp.WebAppContext;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
|
||||
@ -22,8 +22,10 @@ public class WebAppProviderConfiguration {
|
||||
* Modified from routerconsole WebAppStarter.
|
||||
* MUST be called from jetty.xml after the WebAppProvider is created.
|
||||
*/
|
||||
public static void configure(WebAppProvider wap) {
|
||||
String[] classNames = WebAppContext.getDefaultConfigurationClasses();
|
||||
public static void configure(ContextProvider wap) {
|
||||
// Not in Jetty 12 but these are the two defaults
|
||||
//String[] classNames = WebAppContext.getDefaultConfigurationClasses();
|
||||
String[] classNames = { "org.eclipse.jetty.ee8.webapp.WebXMLConfiguration", "org.eclipse.jetty.ee8.webapp.JettyWebXMLConfiguration" };
|
||||
int sz = classNames.length;
|
||||
String[] newClassNames = new String[sz + 1];
|
||||
for (int j = 0; j < sz; j++) {
|
||||
@ -34,7 +36,8 @@ public class WebAppProviderConfiguration {
|
||||
|
||||
// set the temp dir while we're at it,
|
||||
// so the extracted wars don't end up in /tmp
|
||||
wap.setTempDir(I2PAppContext.getGlobalContext().getTempDir());
|
||||
// FIXME
|
||||
//wap.setTempDir(I2PAppContext.getGlobalContext().getTempDir());
|
||||
}
|
||||
|
||||
public static class WAPConfiguration implements Configuration {
|
||||
@ -54,5 +57,15 @@ public class WebAppProviderConfiguration {
|
||||
public void preConfigure(WebAppContext context) {}
|
||||
|
||||
public void postConfigure(WebAppContext context) {}
|
||||
|
||||
/**
|
||||
* @since Jetty 12
|
||||
*/
|
||||
public boolean abort(WebAppContext context) { return false; }
|
||||
|
||||
/**
|
||||
* @since Jetty 12
|
||||
*/
|
||||
public boolean isEnabledByDefault() { return true; }
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,8 @@ import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.ee8.nested.Request;
|
||||
import org.eclipse.jetty.ee8.nested.HandlerWrapper;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
|
@ -1,153 +0,0 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util;
|
||||
|
||||
/**
|
||||
* Java Version Utility class.
|
||||
* <p>Parses java versions to extract a consistent set of version parts</p>
|
||||
*/
|
||||
public class JavaVersion
|
||||
{
|
||||
/**
|
||||
* Context attribute that can be set to target a different version of the jvm than the current runtime.
|
||||
* Acceptable values should correspond to those returned by JavaVersion.getPlatform().
|
||||
*/
|
||||
public static final String JAVA_TARGET_PLATFORM = "org.eclipse.jetty.javaTargetPlatform";
|
||||
|
||||
public static final JavaVersion VERSION = parse(System.getProperty("java.version"));
|
||||
|
||||
public static JavaVersion parse(String v)
|
||||
{
|
||||
// $VNUM is a dot-separated list of integers of arbitrary length
|
||||
String[] split = v.split("[^0-9]");
|
||||
int len = Math.min(split.length, 3);
|
||||
int[] version = new int[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
version[i] = Integer.parseInt(split[i]);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
len = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new JavaVersion(
|
||||
v,
|
||||
(version[0] >= 9 || len == 1) ? version[0] : version[1],
|
||||
version[0],
|
||||
len > 1 ? version[1] : 0,
|
||||
len > 2 ? version[2] : 0);
|
||||
}
|
||||
|
||||
private final String version;
|
||||
private final int platform;
|
||||
private final int major;
|
||||
private final int minor;
|
||||
private final int micro;
|
||||
|
||||
private JavaVersion(String version, int platform, int major, int minor, int micro)
|
||||
{
|
||||
this.version = version;
|
||||
this.platform = platform;
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.micro = micro;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the string from which this JavaVersion was created
|
||||
*/
|
||||
public String getVersion()
|
||||
{
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the Java Platform version, such as {@code 8} for JDK 1.8.0_92 and {@code 9} for JDK 9.2.4.</p>
|
||||
*
|
||||
* @return the Java Platform version
|
||||
*/
|
||||
public int getPlatform()
|
||||
{
|
||||
return platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the major number version, such as {@code 1} for JDK 1.8.0_92 and {@code 9} for JDK 9.2.4.</p>
|
||||
*
|
||||
* @return the major number version
|
||||
*/
|
||||
public int getMajor()
|
||||
{
|
||||
return major;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the minor number version, such as {@code 8} for JDK 1.8.0_92 and {@code 2} for JDK 9.2.4.</p>
|
||||
*
|
||||
* @return the minor number version
|
||||
*/
|
||||
public int getMinor()
|
||||
{
|
||||
return minor;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the micro number version (aka security number), such as {@code 0} for JDK 1.8.0_92 and {@code 4} for JDK 9.2.4.</p>
|
||||
*
|
||||
* @return the micro number version
|
||||
*/
|
||||
public int getMicro()
|
||||
{
|
||||
return micro;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the update number version, such as {@code 92} for JDK 1.8.0_92 and {@code 0} for JDK 9.2.4.</p>
|
||||
*
|
||||
* @return the update number version
|
||||
*/
|
||||
@Deprecated
|
||||
public int getUpdate()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the remaining string after the version numbers, such as {@code -internal} for
|
||||
* JDK 1.8.0_92-internal and {@code -ea} for JDK 9-ea, or {@code +13} for JDK 9.2.4+13.</p>
|
||||
*
|
||||
* @return the remaining string after the version numbers
|
||||
*/
|
||||
@Deprecated
|
||||
public String getSuffix()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return version;
|
||||
}
|
||||
}
|
@ -4,10 +4,6 @@ import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.Addresses;
|
||||
@ -15,7 +11,9 @@ import net.i2p.util.Log;
|
||||
import net.i2p.util.PortMapper;
|
||||
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
||||
/**
|
||||
* Block certain Host headers to prevent DNS rebinding attacks.
|
||||
@ -75,14 +73,13 @@ public class HostCheckHandler extends GzipHandler
|
||||
* redirect HTTP to HTTPS,
|
||||
* pass everything else to the delegate.
|
||||
*/
|
||||
public void handle(String pathInContext,
|
||||
Request baseRequest,
|
||||
HttpServletRequest httpRequest,
|
||||
HttpServletResponse httpResponse)
|
||||
throws IOException, ServletException
|
||||
@Override
|
||||
public boolean handle(Request request,
|
||||
Response response,
|
||||
Callback callback)
|
||||
throws Exception
|
||||
{
|
||||
|
||||
String host = httpRequest.getHeader("Host");
|
||||
String host = request.getHeaders().get("Host");
|
||||
if (!allowHost(host)) {
|
||||
Log log = _context.logManager().getLog(HostCheckHandler.class);
|
||||
host = DataHelper.stripHTML(getHost(host));
|
||||
@ -91,29 +88,28 @@ public class HostCheckHandler extends GzipHandler
|
||||
" add the line \"" + RouterConsoleRunner.PROP_ALLOWED_HOSTS + '=' + host + "\"\n" +
|
||||
" to advanced configuration and restart.";
|
||||
log.logAlways(Log.WARN, s);
|
||||
httpResponse.sendError(403, s);
|
||||
baseRequest.setHandled(true);
|
||||
return;
|
||||
Response.writeError(request, response, callback, 403, s);
|
||||
return true;
|
||||
}
|
||||
|
||||
// redirect HTTP to HTTPS if available, AND:
|
||||
// either 1) PROP_REDIRECT is set to true;
|
||||
// or 2) PROP_REDIRECT is unset and the Upgrade-Insecure-Requests request header is set
|
||||
// https://w3c.github.io/webappsec-upgrade-insecure-requests/
|
||||
if (!httpRequest.isSecure()) {
|
||||
if (!request.isSecure()) {
|
||||
int httpsPort = _portMapper.getPort(PortMapper.SVC_HTTPS_CONSOLE);
|
||||
if (httpsPort > 0 && httpRequest.getLocalPort() != httpsPort) {
|
||||
if (httpsPort > 0 && Request.getLocalPort(request) != httpsPort) {
|
||||
String redir = _context.getProperty(PROP_REDIRECT);
|
||||
if (Boolean.parseBoolean(redir) ||
|
||||
(redir == null && "1".equals(httpRequest.getHeader("Upgrade-Insecure-Requests")))) {
|
||||
sendRedirect(httpsPort, httpRequest, httpResponse);
|
||||
baseRequest.setHandled(true);
|
||||
return;
|
||||
(redir == null && "1".equals(request.getHeaders().get("Upgrade-Insecure-Requests")))) {
|
||||
sendRedirect(httpsPort, request, response);
|
||||
callback.succeeded();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.handle(pathInContext, baseRequest, httpRequest, httpResponse);
|
||||
return super.handle(request, response, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -172,11 +168,11 @@ public class HostCheckHandler extends GzipHandler
|
||||
*
|
||||
* @since 0.9.34
|
||||
*/
|
||||
private static void sendRedirect(int httpsPort, HttpServletRequest httpRequest,
|
||||
HttpServletResponse httpResponse) throws IOException {
|
||||
private static void sendRedirect(int httpsPort, Request request,
|
||||
Response response) throws IOException {
|
||||
StringBuilder buf = new StringBuilder(64);
|
||||
buf.append("https://");
|
||||
String name = httpRequest.getServerName();
|
||||
String name = Request.getServerName(request);
|
||||
boolean ipv6 = name.indexOf(':') >= 0 && !name.startsWith("[");
|
||||
if (ipv6)
|
||||
buf.append('[');
|
||||
@ -184,14 +180,13 @@ public class HostCheckHandler extends GzipHandler
|
||||
if (ipv6)
|
||||
buf.append(']');
|
||||
buf.append(':').append(httpsPort)
|
||||
.append(httpRequest.getRequestURI());
|
||||
String q = httpRequest.getQueryString();
|
||||
.append(request.getHttpURI().getPath());
|
||||
String q = request.getHttpURI().getQuery();
|
||||
if (q != null)
|
||||
buf.append('?').append(q);
|
||||
httpResponse.setHeader("Location", buf.toString());
|
||||
response.getHeaders().put("Location", buf.toString());
|
||||
// https://w3c.github.io/webappsec-upgrade-insecure-requests/
|
||||
httpResponse.setHeader("Vary", "Upgrade-Insecure-Requests");
|
||||
httpResponse.setStatus(307);
|
||||
httpResponse.getOutputStream().close();
|
||||
response.getHeaders().put("Vary", "Upgrade-Insecure-Requests");
|
||||
response.setStatus(307);
|
||||
}
|
||||
}
|
||||
|
@ -11,11 +11,14 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
|
||||
import org.eclipse.jetty.ee8.nested.SessionHandler;
|
||||
import org.eclipse.jetty.ee8.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.ee8.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.http.pathmap.MatchedResource;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
||||
/**
|
||||
* Convert foo.jsp to foo_xx.jsp for language xx.
|
||||
@ -26,7 +29,7 @@ import org.eclipse.jetty.webapp.WebAppContext;
|
||||
*
|
||||
* @author zzz
|
||||
*/
|
||||
public class LocaleWebAppHandler extends HandlerWrapper
|
||||
public class LocaleWebAppHandler extends Handler.Wrapper
|
||||
{
|
||||
private final I2PAppContext _context;
|
||||
private final WebAppContext _wac;
|
||||
@ -50,17 +53,17 @@ public class LocaleWebAppHandler extends HandlerWrapper
|
||||
* or as specified in the routerconsole.lang property.
|
||||
* Unless language == "en".
|
||||
*/
|
||||
public void handle(String pathInContext,
|
||||
Request baseRequest,
|
||||
HttpServletRequest httpRequest,
|
||||
HttpServletResponse httpResponse)
|
||||
throws IOException, ServletException
|
||||
public boolean handle(Request request,
|
||||
Response response,
|
||||
Callback callback)
|
||||
throws Exception
|
||||
{
|
||||
|
||||
String pathInContext = Request.getPathInContext(request);
|
||||
String newPath = pathInContext;
|
||||
// transparent rewriting
|
||||
if (pathInContext.equals("/") || pathInContext.equals("/index.html")) {
|
||||
// home page
|
||||
pathInContext = "/index.jsp";
|
||||
newPath = "/index.jsp";
|
||||
} else if (pathInContext.equals("/favicon.ico")) {
|
||||
// pass thru unchanged
|
||||
} else if (pathInContext.indexOf('/', 1) < 0 &&
|
||||
@ -68,11 +71,10 @@ public class LocaleWebAppHandler extends HandlerWrapper
|
||||
(!pathInContext.endsWith(".log")) &&
|
||||
(!pathInContext.endsWith(".txt"))) {
|
||||
// add .jsp to pages at top level
|
||||
pathInContext += ".jsp";
|
||||
newPath += ".jsp";
|
||||
}
|
||||
|
||||
//System.err.println("Path: " + pathInContext);
|
||||
String newPath = pathInContext;
|
||||
//if (pathInContext.endsWith(".jsp")) {
|
||||
// We only ended up doing this for help.jsp, so save some effort
|
||||
// unless we translate more pages like this
|
||||
@ -87,9 +89,9 @@ public class LocaleWebAppHandler extends HandlerWrapper
|
||||
String testPath = pathInContext.substring(0, len - 4) + '_' + lang + ".jsp";
|
||||
// Do we have a servlet for the new path that isn't the catchall *.jsp?
|
||||
@SuppressWarnings("rawtypes")
|
||||
Map.Entry servlet = _wac.getServletHandler().getHolderEntry(testPath);
|
||||
MatchedResource<ServletHandler.MappedServlet> servlet = _wac.getServletHandler().getMatchedServlet(testPath);
|
||||
if (servlet != null) {
|
||||
String servletPath = (String) servlet.getKey();
|
||||
String servletPath = servlet.getPathSpec().getDeclaration();
|
||||
if (servletPath != null && !servletPath.startsWith("*")) {
|
||||
// success!!
|
||||
//System.err.println("Servlet is: " + servletPath);
|
||||
@ -99,14 +101,20 @@ public class LocaleWebAppHandler extends HandlerWrapper
|
||||
}
|
||||
}
|
||||
} else if (pathInContext.startsWith("/js/")) {
|
||||
// https://stackoverflow.com/questions/78878330/how-to-set-encoding-for-httpservletrequest-and-httpservletresponse-in-jetty12-t
|
||||
// war internal
|
||||
httpResponse.setCharacterEncoding("ISO-8859-1");
|
||||
//response.setCharacterEncoding("ISO-8859-1");
|
||||
// probably not doing anything
|
||||
response.getHeaders().put("Content-Type", "text/javascript;charset=iso-8859-1");
|
||||
} else if (pathInContext.endsWith(".css")) {
|
||||
// war internal
|
||||
httpResponse.setCharacterEncoding("UTF-8");
|
||||
//response.setCharacterEncoding("UTF-8");
|
||||
response.getHeaders().put("Content-Type", "text/css;charset=utf-8");
|
||||
}
|
||||
//System.err.println("New path: " + newPath);
|
||||
super.handle(newPath, baseRequest, httpRequest, httpResponse);
|
||||
if (!newPath.equals(pathInContext))
|
||||
request = Request.serveAs(request, Request.newHttpURIFrom(request, newPath));
|
||||
return super.handle(request, response, callback);
|
||||
//System.err.println("Was handled? " + httpRequest.isHandled());
|
||||
}
|
||||
|
||||
@ -152,4 +160,11 @@ public class LocaleWebAppHandler extends HandlerWrapper
|
||||
context.setInitParameter((String)e.getKey(), (String)e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since Jetty 12
|
||||
*/
|
||||
public WebAppContext getWebAppContext() {
|
||||
return _wac;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import javax.servlet.ServletRequest;
|
||||
import java.util.function.Function;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.app.ClientApp;
|
||||
@ -46,34 +46,38 @@ import net.i2p.util.SecureDirectory;
|
||||
import net.i2p.util.I2PSSLSocketFactory;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
import org.eclipse.jetty.ee8.nested.ServletConstraint;
|
||||
import org.eclipse.jetty.ee8.security.ConstraintMapping;
|
||||
import org.eclipse.jetty.ee8.security.ConstraintSecurityHandler;
|
||||
import org.eclipse.jetty.ee8.security.SecurityHandler;
|
||||
import org.eclipse.jetty.ee8.security.authentication.BasicAuthenticator;
|
||||
import org.eclipse.jetty.ee8.security.authentication.DigestAuthenticator;
|
||||
import org.eclipse.jetty.ee8.security.authentication.LoginAuthenticator;
|
||||
import org.eclipse.jetty.ee8.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.ee8.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.ee8.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.security.Constraint;
|
||||
import org.eclipse.jetty.security.HashLoginService;
|
||||
import org.eclipse.jetty.security.ConstraintMapping;
|
||||
import org.eclipse.jetty.security.ConstraintSecurityHandler;
|
||||
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
|
||||
import org.eclipse.jetty.security.authentication.DigestAuthenticator;
|
||||
import org.eclipse.jetty.security.authentication.LoginAuthenticator;
|
||||
import org.eclipse.jetty.security.UserIdentity;
|
||||
import org.eclipse.jetty.security.UserStore;
|
||||
import org.eclipse.jetty.server.AbstractConnector;
|
||||
import org.eclipse.jetty.server.ConnectionFactory;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.CustomRequestLog;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||
import org.eclipse.jetty.server.NCSARequestLog;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.SecureRequestCustomizer;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.UserIdentity;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.Session;
|
||||
import org.eclipse.jetty.server.SslConnectionFactory;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.server.handler.RequestLogHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.security.Constraint;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.URLResourceFactory;
|
||||
import org.eclipse.jetty.util.security.Credential;
|
||||
import org.eclipse.jetty.util.security.Credential.MD5;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
@ -91,15 +95,8 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
|
||||
static {
|
||||
// To take effect, must be set before any Jetty classes are loaded
|
||||
try {
|
||||
Log.setLog(new I2PLogger());
|
||||
} 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
|
||||
// This causes an NPE in AbstractLifeCycle
|
||||
// http://dev.eclipse.org/mhonarc/lists/jetty-users/msg02587.html
|
||||
//System.setProperty("org.eclipse.jetty.util.log.class", "net.i2p.jetty.I2PLogger");
|
||||
// https://slf4j.org/faq.html
|
||||
System.setProperty("slf4j.provider", "net.i2p.jetty.I2PLoggingServiceProvider");
|
||||
}
|
||||
|
||||
private final RouterContext _context;
|
||||
@ -501,12 +498,10 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
_server = new Server(qtp);
|
||||
//}
|
||||
|
||||
HandlerCollection hColl = new HandlerCollection();
|
||||
Handler.Sequence hColl = new Handler.Sequence();
|
||||
ContextHandlerCollection chColl = new ContextHandlerCollection();
|
||||
HostCheckHandler chCollWrapper = new HostCheckHandler(_context);
|
||||
chCollWrapper.setHandler(chColl);
|
||||
// gone in Jetty 7
|
||||
//_server.addHandler(hColl);
|
||||
_server.setHandler(hColl);
|
||||
hColl.addHandler(chCollWrapper);
|
||||
hColl.addHandler(new DefaultHandler());
|
||||
@ -517,9 +512,7 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
if (!logFile.isAbsolute())
|
||||
logFile = new File(_context.getLogDir(), "logs/" + log);
|
||||
try {
|
||||
RequestLogHandler rhl = new RequestLogHandler();
|
||||
rhl.setRequestLog(new NCSARequestLog(logFile.getAbsolutePath()));
|
||||
hColl.addHandler(rhl);
|
||||
_server.setRequestLog(new CustomRequestLog(logFile.toString(), CustomRequestLog.NCSA_FORMAT));
|
||||
} catch (Exception ioe) {
|
||||
System.err.println("ERROR: Unable to create Jetty log: " + ioe);
|
||||
}
|
||||
@ -544,7 +537,7 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
_webAppsDir += '/';
|
||||
|
||||
Set<String> listenHosts = new HashSet<String>(8);
|
||||
HandlerWrapper rootWebApp = null;
|
||||
LocaleWebAppHandler rootWebApp = null;
|
||||
ServletHandler rootServletHandler = null;
|
||||
List<Connector> connectors = new ArrayList<Connector>(4);
|
||||
try {
|
||||
@ -644,7 +637,8 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
}
|
||||
if (verifyKeyStore(keyStore, altNames)) {
|
||||
// the keystore path and password
|
||||
SslContextFactory sslFactory = new SslContextFactory(keyStore.getAbsolutePath());
|
||||
SslContextFactory.Server sslFactory = new SslContextFactory.Server();
|
||||
sslFactory.setKeyStorePath(keyStore.getAbsolutePath());
|
||||
sslFactory.setKeyStorePassword(_context.getProperty(PROP_KEYSTORE_PASSWORD, KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD));
|
||||
// the X.509 cert password (if not present, verifyKeyStore() returned false)
|
||||
sslFactory.setKeyManagerPassword(_context.getProperty(PROP_KEY_PASSWORD, "thisWontWork"));
|
||||
@ -735,11 +729,11 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
// Got a clue from this ancient post for Tomcat 6:
|
||||
// https://bz.apache.org/bugzilla/show_bug.cgi?id=39804
|
||||
// see also apps/jetty/build.xml
|
||||
Class.forName("org.eclipse.jetty.apache.jsp.JettyJasperInitializer");
|
||||
Class.forName("org.eclipse.jetty.ee8.apache.jsp.JettyJasperInitializer");
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
System.err.println("Warning: JettyJasperInitializer not found");
|
||||
}
|
||||
WebAppContext wac = (WebAppContext)(rootWebApp.getHandler());
|
||||
WebAppContext wac = rootWebApp.getWebAppContext();
|
||||
initialize(_context, wac);
|
||||
WebAppStarter.setWebAppConfiguration(wac, false);
|
||||
chColl.addHandler(rootWebApp);
|
||||
@ -772,7 +766,10 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=364936
|
||||
// WARN:oejw.WebAppContext:Failed startup of context o.e.j.w.WebAppContext{/,jar:file:/.../webapps/routerconsole.war!/},/.../webapps/routerconsole.war
|
||||
// java.lang.IllegalStateException: zip file closed
|
||||
Resource.setDefaultUseCaches(false);
|
||||
// FIXME
|
||||
//URLResourceFactory urlrf = new URLResourceFactory();
|
||||
//urlrf.setUseCaches(false);
|
||||
//ResourceFactory.registerResourceFactory("jar", urlrf);
|
||||
try {
|
||||
// start does a mapContexts()
|
||||
_server.start();
|
||||
@ -994,6 +991,8 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
String rlm = isBasic ? PROMETHEUS_REALM : JETTY_REALM;
|
||||
HashLoginService realm = new CustomHashLoginService(rlm, context.getContextPath(),
|
||||
ctx.logManager().getLog(RouterConsoleRunner.class));
|
||||
UserStore userStore = new UserStore();
|
||||
realm.setUserStore(userStore);
|
||||
sec.setLoginService(realm);
|
||||
LoginAuthenticator auth = isBasic ? basicAuthenticator : authenticator;
|
||||
sec.setAuthenticator(auth);
|
||||
@ -1003,8 +1002,8 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
String pw = e.getValue();
|
||||
// for basic, the password will be the md5 hash itself
|
||||
Credential cred = Credential.getCredential(isBasic ? pw : MD5_CREDENTIAL_TYPE + pw);
|
||||
realm.putUser(user, cred, role);
|
||||
Constraint constraint = new Constraint(user, JETTY_ROLE);
|
||||
userStore.addUser(user, cred, role);
|
||||
ServletConstraint constraint = new ServletConstraint(user, JETTY_ROLE);
|
||||
constraint.setAuthenticate(true);
|
||||
ConstraintMapping cm = new ConstraintMapping();
|
||||
cm.setConstraint(constraint);
|
||||
@ -1023,8 +1022,8 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
try {
|
||||
// each char truncated to 8 bytes
|
||||
String user2 = new String(b2, "ISO-8859-1");
|
||||
realm.putUser(user2, cred, role);
|
||||
constraint = new Constraint(user2, JETTY_ROLE);
|
||||
userStore.addUser(user2, cred, role);
|
||||
constraint = new ServletConstraint(user2, JETTY_ROLE);
|
||||
constraint.setAuthenticate(true);
|
||||
cm = new ConstraintMapping();
|
||||
cm.setConstraint(constraint);
|
||||
@ -1034,8 +1033,8 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
// each UTF-8 byte as a char
|
||||
// this is what chrome does
|
||||
String user3 = new String(b1, "ISO-8859-1");
|
||||
realm.putUser(user3, cred, role);
|
||||
constraint = new Constraint(user3, JETTY_ROLE);
|
||||
userStore.addUser(user3, cred, role);
|
||||
constraint = new ServletConstraint(user2, JETTY_ROLE);
|
||||
constraint.setAuthenticate(true);
|
||||
cm = new ConstraintMapping();
|
||||
cm.setConstraint(constraint);
|
||||
@ -1057,7 +1056,7 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
// See also:
|
||||
// http://old.nabble.com/Disable-HTTP-TRACE-in-Jetty-5.x-td12412607.html
|
||||
|
||||
Constraint sc = new Constraint();
|
||||
ServletConstraint sc = new ServletConstraint();
|
||||
sc.setName("No trace");
|
||||
ConstraintMapping cm = new ConstraintMapping();
|
||||
cm.setMethod("TRACE");
|
||||
@ -1065,8 +1064,6 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
cm.setPathSpec("/");
|
||||
constraints.add(cm);
|
||||
|
||||
sc = new Constraint();
|
||||
sc.setName("No options");
|
||||
cm = new ConstraintMapping();
|
||||
cm.setMethod("OPTIONS");
|
||||
cm.setConstraint(sc);
|
||||
@ -1109,11 +1106,11 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserIdentity login(String username, Object credentials, ServletRequest request) {
|
||||
UserIdentity rv = super.login(username, credentials, request);
|
||||
public UserIdentity login(String username, Object credentials, Request request, Function<Boolean, Session> getOrCreateSession) {
|
||||
UserIdentity rv = super.login(username, credentials, request, getOrCreateSession);
|
||||
if (rv == null)
|
||||
//_log.logAlways(net.i2p.util.Log.WARN, "Console authentication failed, webapp: " + _webapp + ", user: " + username);
|
||||
_log.logAlways(net.i2p.util.Log.WARN, "Console authentication failed, user: " + username + " IP: " + request.getRemoteAddr());
|
||||
_log.logAlways(net.i2p.util.Log.WARN, "Console authentication failed, user: " + username + " IP: " + Request.getRemoteAddr(request));
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,9 @@ import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.FileSuffixFilter;
|
||||
|
||||
import org.apache.tomcat.SimpleInstanceManager;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.WebAppClassLoader;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.ee8.webapp.Configuration;
|
||||
import org.eclipse.jetty.ee8.webapp.WebAppClassLoader;
|
||||
import org.eclipse.jetty.ee8.webapp.WebAppContext;
|
||||
|
||||
|
||||
/**
|
||||
@ -223,4 +223,14 @@ public class WebAppConfiguration implements Configuration {
|
||||
|
||||
/** @since Jetty 7 */
|
||||
public void postConfigure(WebAppContext context) {}
|
||||
|
||||
/**
|
||||
* @since Jetty 12
|
||||
*/
|
||||
public boolean abort(WebAppContext context) { return false; }
|
||||
|
||||
/**
|
||||
* @since Jetty 12
|
||||
*/
|
||||
public boolean isEnabledByDefault() { return true; }
|
||||
}
|
||||
|
@ -17,11 +17,12 @@ import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.PortMapper;
|
||||
import net.i2p.util.SecureDirectory;
|
||||
|
||||
import org.eclipse.jetty.ee.WebAppClassLoading;
|
||||
import org.eclipse.jetty.ee8.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
|
||||
|
||||
/**
|
||||
@ -57,7 +58,7 @@ public class WebAppStarter {
|
||||
// javax-annotations-api.jar
|
||||
private static final String CLASS_ANNOT4 = "javax.annotation.security.RunAs";
|
||||
|
||||
private static final String CLASS_CONFIG = "org.eclipse.jetty.webapp.JettyWebXmlConfiguration";
|
||||
private static final String CLASS_CONFIG = "org.eclipse.jetty.ee8.webapp.JettyWebXmlConfiguration";
|
||||
|
||||
private static final boolean HAS_ANNOTATION_CLASSES;
|
||||
private static final Set<String> BUILTINS = new HashSet<String>(8);
|
||||
@ -202,12 +203,15 @@ public class WebAppStarter {
|
||||
// Without the default configuration, the web.xml isn't read, and the webapp
|
||||
// won't respond to any requests, even though it appears to be running.
|
||||
// See WebAppContext.loadConfigurations() in source
|
||||
if (classNames.length == 0)
|
||||
classNames = wac.getDefaultConfigurationClasses();
|
||||
if (classNames.length == 0) {
|
||||
//classNames = wac.getDefaultConfigurationClasses();
|
||||
// These are the defaults as documented in WebAppContext
|
||||
classNames = new String[] { "org.eclipse.jetty.ee8.webapp.WebXMLConfiguration", "org.eclipse.jetty.ee8.webapp.JettyWebXMLConfiguration" };
|
||||
}
|
||||
List<String> newClassNames = new ArrayList<String>(Arrays.asList(classNames));
|
||||
for (String name : newClassNames) {
|
||||
// fix for Jetty 9.4 ticket #2385
|
||||
wac.prependServerClass("-" + name);
|
||||
WebAppClassLoading.addHiddenClasses(wac, name);
|
||||
}
|
||||
// https://www.eclipse.org/jetty/documentation/current/using-annotations.html
|
||||
// https://www.eclipse.org/jetty/documentation/9.4.x/using-annotations-embedded.html
|
||||
@ -327,14 +331,14 @@ public class WebAppStarter {
|
||||
* @since 0.9.41
|
||||
*/
|
||||
private static ContextHandler getWebApp(ContextHandlerCollection server, String appName) {
|
||||
Handler handlers[] = server.getHandlers();
|
||||
if (handlers == null)
|
||||
List<Handler> handlers = server.getHandlers();
|
||||
if (handlers == null || handlers.isEmpty())
|
||||
return null;
|
||||
String path = '/'+ appName;
|
||||
for (int i = 0; i < handlers.length; i++) {
|
||||
if (!(handlers[i] instanceof ContextHandler))
|
||||
for (Handler h : handlers) {
|
||||
if (!(h instanceof ContextHandler))
|
||||
continue;
|
||||
ContextHandler ch = (ContextHandler) handlers[i];
|
||||
ContextHandler ch = (ContextHandler) h;
|
||||
if (path.equals(ch.getContextPath()))
|
||||
return ch;
|
||||
}
|
||||
@ -360,9 +364,7 @@ public class WebAppStarter {
|
||||
* @since 0.9.41
|
||||
*/
|
||||
private static ContextHandlerCollection getConsoleServer(Server s) {
|
||||
Handler h = s.getChildHandlerByClass(ContextHandlerCollection.class);
|
||||
if (h == null)
|
||||
return null;
|
||||
return (ContextHandlerCollection) h;
|
||||
ContextHandlerCollection h = s.getDescendant(ContextHandlerCollection.class);
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +82,7 @@
|
||||
- in the base context which invalidates it in our context too.
|
||||
-->
|
||||
<context-param>
|
||||
<param-name>org.eclipse.jetty.servlet.SessionCookie</param-name>
|
||||
<param-name>org.eclipse.jetty.session.SessionCookie</param-name>
|
||||
<param-value>SUSIMAILJSESSIONID</param-value>
|
||||
</context-param>
|
||||
|
||||
|
@ -44,8 +44,8 @@ sloccount.report.file=sloccount.sc
|
||||
require.gettext=true
|
||||
|
||||
# Compile for this version of Java
|
||||
#javac.version=1.8
|
||||
#javac.release=8
|
||||
#javac.version=17
|
||||
#javac.release=17
|
||||
|
||||
# Additional classpath if required
|
||||
#javac.classpath=/PATH/TO/pack200.jar
|
||||
|
11
build.xml
11
build.xml
@ -14,7 +14,7 @@
|
||||
and checksum in apps/jetty/build.xml
|
||||
and versions in gradle.properties and apps/jetty/build.gradle
|
||||
-->
|
||||
<property name="jetty.ver" value="9.3.30.v20211001" />
|
||||
<property name="jetty.ver" value="12.0.21" />
|
||||
<property name="tomcat.ver" value="9.0.88" />
|
||||
|
||||
<!-- You probably don't want to change anything from here down -->
|
||||
@ -450,6 +450,9 @@
|
||||
<echo message="Ant: ${ant.version}" />
|
||||
<echo message="JDK: ${java.vendor} ${java.version} (${java.runtime.name} ${java.runtime.version})" />
|
||||
<echo message="Building version ${full.version} (revision ${workspace.version})" />
|
||||
<property name="javac.version" value="17" />
|
||||
<property name="javac.release" value="17" />
|
||||
<echo message="Building for minimum Java version ${javac.version} release ${javac.release}" />
|
||||
</target>
|
||||
|
||||
<target name="setBuildTimestamp" unless="${build.reproducible}" >
|
||||
@ -874,7 +877,7 @@
|
||||
<mkdir dir="./build" />
|
||||
<mkdir dir="./build/javadoc" />
|
||||
<!-- set if unset -->
|
||||
<property name="javac.version" value="1.8" />
|
||||
<property name="javac.version" value="17" />
|
||||
<javadoc access="package"
|
||||
source="${javac.version}"
|
||||
destdir="./build/javadoc"
|
||||
@ -2530,8 +2533,8 @@
|
||||
</ant>
|
||||
<ant dir="apps/jetty/">
|
||||
<!-- not used in Android -->
|
||||
<property name="javac.version" value="1.8" />
|
||||
<property name="javac.release" value="8" />
|
||||
<property name="javac.version" value="17" />
|
||||
<property name="javac.release" value="17" />
|
||||
<target name="servletJar" />
|
||||
<target name="servletJavadocJar" />
|
||||
<target name="servletSourcesJar" />
|
||||
|
Reference in New Issue
Block a user