Compare commits
27 Commits
zzzot-0.4
...
zzzot-0.12
Author | SHA1 | Date | |
---|---|---|---|
953533c6e3 | |||
2e0f7ae4bf | |||
17e5595dd0 | |||
8350d009d4 | |||
a7225a2379 | |||
8a9094cd8e | |||
7f4394aa0f | |||
38f38398ef | |||
8317e3ce9a | |||
c1f6a14367 | |||
7e36455b05 | |||
a85aa6af31 | |||
f33303f394 | |||
ab882f8582 | |||
ce7562c547 | |||
52d8e26ffc | |||
284d7a58d6 | |||
af259e7038 | |||
0b177f317a | |||
0c43324657 | |||
eeeedee076 | |||
d1165b9f9a | |||
a6157ee8f5 | |||
2a795f3d8a | |||
7a13998082 | |||
93a8e5bfd5 | |||
6e3b85ac97 |
66
CHANGES.txt
Normal file
66
CHANGES.txt
Normal file
@ -0,0 +1,66 @@
|
||||
0.12.0
|
||||
2014-11-13
|
||||
Fix parameter decoding for scrape also
|
||||
Add caching for info hashes and peer ids
|
||||
Stop cleaner when plugin stops
|
||||
Move to the ClientApp interface, remove all static refs
|
||||
Attempt to fix crash after update
|
||||
Add zzzot.config file to set interval
|
||||
Don't overwrite index.html and robots.txt in the update
|
||||
Release all resources when shut down (requires 0.9.16-6 or higher)
|
||||
|
||||
0.11.0
|
||||
2014-11-11
|
||||
Critical fix for announce parameter decoding, triggered by recent Jetty versions
|
||||
Change request queueing in jetty.xml (new installs only)
|
||||
SU3 plugin file format
|
||||
|
||||
0.10.0
|
||||
2013-04-14
|
||||
Updates and migration for Jetty 7 (I2P 0.9.6)
|
||||
|
||||
0.9.0
|
||||
2013-01-25
|
||||
Add cache-control directives
|
||||
Set max Jetty to 6.99999
|
||||
|
||||
0.8
|
||||
2012-03-10
|
||||
fix comment in jetty.xml
|
||||
|
||||
0.7
|
||||
2012-03-10
|
||||
Port to Jetty 6
|
||||
Replace QForwardHandler with RewriteHandler
|
||||
Use ${ant.home}/lib/ant.jar instead of pulling ant.jar from Jetty
|
||||
|
||||
0.6
|
||||
2011-12-31
|
||||
Set max jetty version 5.99999
|
||||
Add throttle options
|
||||
Stub out announce-to-seedless
|
||||
Seedless fixes, untested
|
||||
|
||||
0.5
|
||||
2010-07-11
|
||||
Final compact response format
|
||||
|
||||
0.4
|
||||
2010-07-09
|
||||
Compact request/response support - may not be final format
|
||||
Fix NPE if no ip parameter
|
||||
|
||||
0.3
|
||||
2010-04-13
|
||||
Verify dest
|
||||
Add xfs check
|
||||
|
||||
0.2
|
||||
2010-03-23
|
||||
Cache b64 dest strings
|
||||
Help typo fix (thx duck)
|
||||
Lots of seedless fixes
|
||||
Build cleanups
|
||||
|
||||
0.1
|
||||
2010-03-23
|
@ -1,7 +1,7 @@
|
||||
This is a very simple in-memory open tracker, wrapped into an I2P plugin.
|
||||
|
||||
The plugin starts a new http serer tunnel, eepsite, and Jetty server running at port 7662.
|
||||
The tracker status is available at http://127.0.0.1:7661/tracker/ .
|
||||
The tracker status is available at http://127.0.0.1:7662/tracker/ .
|
||||
If other files are desired on the eepsite, they can be added at eepsite/docroot .
|
||||
|
||||
The open tracker code and jsps were written from scratch, but depend on some code
|
||||
|
34
build.xml
34
build.xml
@ -8,10 +8,14 @@
|
||||
</target>
|
||||
|
||||
<target name="plugin" depends="war">
|
||||
<delete file="plugin/i2ptunnel.config" />
|
||||
<delete>
|
||||
<!-- in installer but not update -->
|
||||
<fileset dir="plugin/" includes="i2ptunnel.config zzzot.config eepsite/docroot/index.html eepsite/docroot/robots.txt" />
|
||||
</delete>
|
||||
<delete dir="plugin/eepsite/docroot/torrents/" />
|
||||
<!-- get version number -->
|
||||
<buildnumber file="scripts/build.number" />
|
||||
<property name="release.number" value="0.4" />
|
||||
<property name="release.number" value="0.12.0" />
|
||||
|
||||
<!-- make the update xpi2p -->
|
||||
<!-- this contains everything except i2ptunnel.config -->
|
||||
@ -34,18 +38,31 @@
|
||||
<arg value="plugin/eepsite/webapps/tracker.war.pack" />
|
||||
<arg value="src/build/tracker.war.jar" />
|
||||
</exec>
|
||||
<exec executable="scripts/makeplugin.sh" failonerror="true" >
|
||||
<input message="Enter su3 signing key password:" addproperty="release.password.su3" />
|
||||
<fail message="You must enter a password." >
|
||||
<condition>
|
||||
<equals arg1="${release.password.su3}" arg2=""/>
|
||||
</condition>
|
||||
</fail>
|
||||
<!-- this will fail if no su3 keys exist, as it needs the password twice -->
|
||||
<exec executable="scripts/makeplugin.sh" inputstring="${release.password.su3}" failonerror="true" >
|
||||
<arg value="plugin" />
|
||||
</exec>
|
||||
<move file="zzzot.xpi2p" tofile="zzzot-update.xpi2p" overwrite="true" />
|
||||
<move file="zzzot.su3" tofile="zzzot-update.su3" overwrite="true" />
|
||||
|
||||
<!-- make the install xpi2p -->
|
||||
<copy file="scripts/i2ptunnel.config" todir="plugin/" overwrite="true" />
|
||||
<copy file="scripts/plugin.config" todir="plugin/" overwrite="true" />
|
||||
<!-- Files in installer but not update. Be sure to Add to delete fileset above and clean target below -->
|
||||
<copy file="scripts/i2ptunnel.config" todir="plugin/" overwrite="true" />
|
||||
<copy file="scripts/zzzot.config" todir="plugin/" overwrite="true" />
|
||||
<copy file="scripts/index.html" todir="plugin/eepsite/docroot/" overwrite="true" />
|
||||
<copy file="scripts/robots.txt" todir="plugin/eepsite/docroot/" overwrite="true" />
|
||||
<mkdir dir="plugin/eepsite/docroot/torrents/" />
|
||||
<exec executable="echo" osfamily="unix" failonerror="true" output="plugin/plugin.config" append="true">
|
||||
<arg value="version=${release.number}-b${build.number}" />
|
||||
</exec>
|
||||
<exec executable="scripts/makeplugin.sh" failonerror="true" >
|
||||
<exec executable="scripts/makeplugin.sh" inputstring="${release.password.su3}" failonerror="true" >
|
||||
<arg value="plugin" />
|
||||
</exec>
|
||||
</target>
|
||||
@ -56,12 +73,19 @@
|
||||
<ant dir="src" target="clean" />
|
||||
<delete file="plugin/i2ptunnel.config" />
|
||||
<delete file="plugin/plugin.config" />
|
||||
<delete file="plugin/zzzot.config" />
|
||||
<delete file="plugin/eepsite/docroot/index.html" />
|
||||
<delete file="plugin/eepsite/docroot/robots.txt" />
|
||||
<delete file="plugin/lib/zzzot.jar.pack" />
|
||||
<delete file="plugin/eepsite/webapps/tracker.war.pack" />
|
||||
<delete file="plugin/LICENSE.txt" />
|
||||
<delete file="plugin/README.txt" />
|
||||
<delete file="zzzot.xpi2p" />
|
||||
<delete file="zzzot-update.xpi2p" />
|
||||
<delete file="zzzot.su3" />
|
||||
<delete file="zzzot-update.su3" />
|
||||
<delete file="plugin.zip" />
|
||||
<delete dir="plugin/eepsite/docroot/torrents/" />
|
||||
</target>
|
||||
|
||||
</project>
|
||||
|
23
plugin/templates/contexts/base-context.xml
Normal file
23
plugin/templates/contexts/base-context.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
|
||||
<!--
|
||||
Configure a custom context for the eepsite.
|
||||
|
||||
This context contains only a ServletContextHandler with a default servlet
|
||||
to serve static html files and images.
|
||||
-->
|
||||
|
||||
<Configure class="org.eclipse.jetty.servlet.ServletContextHandler">
|
||||
<Set name="contextPath">/</Set>
|
||||
<Set name="resourceBase">$PLUGIN/eepsite/docroot/</Set>
|
||||
<Call name="setInitParameter">
|
||||
<Arg>cacheControl</Arg>
|
||||
<Arg>max-age=3600,public</Arg>
|
||||
</Call>
|
||||
<Call name="addServlet">
|
||||
<Arg>org.eclipse.jetty.servlet.DefaultServlet</Arg>
|
||||
<Arg>/</Arg>
|
||||
</Call>
|
||||
</Configure>
|
||||
|
36
plugin/templates/contexts/cgi-context.xml
Normal file
36
plugin/templates/contexts/cgi-context.xml
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
|
||||
<!--
|
||||
Configure a custom context for the eepsite.
|
||||
|
||||
* CGI Servlet.
|
||||
*
|
||||
* The cgi bin directory can be set with the "cgibinResourceBase" init parameter
|
||||
* or it will default to the resource base of the context.
|
||||
*
|
||||
* The "commandPrefix" init parameter may be used to set a prefix to all
|
||||
* commands passed to exec. This can be used on systems that need assistance to
|
||||
* execute a particular file type. For example on windows this can be set to
|
||||
* "perl" so that perl scripts are executed.
|
||||
*
|
||||
* The "Path" init param is passed to the exec environment as PATH. Note: Must
|
||||
* be run unpacked somewhere in the filesystem.
|
||||
*
|
||||
* Any initParameter that starts with ENV_ is used to set an environment
|
||||
* variable with the name stripped of the leading ENV_ and using the init
|
||||
* parameter value.
|
||||
-->
|
||||
|
||||
<Configure class="org.eclipse.jetty.servlet.ServletContextHandler">
|
||||
<Set name="contextPath">/cgi-bin</Set>
|
||||
<Set name="resourceBase">$PLUGIN/eepsite/cgi-bin/</Set>
|
||||
<Call name="setInitParameter">
|
||||
<Arg>Path</Arg>
|
||||
<Arg>/usr/local/bin:/bin:/usr/bin</Arg>
|
||||
</Call>
|
||||
<Call name="addServlet">
|
||||
<Arg>org.eclipse.jetty.servlets.CGI</Arg>
|
||||
<Arg>/</Arg>
|
||||
</Call>
|
||||
</Configure>
|
21
plugin/templates/etc/realm.properties
Normal file
21
plugin/templates/etc/realm.properties
Normal file
@ -0,0 +1,21 @@
|
||||
#
|
||||
# This file defines users passwords and roles for a HashUserRealm
|
||||
#
|
||||
# The format is
|
||||
# <username>: <password>[,<rolename> ...]
|
||||
#
|
||||
# Passwords may be clear text, obfuscated or checksummed. The class
|
||||
# org.mortbay.util.Password should be used to generate obfuscated
|
||||
# passwords or password checksums
|
||||
#
|
||||
# If DIGEST Authentication is used, the password must be in a recoverable
|
||||
# format, either plain text or OBF:.
|
||||
#
|
||||
jetty: MD5:164c88b302622e17050af52c89945d44,user
|
||||
admin: CRYPT:ad1ks..kc.1Ug,server-administrator,content-administrator,admin
|
||||
other: OBF:1xmk1w261u9r1w1c1xmq
|
||||
plain: plain
|
||||
user: password
|
||||
|
||||
# This entry is for digest auth. The credential is a MD5 hash of username:realmname:password
|
||||
digest: MD5:6e120743ad67abfbc385bc2bb754e297
|
408
plugin/templates/etc/webdefault.xml
Normal file
408
plugin/templates/etc/webdefault.xml
Normal file
@ -0,0 +1,408 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- This file contains the default descriptor for web applications. -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- The intent of this descriptor is to include jetty specific or common -->
|
||||
<!-- configuration for all webapps. If a context has a webdefault.xml -->
|
||||
<!-- descriptor, it is applied before the contexts own web.xml file -->
|
||||
<!-- -->
|
||||
<!-- A context may be assigned a default descriptor by: -->
|
||||
<!-- + Calling WebApplicationContext.setDefaultsDescriptor -->
|
||||
<!-- + Passed an arg to addWebApplications -->
|
||||
<!-- -->
|
||||
<!-- This file is used both as the resource within the jetty.jar (which is -->
|
||||
<!-- used as the default if no explicit defaults descriptor is set) and it -->
|
||||
<!-- is copied to the etc directory of the Jetty distro and explicitly -->
|
||||
<!-- by the jetty.xml file. -->
|
||||
<!-- -->
|
||||
<!-- ===================================================================== -->
|
||||
<web-app
|
||||
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||
metadata-complete="true"
|
||||
version="2.5">
|
||||
|
||||
<description>
|
||||
Default web.xml file.
|
||||
This file is applied to a Web application before it's own WEB_INF/web.xml file
|
||||
</description>
|
||||
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<!-- Context params to control Session Cookies -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- UNCOMMENT TO ACTIVATE
|
||||
<context-param>
|
||||
<param-name>org.eclipse.jetty.servlet.SessionDomain</param-name>
|
||||
<param-value>127.0.0.1</param-value>
|
||||
</context-param>
|
||||
|
||||
<context-param>
|
||||
<param-name>org.eclipse.jetty.servlet.SessionPath</param-name>
|
||||
<param-value>/</param-value>
|
||||
</context-param>
|
||||
|
||||
<context-param>
|
||||
<param-name>org.eclipse.jetty.servlet.MaxAge</param-name>
|
||||
<param-value>-1</param-value>
|
||||
</context-param>
|
||||
-->
|
||||
|
||||
<context-param>
|
||||
<param-name>org.eclipse.jetty.webapp.NoTLDJarPattern</param-name>
|
||||
<param-value>start.jar|ant-.*\.jar|dojo-.*\.jar|jetty-.*\.jar|jsp-api-.*\.jar|junit-.*\.jar|servlet-api-.*\.jar|dnsns\.jar|rt\.jar|jsse\.jar|tools\.jar|sunpkcs11\.jar|sunjce_provider\.jar|xerces.*\.jar</param-value>
|
||||
</context-param>
|
||||
|
||||
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<!-- The default servlet. -->
|
||||
<!-- This servlet, normally mapped to /, provides the handling for static -->
|
||||
<!-- content, OPTIONS and TRACE methods for the context. -->
|
||||
<!-- The following initParameters are supported: -->
|
||||
<!-- -->
|
||||
<!-- acceptRanges If true, range requests and responses are -->
|
||||
<!-- supported -->
|
||||
<!-- -->
|
||||
<!-- dirAllowed If true, directory listings are returned if no -->
|
||||
<!-- welcome file is found. Else 403 Forbidden. -->
|
||||
<!-- -->
|
||||
<!-- welcomeServlets If true, attempt to dispatch to welcome files -->
|
||||
<!-- that are servlets, if no matching static -->
|
||||
<!-- resources can be found. -->
|
||||
<!-- -->
|
||||
<!-- redirectWelcome If true, redirect welcome file requests -->
|
||||
<!-- else use request dispatcher forwards -->
|
||||
<!-- -->
|
||||
<!-- gzip If set to true, then static content will be served-->
|
||||
<!-- as gzip content encoded if a matching resource is -->
|
||||
<!-- found ending with ".gz" -->
|
||||
<!-- -->
|
||||
<!-- resoureBase Can be set to replace the context resource base -->
|
||||
<!-- -->
|
||||
<!-- relativeResourceBase -->
|
||||
<!-- Set with a pathname relative to the base of the -->
|
||||
<!-- servlet context root. Useful for only serving -->
|
||||
<!-- static content from only specific subdirectories. -->
|
||||
<!-- -->
|
||||
<!-- useFileMappedBuffer -->
|
||||
<!-- If set to true (the default), a memory mapped -->
|
||||
<!-- file buffer will be used to serve static content -->
|
||||
<!-- when using an NIO connector. Setting this value -->
|
||||
<!-- to false means that a direct buffer will be used -->
|
||||
<!-- instead. If you are having trouble with Windows -->
|
||||
<!-- file locking, set this to false. -->
|
||||
<!-- -->
|
||||
<!-- cacheControl If set, all static content will have this value -->
|
||||
<!-- set as the cache-control header. -->
|
||||
<!-- -->
|
||||
<!-- maxCacheSize Maximum size of the static resource cache -->
|
||||
<!-- -->
|
||||
<!-- maxCachedFileSize Maximum size of any single file in the cache -->
|
||||
<!-- -->
|
||||
<!-- maxCachedFiles Maximum number of files in the cache -->
|
||||
<!-- -->
|
||||
<!-- cacheType "nio", "bio" or "both" to determine the type(s) -->
|
||||
<!-- of resource cache. A bio cached buffer may be used-->
|
||||
<!-- by nio but is not as efficient as a nio buffer. -->
|
||||
<!-- An nio cached buffer may not be used by bio. -->
|
||||
<!-- -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<servlet>
|
||||
<servlet-name>default</servlet-name>
|
||||
<servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
|
||||
<init-param>
|
||||
<param-name>acceptRanges</param-name>
|
||||
<param-value>true</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>dirAllowed</param-name>
|
||||
<param-value>true</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>welcomeServlets</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>redirectWelcome</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>maxCacheSize</param-name>
|
||||
<param-value>256000000</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>maxCachedFileSize</param-name>
|
||||
<param-value>10000000</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>maxCachedFiles</param-name>
|
||||
<param-value>1000</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>cacheType</param-name>
|
||||
<param-value>both</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>gzip</param-name>
|
||||
<param-value>true</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>useFileMappedBuffer</param-name>
|
||||
<param-value>true</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>cacheControl</param-name>
|
||||
<param-value>max-age=3600,public</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>0</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
|
||||
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<!-- JSP Servlet -->
|
||||
<!-- This is the jasper JSP servlet from the jakarta project -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- The JSP page compiler and execution servlet, which is the mechanism -->
|
||||
<!-- used by Glassfish to support JSP pages. Traditionally, this servlet -->
|
||||
<!-- is mapped to URL patterh "*.jsp". This servlet supports the -->
|
||||
<!-- following initialization parameters (default values are in square -->
|
||||
<!-- brackets): -->
|
||||
<!-- -->
|
||||
<!-- checkInterval If development is false and reloading is true, -->
|
||||
<!-- background compiles are enabled. checkInterval -->
|
||||
<!-- is the time in seconds between checks to see -->
|
||||
<!-- if a JSP page needs to be recompiled. [300] -->
|
||||
<!-- -->
|
||||
<!-- compiler Which compiler Ant should use to compile JSP -->
|
||||
<!-- pages. See the Ant documenation for more -->
|
||||
<!-- information. [javac] -->
|
||||
<!-- -->
|
||||
<!-- classdebuginfo Should the class file be compiled with -->
|
||||
<!-- debugging information? [true] -->
|
||||
<!-- -->
|
||||
<!-- classpath What class path should I use while compiling -->
|
||||
<!-- generated servlets? [Created dynamically -->
|
||||
<!-- based on the current web application] -->
|
||||
<!-- Set to ? to make the container explicitly set -->
|
||||
<!-- this parameter. -->
|
||||
<!-- -->
|
||||
<!-- development Is Jasper used in development mode (will check -->
|
||||
<!-- for JSP modification on every access)? [true] -->
|
||||
<!-- -->
|
||||
<!-- enablePooling Determines whether tag handler pooling is -->
|
||||
<!-- enabled [true] -->
|
||||
<!-- -->
|
||||
<!-- fork Tell Ant to fork compiles of JSP pages so that -->
|
||||
<!-- a separate JVM is used for JSP page compiles -->
|
||||
<!-- from the one Tomcat is running in. [true] -->
|
||||
<!-- -->
|
||||
<!-- ieClassId The class-id value to be sent to Internet -->
|
||||
<!-- Explorer when using <jsp:plugin> tags. -->
|
||||
<!-- [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93] -->
|
||||
<!-- -->
|
||||
<!-- javaEncoding Java file encoding to use for generating java -->
|
||||
<!-- source files. [UTF-8] -->
|
||||
<!-- -->
|
||||
<!-- keepgenerated Should we keep the generated Java source code -->
|
||||
<!-- for each page instead of deleting it? [true] -->
|
||||
<!-- -->
|
||||
<!-- logVerbosityLevel The level of detailed messages to be produced -->
|
||||
<!-- by this servlet. Increasing levels cause the -->
|
||||
<!-- generation of more messages. Valid values are -->
|
||||
<!-- FATAL, ERROR, WARNING, INFORMATION, and DEBUG. -->
|
||||
<!-- [WARNING] -->
|
||||
<!-- -->
|
||||
<!-- mappedfile Should we generate static content with one -->
|
||||
<!-- print statement per input line, to ease -->
|
||||
<!-- debugging? [false] -->
|
||||
<!-- -->
|
||||
<!-- -->
|
||||
<!-- reloading Should Jasper check for modified JSPs? [true] -->
|
||||
<!-- -->
|
||||
<!-- suppressSmap Should the generation of SMAP info for JSR45 -->
|
||||
<!-- debugging be suppressed? [false] -->
|
||||
<!-- -->
|
||||
<!-- dumpSmap Should the SMAP info for JSR45 debugging be -->
|
||||
<!-- dumped to a file? [false] -->
|
||||
<!-- False if suppressSmap is true -->
|
||||
<!-- -->
|
||||
<!-- scratchdir What scratch directory should we use when -->
|
||||
<!-- compiling JSP pages? [default work directory -->
|
||||
<!-- for the current web application] -->
|
||||
<!-- -->
|
||||
<!-- tagpoolMaxSize The maximum tag handler pool size [5] -->
|
||||
<!-- -->
|
||||
<!-- xpoweredBy Determines whether X-Powered-By response -->
|
||||
<!-- header is added by generated servlet [false] -->
|
||||
<!-- -->
|
||||
<!-- If you wish to use Jikes to compile JSP pages: -->
|
||||
<!-- Set the init parameter "compiler" to "jikes". Define -->
|
||||
<!-- the property "-Dbuild.compiler.emacs=true" when starting Jetty -->
|
||||
<!-- to cause Jikes to emit error messages in a format compatible with -->
|
||||
<!-- Jasper. -->
|
||||
<!-- If you get an error reporting that jikes can't use UTF-8 encoding, -->
|
||||
<!-- try setting the init parameter "javaEncoding" to "ISO-8859-1". -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<servlet id="jsp">
|
||||
<servlet-name>jsp</servlet-name>
|
||||
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
|
||||
<init-param>
|
||||
<param-name>logVerbosityLevel</param-name>
|
||||
<param-value>DEBUG</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>fork</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>xpoweredBy</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
<!--
|
||||
<init-param>
|
||||
<param-name>classpath</param-name>
|
||||
<param-value>?</param-value>
|
||||
</init-param>
|
||||
-->
|
||||
<load-on-startup>0</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>jsp</servlet-name>
|
||||
<url-pattern>*.jsp</url-pattern>
|
||||
<url-pattern>*.jspf</url-pattern>
|
||||
<url-pattern>*.jspx</url-pattern>
|
||||
<url-pattern>*.xsp</url-pattern>
|
||||
<url-pattern>*.JSP</url-pattern>
|
||||
<url-pattern>*.JSPF</url-pattern>
|
||||
<url-pattern>*.JSPX</url-pattern>
|
||||
<url-pattern>*.XSP</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<!-- Dynamic Servlet Invoker. -->
|
||||
<!-- This servlet invokes anonymous servlets that have not been defined -->
|
||||
<!-- in the web.xml or by other means. The first element of the pathInfo -->
|
||||
<!-- of a request passed to the envoker is treated as a servlet name for -->
|
||||
<!-- an existing servlet, or as a class name of a new servlet. -->
|
||||
<!-- This servlet is normally mapped to /servlet/* -->
|
||||
<!-- This servlet support the following initParams: -->
|
||||
<!-- -->
|
||||
<!-- nonContextServlets If false, the invoker can only load -->
|
||||
<!-- servlets from the contexts classloader. -->
|
||||
<!-- This is false by default and setting this -->
|
||||
<!-- to true may have security implications. -->
|
||||
<!-- -->
|
||||
<!-- verbose If true, log dynamic loads -->
|
||||
<!-- -->
|
||||
<!-- * All other parameters are copied to the -->
|
||||
<!-- each dynamic servlet as init parameters -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- Uncomment for dynamic invocation
|
||||
<servlet>
|
||||
<servlet-name>invoker</servlet-name>
|
||||
<servlet-class>org.eclipse.jetty.servlet.Invoker</servlet-class>
|
||||
<init-param>
|
||||
<param-name>verbose</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>nonContextServlets</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>dynamicParam</param-name>
|
||||
<param-value>anyValue</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>0</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping> <servlet-name>invoker</servlet-name> <url-pattern>/servlet/*</url-pattern> </servlet-mapping>
|
||||
-->
|
||||
|
||||
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<session-config>
|
||||
<session-timeout>30</session-timeout>
|
||||
</session-config>
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<!-- Default MIME mappings -->
|
||||
<!-- The default MIME mappings are provided by the mime.properties -->
|
||||
<!-- resource in the org.mortbay.jetty.jar file. Additional or modified -->
|
||||
<!-- mappings may be specified here -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- UNCOMMENT TO ACTIVATE
|
||||
<mime-mapping>
|
||||
<extension>mysuffix</extension>
|
||||
<mime-type>mymime/type</mime-type>
|
||||
</mime-mapping>
|
||||
-->
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.html</welcome-file>
|
||||
<welcome-file>index.htm</welcome-file>
|
||||
<welcome-file>index.jsp</welcome-file>
|
||||
</welcome-file-list>
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<locale-encoding-mapping-list>
|
||||
<locale-encoding-mapping><locale>ar</locale><encoding>ISO-8859-6</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>be</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>bg</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>ca</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>cs</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>da</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>de</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>el</locale><encoding>ISO-8859-7</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>en</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>es</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>et</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>fi</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>fr</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>hr</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>hu</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>is</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>it</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>iw</locale><encoding>ISO-8859-8</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>ja</locale><encoding>Shift_JIS</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>ko</locale><encoding>EUC-KR</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>lt</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>lv</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>mk</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>nl</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>no</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>pl</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>pt</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>ro</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>ru</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>sh</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>sk</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>sl</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>sq</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>sr</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>sv</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>tr</locale><encoding>ISO-8859-9</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>uk</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>zh</locale><encoding>GB2312</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>zh_TW</locale><encoding>Big5</encoding></locale-encoding-mapping>
|
||||
</locale-encoding-mapping-list>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Disable TRACE</web-resource-name>
|
||||
<url-pattern>/</url-pattern>
|
||||
<http-method>TRACE</http-method>
|
||||
</web-resource-collection>
|
||||
<auth-constraint/>
|
||||
</security-constraint>
|
||||
|
||||
</web-app>
|
||||
|
@ -10,6 +10,9 @@ This link is also at the top of your router console when ZzzOT is running.
|
||||
<p>Report bugs or add comments on
|
||||
<a href="http://zzz.i2p//forums/16">the plugin forum on zzz.i2p</a>.
|
||||
|
||||
<p><b>This help file is $PLUGIN/eepsite/docroot/help.html, you should probably move it
|
||||
outside of the document root before you announce your eepsite as it may contain your user name.</b>
|
||||
|
||||
<h3>Eepsite Key and Helpful Hints for I2P</h3>
|
||||
|
||||
<p>Your Base 32 address is <a href="http://$B32/">$B32</a>.
|
||||
@ -20,7 +23,7 @@ This link is also at the top of your router console when ZzzOT is running.
|
||||
<br>You will need this key to register a hostname at <a href="http://stats.i2p/i2p/addkey.html">stats.i2p</a>.
|
||||
<p>Your private key file is $PLUGIN/eepPriv.dat - back it up!!!
|
||||
<p>Your eepsite document root is $PLUGIN/eepsite/docroot,
|
||||
you may put other files there is you wish to have additional content on your eepsite.
|
||||
you may put other files there if you wish to have additional content on your eepsite.
|
||||
<p>The supported announce URLs are:
|
||||
<ul>
|
||||
<li><a href="http://$B32/a">http://$B32/a</a>
|
||||
@ -47,8 +50,6 @@ This link is also at the top of your router console when ZzzOT is running.
|
||||
If your tracker gets over 1000 peers, you will probably want to increase the number of tunnels.
|
||||
<p>The Jetty webserver port is 7662. If you must change it, edit jetty.xml, i2ptunnel.config, and plugins.config
|
||||
in the directory $PLUGIN. Then stop and restart the plugin.
|
||||
<p>This help file is $PLUGIN/eepsite/docroot/help.html, you should probably move it
|
||||
outside of the document root before you announce your eepsite as it may contain your user name.
|
||||
<p>As you probably know, an open tracker does not require torrents to be registered,
|
||||
and it does not host torrent files. You can, however, host torrent files elsewhere on
|
||||
the eepsite, for example at <a href="http://$B32/torrents/">/torrents</a>.
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure 1.2//EN" "http://jetty.mortbay.org/configure_1_2.dtd">
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
|
||||
<!-- ========================================================================= -->
|
||||
<!-- This file configures the Jetty server. -->
|
||||
@ -8,183 +8,381 @@
|
||||
<!-- Commonly changed settings: -->
|
||||
<!-- * host: Change 127.0.0.1 to 0.0.0.0 in the addListener section -->
|
||||
<!-- to access the server directly (bypassing i2p) -->
|
||||
<!-- from other computers. The included version of Jetty has -->
|
||||
<!-- been patched to allow IPv6 addresses as well, -->
|
||||
<!-- enclosed in brackets e.g. [::1] -->
|
||||
<!-- * port: Default 7662 in the addListener section -->
|
||||
<!-- * threads: Raise MaxThreads in the addListener section -->
|
||||
<!-- from other computers. -->
|
||||
<!-- * port: Default 7662 in the addConnector section -->
|
||||
<!-- * docroot: Change the ResourceBase in the contexts/base-context.xml file -->
|
||||
<!-- to serve files from a different location. -->
|
||||
<!-- * threads: Raise maximumPoolSize in the ThreadPool section -->
|
||||
<!-- if you have a high-traffic site and get a lot of warnings. -->
|
||||
<!-- -->
|
||||
<!-- I2P uses Jetty 5.1.15. We have no plans to upgrade to Jetty 6, due to -->
|
||||
<!-- the significant changes in the API. If you need web server features not -->
|
||||
<!-- found in Jetty 5, you may install and run Jetty 6 in a different JVM, -->
|
||||
<!-- or run any other web server such as Apache. If you do run another -->
|
||||
<!-- web server instead, be sure and disable the Jetty 5 server for your -->
|
||||
<!-- eepsite on http://127.0.0.1/configclients.jsp . -->
|
||||
<!-- I2P uses Jetty 7. If you need web server features not found -->
|
||||
<!-- in Jetty 7, you may install and run Jetty 7 or 8 in a different JVM -->
|
||||
<!-- or run any other web server such as Apache. If you do run another web -->
|
||||
<!-- server instead, be sure and disable the Jetty 6 server for your -->
|
||||
<!-- eepsite on http://127.0.0.1:7657/configclients.jsp . -->
|
||||
<!-- -->
|
||||
<!-- Jetty now uses the I2P logging system rather than wrapper.log. -->
|
||||
<!-- Use the log override org.eclipse.jetty.server.Server to adjust the log level. -->
|
||||
<!-- -->
|
||||
<!-- Note that the XML encoding for this file is UTF-8. -->
|
||||
<!-- -->
|
||||
<!-- Jetty errors and warnings will appear in wrapper.log, check there -->
|
||||
<!-- to diagnose problems. -->
|
||||
<!-- ========================================================================= -->
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the Jetty Server -->
|
||||
<!-- -->
|
||||
<!-- Documentation of this file format can be found at: -->
|
||||
<!-- http://docs.codehaus.org/display/JETTY/jetty.xml -->
|
||||
<!-- -->
|
||||
<!-- =============================================================== -->
|
||||
<Configure class="org.mortbay.jetty.Server">
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the Request Listeners -->
|
||||
<!-- =============================================================== -->
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- Add and configure a HTTP listener to port 8080 -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<Call name="addListener">
|
||||
<Arg>
|
||||
<New class="org.mortbay.http.SocketListener">
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Server Thread Pool -->
|
||||
<!-- =========================================================== -->
|
||||
<Set name="ThreadPool">
|
||||
|
||||
<!-- PICK ONE -->
|
||||
|
||||
<!--
|
||||
Recommended.
|
||||
Requests above the maxThreads + queue_size will be rejected and logged.
|
||||
ref:
|
||||
https://wiki.eclipse.org/Jetty/Howto/High_Load
|
||||
http://trac.i2p2.i2p/ticket/1395
|
||||
-->
|
||||
<New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
|
||||
<Arg>
|
||||
<New class="org.mortbay.util.InetAddrPort">
|
||||
<New class="java.util.concurrent.LinkedBlockingQueue">
|
||||
<Arg type="int">50</Arg>
|
||||
</New>
|
||||
</Arg>
|
||||
<Set name="minThreads">4</Set>
|
||||
<Set name="maxThreads">20</Set>
|
||||
<Set name="maxIdleTimeMs">60000</Set>
|
||||
<Set name="daemon">true</Set>
|
||||
<Set name="name">Zzzot Jetty</Set>
|
||||
</New>
|
||||
|
||||
<!-- Optional Java 5 bounded threadpool with job queue
|
||||
Requests above the max will be rejected and logged.
|
||||
High-traffic sites should increase maximumPoolSize.
|
||||
|
||||
Args are:
|
||||
corePoolSize (should be at least 3)
|
||||
maximumPoolSize
|
||||
keepAliveTime (milliseconds)
|
||||
timeout (TimeUnit)
|
||||
queue (BlockingQueue)
|
||||
|
||||
Not recommended.
|
||||
ref:
|
||||
http://trac.i2p2.i2p/ticket/1395
|
||||
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html
|
||||
-->
|
||||
<!--
|
||||
<New class="org.eclipse.jetty.util.thread.ExecutorThreadPool">
|
||||
<Arg type="int">3</Arg>
|
||||
<Arg type="int">20</Arg>
|
||||
<Arg type="long">60000</Arg>
|
||||
<Arg>
|
||||
<Call class="java.util.concurrent.TimeUnit" name="valueOf" >
|
||||
<Arg>MILLISECONDS</Arg>
|
||||
</Call>
|
||||
</Arg>
|
||||
<Arg>
|
||||
<New class="java.util.concurrent.SynchronousQueue" />
|
||||
</Arg>
|
||||
</New>
|
||||
-->
|
||||
</Set>
|
||||
|
||||
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Set connectors -->
|
||||
<!-- =========================================================== -->
|
||||
<!-- One of each type! -->
|
||||
<!-- =========================================================== -->
|
||||
|
||||
<!-- Use this connector for many frequently idle connections
|
||||
and for threadless continuations.
|
||||
Not recommended on Java 5 - comment this out, and uncomment the
|
||||
SocketConnector below.
|
||||
Do not use for gij or JamVM - comment this out, and uncomment the
|
||||
SocketConnector below.
|
||||
-->
|
||||
<Call name="addConnector">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
|
||||
<Set name="host">127.0.0.1</Set>
|
||||
<Set name="port">7662</Set>
|
||||
<Set name="maxIdleTime">60000</Set>
|
||||
<Set name="Acceptors">1</Set>
|
||||
<Set name="statsOn">false</Set>
|
||||
<Set name="confidentialPort">8443</Set>
|
||||
<Set name="lowResourcesConnections">5000</Set>
|
||||
<Set name="lowResourcesMaxIdleTime">5000</Set>
|
||||
<Set name="useDirectBuffers">false</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
<!-- Recommended to use this connector on Java 5, as
|
||||
Jetty 6 and Java 5 NIO don't play well together.
|
||||
-->
|
||||
<!--
|
||||
<Call name="addConnector">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.server.bio.SocketConnector">
|
||||
<Set name="host">127.0.0.1</Set>
|
||||
<Set name="port">7662</Set>
|
||||
<Set name="maxIdleTime">60000</Set>
|
||||
<Set name="Acceptors">1</Set>
|
||||
<Set name="statsOn">false</Set>
|
||||
<Set name="confidentialPort">8443</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
-->
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Set up global session ID manager -->
|
||||
<!-- =========================================================== -->
|
||||
<!--
|
||||
<Set name="sessionIdManager">
|
||||
<New class="org.eclipse.jetty.server.session.HashSessionIdManager">
|
||||
<Set name="workerName">node1</Set>
|
||||
</New>
|
||||
</Set>
|
||||
-->
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Set handler Collection Structure -->
|
||||
<!-- -->
|
||||
<!-- We use a RewriteHandler at the top level so that we may -->
|
||||
<!-- convert any top-level URLs for the tracker down into the -->
|
||||
<!-- tracker servlet, without interfering with anything else -->
|
||||
<!-- that is hosted on the same eepsite. -->
|
||||
<!-- =========================================================== -->
|
||||
<Set name="handler">
|
||||
<New id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RewriteHandler">
|
||||
<Set name="rewriteRequestURI">true</Set>
|
||||
<Set name="rewritePathInfo">false</Set>
|
||||
<Set name="originalPathAttribute">requestedPath</Set>
|
||||
<Set name="rules">
|
||||
<Array type="org.eclipse.jetty.rewrite.handler.Rule">
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
|
||||
<Set name="pattern">/a</Set>
|
||||
<Set name="replacement">/tracker/announce.jsp</Set>
|
||||
</New>
|
||||
</Item>
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
|
||||
<Set name="pattern">/announce</Set>
|
||||
<Set name="replacement">/tracker/announce.jsp</Set>
|
||||
</New>
|
||||
</Item>
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
|
||||
<Set name="pattern">/announce.jsp</Set>
|
||||
<Set name="replacement">/tracker/announce.jsp</Set>
|
||||
</New>
|
||||
</Item>
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
|
||||
<Set name="pattern">/announce.php</Set>
|
||||
<Set name="replacement">/tracker/announce.jsp</Set>
|
||||
</New>
|
||||
</Item>
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
|
||||
<Set name="pattern">/scrape</Set>
|
||||
<Set name="replacement">/tracker/scrape.jsp</Set>
|
||||
</New>
|
||||
</Item>
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
|
||||
<Set name="pattern">/scrape.jsp</Set>
|
||||
<Set name="replacement">/tracker/scrape.jsp</Set>
|
||||
</New>
|
||||
</Item>
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
|
||||
<Set name="pattern">/scrape.php</Set>
|
||||
<Set name="replacement">/tracker/scrape.jsp</Set>
|
||||
</New>
|
||||
</Item>
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
|
||||
<Set name="pattern">/Seedless</Set>
|
||||
<Set name="replacement">/tracker/seedless.jsp</Set>
|
||||
</New>
|
||||
</Item>
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
|
||||
<Set name="pattern">/Seedless/</Set>
|
||||
<Set name="replacement">/tracker/seedless.jsp</Set>
|
||||
</New>
|
||||
</Item>
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
|
||||
<Set name="pattern">/Seedless/index.jsp</Set>
|
||||
<Set name="replacement">/tracker/seedless.jsp</Set>
|
||||
</New>
|
||||
</Item>
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
|
||||
<Set name="pattern">/Seedless/seedless</Set>
|
||||
<Set name="replacement">/tracker/seedless.jsp</Set>
|
||||
</New>
|
||||
</Item>
|
||||
</Array>
|
||||
</Set>
|
||||
<Set name="handler">
|
||||
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
|
||||
<Set name="handlers">
|
||||
<Array type="org.eclipse.jetty.server.Handler">
|
||||
<Item>
|
||||
<New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"/>
|
||||
</Item>
|
||||
</Array>
|
||||
</Set>
|
||||
</New>
|
||||
</Set>
|
||||
</New>
|
||||
</Set>
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Create the deployment manager -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- The deplyment manager handles the lifecycle of deploying web -->
|
||||
<!-- applications. Apps are provided by instances of the -->
|
||||
<!-- AppProvider interface. Typically these are provided by -->
|
||||
<!-- one or more of: -->
|
||||
<!-- jetty-webapps.xml - monitors webapps for wars and dirs -->
|
||||
<!-- jetty-contexts.xml - monitors contexts for context xml -->
|
||||
<!-- jetty-templates.xml - monitors contexts and templates -->
|
||||
<!-- =============================================================== -->
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
|
||||
<Set name="contexts">
|
||||
<Ref id="Contexts" />
|
||||
</Set>
|
||||
<Call name="setContextAttribute">
|
||||
<Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
|
||||
<Arg>.*/.*jsp-api-[^/]*\.jar$|.*/.*jsp-[^/]*\.jar$|.*/.*taglibs[^/]*\.jar$</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Configure the context deployer -->
|
||||
<!-- A context deployer will deploy contexts described in -->
|
||||
<!-- configuration files discovered in a directory. -->
|
||||
<!-- The configuration directory can be scanned for hot -->
|
||||
<!-- deployments at the configured scanInterval. -->
|
||||
<!-- -->
|
||||
<!-- This deployer is configured to deploy contexts configured -->
|
||||
<!-- in the $JETTY_HOME/contexts directory -->
|
||||
<!-- -->
|
||||
<!-- =========================================================== -->
|
||||
<Ref id="DeploymentManager">
|
||||
<Call name="addAppProvider">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.deploy.providers.ContextProvider">
|
||||
<Set name="monitoredDirName">$PLUGIN/contexts</Set>
|
||||
<Set name="scanInterval">120</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
<Set name="MinThreads">3</Set>
|
||||
<Set name="MaxThreads">10</Set>
|
||||
<Set name="MaxIdleTimeMs">60000</Set>
|
||||
<Set name="LowResourcePersistTimeMs">1000</Set>
|
||||
<Set name="ConfidentialPort">8443</Set>
|
||||
<Set name="IntegralPort">8443</Set>
|
||||
<Set name="PoolName">main</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
</Call>
|
||||
</Ref>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Configure the webapp deployer. -->
|
||||
<!-- A webapp deployer will deploy standard webapps discovered -->
|
||||
<!-- in a directory at startup, without the need for additional -->
|
||||
<!-- configuration files. It does not support hot deploy or -->
|
||||
<!-- non standard contexts (see ContextDeployer above). -->
|
||||
<!-- -->
|
||||
<!-- This deployer is configured to deploy webapps from the -->
|
||||
<!-- $JETTY_HOME/webapps directory -->
|
||||
<!-- -->
|
||||
<!-- Normally only one type of deployer need be used. -->
|
||||
<!-- -->
|
||||
<!-- =========================================================== -->
|
||||
<Ref id="DeploymentManager">
|
||||
<Call id="webappprovider" name="addAppProvider">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
|
||||
<Set name="monitoredDirName">$PLUGIN/eepsite/webapps</Set>
|
||||
<Set name="parentLoaderPriority">false</Set>
|
||||
<Set name="extractWars">false</Set>
|
||||
<Set name="defaultsDescriptor">$PLUGIN/etc/webdefault.xml</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
</Ref>
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the Contexts -->
|
||||
<!-- =============================================================== -->
|
||||
<!-- =========================================================== -->
|
||||
<!-- Configure Authentication Realms -->
|
||||
<!-- Realms may be configured for the entire server here, or -->
|
||||
<!-- they can be configured for a specific web app in a context -->
|
||||
<!-- configuration (see $(jetty.home)/contexts/test.xml for an -->
|
||||
<!-- example). -->
|
||||
<!-- =========================================================== -->
|
||||
<!-- UNCOMMENT TO ACTIVATE
|
||||
<Set name="UserRealms">
|
||||
<Array type="org.eclipse.jetty.security.LoginService">
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.security.HashLoginService">
|
||||
<Set name="name">Test Realm</Set>
|
||||
<Set name="config">$PLUGIN/etc/realm.properties</Set>
|
||||
<Set name="refreshInterval">0</Set>
|
||||
</New>
|
||||
</Item>
|
||||
</Array>
|
||||
</Set>
|
||||
-->
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Configure Request Log -->
|
||||
<!-- Request logs may be configured for the entire server here, -->
|
||||
<!-- or they can be configured for a specific web app in a -->
|
||||
<!-- contexts configuration (see $(jetty.home)/contexts/test.xml -->
|
||||
<!-- for an example). -->
|
||||
<!-- =========================================================== -->
|
||||
<Ref id="RequestLog">
|
||||
<Set name="requestLog">
|
||||
<New id="RequestLogImpl" class="net.i2p.jetty.I2PRequestLog">
|
||||
<Set name="filename">$PLUGIN/eepsite/logs/yyyy_mm_dd.request.log</Set>
|
||||
<Set name="filenameDateFormat">yyyy_MM_dd</Set>
|
||||
<Set name="retainDays">90</Set>
|
||||
<Set name="append">true</Set>
|
||||
<Set name="extended">false</Set>
|
||||
<Set name="logCookies">false</Set>
|
||||
<Set name="LogTimeZone">GMT</Set>
|
||||
</New>
|
||||
</Set>
|
||||
</Ref>
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- Add a all web application within the webapps directory. -->
|
||||
<!-- + No virtual host specified -->
|
||||
<!-- + Look in the webapps directory relative to jetty.home or . -->
|
||||
<!-- + Use the default webdefault.xml in jetty's install -->
|
||||
<!-- + Upack the war file -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<Set name="rootWebApp">root</Set>
|
||||
<Call name="addWebApplications">
|
||||
<Arg></Arg>
|
||||
<Arg>$PLUGIN/eepsite/webapps/</Arg>
|
||||
<Arg></Arg>
|
||||
<Arg type="boolean">true</Arg>
|
||||
</Call>
|
||||
|
||||
<Call name="addContext">
|
||||
<Arg>
|
||||
<New class="org.mortbay.http.HttpContext">
|
||||
<Set name="contextPath">/</Set>
|
||||
<Set name="resourceBase">$PLUGIN/eepsite/docroot</Set>
|
||||
<Call name="addHandler">
|
||||
<Arg>
|
||||
<New class="org.mortbay.http.handler.ResourceHandler">
|
||||
<Set name="redirectWelcome">FALSE</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
<!-- This custom handler is like Jetty's ForwardHandler,
|
||||
- but it passes CGI query parameters through.
|
||||
- Note that it is somewhat misnamed - it does NOT
|
||||
- return a 301/302, it handles the request directly.
|
||||
-->
|
||||
<Call name="addHandler">
|
||||
<Arg>
|
||||
<New class="net.i2p.zzzot.QForwardHandler">
|
||||
<Call name="setHandleQueries">
|
||||
<Arg type="boolean">true</Arg>
|
||||
</Call>
|
||||
<!-- Forward announce requests to /tracker/announce.jsp -->
|
||||
<Call name="addForward">
|
||||
<Arg>/a</Arg>
|
||||
<Arg>/tracker/announce.jsp</Arg>
|
||||
</Call>
|
||||
<Call name="addForward">
|
||||
<Arg>/announce</Arg>
|
||||
<Arg>/tracker/announce.jsp</Arg>
|
||||
</Call>
|
||||
<Call name="addForward">
|
||||
<Arg>/announce.jsp</Arg>
|
||||
<Arg>/tracker/announce.jsp</Arg>
|
||||
</Call>
|
||||
<Call name="addForward">
|
||||
<Arg>/announce.php</Arg>
|
||||
<Arg>/tracker/announce.jsp</Arg>
|
||||
</Call>
|
||||
<!-- Forward scrape requests to /tracker/scrape.jsp -->
|
||||
<Call name="addForward">
|
||||
<Arg>/scrape</Arg>
|
||||
<Arg>/tracker/scrape.jsp</Arg>
|
||||
</Call>
|
||||
<Call name="addForward">
|
||||
<Arg>/scrape.jsp</Arg>
|
||||
<Arg>/tracker/scrape.jsp</Arg>
|
||||
</Call>
|
||||
<Call name="addForward">
|
||||
<Arg>/scrape.php</Arg>
|
||||
<Arg>/tracker/scrape.jsp</Arg>
|
||||
</Call>
|
||||
<!-- Forward Seedless requests to /tracker/seedless.jsp -->
|
||||
<Call name="addForward">
|
||||
<Arg>/Seedless</Arg>
|
||||
<Arg>/tracker/seedless.jsp</Arg>
|
||||
</Call>
|
||||
<Call name="addForward">
|
||||
<Arg>/Seedless/</Arg>
|
||||
<Arg>/tracker/seedless.jsp</Arg>
|
||||
</Call>
|
||||
<Call name="addForward">
|
||||
<Arg>/Seedless/index.jsp</Arg>
|
||||
<Arg>/tracker/seedless.jsp</Arg>
|
||||
</Call>
|
||||
<Call name="addForward">
|
||||
<Arg>/Seedless/seedless</Arg>
|
||||
<Arg>/tracker/seedless.jsp</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
<Call name="addContext">
|
||||
<Arg>/cgi-bin/*</Arg>
|
||||
<Set name="ResourceBase">$PLUGIN/eepsite/cgi-bin</Set>
|
||||
<Call name="addServlet">
|
||||
<Arg>Common Gateway Interface</Arg>
|
||||
<Arg>/</Arg>
|
||||
<Arg>org.mortbay.servlet.CGI</Arg>
|
||||
<Put name="Path">/usr/local/bin:/usr/ucb:/bin:/usr/bin</Put>
|
||||
</Call>
|
||||
</Call>
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the Request Log -->
|
||||
<!-- =============================================================== -->
|
||||
<Set name="RequestLog">
|
||||
<New class="org.mortbay.http.I2PRequestLog">
|
||||
<Arg>$PLUGIN/eepsite/logs/yyyy_mm_dd.request.log</Arg>
|
||||
<Set name="retainDays">30</Set>
|
||||
<Set name="append">true</Set>
|
||||
<Set name="extended">false</Set>
|
||||
<Set name="buffered">false</Set>
|
||||
<Set name="LogTimeZone">GMT</Set>
|
||||
</New>
|
||||
</Set>
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the Other Server Options -->
|
||||
<!-- =============================================================== -->
|
||||
<Set name="requestsPerGC">2000</Set>
|
||||
<Set name="statsOn">false</Set>
|
||||
<!-- =========================================================== -->
|
||||
<!-- extra options -->
|
||||
<!-- =========================================================== -->
|
||||
<Set name="stopAtShutdown">true</Set>
|
||||
<Set name="sendServerVersion">false</Set>
|
||||
<Set name="sendDateHeader">true</Set>
|
||||
<Set name="gracefulShutdown">1000</Set>
|
||||
|
||||
</Configure>
|
||||
|
@ -8,6 +8,11 @@ tunnel.0.option.i2cp.reduceIdleTime=1200000
|
||||
tunnel.0.option.i2cp.reduceOnIdle=true
|
||||
tunnel.0.option.i2cp.reduceQuantity=1
|
||||
tunnel.0.option.i2p.streaming.connectDelay=0
|
||||
tunnel.0.option.i2p.streaming.maxConcurrentStreams=40
|
||||
tunnel.0.option.i2p.streaming.maxConnsPerHour=100
|
||||
tunnel.0.option.i2p.streaming.maxConnsPerMinute=10
|
||||
tunnel.0.option.i2p.streaming.maxTotalConnsPerHour=2500
|
||||
tunnel.0.option.i2p.streaming.maxTotalConnsPerMinute=60
|
||||
tunnel.0.option.inbound.backupQuantity=0
|
||||
tunnel.0.option.inbound.length=3
|
||||
tunnel.0.option.inbound.lengthVariance=0
|
||||
|
@ -5,11 +5,16 @@
|
||||
# usage: makeplugin.sh plugindir
|
||||
#
|
||||
# zzz 2010-02
|
||||
# zzz 2014-08 added support for su3 files
|
||||
#
|
||||
PUBKEYDIR=$HOME/.i2p-plugin-keys
|
||||
PUBKEYFILE=$PUBKEYDIR/plugin-public-signing.key
|
||||
PRIVKEYFILE=$PUBKEYDIR/plugin-private-signing.key
|
||||
B64KEYFILE=$PUBKEYDIR/plugin-public-signing.txt
|
||||
PUBKEYSTORE=$PUBKEYDIR/plugin-su3-public-signing.crt
|
||||
PRIVKEYSTORE=$PUBKEYDIR/plugin-su3-keystore.ks
|
||||
KEYTYPE=RSA_SHA512_4096
|
||||
|
||||
export I2P=../i2p/pkg-temp
|
||||
|
||||
PLUGINDIR=${1:-plugin}
|
||||
@ -17,46 +22,67 @@ PLUGINDIR=${1:-plugin}
|
||||
PC=plugin.config
|
||||
PCT=${PC}.tmp
|
||||
|
||||
if [ ! -f $PRIVKEYFILE ]
|
||||
then
|
||||
mkdir -p $PUBKEYDIR
|
||||
java -cp $I2P/lib/i2p.jar net.i2p.crypto.TrustedUpdate keygen $PUBKEYFILE $PRIVKEYFILE || exit 1
|
||||
java -cp $I2P/lib/i2p.jar net.i2p.data.Base64 encode $PUBKEYFILE $B64KEYFILE || exit 1
|
||||
rm -rf logs/
|
||||
chmod 444 $PUBKEYFILE $B64KEYFILE
|
||||
chmod 400 $PRIVKEYFILE
|
||||
echo "Created new keys: $PUBKEYFILE $PRIVKEYFILE"
|
||||
fi
|
||||
|
||||
rm -f plugin.zip
|
||||
if [ ! -d $PLUGINDIR ]
|
||||
then
|
||||
echo "You must have a $PLUGINDIR directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OPWD=$PWD
|
||||
cd $PLUGINDIR
|
||||
|
||||
if [ ! -f $PC ]
|
||||
if [ ! -f $PLUGINDIR/$PC ]
|
||||
then
|
||||
echo "You must have a $PC file"
|
||||
echo "You must have a $PLUGINDIR/$PC file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
grep -q '^signer=' $PC
|
||||
SIGNER=`grep '^signer=' $PLUGINDIR/$PC`
|
||||
if [ "$?" -ne "0" ]
|
||||
then
|
||||
echo "You must have a signer in $PC"
|
||||
echo 'For example signer=joe@mail.i2p'
|
||||
echo "You must have a plugin name in $PC"
|
||||
echo 'For example name=foo'
|
||||
exit 1
|
||||
fi
|
||||
SIGNER=`echo $SIGNER | cut -f 2 -d '='`
|
||||
|
||||
if [ ! -f $PRIVKEYFILE ]
|
||||
then
|
||||
echo "Creating new XPI2P DSA keys"
|
||||
mkdir -p $PUBKEYDIR || exit 1
|
||||
java -cp $I2P/lib/i2p.jar net.i2p.crypto.TrustedUpdate keygen $PUBKEYFILE $PRIVKEYFILE || exit 1
|
||||
java -cp $I2P/lib/i2p.jar net.i2p.data.Base64 encode $PUBKEYFILE $B64KEYFILE || exit 1
|
||||
rm -rf logs/
|
||||
chmod 444 $PUBKEYFILE $B64KEYFILE
|
||||
chmod 400 $PRIVKEYFILE
|
||||
echo "Created new XPI2P keys: $PUBKEYFILE $PRIVKEYFILE"
|
||||
fi
|
||||
|
||||
if [ ! -f $PRIVKEYSTORE ]
|
||||
then
|
||||
echo "Creating new SU3 $KEYTYPE keys for $SIGNER"
|
||||
java -cp $I2P/lib/i2p.jar net.i2p.crypto.SU3File keygen -t $KEYTYPE $PUBKEYSTORE $PRIVKEYSTORE $SIGNER || exit 1
|
||||
echo '*** Save your password in a safe place!!! ***'
|
||||
rm -rf logs/
|
||||
# copy to the router dir so verify will work
|
||||
CDIR=$I2P/certificates/plugin
|
||||
mkdir -p $CDIR || exit 1
|
||||
CFILE=$CDIR/`echo $SIGNER | sed s/@/_at_/`.crt
|
||||
cp $PUBKEYSTORE $CFILE
|
||||
chmod 444 $PUBKEYSTORE
|
||||
chmod 400 $PRIVKEYSTORE
|
||||
chmod 644 $CFILE
|
||||
echo "Created new SU3 keys: $PUBKEYSTORE $PRIVKEYSTORE"
|
||||
echo "Copied public key to $CFILE for testing"
|
||||
fi
|
||||
|
||||
rm -f plugin.zip
|
||||
|
||||
OPWD=$PWD
|
||||
cd $PLUGINDIR
|
||||
|
||||
grep -q '^name=' $PC
|
||||
if [ "$?" -ne "0" ]
|
||||
then
|
||||
echo "You must have a plugin name in $PC"
|
||||
echo 'For example name=foo'
|
||||
echo 'For example name=foo'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@ -64,7 +90,7 @@ grep -q '^version=' $PC
|
||||
if [ "$?" -ne "0" ]
|
||||
then
|
||||
echo "You must have a version in $PC"
|
||||
echo 'For example version=0.1.2'
|
||||
echo 'For example version=0.1.2'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@ -72,33 +98,41 @@ fi
|
||||
grep -v '^date=' $PC > $PCT
|
||||
DATE=`date '+%s000'`
|
||||
echo "date=$DATE" >> $PCT
|
||||
mv $PCT $PC
|
||||
mv $PCT $PC || exit 1
|
||||
|
||||
# add our Base64 key
|
||||
grep -v '^key=' $PC > $PCT
|
||||
B64KEY=`cat $B64KEYFILE`
|
||||
echo "key=$B64KEY" >> $PCT || exit 1
|
||||
mv $PCT $PC
|
||||
mv $PCT $PC || exit 1
|
||||
|
||||
# zip it
|
||||
zip -r $OPWD/plugin.zip * -x \*.jar || exit 1
|
||||
zip -r $OPWD/plugin.zip * || exit 1
|
||||
|
||||
# get the version and use it for the sud header
|
||||
VERSION=`grep '^version=' $PC | cut -f 2 -d '='`
|
||||
# get the name and use it for the file name
|
||||
NAME=`grep '^name=' $PC | cut -f 2 -d '='`
|
||||
XPI2P=${NAME}.xpi2p
|
||||
SU3=${NAME}.su3
|
||||
cd $OPWD
|
||||
|
||||
# sign it
|
||||
echo 'Signing. ...'
|
||||
java -cp $I2P/lib/i2p.jar net.i2p.crypto.TrustedUpdate sign plugin.zip $XPI2P $PRIVKEYFILE $VERSION || exit 1
|
||||
java -cp $I2P/lib/i2p.jar net.i2p.crypto.SU3File sign -c PLUGIN -t $KEYTYPE plugin.zip $SU3 $PRIVKEYSTORE $VERSION $SIGNER || exit 1
|
||||
rm -f plugin.zip
|
||||
|
||||
# verify
|
||||
echo 'Verifying. ...'
|
||||
java -cp $I2P/lib/i2p.jar net.i2p.crypto.TrustedUpdate showversion $XPI2P || exit 1
|
||||
java -cp $I2P/lib/i2p.jar -Drouter.trustedUpdateKeys=$B64KEY net.i2p.crypto.TrustedUpdate verifysig $XPI2P || exit 1
|
||||
java -cp $I2P/lib/i2p.jar net.i2p.crypto.SU3File showversion $SU3 || exit 1
|
||||
java -cp $I2P/lib/i2p.jar net.i2p.crypto.SU3File verifysig -k $PUBKEYSTORE $SU3 || exit 1
|
||||
rm -rf logs/
|
||||
|
||||
echo -n 'Plugin created: '
|
||||
echo 'Plugin files created: '
|
||||
wc -c $XPI2P
|
||||
wc -c $SU3
|
||||
|
||||
exit 0
|
||||
|
@ -5,4 +5,9 @@ consoleLinkURL=http://127.0.0.1:7662/tracker/index.jsp
|
||||
description=Open tracker
|
||||
author=zzz
|
||||
updateURL=http://stats.i2p/i2p/plugins/zzzot-update.xpi2p
|
||||
updateURL.su3=http://stats.i2p/i2p/plugins/zzzot-update.su3
|
||||
websiteURL=http://zzz.i2p/forums/16
|
||||
license=Apache 2.0
|
||||
min-jetty-version=7
|
||||
max-jetty-version=8.9999
|
||||
min-i2p-version=0.9.9
|
||||
|
3
scripts/zzzot.config
Normal file
3
scripts/zzzot.config
Normal file
@ -0,0 +1,3 @@
|
||||
# announce interval in seconds
|
||||
# minimum 900 (15 minutes), maximum 21600 (6 hours)
|
||||
interval=1620
|
@ -3,18 +3,18 @@
|
||||
<property name="i2pbase" value="../../i2p.i2p"/>
|
||||
<property name="i2plib" value="${i2pbase}/build"/>
|
||||
<property name="jettylib" value="${i2pbase}/apps/jetty/jettylib"/>
|
||||
<property name="war" value="../plugin/eepsite/webapps/blog"/>
|
||||
<property name="lib" value="${war}/WEB-INF/lib"/>
|
||||
<path id="cp">
|
||||
<pathelement path="${java.class.path}" />
|
||||
<pathelement location="${i2plib}/i2p.jar" />
|
||||
<pathelement location="${i2plib}/i2ptunnel.jar" />
|
||||
<pathelement location="${i2plib}/i2psnark.jar" />
|
||||
<pathelement location="${jettylib}/ant.jar"/>
|
||||
<pathelement location="${i2plib}/mstreaming.jar" />
|
||||
<pathelement location="${ant.home}/lib/ant.jar"/>
|
||||
<pathelement location="${jettylib}/org.mortbay.jetty.jar"/>
|
||||
<pathelement location="${jettylib}/jasper-compiler.jar" />
|
||||
<pathelement location="${jettylib}/jasper-runtime.jar" />
|
||||
<pathelement location="${jettylib}/javax.servlet.jar" />
|
||||
<pathelement location="${jettylib}/jetty-util.jar" />
|
||||
<pathelement location="${jettylib}/jetty-xml.jar" />
|
||||
<pathelement location="${jettylib}/commons-logging.jar" />
|
||||
<pathelement location="${jettylib}/commons-el.jar" />
|
||||
</path>
|
||||
@ -33,7 +33,8 @@
|
||||
srcdir="./java"
|
||||
debug="true" deprecation="on" source="1.5" target="1.5"
|
||||
destdir="./build/obj"
|
||||
classpath="${i2plib}/i2p.jar:${i2plib}/i2ptunnel.jar:${i2plib}/i2psnark.jar:${i2plib}/systray.jar:${i2plib}/org.mortbay.jetty.jar" >
|
||||
includeAntRuntime="false"
|
||||
classpath="${i2plib}/i2p.jar:${i2plib}/i2ptunnel.jar:${i2plib}/i2psnark.jar:${i2plib}/mstreaming.jar:${i2plib}/systray.jar:${jettylib}/org.mortbay.jetty.jar:${jettylib}/jetty-util.jar:${jettylib}/jetty-xml.jar" >
|
||||
<compilerarg line="${javac.compilerargs}" />
|
||||
</javac>
|
||||
</target>
|
||||
@ -69,6 +70,7 @@
|
||||
destdir="build/war/WEB-INF/classes"
|
||||
srcdir="./build/jspjava"
|
||||
includes="**/*.java"
|
||||
includeAntRuntime="false"
|
||||
classpathref="jspcp"
|
||||
failonerror="true" />
|
||||
|
||||
|
@ -16,22 +16,20 @@ package net.i2p.zzzot;
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import net.i2p.data.ByteArray;
|
||||
import net.i2p.data.SimpleDataStructure;
|
||||
|
||||
/**
|
||||
* A 20-byte SHA1 info hash
|
||||
*/
|
||||
public class InfoHash extends ByteArray {
|
||||
public class InfoHash extends SimpleDataStructure {
|
||||
|
||||
public InfoHash(String data) throws UnsupportedEncodingException {
|
||||
this(data.getBytes("ISO-8859-1"));
|
||||
}
|
||||
public static final int LENGTH = 20;
|
||||
|
||||
public InfoHash(byte[] data) {
|
||||
super(data);
|
||||
if (data.length != 20)
|
||||
throw new IllegalArgumentException("Bad infohash length: " + data.length);
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return LENGTH;
|
||||
}
|
||||
}
|
||||
|
@ -16,22 +16,20 @@ package net.i2p.zzzot;
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import net.i2p.data.ByteArray;
|
||||
import net.i2p.data.SimpleDataStructure;
|
||||
|
||||
/**
|
||||
* A 20-byte peer ID
|
||||
*/
|
||||
public class PID extends ByteArray {
|
||||
public class PID extends SimpleDataStructure {
|
||||
|
||||
public PID(String data) throws UnsupportedEncodingException {
|
||||
this(data.getBytes("ISO-8859-1"));
|
||||
}
|
||||
public static final int LENGTH = 20;
|
||||
|
||||
public PID(byte[] data) {
|
||||
super(data);
|
||||
if (data.length != 20)
|
||||
throw new IllegalArgumentException("Bad peer ID length: " + data.length);
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return LENGTH;
|
||||
}
|
||||
}
|
||||
|
@ -1,158 +0,0 @@
|
||||
// ========================================================================
|
||||
// $Id: ForwardHandler.java,v 1.16 2005/08/13 00:01:26 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 net.i2p.zzzot;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mortbay.http.HttpException;
|
||||
import org.mortbay.http.HttpMessage;
|
||||
import org.mortbay.http.HttpRequest;
|
||||
import org.mortbay.http.HttpResponse;
|
||||
import org.mortbay.http.PathMap;
|
||||
import org.mortbay.http.handler.AbstractHttpHandler;
|
||||
import org.mortbay.util.URI;
|
||||
import org.mortbay.util.UrlEncoded;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Forward Request Handler.
|
||||
* Forwards a request to a new URI. Experimental - use with caution.
|
||||
* @version $Revision: 1.16 $
|
||||
* @author Greg Wilkins (gregw)
|
||||
*
|
||||
* Just like ForwardHandler but forwards query parameters too
|
||||
* And took out the dependency on apache logging
|
||||
* @author zzz
|
||||
*/
|
||||
public class QForwardHandler extends AbstractHttpHandler
|
||||
{
|
||||
PathMap _forward = new PathMap();
|
||||
String _root;
|
||||
boolean _handleQueries = false;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
*/
|
||||
public QForwardHandler()
|
||||
{}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param rootForward
|
||||
*/
|
||||
public QForwardHandler(String rootForward)
|
||||
{
|
||||
_root=rootForward;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add a forward mapping.
|
||||
* @param pathSpecInContext The path to forward from
|
||||
* @param newPath The path to forward to.
|
||||
*/
|
||||
public void addForward(String pathSpecInContext,
|
||||
String newPath)
|
||||
{
|
||||
_forward.put(pathSpecInContext,newPath);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add a forward mapping for root path.
|
||||
* This allows a forward for exactly / which is the default
|
||||
* path in a pathSpec.
|
||||
* @param newPath The path to forward to.
|
||||
*/
|
||||
public void setRootForward(String newPath)
|
||||
{
|
||||
_root=newPath;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the Handler up to cope with forwards to paths that contain query
|
||||
* elements (e.g. "/blah"->"/foo?a=b").
|
||||
* AND (I2P) pass params through (e.g. "/blah?c=d? -> "/foo?c=d? ).
|
||||
* @param b
|
||||
*/
|
||||
public void setHandleQueries(boolean b)
|
||||
{
|
||||
_handleQueries = b;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void handle(String pathInContext,
|
||||
String pathParams,
|
||||
HttpRequest request,
|
||||
HttpResponse response)
|
||||
throws HttpException, IOException
|
||||
{
|
||||
String newPath=null;
|
||||
String query=null;
|
||||
if (_root!=null && ("/".equals(pathInContext) || pathInContext.startsWith("/;")))
|
||||
newPath=_root;
|
||||
else
|
||||
{
|
||||
Map.Entry entry = _forward.getMatch(pathInContext);
|
||||
if (entry!=null)
|
||||
{
|
||||
String match = (String)entry.getValue();
|
||||
if (_handleQueries)
|
||||
{
|
||||
int hook = match.indexOf('?');
|
||||
if (hook != -1){
|
||||
query = match.substring(hook+1);
|
||||
match = match.substring(0, hook);
|
||||
}
|
||||
}
|
||||
String info=PathMap.pathInfo((String)entry.getKey(),pathInContext);
|
||||
newPath=info==null?match:(URI.addPaths(match,info));
|
||||
}
|
||||
}
|
||||
|
||||
if (newPath!=null)
|
||||
{
|
||||
// this is the new part for i2p
|
||||
// setPath() changes the request URI and loses the parameters
|
||||
// so save them and add them back
|
||||
Map saved = null;
|
||||
if (_handleQueries){
|
||||
request.setCharacterEncoding("ISO-8859-1", false);
|
||||
saved = request.getParameters();
|
||||
}
|
||||
|
||||
int last=request.setState(HttpMessage.__MSG_EDITABLE);
|
||||
String context=getHttpContext().getContextPath();
|
||||
if (context.length()==1)
|
||||
request.setPath(newPath);
|
||||
else
|
||||
request.setPath(URI.addPaths(context,newPath));
|
||||
if (_handleQueries && query != null){
|
||||
// add forwarded to query string to parameters
|
||||
UrlEncoded.decodeTo(query, request.getParameters());
|
||||
}
|
||||
|
||||
// this is the new part for i2p
|
||||
if (_handleQueries){
|
||||
// add them back
|
||||
request.getParameters().putAll(saved);
|
||||
}
|
||||
|
||||
request.setState(last);
|
||||
getHttpContext().getHttpServer().service(request,response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
60
src/java/net/i2p/zzzot/SeedlessAnnouncer.java
Normal file
60
src/java/net/i2p/zzzot/SeedlessAnnouncer.java
Normal file
@ -0,0 +1,60 @@
|
||||
package net.i2p.zzzot;
|
||||
/*
|
||||
* Copyright 2010 zzz (zzz@mail.i2p)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.streaming.I2PSocketEepGet;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.i2ptunnel.TunnelController;
|
||||
import net.i2p.util.EepGet;
|
||||
|
||||
/**
|
||||
* Announce to seedless
|
||||
* @since 0.6
|
||||
*/
|
||||
public class SeedlessAnnouncer {
|
||||
|
||||
private static final String SPONGE =
|
||||
"VG4Bd~q1RA3BdoF3z5fSR7p0xe1CTVgDMWVGyFchA9Wm2iXUkIR35G45XE31Uc9~IOt-ktNLL2~TYQZ13Vl8udosngDn8RJG1NtVASH4khsbgkkoFLWd6UuvuOjQKBFKjaEPJgxOzh0kxolRPPNHhFuuAGzNLKvz~LI2MTf0P6nwmRg1lBoRIUpSVocEHY4X306nT2VtY07FixbJcPCU~EeRin24yNoiZop-C3Wi1SGwJJK-NS7mnkNzd8ngDJXDJtR-wLP1vNyyBY6NySgqPiIhENHoVeXd5krlR42HORCxEDb4jhoqlbyJq-PrhTJ5HdH4-~gEq09B~~NIHzy7X02XgmBXhTYRtl6HbLMXs6SI5fq9OFgVp5YZWYUklJjMDI7jOrGrEZGSHhnJK9kT6D3CqVIM0cYEhe4ttmTegbZvC~J6DrRTIAX422qRQJBPsTUnv4iFyuJE-8SodP6ikTjRH21Qx73SxqOvmrOiu7Bsp0lvVDa84aoaYLdiGv87AAAA";
|
||||
|
||||
private static final String ANNOUNCE = "announce " + Base64.encode("seedless,eepsite,torrent");
|
||||
|
||||
public void announce(TunnelController controller) {
|
||||
// get the I2PTunnel from the controller (no method now)
|
||||
|
||||
// get the I2PTunnelTask from I2PTunnel
|
||||
|
||||
// cast to an I2PTunnelServer
|
||||
|
||||
// get the SocketManager from the server (no method now)
|
||||
I2PSocketManager mgr = null;
|
||||
|
||||
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||
String url = "http://" + SPONGE + "/Seedless/seedless";
|
||||
EepGet get = new I2PSocketEepGet(ctx, mgr, 1, -1, 1024, null, new DummyOutputStream(), url);
|
||||
get.addHeader("X-Seedless", ANNOUNCE);
|
||||
get.fetch();
|
||||
}
|
||||
|
||||
private static class DummyOutputStream extends OutputStream {
|
||||
public void write(int b) {}
|
||||
}
|
||||
}
|
@ -18,13 +18,30 @@ package net.i2p.zzzot;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import net.i2p.CoreVersion;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.SDSCache;
|
||||
import net.i2p.util.VersionComparator;
|
||||
|
||||
|
||||
/**
|
||||
* All the torrents
|
||||
*/
|
||||
public class Torrents extends ConcurrentHashMap<InfoHash, Peers> {
|
||||
|
||||
public Torrents() {
|
||||
private static final int CACHE_SIZE = 2048;
|
||||
private final SDSCache<InfoHash> _hashCache;
|
||||
private final SDSCache<PID> _pidCache;
|
||||
private final Integer _interval;
|
||||
|
||||
/**
|
||||
* @param interval in seconds
|
||||
*/
|
||||
public Torrents(int interval) {
|
||||
super();
|
||||
_hashCache = new SDSCache<InfoHash>(InfoHash.class, InfoHash.LENGTH, CACHE_SIZE);
|
||||
_pidCache = new SDSCache<PID>(PID.class, PID.LENGTH, CACHE_SIZE);
|
||||
_interval = Integer.valueOf(interval);
|
||||
}
|
||||
|
||||
public int countPeers() {
|
||||
@ -34,4 +51,60 @@ public class Torrents extends ConcurrentHashMap<InfoHash, Peers> {
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return in seconds
|
||||
* @since 0.12.0
|
||||
*/
|
||||
public Integer getInterval() {
|
||||
return _interval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull from cache or return new
|
||||
*
|
||||
* @throws IllegalArgumentException if data is not the correct number of bytes
|
||||
* @since 0.12.0
|
||||
*/
|
||||
public InfoHash createInfoHash(String data) throws IllegalArgumentException {
|
||||
byte[] d = DataHelper.getASCII(data);
|
||||
if (d.length != InfoHash.LENGTH)
|
||||
throw new IllegalArgumentException("bad infohash length " + d.length);
|
||||
return _hashCache.get(d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull from cache or return new
|
||||
*
|
||||
* @throws IllegalArgumentException if data is not the correct number of bytes
|
||||
* @since 0.12.0
|
||||
*/
|
||||
public PID createPID(String data) throws IllegalArgumentException {
|
||||
byte[] d = DataHelper.getASCII(data);
|
||||
if (d.length != PID.LENGTH)
|
||||
throw new IllegalArgumentException("bad peer id length " + d.length);
|
||||
return _pidCache.get(d);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.12.0
|
||||
*/
|
||||
@Override
|
||||
public void clear() {
|
||||
super.clear();
|
||||
clearCaches();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.12.0
|
||||
*/
|
||||
private void clearCaches() {
|
||||
// not available until 0.9.17
|
||||
if (VersionComparator.comp(CoreVersion.VERSION, "0.9.17") >= 0) {
|
||||
try {
|
||||
_hashCache.clear();
|
||||
_pidCache.clear();
|
||||
} catch (Throwable t) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,34 +17,62 @@ package net.i2p.zzzot;
|
||||
*/
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.util.SimpleScheduler;
|
||||
import net.i2p.util.SimpleTimer;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.SimpleTimer2;
|
||||
|
||||
/**
|
||||
* Instantiate this to fire it up
|
||||
*/
|
||||
class ZzzOT {
|
||||
|
||||
private Torrents _torrents;
|
||||
private static final long CLEAN_TIME = 4*60*1000;
|
||||
private static final long EXPIRE_TIME = 60*60*1000;
|
||||
private final Torrents _torrents;
|
||||
private final Cleaner _cleaner;
|
||||
private final long EXPIRE_TIME;
|
||||
|
||||
ZzzOT() {
|
||||
_torrents = new Torrents();
|
||||
SimpleScheduler.getInstance().addPeriodicEvent(new Cleaner(), CLEAN_TIME);
|
||||
private static final String PROP_INTERVAL = "interval";
|
||||
private static final long CLEAN_TIME = 4*60*1000;
|
||||
private static final int DEFAULT_INTERVAL = 27*60;
|
||||
private static final int MIN_INTERVAL = 15*60;
|
||||
private static final int MAX_INTERVAL = 6*60*60;
|
||||
|
||||
ZzzOT(I2PAppContext ctx, Properties p) {
|
||||
String intv = p.getProperty(PROP_INTERVAL);
|
||||
int interval = DEFAULT_INTERVAL;
|
||||
if (intv != null) {
|
||||
try {
|
||||
interval = Integer.parseInt(intv);
|
||||
if (interval < MIN_INTERVAL)
|
||||
interval = MIN_INTERVAL;
|
||||
else if (interval > MAX_INTERVAL)
|
||||
interval = MAX_INTERVAL;
|
||||
} catch (NumberFormatException nfe) {}
|
||||
}
|
||||
_torrents = new Torrents(interval);
|
||||
EXPIRE_TIME = 1000 * (interval + interval / 2);
|
||||
_cleaner = new Cleaner(ctx);
|
||||
}
|
||||
|
||||
Torrents getTorrents() {
|
||||
return _torrents;
|
||||
}
|
||||
|
||||
void stop() {
|
||||
_torrents.clear();
|
||||
// no way to stop the cleaner
|
||||
void start() {
|
||||
_cleaner.forceReschedule(CLEAN_TIME);
|
||||
}
|
||||
|
||||
private class Cleaner implements SimpleTimer.TimedEvent {
|
||||
void stop() {
|
||||
_cleaner.cancel();
|
||||
_torrents.clear();
|
||||
}
|
||||
|
||||
private class Cleaner extends SimpleTimer2.TimedEvent {
|
||||
|
||||
/** must schedule later */
|
||||
public Cleaner(I2PAppContext ctx) {
|
||||
super(ctx.simpleTimer2());
|
||||
}
|
||||
|
||||
public void timeReached() {
|
||||
long now = System.currentTimeMillis();
|
||||
@ -61,6 +89,7 @@ class ZzzOT {
|
||||
if (recent <= 0)
|
||||
iter.remove();
|
||||
}
|
||||
schedule(CLEAN_TIME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,19 +22,26 @@ import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.CoreVersion;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.app.ClientApp;
|
||||
import net.i2p.app.ClientAppManager;
|
||||
import net.i2p.app.ClientAppState;
|
||||
import static net.i2p.app.ClientAppState.*;
|
||||
import net.i2p.apps.systray.UrlLauncher;
|
||||
import net.i2p.data.Base32;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.PrivateKeyFile;
|
||||
import net.i2p.i2ptunnel.TunnelController;
|
||||
import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.i2ptunnel.TunnelController;
|
||||
import net.i2p.apps.systray.UrlLauncher;
|
||||
import net.i2p.util.VersionComparator;
|
||||
|
||||
import org.mortbay.http.HttpContext;
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
|
||||
/**
|
||||
* This handles the starting and stopping of an eepsite tunnel and jetty
|
||||
@ -47,34 +54,77 @@ import org.mortbay.jetty.Server;
|
||||
*
|
||||
* @author zzz
|
||||
*/
|
||||
public class ZzzOTController {
|
||||
private static final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(ZzzOTController.class);
|
||||
private static Server _server;
|
||||
private static TunnelController _tunnel;
|
||||
private static ZzzOT _zzzot;
|
||||
private static Object _lock = new Object();
|
||||
public class ZzzOTController implements ClientApp {
|
||||
private final I2PAppContext _context;
|
||||
private final Log _log;
|
||||
private final String[] _args;
|
||||
private final ClientAppManager _mgr;
|
||||
private Server _server;
|
||||
private TunnelController _tunnel;
|
||||
private final ZzzOT _zzzot;
|
||||
/** only for main() */
|
||||
private static volatile ZzzOTController _controller;
|
||||
|
||||
public static void main(String args[]) {
|
||||
if (args.length != 3 || (!"-d".equals(args[0])))
|
||||
throw new IllegalArgumentException("Usage: PluginController -d $PLUGIN [start|stop]");
|
||||
if ("start".equals(args[2]))
|
||||
start(args);
|
||||
else if ("stop".equals(args[2]))
|
||||
stop();
|
||||
else
|
||||
throw new IllegalArgumentException("Usage: PluginController -d $PLUGIN [start|stop]");
|
||||
}
|
||||
private ClientAppState _state = UNINITIALIZED;
|
||||
|
||||
public static Torrents getTorrents() {
|
||||
synchronized(_lock) {
|
||||
if (_zzzot == null)
|
||||
_zzzot = new ZzzOT();
|
||||
private static final String NAME = "ZzzOT";
|
||||
private static final String CONFIG_FILE = "zzzot.config";
|
||||
private static final String BACKUP_SUFFIX = ".jetty6";
|
||||
private static final String[] xmlFiles = {
|
||||
"jetty.xml", "contexts/base-context.xml", "contexts/cgi-context.xml",
|
||||
"etc/realm.properties", "etc/webdefault.xml" };
|
||||
|
||||
/**
|
||||
* @since 0.12.0
|
||||
*/
|
||||
public ZzzOTController(I2PAppContext ctx, ClientAppManager mgr, String args[]) {
|
||||
_context = ctx;
|
||||
_log = ctx.logManager().getLog(ZzzOTController.class);
|
||||
_mgr = mgr;
|
||||
_args = args;
|
||||
File cfile = new File(_context.getAppDir(), "plugins/zzzot/" + CONFIG_FILE);
|
||||
Properties props = new Properties();
|
||||
if (cfile.exists()) {
|
||||
try {
|
||||
DataHelper.loadProps(props, cfile);
|
||||
} catch (IOException ioe) {
|
||||
_log.error("Failed loading zzzot config from " + cfile, ioe);
|
||||
}
|
||||
} else {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("No config file " + cfile);
|
||||
}
|
||||
return _zzzot.getTorrents();
|
||||
_zzzot = new ZzzOT(ctx, props);
|
||||
_state = INITIALIZED;
|
||||
}
|
||||
|
||||
private static void start(String args[]) {
|
||||
File pluginDir = new File(args[1]);
|
||||
/**
|
||||
* No longer supported, as we now need the ClientAppManager for the webapp to find us
|
||||
*/
|
||||
public synchronized static void main(String args[]) {
|
||||
throw new UnsupportedOperationException("Must use ClientApp interface");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null if not running
|
||||
*/
|
||||
public static Torrents getTorrents() {
|
||||
ClientAppManager mgr = I2PAppContext.getGlobalContext().clientAppManager();
|
||||
if (mgr == null)
|
||||
return null;
|
||||
ClientApp z = mgr.getRegisteredApp(NAME);
|
||||
if (z == null)
|
||||
return null;
|
||||
ZzzOTController ctrlr = (ZzzOTController) z;
|
||||
return ctrlr._zzzot.getTorrents();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param args ignored
|
||||
*/
|
||||
private void start(String args[]) {
|
||||
//File pluginDir = new File(args[1]);
|
||||
File pluginDir = new File(_context.getAppDir(), "plugins/zzzot");
|
||||
if (!pluginDir.exists())
|
||||
throw new IllegalArgumentException("Plugin directory " + pluginDir.getAbsolutePath() + " does not exist");
|
||||
|
||||
@ -91,19 +141,21 @@ public class ZzzOTController {
|
||||
_log.error("Unable to create " + key.getAbsolutePath() + ' ' + e);
|
||||
throw new IllegalArgumentException("Unable to create " + key.getAbsolutePath() + ' ' + e);
|
||||
}
|
||||
_log.error("NOTICE: ZzzOT: New eepsite keys created in " + key.getAbsolutePath());
|
||||
_log.error("NOTICE: ZzzOT: You should back up this file!");
|
||||
_log.logAlways(Log.INFO, "NOTICE: ZzzOT: New eepsite keys created in " + key.getAbsolutePath());
|
||||
_log.logAlways(Log.INFO, "NOTICE: ZzzOT: You should back up this file!");
|
||||
String b32 = Base32.encode(dest.calculateHash().getData()) + ".b32.i2p";
|
||||
String b64 = dest.toBase64();
|
||||
_log.error("NOTICE: ZzzOT: Your base 32 address is " + b32);
|
||||
_log.error("NOTICE: ZzzOT: Your base 64 address is " + b64);
|
||||
_log.logAlways(Log.INFO, "NOTICE: ZzzOT: Your base 32 address is " + b32);
|
||||
_log.logAlways(Log.INFO, "NOTICE: ZzzOT: Your base 64 address is " + b64);
|
||||
}
|
||||
startJetty(pluginDir, dest);
|
||||
startI2PTunnel(pluginDir, dest);
|
||||
_zzzot.start();
|
||||
// SeedlessAnnouncer.announce(_tunnel);
|
||||
}
|
||||
|
||||
|
||||
private static void startI2PTunnel(File pluginDir, Destination dest) {
|
||||
private void startI2PTunnel(File pluginDir, Destination dest) {
|
||||
File i2ptunnelConfig = new File(pluginDir, "i2ptunnel.config");
|
||||
Properties i2ptunnelProps = new Properties();
|
||||
try {
|
||||
@ -125,19 +177,20 @@ public class ZzzOTController {
|
||||
_tunnel = tun;
|
||||
}
|
||||
|
||||
private static void startJetty(File pluginDir, Destination dest) {
|
||||
private void startJetty(File pluginDir, Destination dest) {
|
||||
if (_server != null)
|
||||
throw new IllegalArgumentException("Jetty already running!");
|
||||
migrateJettyXML(pluginDir);
|
||||
I2PAppContext context = I2PAppContext.getGlobalContext();
|
||||
File tmpdir = new File(context.getTempDir().getAbsolutePath(), "/zzzot-work");
|
||||
File tmpdir = new File(_context.getTempDir().getAbsolutePath(), "/zzzot-work");
|
||||
tmpdir.mkdir();
|
||||
File jettyXml = new File(pluginDir, "jetty.xml");
|
||||
try {
|
||||
Server serv = new Server(jettyXml.getAbsolutePath());
|
||||
HttpContext[] hcs = serv.getContexts();
|
||||
for (int i = 0; i < hcs.length; i++)
|
||||
hcs[i].setTempDirectory(tmpdir);
|
||||
Resource.setDefaultUseCaches(false);
|
||||
XmlConfiguration xmlc = new XmlConfiguration(jettyXml.toURI().toURL());
|
||||
Server serv = (Server) xmlc.configure();
|
||||
//HttpContext[] hcs = serv.getContexts();
|
||||
//for (int i = 0; i < hcs.length; i++)
|
||||
// hcs[i].setTempDirectory(tmpdir);
|
||||
serv.start();
|
||||
_server = serv;
|
||||
} catch (Throwable t) {
|
||||
@ -148,18 +201,29 @@ public class ZzzOTController {
|
||||
launchHelp(pluginDir, dest);
|
||||
}
|
||||
|
||||
private static void stop() {
|
||||
private void stop() {
|
||||
stopI2PTunnel();
|
||||
stopJetty();
|
||||
if (_zzzot != null)
|
||||
_zzzot.stop();
|
||||
_zzzot.stop();
|
||||
}
|
||||
|
||||
private static void stopI2PTunnel() {
|
||||
private void stopI2PTunnel() {
|
||||
if (_tunnel == null)
|
||||
return;
|
||||
try {
|
||||
_tunnel.stopTunnel();
|
||||
// destroyTunnel() not available until 0.9.17, but we put 0.9.16 here for now
|
||||
// so we get testing in 0.9.16-6 or later dev builds.
|
||||
// No access to RouterVersion here.
|
||||
// TODO change to 0.9.17
|
||||
if (VersionComparator.comp(CoreVersion.VERSION, "0.9.16") >= 0) {
|
||||
try {
|
||||
_tunnel.destroyTunnel();
|
||||
} catch (Throwable t) {
|
||||
_tunnel.stopTunnel();
|
||||
}
|
||||
} else {
|
||||
_tunnel.stopTunnel();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
_log.error("ZzzOT tunnel stop failed", t);
|
||||
throw new IllegalArgumentException("Tunnel stop failed " + t);
|
||||
@ -167,7 +231,7 @@ public class ZzzOTController {
|
||||
_tunnel = null;
|
||||
}
|
||||
|
||||
private static void stopJetty() {
|
||||
private void stopJetty() {
|
||||
if (_server == null)
|
||||
return;
|
||||
try {
|
||||
@ -179,27 +243,92 @@ public class ZzzOTController {
|
||||
_server = null;
|
||||
}
|
||||
|
||||
/** put the directory in the jetty.xml file */
|
||||
private static void migrateJettyXML(File pluginDir) {
|
||||
File outFile = new File(pluginDir, "jetty.xml");
|
||||
if (outFile.exists())
|
||||
/**
|
||||
* Migate the jetty configuration files.
|
||||
* Save old jetty.xml if moving from jetty 5 to jetty 6
|
||||
*/
|
||||
private void migrateJettyXML(File pluginDir) {
|
||||
// contexts dir does not exist in Jetty 5
|
||||
File file = new File(pluginDir, "contexts");
|
||||
file.mkdir();
|
||||
file = new File(pluginDir, "etc");
|
||||
file.mkdir();
|
||||
file = new File(pluginDir, "jetty.xml");
|
||||
if (!shouldMigrate(file))
|
||||
return;
|
||||
File fileTmpl = new File(pluginDir, "templates/jetty.xml");
|
||||
for (int i = 0; i < xmlFiles.length; i++) {
|
||||
backupAndMigrateFile(pluginDir, xmlFiles[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return should we copy over all the files, based on the contents of this one
|
||||
* @since 0.10 (Jetty 7)
|
||||
*/
|
||||
private static boolean shouldMigrate(File f) {
|
||||
String xml = FileUtil.readTextFile(f.getAbsolutePath(), 100, true);
|
||||
if (xml == null)
|
||||
return true;
|
||||
return xml.contains("class=\"org.mortbay.jetty.Server\"");
|
||||
}
|
||||
|
||||
/**
|
||||
* Backup a file and migrate new XML
|
||||
* @return success
|
||||
* @since Jetty 7
|
||||
*/
|
||||
private boolean backupAndMigrateFile(File toDir, String filename) {
|
||||
File to = new File(toDir, filename);
|
||||
boolean rv = backupFile(to);
|
||||
boolean rv2 = migrateJettyFile(toDir, filename);
|
||||
return rv && rv2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backup a file
|
||||
* @return success
|
||||
* @since Jetty 7
|
||||
*/
|
||||
private static boolean backupFile(File from) {
|
||||
if (!from.exists())
|
||||
return true;
|
||||
File to = new File(from.getAbsolutePath() + BACKUP_SUFFIX);
|
||||
if (to.exists())
|
||||
to = new File(to.getAbsolutePath() + "." + System.currentTimeMillis());
|
||||
boolean rv = FileUtil.copy(from, to, false, true);
|
||||
if (rv)
|
||||
System.err.println("Backed up file " + from + " to " + to);
|
||||
else
|
||||
System.err.println("WARNING: Failed to back up file " + from + " to " + to);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migate a single jetty config file, replacing $PLUGIN as we copy it.
|
||||
*/
|
||||
private boolean migrateJettyFile(File pluginDir, String name) {
|
||||
File templateDir = new File(pluginDir, "templates");
|
||||
File fileTmpl = new File(templateDir, name);
|
||||
File outFile = new File(pluginDir, name);
|
||||
FileOutputStream os = null;
|
||||
try {
|
||||
String props = FileUtil.readTextFile(fileTmpl.getAbsolutePath(), 250, true);
|
||||
String props = FileUtil.readTextFile(fileTmpl.getAbsolutePath(), 600, true);
|
||||
if (props == null)
|
||||
throw new IOException(fileTmpl.getAbsolutePath() + " open failed");
|
||||
props = props.replace("$PLUGIN", pluginDir.getAbsolutePath());
|
||||
FileOutputStream os = new FileOutputStream(outFile);
|
||||
os = new FileOutputStream(outFile);
|
||||
os.write(props.getBytes("UTF-8"));
|
||||
os.close();
|
||||
return true;
|
||||
} catch (IOException ioe) {
|
||||
_log.error("jetty.xml migrate failed", ioe);
|
||||
_log.error(outFile + " migrate failed", ioe);
|
||||
return false;
|
||||
} finally {
|
||||
if (os != null) try { os.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
/** put the directory, base32, and base64 info in the help.html file and launch a browser window to display it */
|
||||
private static void launchHelp(File pluginDir, Destination dest) {
|
||||
private void launchHelp(File pluginDir, Destination dest) {
|
||||
File fileTmpl = new File(pluginDir, "templates/help.html");
|
||||
File outFile = new File(pluginDir, "eepsite/docroot/help.html");
|
||||
String b32 = Base32.encode(dest.calculateHash().getData()) + ".b32.i2p";
|
||||
@ -226,4 +355,83 @@ public class ZzzOTController {
|
||||
UrlLauncher.main(new String[] { "http://127.0.0.1:7662/help.html" } );
|
||||
}
|
||||
}
|
||||
|
||||
/////// ClientApp methods
|
||||
|
||||
/** @since 0.12.0 */
|
||||
public synchronized void startup() {
|
||||
if (_mgr != null) {
|
||||
// this is really ugly, but thru 0.9.16,
|
||||
// stopping a ClientApp plugin with $PLUGIN in the args fails,
|
||||
// and it tries to start a second one instead.
|
||||
// Find the first one and stop it.
|
||||
ClientApp z = _mgr.getRegisteredApp(NAME);
|
||||
if (z != null) {
|
||||
if (VersionComparator.comp(CoreVersion.VERSION, "0.9.17") < 0) {
|
||||
ZzzOTController ctrlr = (ZzzOTController) z;
|
||||
_log.warn("Got start when another zzzot running, stopping him instead");
|
||||
ctrlr.shutdown(null);
|
||||
} else {
|
||||
_log.error("ZzzOT already running");
|
||||
}
|
||||
changeState(START_FAILED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_state != STOPPED && _state != INITIALIZED && _state != START_FAILED) {
|
||||
_log.error("Start while state = " + _state);
|
||||
return;
|
||||
}
|
||||
changeState(STARTING);
|
||||
try {
|
||||
start(_args);
|
||||
changeState(RUNNING);
|
||||
if (_mgr != null)
|
||||
_mgr.register(this);
|
||||
} catch (Exception e) {
|
||||
changeState(START_FAILED, "Start failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 0.12.0 */
|
||||
public synchronized void shutdown(String[] args) {
|
||||
if (_state == STOPPED)
|
||||
return;
|
||||
changeState(STOPPING);
|
||||
if (_mgr != null)
|
||||
_mgr.unregister(this);
|
||||
stop();
|
||||
changeState(STOPPED);
|
||||
}
|
||||
|
||||
/** @since 0.12.0 */
|
||||
public ClientAppState getState() {
|
||||
return _state;
|
||||
}
|
||||
|
||||
/** @since 0.12.0 */
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
/** @since 0.12.0 */
|
||||
public String getDisplayName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
/////// end ClientApp methods
|
||||
|
||||
/** @since 0.12.0 */
|
||||
private synchronized void changeState(ClientAppState state) {
|
||||
_state = state;
|
||||
if (_mgr != null)
|
||||
_mgr.notify(this, state, null, null);
|
||||
}
|
||||
|
||||
/** @since 0.12.0 */
|
||||
private synchronized void changeState(ClientAppState state, String msg, Exception e) {
|
||||
_state = state;
|
||||
if (_mgr != null)
|
||||
_mgr.notify(this, state, msg, e);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<%@page import="java.util.ArrayList" %><%@page import="java.util.Collections" %><%@page import="java.util.List" %><%@page import="java.util.Map" %><%@page import="java.util.HashMap" %><%@page import="net.i2p.data.Base64" %><%@page import="net.i2p.data.Destination" %><%@page import="net.i2p.zzzot.*" %><%@page import="org.klomp.snark.bencode.BEncoder" %><%
|
||||
<%@page import="java.io.ByteArrayInputStream,java.util.ArrayList,java.util.Collections,java.util.List,java.util.Map,java.util.HashMap,net.i2p.data.Base64,net.i2p.data.Destination,net.i2p.zzzot.*,org.klomp.snark.bencode.BEncoder" %><%
|
||||
|
||||
/*
|
||||
* Above one-liner is so there is no whitespace -> IllegalStateException
|
||||
@ -27,12 +27,15 @@
|
||||
*/
|
||||
// would be nice to make these configurable
|
||||
final int MAX_RESPONSES = 25;
|
||||
final int INTERVAL = 27*60;
|
||||
final boolean ALLOW_IP_MISMATCH = false;
|
||||
final boolean ALLOW_COMPACT_RESPONSE = true;
|
||||
|
||||
// so the chars will turn into bytes correctly
|
||||
request.setCharacterEncoding("ISO-8859-1");
|
||||
// above doesn't work for the query string
|
||||
// https://wiki.eclipse.org/Jetty/Howto/International_Characters
|
||||
// we could also do ((org.eclipse.jetty.server.Request) request).setQueryEncoding("ISO-8859-1")
|
||||
request.setAttribute("org.eclipse.jetty.server.Request.queryEncoding", "ISO-8859-1");
|
||||
java.io.OutputStream cout = response.getOutputStream();
|
||||
response.setCharacterEncoding("ISO-8859-1");
|
||||
response.setContentType("text/plain");
|
||||
@ -69,6 +72,11 @@
|
||||
msg = "no info hash";
|
||||
}
|
||||
|
||||
if (info_hash.length() != 20 && !fail) {
|
||||
fail = true;
|
||||
msg = "bad info hash length " + info_hash.length();
|
||||
}
|
||||
|
||||
if (ip == null && !fail) {
|
||||
fail = true;
|
||||
msg = "no ip (dest)";
|
||||
@ -79,11 +87,22 @@
|
||||
msg = "no peer id";
|
||||
}
|
||||
|
||||
if (peer_id.length() != 20 && !fail) {
|
||||
fail = true;
|
||||
msg = "bad peer id length " + peer_id.length();
|
||||
}
|
||||
|
||||
Torrents torrents = ZzzOTController.getTorrents();
|
||||
if (torrents == null && !fail) {
|
||||
fail = true;
|
||||
msg = "tracker is down";
|
||||
}
|
||||
|
||||
InfoHash ih = null;
|
||||
if (!fail) {
|
||||
try {
|
||||
ih = new InfoHash(info_hash);
|
||||
} catch (Exception e) {
|
||||
ih = torrents.createInfoHash(info_hash);
|
||||
} catch (IllegalArgumentException e) {
|
||||
fail = true;
|
||||
msg = "bad infohash " + e;
|
||||
}
|
||||
@ -94,7 +113,10 @@
|
||||
try {
|
||||
if (ip.endsWith(".i2p"))
|
||||
ip = ip.substring(0, ip.length() - 4);
|
||||
d = new Destination(ip); // from b64 string
|
||||
byte[] b = Base64.decode(ip);
|
||||
if (b == null)
|
||||
throw new Exception();
|
||||
d = Destination.create(new ByteArrayInputStream(b)); // cache
|
||||
} catch (Exception e) {
|
||||
fail = true;
|
||||
msg = "bad dest " + e;
|
||||
@ -104,8 +126,8 @@
|
||||
PID pid = null;
|
||||
if (!fail) {
|
||||
try {
|
||||
pid = new PID(peer_id);
|
||||
} catch (Exception e) {
|
||||
pid = torrents.createPID(peer_id);
|
||||
} catch (IllegalArgumentException e) {
|
||||
fail = true;
|
||||
msg = "bad peer id " + e;
|
||||
}
|
||||
@ -155,15 +177,14 @@
|
||||
} catch (NumberFormatException nfe) {};
|
||||
}
|
||||
|
||||
Torrents torrents = ZzzOTController.getTorrents();
|
||||
Map<String, Object> m = new HashMap();
|
||||
Map<String, Object> m = new HashMap(8);
|
||||
if (fail) {
|
||||
m.put("failure reason", msg);
|
||||
} else if ("stopped".equals(event)) {
|
||||
Peers peers = torrents.get(ih);
|
||||
if (matchIP && peers != null)
|
||||
peers.remove(pid);
|
||||
m.put("interval", Integer.valueOf(INTERVAL));
|
||||
m.put("interval", torrents.getInterval());
|
||||
} else {
|
||||
Peers peers = torrents.get(ih);
|
||||
if (peers == null) {
|
||||
@ -188,7 +209,7 @@
|
||||
if (matchIP)
|
||||
p.setLeft(left);
|
||||
|
||||
m.put("interval", Integer.valueOf(INTERVAL));
|
||||
m.put("interval", torrents.getInterval());
|
||||
int size = peers.size();
|
||||
int seeds = peers.countSeeds();
|
||||
m.put("complete", Integer.valueOf(seeds));
|
||||
@ -204,10 +225,15 @@
|
||||
peerlist = peerlist.subList(0, want);
|
||||
}
|
||||
if (compact) {
|
||||
List<String> peerhashes = new ArrayList(peerlist.size());
|
||||
for (Peer pe : peerlist) {
|
||||
peerhashes.add(pe.getHash());
|
||||
}
|
||||
// old experimental way - list of hashes
|
||||
//List<String> peerhashes = new ArrayList(peerlist.size());
|
||||
//for (Peer pe : peerlist) {
|
||||
// peerhashes.add(pe.getHash());
|
||||
//}
|
||||
// new way - one big string
|
||||
byte[] peerhashes = new byte[32 * peerlist.size()];
|
||||
for (int i = 0; i < peerlist.size(); i++)
|
||||
System.arraycopy(peerlist.get(i).getHash().getBytes("ISO-8859-1"), 0, peerhashes, i * 32, 32);
|
||||
m.put("peers", peerhashes);
|
||||
} else {
|
||||
m.put("peers", peerlist);
|
||||
|
@ -1,4 +1,4 @@
|
||||
<%@page import="net.i2p.zzzot.ZzzOTController" %>
|
||||
<%@page import="net.i2p.zzzot.ZzzOTController,net.i2p.zzzot.Torrents" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>ZzzOT</title>
|
||||
@ -6,9 +6,20 @@
|
||||
<p>
|
||||
zzzot
|
||||
<p>
|
||||
<%
|
||||
Torrents torrents = ZzzOTController.getTorrents();
|
||||
if (torrents != null) {
|
||||
%>
|
||||
<table cellspacing="8">
|
||||
<tr><td>Torrents:<td align="right"><%=ZzzOTController.getTorrents().size()%>
|
||||
<tr><td>Peers:<td align="right"><%=ZzzOTController.getTorrents().countPeers()%>
|
||||
<tr><td>Torrents:<td align="right"><%=torrents.size()%>
|
||||
<tr><td>Peers:<td align="right"><%=torrents.countPeers()%>
|
||||
</table>
|
||||
<%
|
||||
} else {
|
||||
%>
|
||||
ZzzOT is not running
|
||||
<%
|
||||
}
|
||||
%>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<%@page import="java.util.ArrayList" %><%@page import="java.util.List" %><%@page import="java.util.Map" %><%@page import="java.util.HashMap" %><%@page import="net.i2p.zzzot.*" %><%@page import="org.klomp.snark.bencode.BEncoder" %><%
|
||||
<%@page import="java.util.ArrayList,java.util.List,java.util.Map,java.util.HashMap,net.i2p.zzzot.*,org.klomp.snark.bencode.BEncoder" %><%
|
||||
|
||||
/*
|
||||
* Above one-liner is so there is no whitespace -> IllegalStateException
|
||||
@ -27,6 +27,10 @@
|
||||
*/
|
||||
// so the chars will turn into bytes correctly
|
||||
request.setCharacterEncoding("ISO-8859-1");
|
||||
// above doesn't work for the query string
|
||||
// https://wiki.eclipse.org/Jetty/Howto/International_Characters
|
||||
// we could also do ((org.eclipse.jetty.server.Request) request).setQueryEncoding("ISO-8859-1")
|
||||
request.setAttribute("org.eclipse.jetty.server.Request.queryEncoding", "ISO-8859-1");
|
||||
java.io.OutputStream cout = response.getOutputStream();
|
||||
response.setCharacterEncoding("ISO-8859-1");
|
||||
response.setContentType("text/plain");
|
||||
@ -46,20 +50,24 @@
|
||||
|
||||
boolean all = info_hash == null;
|
||||
|
||||
Torrents torrents = ZzzOTController.getTorrents();
|
||||
if (torrents == null && !fail) {
|
||||
fail = true;
|
||||
msg = "tracker is down";
|
||||
}
|
||||
|
||||
InfoHash ih = null;
|
||||
if ((!all) && !fail) {
|
||||
try {
|
||||
ih = new InfoHash(info_hash);
|
||||
ih = torrents.createInfoHash(info_hash);
|
||||
} catch (Exception e) {
|
||||
fail = true;
|
||||
msg = "bad infohash " + e;
|
||||
}
|
||||
}
|
||||
|
||||
Torrents torrents = ZzzOTController.getTorrents();
|
||||
|
||||
// build 3-level dictionary
|
||||
Map<String, Object> m = new HashMap();
|
||||
Map<String, Object> m = new HashMap(4);
|
||||
if (fail) {
|
||||
m.put("failure reason", msg);
|
||||
} else {
|
||||
|
@ -1,4 +1,4 @@
|
||||
<%@page import="net.i2p.crypto.SHA256Generator" %><%@page import="net.i2p.data.Base32" %><%@page import="net.i2p.data.Base64" %><%@page import="net.i2p.data.DataHelper" %><%@page import="net.i2p.zzzot.*" %><%
|
||||
<%@page import="net.i2p.crypto.SHA256Generator,net.i2p.data.Base32,net.i2p.data.Base64,net.i2p.data.DataHelper,net.i2p.zzzot.*" %><%
|
||||
|
||||
/*
|
||||
* Copyright 2010 zzz (zzz@mail.i2p)
|
||||
@ -27,11 +27,13 @@
|
||||
me = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b32.i2p";
|
||||
// unused, we don't accept announces
|
||||
String him = request.getHeader("X-I2P-DestB32");
|
||||
if (him == null)
|
||||
him = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b32.i2p";
|
||||
String xff = request.getHeader("X-Forwarded-For");
|
||||
String xfs = request.getHeader("X-Forwarded-Server");
|
||||
|
||||
response.setContentType("text/plain");
|
||||
response.setHeader("X-Seedless", me);
|
||||
response.setHeader("X-Seedless", him);
|
||||
|
||||
final int US_MINUTES = 360;
|
||||
final int PEER_MINUTES = 60;
|
||||
@ -47,14 +49,23 @@
|
||||
out.println("seedless " + US_MINUTES);
|
||||
} else if (req.startsWith("announce")) {
|
||||
out.println("thanks");
|
||||
} else if (req.startsWith("locate")) {
|
||||
} else if (req.startsWith("locate c2VlZGxlc")) { // locate b64(seedless)
|
||||
// ignore the search string, if any, in the request
|
||||
// us
|
||||
out.println(Base64.encode(me + ' ' + US_MINUTES + " tracker"));
|
||||
out.println(Base64.encode(me + ' ' + US_MINUTES + " seedless"));
|
||||
out.println(Base64.encode(me + ' ' + US_MINUTES + " eepsite"));
|
||||
} else if (req.startsWith("locate ZWVwc2l0Z")) { // locate b64(eepsite)
|
||||
// ignore the search string, if any, in the request
|
||||
// us
|
||||
out.println(Base64.encode(me + ' ' + US_MINUTES + " zzzot"));
|
||||
} else if (req.startsWith("locate dG9ycmVud")) { // locate b64(torrent)
|
||||
// all the peers
|
||||
Torrents torrents = ZzzOTController.getTorrents();
|
||||
if (torrents == null) {
|
||||
response.setStatus(503, "Down");
|
||||
return;
|
||||
}
|
||||
for (InfoHash ihash : torrents.keySet()) {
|
||||
Peers peers = torrents.get(ihash);
|
||||
if (peers == null)
|
||||
@ -68,19 +79,20 @@
|
||||
// service type
|
||||
String role;
|
||||
if (p.isSeed())
|
||||
role = " bt-seed";
|
||||
role = "seed";
|
||||
else
|
||||
role = " bt-leech";
|
||||
role = "leech";
|
||||
// spg wants UTF-8 but all we have is binary data, so hex it
|
||||
String ihs = DataHelper.toHexString(ihash.getData());
|
||||
String ids = DataHelper.toHexString((byte[])p.get("peer id"));
|
||||
out.println(Base64.encode(b32 + PEER_MINUTES + role +
|
||||
" info_hash=" + ihs +
|
||||
";peer_id=" + ids));
|
||||
out.println(Base64.encode(b32 + PEER_MINUTES + ihs + '\n' +
|
||||
ids + '\n' +
|
||||
role));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// error code
|
||||
response.setStatus(406, "Bad request");
|
||||
out.println("SC_NOT_ACCEPTABLE");
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user