propagate from branch 'i2p.i2p' (head e1c79060790ae24b2a96aff2857477d6528ae7c6)
to branch 'i2p.i2p.unittests' (head 357abd51672dd9950cbac6dd30ded117fe5695e0)
@@ -2,6 +2,7 @@
|
||||
source_file = apps/i2ptunnel/locale/messages_en.po
|
||||
source_lang = en
|
||||
trans.ar = apps/i2ptunnel/locale/messages_ar.po
|
||||
trans.cs = apps/i2ptunnel/locale/messages_cs.po
|
||||
trans.da = apps/i2ptunnel/locale/messages_da.po
|
||||
trans.de = apps/i2ptunnel/locale/messages_de.po
|
||||
trans.es = apps/i2ptunnel/locale/messages_es.po
|
||||
@@ -18,6 +19,7 @@ trans.zh_CN = apps/i2ptunnel/locale/messages_zh.po
|
||||
source_file = apps/routerconsole/locale/messages_en.po
|
||||
source_lang = en
|
||||
trans.ar = apps/routerconsole/locale/messages_ar.po
|
||||
trans.cs = apps/routerconsole/locale/messages_cs.po
|
||||
trans.da = apps/routerconsole/locale/messages_da.po
|
||||
trans.de = apps/routerconsole/locale/messages_de.po
|
||||
trans.et_EE = apps/routerconsole/locale/messages_ee.po
|
||||
@@ -37,6 +39,7 @@ trans.zh_CN = apps/routerconsole/locale/messages_zh.po
|
||||
source_file = apps/i2psnark/locale/messages_en.po
|
||||
source_lang = en
|
||||
trans.ar = apps/i2psnark/locale/messages_ar.po
|
||||
trans.cs = apps/i2psnark/locale/messages_cs.po
|
||||
trans.de = apps/i2psnark/locale/messages_de.po
|
||||
trans.es = apps/i2psnark/locale/messages_es.po
|
||||
trans.fr = apps/i2psnark/locale/messages_fr.po
|
||||
@@ -53,6 +56,7 @@ trans.zh_CN = apps/i2psnark/locale/messages_zh.po
|
||||
source_file = apps/susidns/locale/messages_en.po
|
||||
source_lang = en
|
||||
trans.ar = apps/susidns/locale/messages_ar.po
|
||||
trans.cs = apps/susidns/locale/messages_cs.po
|
||||
trans.da = apps/susidns/locale/messages_da.po
|
||||
trans.de = apps/susidns/locale/messages_de.po
|
||||
trans.es = apps/susidns/locale/messages_es.po
|
||||
@@ -70,6 +74,7 @@ trans.zh_CN = apps/susidns/locale/messages_zh.po
|
||||
source_file = apps/desktopgui/locale/messages_en.po
|
||||
source_lang = en
|
||||
trans.ar = apps/desktopgui/locale/messages_ar.po
|
||||
trans.cs = apps/desktopgui/locale/messages_cs.po
|
||||
trans.da = apps/desktopgui/locale/messages_da.po
|
||||
trans.de = apps/desktopgui/locale/messages_de.po
|
||||
trans.es = apps/desktopgui/locale/messages_es.po
|
||||
@@ -86,6 +91,7 @@ trans.zh_CN = apps/desktopgui/locale/messages_zh.po
|
||||
[I2P.susimail]
|
||||
source_file = apps/susimail/locale/messages_en.po
|
||||
source_lang = en
|
||||
trans.cs = apps/susimail/locale/messages_cs.po
|
||||
trans.de = apps/susimail/locale/messages_de.po
|
||||
trans.es = apps/susimail/locale/messages_es.po
|
||||
trans.fr = apps/susimail/locale/messages_fr.po
|
||||
@@ -101,6 +107,7 @@ trans.zh_CN = apps/susimail/locale/messages_zh.po
|
||||
[I2P.debconf]
|
||||
source_file = debian/po/templates.pot
|
||||
source_lang = en
|
||||
trans.cs = debian/po/cs.po
|
||||
trans.de = debian/po/de.po
|
||||
trans.es = debian/po/es.po
|
||||
trans.pl = debian/po/pl.po
|
||||
|
||||
15
LICENSE.txt
@@ -172,8 +172,9 @@ Applications:
|
||||
By welterde.
|
||||
See licenses/LICENSE-GPLv2.txt
|
||||
|
||||
Jetty 5.1.15:
|
||||
Copyright 2000-2004 Mort Bay Consulting Pty. Ltd.
|
||||
Jetty 6.1.26:
|
||||
Copyright 1995-2009 Mort Bay Consulting Pty Ltd
|
||||
See licenses/LICENSE-Jetty.txt
|
||||
See licenses/LICENSE-Apache2.0.txt
|
||||
See licenses/NOTICE-Commons-Logging.txt
|
||||
|
||||
@@ -215,8 +216,10 @@ Applications:
|
||||
Copyright (C) 2005 <susi23@mail.i2p>
|
||||
GPLv2 (or any later version)
|
||||
See licenses/LICENSE-GPLv2.txt
|
||||
Uses Apache Jakarta Standard Tag Library 1.1.2:
|
||||
See licenses/LICENSE-Apache2.0.txt
|
||||
Uses Glassfish Standard Tag Library (JSTL) 1.2:
|
||||
Common Development and Distribution License (CDDL) version 1.0 + GNU General Public License (GPL) version 2
|
||||
See https://glassfish.dev.java.net/public/CDDL+GPL.html
|
||||
See licenses/LICENSE-GPLv2.txt
|
||||
|
||||
SusiMail:
|
||||
Copyright (C) 2004-2005 <susi23@mail.i2p>
|
||||
@@ -228,6 +231,10 @@ Applications:
|
||||
Bundles systray4j-2.4.1:
|
||||
See licenses/LICENSE-LGPLv2.1.txt
|
||||
|
||||
Tomcat 6.0.35:
|
||||
Copyright 1999-2011 The Apache Software Foundation
|
||||
See licenses/LICENSE-Apache2.0.txt
|
||||
See licenses/NOTICE-Tomcat.txt
|
||||
|
||||
|
||||
Other Applications and Libraries
|
||||
|
||||
@@ -26,9 +26,9 @@ for i in *.config ; {
|
||||
|
||||
( cd $INST_DIR/eepsite
|
||||
if [ -f jetty.xml ] ; then
|
||||
rm jetty.xml.new
|
||||
echo "Please check ${INST_DIR}/eepsite, as there are new files."
|
||||
else
|
||||
mv jetty.xml.new jetty.xml
|
||||
find $PKG/$INSTALL_DIR/i2p -name "*.xml.new" -exec sh -c 'mv "$0" "${0/.new}"' {} \;
|
||||
fi
|
||||
)
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#
|
||||
|
||||
BUILD=1sponge
|
||||
# INSTALL_DIR is referenced from /, don't prefix it with a '/'
|
||||
INSTALL_DIR=opt
|
||||
NAME=i2p
|
||||
ARCH=noarch
|
||||
@@ -104,7 +105,10 @@ sed "s|%INSTALL_PATH|/$INSTALL_DIR/i2p|g" runplain.sh > a
|
||||
sed "s|%SYSTEM_java_io_tmpdir|/$INSTALL_DIR/i2p|g" a > runplain.sh
|
||||
# i2prouter %INSTALL_PATH and %SYSTEM_java_io_tmpdir
|
||||
sed "s|%INSTALL_PATH|/$INSTALL_DIR/i2p|g" i2prouter > a
|
||||
sed "s|%SYSTEM_java_io_tmpdir|/$INSTALL_DIR/i2p|g" a > i2prouter
|
||||
rm i2prouter
|
||||
mv a i2prouter
|
||||
sed "s|%SYSTEM_java_io_tmpdir|/$INSTALL_DIR/i2p|g" i2prouter > a
|
||||
sed "s|#ALLOW_ROOT=true|ALLOW_ROOT=true|g" a > i2prouter
|
||||
|
||||
chmod 744 ./i2prouter
|
||||
chmod 744 ./osid
|
||||
@@ -116,7 +120,7 @@ rm -Rf ./lib/*.dll ./*.bat ./*.exe ./installer ./icons ./a postinstall.sh
|
||||
|
||||
mv $PKG/$INSTALL_DIR/i2p/*.config $PKG/install
|
||||
mv $PKG/$INSTALL_DIR/i2p/blocklist.txt $PKG/$INSTALL_DIR/i2p/blocklist.txt.new
|
||||
mv $PKG/$INSTALL_DIR/i2p/eepsite/jetty.xml $PKG/$INSTALL_DIR/i2p/eepsite/jetty.xml.new
|
||||
find $PKG/$INSTALL_DIR/i2p -name "*.xml" -exec mv {} {}.new \;
|
||||
mv $PKG/$INSTALL_DIR/i2p/eepsite/docroot/index.html $PKG/$INSTALL_DIR/i2p/eepsite/docroot/index.html.new
|
||||
mv $PKG/$INSTALL_DIR/i2p/eepsite/docroot/favicon.ico $PKG/$INSTALL_DIR/i2p/eepsite/docroot/favicon.ico.new
|
||||
sed "s|directory|/$INSTALL_DIR/i2p/|g" $CWD/doinst.sh > $PKG/install/doinst.sh
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="addressbook.Daemon"/>
|
||||
<attribute name="Implementation-Version" value="${full.version}" />
|
||||
<attribute name="Built-By" value="${build.built-by}" />
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes}" />
|
||||
@@ -75,6 +76,7 @@
|
||||
<war basedir="${dist}/tmp" webxml="web.xml" destfile="${dist}/${war}">
|
||||
<manifest>
|
||||
<attribute name="Implementation-Version" value="${full.version}" />
|
||||
<attribute name="Built-By" value="${build.built-by}" />
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
|
||||
|
||||
@@ -84,7 +84,7 @@ public class Servlet extends HttpServlet {
|
||||
this.thread.setDaemon(true);
|
||||
this.thread.setName("Addressbook");
|
||||
this.thread.start();
|
||||
System.out.println("INFO: Starting Addressbook " + Daemon.VERSION);
|
||||
//System.out.println("INFO: Starting Addressbook " + Daemon.VERSION);
|
||||
//System.out.println("INFO: config root under " + args[0]);
|
||||
}
|
||||
|
||||
|
||||
55
apps/desktopgui/locale/messages_cs.po
Normal file
@@ -0,0 +1,55 @@
|
||||
# I2P
|
||||
# Copyright (C) 2009 The I2P Project
|
||||
# This file is distributed under the same license as the desktopgui package.
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: https://trac.i2p2.de/\n"
|
||||
"POT-Creation-Date: 2011-03-03 18:29+0000\n"
|
||||
"PO-Revision-Date: 2012-02-12 19:44+0000\n"
|
||||
"Last-Translator: Waseihou Watashi <waseihou@gmail.com>\n"
|
||||
"Language-Team: Czech (http://www.transifex.net/projects/p/I2P/language/cs/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: cs\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
||||
msgid "Start I2P"
|
||||
msgstr "Spustit I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
||||
msgid "I2P is starting!"
|
||||
msgstr "I2P startuje!"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
||||
msgid "Starting"
|
||||
msgstr "Startuji"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:26
|
||||
msgid "Launch I2P Browser"
|
||||
msgstr "Spouštím I2P Browser"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:50
|
||||
msgid "Configure desktopgui"
|
||||
msgstr "Nastavuji desktopgui"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:67
|
||||
msgid "Restart I2P"
|
||||
msgstr "Restart I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:85
|
||||
msgid "Stop I2P"
|
||||
msgstr "Zastavit I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:44
|
||||
msgid "Tray icon configuration"
|
||||
msgstr "Nastavení ikony na liště (tray icon)"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:47
|
||||
msgid "Should tray icon be enabled?"
|
||||
msgstr "Zapnout ikonu na liště?"
|
||||
|
Before Width: | Height: | Size: 464 B After Width: | Height: | Size: 464 B |
|
Before Width: | Height: | Size: 587 B After Width: | Height: | Size: 587 B |
|
Before Width: | Height: | Size: 673 B After Width: | Height: | Size: 673 B |
|
Before Width: | Height: | Size: 882 B After Width: | Height: | Size: 882 B |
|
Before Width: | Height: | Size: 889 B After Width: | Height: | Size: 889 B |
|
Before Width: | Height: | Size: 766 B After Width: | Height: | Size: 766 B |
|
Before Width: | Height: | Size: 653 B After Width: | Height: | Size: 653 B |
|
Before Width: | Height: | Size: 537 B After Width: | Height: | Size: 537 B |
|
Before Width: | Height: | Size: 578 B After Width: | Height: | Size: 578 B |
|
Before Width: | Height: | Size: 591 B After Width: | Height: | Size: 591 B |
|
Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 385 B |
|
Before Width: | Height: | Size: 853 B After Width: | Height: | Size: 853 B |
|
Before Width: | Height: | Size: 635 B After Width: | Height: | Size: 635 B |
|
Before Width: | Height: | Size: 294 B After Width: | Height: | Size: 294 B |
|
Before Width: | Height: | Size: 591 B After Width: | Height: | Size: 591 B |
|
Before Width: | Height: | Size: 589 B After Width: | Height: | Size: 589 B |
|
Before Width: | Height: | Size: 591 B After Width: | Height: | Size: 591 B |
|
Before Width: | Height: | Size: 537 B After Width: | Height: | Size: 537 B |
@@ -19,6 +19,7 @@
|
||||
<pathelement location="../../ministreaming/java/build/obj" />
|
||||
<pathelement location="../../jetty/jettylib/org.mortbay.jetty.jar" />
|
||||
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-util.jar" />
|
||||
</classpath>
|
||||
</depend>
|
||||
</target>
|
||||
@@ -34,7 +35,7 @@
|
||||
debug="true" deprecation="on" source="1.5" target="1.5"
|
||||
destdir="./build/obj"
|
||||
includeAntRuntime="false"
|
||||
classpath="../../../core/java/build/i2p.jar:../../jetty/jettylib/org.mortbay.jetty.jar:../../jetty/jettylib/javax.servlet.jar:../../ministreaming/java/build/mstreaming.jar" >
|
||||
classpath="../../../core/java/build/i2p.jar:../../jetty/jettylib/org.mortbay.jetty.jar:../../jetty/jettylib/javax.servlet.jar:../../jetty/jettylib/jetty-util.jar:../../ministreaming/java/build/mstreaming.jar" >
|
||||
<compilerarg line="${javac.compilerargs}" />
|
||||
</javac>
|
||||
</target>
|
||||
@@ -61,6 +62,7 @@
|
||||
<attribute name="Main-Class" value="org.klomp.snark.Snark" />
|
||||
<attribute name="Class-Path" value="i2p.jar mstreaming.jar streaming.jar" />
|
||||
<attribute name="Implementation-Version" value="${full.version}" />
|
||||
<attribute name="Built-By" value="${build.built-by}" />
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
|
||||
@@ -95,11 +97,16 @@
|
||||
<target name="war" depends="jar, bundle, warUpToDate, listChangedFiles" unless="war.uptodate" >
|
||||
<!-- set if unset -->
|
||||
<property name="workspace.changes.tr" value="" />
|
||||
<war destfile="../i2psnark.war" webxml="../web.xml" basedir="../" includes="_icons/*" >
|
||||
<copy todir="build/icons/.icons" >
|
||||
<fileset dir="../icons/" />
|
||||
</copy>
|
||||
<war destfile="../i2psnark.war" webxml="../web.xml" >
|
||||
<!-- include only the web stuff, as of 0.7.12 the router will add i2psnark.jar to the classpath for the war -->
|
||||
<classes dir="./build/obj" includes="**/web/*.class" />
|
||||
<fileset dir="build/icons/" />
|
||||
<manifest>
|
||||
<attribute name="Implementation-Version" value="${full.version}" />
|
||||
<attribute name="Built-By" value="${build.built-by}" />
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
|
||||
@@ -109,7 +116,7 @@
|
||||
|
||||
<target name="warUpToDate">
|
||||
<uptodate property="war.uptodate" targetfile="../i2psnark.war" >
|
||||
<srcfiles dir= "." includes="build/obj/org/klomp/snark/web/*.class ../_icons/* ../web.xml" />
|
||||
<srcfiles dir= "." includes="build/obj/org/klomp/snark/web/*.class ../icons/* ../web.xml" />
|
||||
</uptodate>
|
||||
</target>
|
||||
|
||||
|
||||
@@ -24,8 +24,6 @@ import org.klomp.snark.bencode.InvalidBEncodingException;
|
||||
*/
|
||||
abstract class ExtensionHandler {
|
||||
|
||||
private static final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(ExtensionHandler.class);
|
||||
|
||||
public static final int ID_HANDSHAKE = 0;
|
||||
public static final int ID_METADATA = 1;
|
||||
public static final String TYPE_METADATA = "ut_metadata";
|
||||
@@ -39,15 +37,19 @@ abstract class ExtensionHandler {
|
||||
|
||||
/**
|
||||
* @param metasize -1 if unknown
|
||||
* @param pexAndMetadata advertise these capabilities
|
||||
* @return bencoded outgoing handshake message
|
||||
*/
|
||||
public static byte[] getHandshake(int metasize) {
|
||||
public static byte[] getHandshake(int metasize, boolean pexAndMetadata) {
|
||||
Map<String, Object> handshake = new HashMap();
|
||||
Map<String, Integer> m = new HashMap();
|
||||
m.put(TYPE_METADATA, Integer.valueOf(ID_METADATA));
|
||||
m.put(TYPE_PEX, Integer.valueOf(ID_PEX));
|
||||
if (metasize >= 0)
|
||||
handshake.put("metadata_size", Integer.valueOf(metasize));
|
||||
if (pexAndMetadata) {
|
||||
m.put(TYPE_METADATA, Integer.valueOf(ID_METADATA));
|
||||
m.put(TYPE_PEX, Integer.valueOf(ID_PEX));
|
||||
if (metasize >= 0)
|
||||
handshake.put("metadata_size", Integer.valueOf(metasize));
|
||||
}
|
||||
// include the map even if empty so the far-end doesn't NPE
|
||||
handshake.put("m", m);
|
||||
handshake.put("p", Integer.valueOf(6881));
|
||||
handshake.put("v", "I2PSnark");
|
||||
@@ -56,21 +58,22 @@ abstract class ExtensionHandler {
|
||||
}
|
||||
|
||||
public static void handleMessage(Peer peer, PeerListener listener, int id, byte[] bs) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Got extension msg " + id + " length " + bs.length + " from " + peer);
|
||||
Log log = I2PAppContext.getGlobalContext().logManager().getLog(ExtensionHandler.class);
|
||||
if (log.shouldLog(Log.INFO))
|
||||
log.info("Got extension msg " + id + " length " + bs.length + " from " + peer);
|
||||
if (id == ID_HANDSHAKE)
|
||||
handleHandshake(peer, listener, bs);
|
||||
handleHandshake(peer, listener, bs, log);
|
||||
else if (id == ID_METADATA)
|
||||
handleMetadata(peer, listener, bs);
|
||||
handleMetadata(peer, listener, bs, log);
|
||||
else if (id == ID_PEX)
|
||||
handlePEX(peer, listener, bs);
|
||||
else if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Unknown extension msg " + id + " from " + peer);
|
||||
handlePEX(peer, listener, bs, log);
|
||||
else if (log.shouldLog(Log.INFO))
|
||||
log.info("Unknown extension msg " + id + " from " + peer);
|
||||
}
|
||||
|
||||
private static void handleHandshake(Peer peer, PeerListener listener, byte[] bs) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Got handshake msg from " + peer);
|
||||
private static void handleHandshake(Peer peer, PeerListener listener, byte[] bs, Log log) {
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Got handshake msg from " + peer);
|
||||
try {
|
||||
// this throws NPE on missing keys
|
||||
InputStream is = new ByteArrayInputStream(bs);
|
||||
@@ -81,20 +84,20 @@ abstract class ExtensionHandler {
|
||||
Map<String, BEValue> msgmap = map.get("m").getMap();
|
||||
|
||||
if (msgmap.get(TYPE_PEX) != null) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.debug("Peer supports PEX extension: " + peer);
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Peer supports PEX extension: " + peer);
|
||||
// peer state calls peer listener calls sendPEX()
|
||||
}
|
||||
|
||||
MagnetState state = peer.getMagnetState();
|
||||
|
||||
if (msgmap.get(TYPE_METADATA) == null) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.debug("Peer does not support metadata extension: " + peer);
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Peer does not support metadata extension: " + peer);
|
||||
// drop if we need metainfo and we haven't found anybody yet
|
||||
synchronized(state) {
|
||||
if (!state.isInitialized()) {
|
||||
_log.debug("Dropping peer, we need metadata! " + peer);
|
||||
log.debug("Dropping peer, we need metadata! " + peer);
|
||||
peer.disconnect();
|
||||
}
|
||||
}
|
||||
@@ -103,20 +106,20 @@ abstract class ExtensionHandler {
|
||||
|
||||
BEValue msize = map.get("metadata_size");
|
||||
if (msize == null) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.debug("Peer does not have the metainfo size yet: " + peer);
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Peer does not have the metainfo size yet: " + peer);
|
||||
// drop if we need metainfo and we haven't found anybody yet
|
||||
synchronized(state) {
|
||||
if (!state.isInitialized()) {
|
||||
_log.debug("Dropping peer, we need metadata! " + peer);
|
||||
log.debug("Dropping peer, we need metadata! " + peer);
|
||||
peer.disconnect();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
int metaSize = msize.getInt();
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.debug("Got the metainfo size: " + metaSize);
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Got the metainfo size: " + metaSize);
|
||||
|
||||
int remaining;
|
||||
synchronized(state) {
|
||||
@@ -125,21 +128,21 @@ abstract class ExtensionHandler {
|
||||
|
||||
if (state.isInitialized()) {
|
||||
if (state.getSize() != metaSize) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.debug("Wrong metainfo size " + metaSize + " from: " + peer);
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Wrong metainfo size " + metaSize + " from: " + peer);
|
||||
peer.disconnect();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// initialize it
|
||||
if (metaSize > MAX_METADATA_SIZE) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.debug("Huge metainfo size " + metaSize + " from: " + peer);
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Huge metainfo size " + metaSize + " from: " + peer);
|
||||
peer.disconnect(false);
|
||||
return;
|
||||
}
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Initialized state, metadata size = " + metaSize + " from " + peer);
|
||||
if (log.shouldLog(Log.INFO))
|
||||
log.info("Initialized state, metadata size = " + metaSize + " from " + peer);
|
||||
state.initialize(metaSize);
|
||||
}
|
||||
remaining = state.chunksRemaining();
|
||||
@@ -152,13 +155,13 @@ abstract class ExtensionHandler {
|
||||
synchronized(state) {
|
||||
chk = state.getNextRequest();
|
||||
}
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Request chunk " + chk + " from " + peer);
|
||||
if (log.shouldLog(Log.INFO))
|
||||
log.info("Request chunk " + chk + " from " + peer);
|
||||
sendRequest(peer, chk);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Handshake exception from " + peer, e);
|
||||
if (log.shouldLog(Log.WARN))
|
||||
log.warn("Handshake exception from " + peer, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,9 +175,9 @@ abstract class ExtensionHandler {
|
||||
* REF: BEP 9
|
||||
* @since 0.8.4
|
||||
*/
|
||||
private static void handleMetadata(Peer peer, PeerListener listener, byte[] bs) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Got metadata msg from " + peer);
|
||||
private static void handleMetadata(Peer peer, PeerListener listener, byte[] bs, Log log) {
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Got metadata msg from " + peer);
|
||||
try {
|
||||
InputStream is = new ByteArrayInputStream(bs);
|
||||
BDecoder dec = new BDecoder(is);
|
||||
@@ -185,8 +188,8 @@ abstract class ExtensionHandler {
|
||||
|
||||
MagnetState state = peer.getMagnetState();
|
||||
if (type == TYPE_REQUEST) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Got request for " + piece + " from: " + peer);
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Got request for " + piece + " from: " + peer);
|
||||
byte[] pc;
|
||||
synchronized(state) {
|
||||
pc = state.getChunk(piece);
|
||||
@@ -197,8 +200,8 @@ abstract class ExtensionHandler {
|
||||
listener.uploaded(peer, pc.length);
|
||||
} else if (type == TYPE_DATA) {
|
||||
int size = map.get("total_size").getInt();
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Got data for " + piece + " length " + size + " from: " + peer);
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Got data for " + piece + " length " + size + " from: " + peer);
|
||||
boolean done;
|
||||
int chk = -1;
|
||||
synchronized(state) {
|
||||
@@ -207,14 +210,14 @@ abstract class ExtensionHandler {
|
||||
int len = is.available();
|
||||
if (len != size) {
|
||||
// probably fatal
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("total_size " + size + " but avail data " + len);
|
||||
if (log.shouldLog(Log.WARN))
|
||||
log.warn("total_size " + size + " but avail data " + len);
|
||||
}
|
||||
peer.downloaded(len);
|
||||
listener.downloaded(peer, len);
|
||||
done = state.saveChunk(piece, bs, bs.length - len, len);
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Got chunk " + piece + " from " + peer);
|
||||
if (log.shouldLog(Log.INFO))
|
||||
log.info("Got chunk " + piece + " from " + peer);
|
||||
if (!done)
|
||||
chk = state.getNextRequest();
|
||||
}
|
||||
@@ -223,26 +226,26 @@ abstract class ExtensionHandler {
|
||||
// Done!
|
||||
// PeerState will call the listener (peer coord), who will
|
||||
// check to see if the MagnetState has it
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Got last chunk from " + peer);
|
||||
if (log.shouldLog(Log.WARN))
|
||||
log.warn("Got last chunk from " + peer);
|
||||
} else {
|
||||
// get the next chunk
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Request chunk " + chk + " from " + peer);
|
||||
if (log.shouldLog(Log.INFO))
|
||||
log.info("Request chunk " + chk + " from " + peer);
|
||||
sendRequest(peer, chk);
|
||||
}
|
||||
} else if (type == TYPE_REJECT) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Got reject msg from " + peer);
|
||||
if (log.shouldLog(Log.WARN))
|
||||
log.warn("Got reject msg from " + peer);
|
||||
peer.disconnect(false);
|
||||
} else {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Got unknown metadata msg from " + peer);
|
||||
if (log.shouldLog(Log.WARN))
|
||||
log.warn("Got unknown metadata msg from " + peer);
|
||||
peer.disconnect(false);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.info("Metadata ext. msg. exception from " + peer, e);
|
||||
if (log.shouldLog(Log.INFO))
|
||||
log.info("Metadata ext. msg. exception from " + peer, e);
|
||||
// fatal ?
|
||||
peer.disconnect(false);
|
||||
}
|
||||
@@ -267,8 +270,8 @@ abstract class ExtensionHandler {
|
||||
peer.sendExtension(hisMsgCode, payload);
|
||||
} catch (Exception e) {
|
||||
// NPE, no metadata capability
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.info("Metadata send req msg exception to " + peer, e);
|
||||
//if (log.shouldLog(Log.INFO))
|
||||
// log.info("Metadata send req msg exception to " + peer, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,8 +289,8 @@ abstract class ExtensionHandler {
|
||||
peer.sendExtension(hisMsgCode, payload);
|
||||
} catch (Exception e) {
|
||||
// NPE, no metadata caps
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.info("Metadata send piece msg exception to " + peer, e);
|
||||
//if (log.shouldLog(Log.INFO))
|
||||
// log.info("Metadata send piece msg exception to " + peer, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,9 +304,9 @@ abstract class ExtensionHandler {
|
||||
* added.f and dropped unsupported
|
||||
* @since 0.8.4
|
||||
*/
|
||||
private static void handlePEX(Peer peer, PeerListener listener, byte[] bs) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Got PEX msg from " + peer);
|
||||
private static void handlePEX(Peer peer, PeerListener listener, byte[] bs, Log log) {
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Got PEX msg from " + peer);
|
||||
try {
|
||||
InputStream is = new ByteArrayInputStream(bs);
|
||||
BDecoder dec = new BDecoder(is);
|
||||
@@ -325,8 +328,8 @@ abstract class ExtensionHandler {
|
||||
// could include ourselves, listener must remove
|
||||
listener.gotPeers(peer, peers);
|
||||
} catch (Exception e) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.info("PEX msg exception from " + peer, e);
|
||||
if (log.shouldLog(Log.INFO))
|
||||
log.info("PEX msg exception from " + peer, e);
|
||||
//peer.disconnect(false);
|
||||
}
|
||||
}
|
||||
@@ -353,8 +356,8 @@ abstract class ExtensionHandler {
|
||||
peer.sendExtension(hisMsgCode, payload);
|
||||
} catch (Exception e) {
|
||||
// NPE, no PEX caps
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.info("PEX msg exception to " + peer, e);
|
||||
//if (log.shouldLog(Log.INFO))
|
||||
// log.info("PEX msg exception to " + peer, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -219,6 +219,10 @@ public class I2PSnarkUtil {
|
||||
// opts.setProperty("i2p.streaming.writeTimeout", "90000");
|
||||
//if (opts.getProperty("i2p.streaming.readTimeout") == null)
|
||||
// opts.setProperty("i2p.streaming.readTimeout", "120000");
|
||||
if (opts.getProperty("i2p.streaming.maxConnsPerMinute") == null)
|
||||
opts.setProperty("i2p.streaming.maxConnsPerMinute", "2");
|
||||
if (opts.getProperty("i2p.streaming.maxTotalConnsPerMinute") == null)
|
||||
opts.setProperty("i2p.streaming.maxTotalConnsPerMinute", "6");
|
||||
_manager = I2PSocketManagerFactory.createManager(_i2cpHost, _i2cpPort, opts);
|
||||
}
|
||||
// FIXME this only instantiates krpc once, left stuck with old manager
|
||||
|
||||
@@ -61,6 +61,7 @@ public class MetaInfo
|
||||
private final int piece_length;
|
||||
private final byte[] piece_hashes;
|
||||
private final long length;
|
||||
private final boolean privateTorrent;
|
||||
private Map<String, BEValue> infoMap;
|
||||
|
||||
/**
|
||||
@@ -71,7 +72,7 @@ public class MetaInfo
|
||||
* @param lengths null for single-file torrent
|
||||
*/
|
||||
MetaInfo(String announce, String name, String name_utf8, List<List<String>> files, List<Long> lengths,
|
||||
int piece_length, byte[] piece_hashes, long length)
|
||||
int piece_length, byte[] piece_hashes, long length, boolean privateTorrent)
|
||||
{
|
||||
this.announce = announce;
|
||||
this.name = name;
|
||||
@@ -82,6 +83,7 @@ public class MetaInfo
|
||||
this.piece_length = piece_length;
|
||||
this.piece_hashes = piece_hashes;
|
||||
this.length = length;
|
||||
this.privateTorrent = privateTorrent;
|
||||
|
||||
// TODO if we add a parameter for other keys
|
||||
//if (other != null) {
|
||||
@@ -160,6 +162,10 @@ public class MetaInfo
|
||||
else
|
||||
name_utf8 = null;
|
||||
|
||||
// BEP 27
|
||||
val = info.get("private");
|
||||
privateTorrent = val != null && val.getString().equals("1");
|
||||
|
||||
val = info.get("piece length");
|
||||
if (val == null)
|
||||
throw new InvalidBEncodingException("Missing piece length number");
|
||||
@@ -318,6 +324,14 @@ public class MetaInfo
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is it a private torrent?
|
||||
* @since 0.9
|
||||
*/
|
||||
public boolean isPrivate() {
|
||||
return privateTorrent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of lists of file name hierarchies or null if it is
|
||||
* a single name. It has the same size as the list returned by
|
||||
@@ -439,7 +453,7 @@ public class MetaInfo
|
||||
{
|
||||
return new MetaInfo(announce, name, name_utf8, files,
|
||||
lengths, piece_length,
|
||||
piece_hashes, length);
|
||||
piece_hashes, length, privateTorrent);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -475,6 +489,10 @@ public class MetaInfo
|
||||
info.put("name", name);
|
||||
if (name_utf8 != null)
|
||||
info.put("name.utf-8", name_utf8);
|
||||
// BEP 27
|
||||
if (privateTorrent)
|
||||
info.put("private", "1");
|
||||
|
||||
info.put("piece length", Integer.valueOf(piece_length));
|
||||
info.put("pieces", piece_hashes);
|
||||
if (files == null)
|
||||
|
||||
@@ -268,7 +268,8 @@ public class Peer implements Comparable
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Peer supports extensions, sending reply message");
|
||||
int metasize = metainfo != null ? metainfo.getInfoBytes().length : -1;
|
||||
out.sendExtension(0, ExtensionHandler.getHandshake(metasize));
|
||||
boolean pexAndMetadata = metainfo == null || !metainfo.isPrivate();
|
||||
out.sendExtension(0, ExtensionHandler.getHandshake(metasize, pexAndMetadata));
|
||||
}
|
||||
|
||||
if ((options & OPTION_I2P_DHT) != 0 && util.getDHT() != null) {
|
||||
|
||||
@@ -1186,6 +1186,8 @@ public class PeerCoordinator implements PeerListener
|
||||
* @since 0.8.4
|
||||
*/
|
||||
void sendPeers(Peer peer) {
|
||||
if (metainfo != null && metainfo.isPrivate())
|
||||
return;
|
||||
Map<String, BEValue> handshake = peer.getHandshakeMap();
|
||||
if (handshake == null)
|
||||
return;
|
||||
|
||||
@@ -489,6 +489,13 @@ class PeerState implements DataLoader
|
||||
/** @since 0.8.2 */
|
||||
void extensionMessage(int id, byte[] bs)
|
||||
{
|
||||
if (metainfo != null && metainfo.isPrivate() &&
|
||||
(id == ExtensionHandler.ID_METADATA || id == ExtensionHandler.ID_PEX)) {
|
||||
// shouldn't get this since we didn't advertise it but they could send it anyway
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Private torrent, ignoring ext msg " + id);
|
||||
return;
|
||||
}
|
||||
ExtensionHandler.handleMessage(peer, listener, id, bs);
|
||||
// Peer coord will get metadata from MagnetState,
|
||||
// verify, and then call gotMetaInfo()
|
||||
|
||||
@@ -8,6 +8,8 @@ import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@@ -35,8 +37,6 @@ import net.i2p.util.SecureFileOutputStream;
|
||||
* Manage multiple snarks
|
||||
*/
|
||||
public class SnarkManager implements Snark.CompleteListener {
|
||||
private static SnarkManager _instance = new SnarkManager();
|
||||
public static SnarkManager instance() { return _instance; }
|
||||
|
||||
/**
|
||||
* Map of (canonical) filename of the .torrent file to Snark instance.
|
||||
@@ -57,6 +57,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
private ConnectionAcceptor _connectionAcceptor;
|
||||
private Thread _monitor;
|
||||
private volatile boolean _running;
|
||||
private final Map<String, String> _trackerMap;
|
||||
|
||||
public static final String PROP_I2CP_HOST = "i2psnark.i2cpHost";
|
||||
public static final String PROP_I2CP_PORT = "i2psnark.i2cpPort";
|
||||
@@ -89,6 +90,34 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
public static final int DEFAULT_STARTUP_DELAY = 3;
|
||||
public static final int DEFAULT_REFRESH_DELAY_SECS = 60;
|
||||
|
||||
/**
|
||||
* "name", "announceURL=websiteURL" pairs
|
||||
* '=' in announceURL must be escaped as ,
|
||||
*/
|
||||
private static final String DEFAULT_TRACKERS[] = {
|
||||
// "Postman", "http://YRgrgTLGnbTq2aZOZDJQ~o6Uk5k6TK-OZtx0St9pb0G-5EGYURZioxqYG8AQt~LgyyI~NCj6aYWpPO-150RcEvsfgXLR~CxkkZcVpgt6pns8SRc3Bi-QSAkXpJtloapRGcQfzTtwllokbdC-aMGpeDOjYLd8b5V9Im8wdCHYy7LRFxhEtGb~RL55DA8aYOgEXcTpr6RPPywbV~Qf3q5UK55el6Kex-6VCxreUnPEe4hmTAbqZNR7Fm0hpCiHKGoToRcygafpFqDw5frLXToYiqs9d4liyVB-BcOb0ihORbo0nS3CLmAwZGvdAP8BZ7cIYE3Z9IU9D1G8JCMxWarfKX1pix~6pIA-sp1gKlL1HhYhPMxwyxvuSqx34o3BqU7vdTYwWiLpGM~zU1~j9rHL7x60pVuYaXcFQDR4-QVy26b6Pt6BlAZoFmHhPcAuWfu-SFhjyZYsqzmEmHeYdAwa~HojSbofg0TMUgESRXMw6YThK1KXWeeJVeztGTz25sL8AAAA.i2p/announce.php=http://tracker.postman.i2p/"
|
||||
// , "eBook", "http://E71FRom6PZNEqTN2Lr8P-sr23b7HJVC32KoGnVQjaX6zJiXwhJy2HsXob36Qmj81TYFZdewFZa9mSJ533UZgGyQkXo2ahctg82JKYZfDe5uDxAn1E9YPjxZCWJaFJh0S~UwSs~9AZ7UcauSJIoNtpxrtbmRNVFLqnkEDdLZi26TeucfOmiFmIWnVblLniWv3tG1boE9Abd-6j3FmYVrRucYuepAILYt6katmVNOk6sXmno1Eynrp~~MBuFq0Ko6~jsc2E2CRVYXDhGHEMdt-j6JUz5D7S2RIVzDRqQyAZLKJ7OdQDmI31przzmne1vOqqqLC~1xUumZVIvF~yOeJUGNjJ1Vx0J8i2BQIusn1pQJ6UCB~ZtZZLQtEb8EPVCfpeRi2ri1M5CyOuxN0V5ekmPHrYIBNevuTCRC26NP7ZS5VDgx1~NaC3A-CzJAE6f1QXi0wMI9aywNG5KGzOPifcsih8eyGyytvgLtrZtV7ykzYpPCS-rDfITncpn5hliPUAAAA.i2p/pub/bt/announce.php=http://de-ebook-archiv.i2p/pub/bt/"
|
||||
// , "Gaytorrents", "http://uxPWHbK1OIj9HxquaXuhMiIvi21iK0~ZiG9d8G0840ZXIg0r6CbiV71xlsqmdnU6wm0T2LySriM0doW2gUigo-5BNkUquHwOjLROiETnB3ZR0Ml4IGa6QBPn1aAq2d9~g1r1nVjLE~pcFnXB~cNNS7kIhX1d6nLgYVZf0C2cZopEow2iWVUggGGnAA9mHjE86zLEnTvAyhbAMTqDQJhEuLa0ZYSORqzJDMkQt90MV4YMjX1ICY6RfUSFmxEqu0yWTrkHsTtRw48l~dz9wpIgc0a0T9C~eeWvmBFTqlJPtQZwntpNeH~jF7nlYzB58olgV2HHFYpVYD87DYNzTnmNWxCJ5AfDorm6AIUCV2qaE7tZtI1h6fbmGpGlPyW~Kw5GXrRfJwNvr6ajwAVi~bPVnrBwDZezHkfW4slOO8FACPR28EQvaTu9nwhAbqESxV2hCTq6vQSGjuxHeOuzBOEvRWkLKOHWTC09t2DbJ94FSqETmZopTB1ukEmaxRWbKSIaAAAA.i2p/announce.php=http://gaytorrents.i2p/"
|
||||
// , "NickyB", "http://9On6d3cZ27JjwYCtyJJbowe054d5tFnfMjv4PHsYs-EQn4Y4mk2zRixatvuAyXz2MmRfXG-NAUfhKr0KCxRNZbvHmlckYfT-WBzwwpiMAl0wDFY~Pl8cqXuhfikSG5WrqdPfDNNIBuuznS0dqaczf~OyVaoEOpvuP3qV6wKqbSSLpjOwwAaQPHjlRtNIW8-EtUZp-I0LT45HSoowp~6b7zYmpIyoATvIP~sT0g0MTrczWhbVTUZnEkZeLhOR0Duw1-IRXI2KHPbA24wLO9LdpKKUXed05RTz0QklW5ROgR6TYv7aXFufX8kC0-DaKvQ5JKG~h8lcoHvm1RCzNqVE-2aiZnO2xH08H-iCWoLNJE-Td2kT-Tsc~3QdQcnEUcL5BF-VT~QYRld2--9r0gfGl-yDrJZrlrihHGr5J7ImahelNn9PpkVp6eIyABRmJHf2iicrk3CtjeG1j9OgTSwaNmEpUpn4aN7Kx0zNLdH7z6uTgCGD9Kmh1MFYrsoNlTp4AAAA.i2p/bittorrent/announce.php=http://nickyb.i2p/bittorrent/"
|
||||
// , "Orion", "http://gKik1lMlRmuroXVGTZ~7v4Vez3L3ZSpddrGZBrxVriosCQf7iHu6CIk8t15BKsj~P0JJpxrofeuxtm7SCUAJEr0AIYSYw8XOmp35UfcRPQWyb1LsxUkMT4WqxAT3s1ClIICWlBu5An~q-Mm0VFlrYLIPBWlUFnfPR7jZ9uP5ZMSzTKSMYUWao3ejiykr~mtEmyls6g-ZbgKZawa9II4zjOy-hdxHgP-eXMDseFsrym4Gpxvy~3Fv9TuiSqhpgm~UeTo5YBfxn6~TahKtE~~sdCiSydqmKBhxAQ7uT9lda7xt96SS09OYMsIWxLeQUWhns-C~FjJPp1D~IuTrUpAFcVEGVL-BRMmdWbfOJEcWPZ~CBCQSO~VkuN1ebvIOr9JBerFMZSxZtFl8JwcrjCIBxeKPBmfh~xYh16BJm1BBBmN1fp2DKmZ2jBNkAmnUbjQOqWvUcehrykWk5lZbE7bjJMDFH48v3SXwRuDBiHZmSbsTY6zhGY~GkMQHNGxPMMSIAAAA.i2p/bt/announce.php=http://orion.i2p/bt/"
|
||||
// , "anonymity", "http://8EoJZIKrWgGuDrxA3nRJs1jsPfiGwmFWL91hBrf0HA7oKhEvAna4Ocx47VLUR9retVEYBAyWFK-eZTPcvhnz9XffBEiJQQ~kFSCqb1fV6IfPiV3HySqi9U5Caf6~hC46fRd~vYnxmaBLICT3N160cxBETqH3v2rdxdJpvYt8q4nMk9LUeVXq7zqCTFLLG5ig1uKgNzBGe58iNcsvTEYlnbYcE930ABmrzj8G1qQSgSwJ6wx3tUQNl1z~4wSOUMan~raZQD60lRK70GISjoX0-D0Po9WmPveN3ES3g72TIET3zc3WPdK2~lgmKGIs8GgNLES1cXTolvbPhdZK1gxddRMbJl6Y6IPFyQ9o4-6Rt3Lp-RMRWZ2TG7j2OMcNSiOmATUhKEFBDfv-~SODDyopGBmfeLw16F4NnYednvn4qP10dyMHcUASU6Zag4mfc2-WivrOqeWhD16fVAh8MoDpIIT~0r9XmwdaVFyLcjbXObabJczxCAW3fodQUnvuSkwzAAAA.i2p/anonymityTracker/announce.php=http://anonymityweb.i2p/anonymityTracker/"
|
||||
// , "The freak's tracker", "http://mHKva9x24E5Ygfey2llR1KyQHv5f8hhMpDMwJDg1U-hABpJ2NrQJd6azirdfaR0OKt4jDlmP2o4Qx0H598~AteyD~RJU~xcWYdcOE0dmJ2e9Y8-HY51ie0B1yD9FtIV72ZI-V3TzFDcs6nkdX9b81DwrAwwFzx0EfNvK1GLVWl59Ow85muoRTBA1q8SsZImxdyZ-TApTVlMYIQbdI4iQRwU9OmmtefrCe~ZOf4UBS9-KvNIqUL0XeBSqm0OU1jq-D10Ykg6KfqvuPnBYT1BYHFDQJXW5DdPKwcaQE4MtAdSGmj1epDoaEBUa9btQlFsM2l9Cyn1hzxqNWXELmx8dRlomQLlV4b586dRzW~fLlOPIGC13ntPXogvYvHVyEyptXkv890jC7DZNHyxZd5cyrKC36r9huKvhQAmNABT2Y~pOGwVrb~RpPwT0tBuPZ3lHYhBFYmD8y~AOhhNHKMLzea1rfwTvovBMByDdFps54gMN1mX4MbCGT4w70vIopS9yAAAA.i2p/bytemonsoon/announce.php"
|
||||
// , "mastertracker", "http://VzXD~stRKbL3MOmeTn1iaCQ0CFyTmuFHiKYyo0Rd~dFPZFCYH-22rT8JD7i-C2xzYFa4jT5U2aqHzHI-Jre4HL3Ri5hFtZrLk2ax3ji7Qfb6qPnuYkuiF2E2UDmKUOppI8d9Ye7tjdhQVCy0izn55tBaB-U7UWdcvSK2i85sauyw3G0Gfads1Rvy5-CAe2paqyYATcDmGjpUNLoxbfv9KH1KmwRTNH6k1v4PyWYYnhbT39WfKMbBjSxVQRdi19cyJrULSWhjxaQfJHeWx5Z8Ev4bSPByBeQBFl2~4vqy0S5RypINsRSa3MZdbiAAyn5tr5slWR6QdoqY3qBQgBJFZppy-3iWkFqqKgSxCPundF8gdDLC5ddizl~KYcYKl42y9SGFHIukH-TZs8~em0~iahzsqWVRks3zRG~tlBcX2U3M2~OJs~C33-NKhyfZT7-XFBREvb8Szmd~p66jDxrwOnKaku-G6DyoQipJqIz4VHmY9-y5T8RrUcJcM-5lVoMpAAAA.i2p/announce.php=http://tracker.mastertracker.i2p/"
|
||||
// , "Galen", "http://5jpwQMI5FT303YwKa5Rd38PYSX04pbIKgTaKQsWbqoWjIfoancFdWCShXHLI5G5ofOb0Xu11vl2VEMyPsg1jUFYSVnu4-VfMe3y4TKTR6DTpetWrnmEK6m2UXh91J5DZJAKlgmO7UdsFlBkQfR2rY853-DfbJtQIFl91tbsmjcA5CGQi4VxMFyIkBzv-pCsuLQiZqOwWasTlnzey8GcDAPG1LDcvfflGV~6F5no9mnuisZPteZKlrv~~TDoXTj74QjByWc4EOYlwqK8sbU9aOvz~s31XzErbPTfwiawiaZ0RUI-IDrKgyvmj0neuFTWgjRGVTH8bz7cBZIc3viy6ioD-eMQOrXaQL0TCWZUelRwHRvgdPiQrxdYQs7ixkajeHzxi-Pq0EMm5Vbh3j3Q9kfUFW3JjFDA-MLB4g6XnjCbM5J1rC0oOBDCIEfhQkszru5cyLjHiZ5yeA0VThgu~c7xKHybv~OMXION7V8pBKOgET7ZgAkw1xgYe3Kkyq5syAAAA.i2p/tr/announce.php=http://galen.i2p/tr/"
|
||||
"Postman", "http://tracker2.postman.i2p/announce.php=http://tracker2.postman.i2p/"
|
||||
,"Welterde", "http://tracker.welterde.i2p/a=http://tracker.welterde.i2p/stats?mode=top5"
|
||||
,"Diftracker", "http://n--XWjHjUPjnMNrSwXA2OYXpMIUL~u4FNXnrt2HtjK3y6j~4SOClyyeKzd0zRPlixxkCe2wfBIYye3bZsaqAD8bd0QMmowxbq91WpjsPfKMiphJbePKXtYAVARiy0cqyvh1d2LyDE-6wkvgaw45hknmS0U-Dg3YTJZbAQRU2SKXgIlAbWCv4R0kDFBLEVpReDiJef3rzAWHiW8yjmJuJilkYjMwlfRjw8xx1nl2s~yhlljk1pl13jGYb0nfawQnuOWeP-ASQWvAAyVgKvZRJE2O43S7iveu9piuv7plXWbt36ef7ndu2GNoNyPOBdpo9KUZ-NOXm4Kgh659YtEibL15dEPAOdxprY0sYUurVw8OIWqrpX7yn08nbi6qHVGqQwTpxH35vkL8qrCbm-ym7oQJQnNmSDrNTyWYRFSq5s5~7DAdFDzqRPW-pX~g0zEivWj5tzkhvG9rVFgFo0bpQX3X0PUAV9Xbyf8u~v8Zbr9K1pCPqBq9XEr4TqaLHw~bfAAAA.i2p/announce.php=http://diftracker.i2p/"
|
||||
// , "CRSTRACK", "http://b4G9sCdtfvccMAXh~SaZrPqVQNyGQbhbYMbw6supq2XGzbjU4NcOmjFI0vxQ8w1L05twmkOvg5QERcX6Mi8NQrWnR0stLExu2LucUXg1aYjnggxIR8TIOGygZVIMV3STKH4UQXD--wz0BUrqaLxPhrm2Eh9Hwc8TdB6Na4ShQUq5Xm8D4elzNUVdpM~RtChEyJWuQvoGAHY3ppX-EJJLkiSr1t77neS4Lc-KofMVmgI9a2tSSpNAagBiNI6Ak9L1T0F9uxeDfEG9bBSQPNMOSUbAoEcNxtt7xOW~cNOAyMyGydwPMnrQ5kIYPY8Pd3XudEko970vE0D6gO19yoBMJpKx6Dh50DGgybLQ9CpRaynh2zPULTHxm8rneOGRcQo8D3mE7FQ92m54~SvfjXjD2TwAVGI~ae~n9HDxt8uxOecAAvjjJ3TD4XM63Q9TmB38RmGNzNLDBQMEmJFpqQU8YeuhnS54IVdUoVQFqui5SfDeLXlSkh4vYoMU66pvBfWbAAAA.i2p/tracker/announce.php=http://crstrack.i2p/tracker/"
|
||||
// ,"Exotrack", "http://blbgywsjubw3d2zih2giokakhe3o2cko7jtte4risb3hohbcoyva.b32.i2p/announce.php=http://exotrack.i2p/"
|
||||
};
|
||||
|
||||
/** comma delimited list of name=announceURL=baseURL for the trackers to be displayed */
|
||||
public static final String PROP_TRACKERS = "i2psnark.trackers";
|
||||
|
||||
private static final SnarkManager _instance = new SnarkManager();
|
||||
|
||||
public static SnarkManager instance() { return _instance; }
|
||||
|
||||
private SnarkManager() {
|
||||
_snarks = new ConcurrentHashMap();
|
||||
_magnets = new ConcurrentHashSet();
|
||||
@@ -100,6 +129,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
_configFile = new File(CONFIG_FILE);
|
||||
if (!_configFile.isAbsolute())
|
||||
_configFile = new File(_context.getConfigDir(), CONFIG_FILE);
|
||||
_trackerMap = Collections.synchronizedMap(new TreeMap(new IgnoreCaseComparator()));
|
||||
loadConfig(null);
|
||||
}
|
||||
|
||||
@@ -312,6 +342,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
boolean bOT = useOT == null || Boolean.valueOf(useOT).booleanValue();
|
||||
_util.setUseOpenTrackers(bOT);
|
||||
getDataDir().mkdirs();
|
||||
initTrackerMap();
|
||||
}
|
||||
|
||||
private int getInt(String prop, int defaultVal) {
|
||||
@@ -663,7 +694,9 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
}
|
||||
|
||||
if (!TrackerClient.isValidAnnounce(info.getAnnounce())) {
|
||||
if (_util.shouldUseOpenTrackers() && _util.getOpenTrackers() != null) {
|
||||
if (info.isPrivate()) {
|
||||
addMessage(_("ERROR - No I2P trackers in private torrent \"{0}\"", info.getName()));
|
||||
} else if (_util.shouldUseOpenTrackers() && _util.getOpenTrackers() != null) {
|
||||
//addMessage(_("Warning - No I2P trackers in \"{0}\", will announce to I2P open trackers and DHT only.", info.getName()));
|
||||
addMessage(_("Warning - No I2P trackers in \"{0}\", will announce to I2P open trackers only.", info.getName()));
|
||||
//} else if (_util.getDHT() != null) {
|
||||
@@ -1356,57 +1389,59 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* "name", "announceURL=websiteURL" pairs
|
||||
* Sorted map of name to announceURL=baseURL
|
||||
* Modifiable, not a copy
|
||||
*/
|
||||
private static final String DEFAULT_TRACKERS[] = {
|
||||
// "Postman", "http://YRgrgTLGnbTq2aZOZDJQ~o6Uk5k6TK-OZtx0St9pb0G-5EGYURZioxqYG8AQt~LgyyI~NCj6aYWpPO-150RcEvsfgXLR~CxkkZcVpgt6pns8SRc3Bi-QSAkXpJtloapRGcQfzTtwllokbdC-aMGpeDOjYLd8b5V9Im8wdCHYy7LRFxhEtGb~RL55DA8aYOgEXcTpr6RPPywbV~Qf3q5UK55el6Kex-6VCxreUnPEe4hmTAbqZNR7Fm0hpCiHKGoToRcygafpFqDw5frLXToYiqs9d4liyVB-BcOb0ihORbo0nS3CLmAwZGvdAP8BZ7cIYE3Z9IU9D1G8JCMxWarfKX1pix~6pIA-sp1gKlL1HhYhPMxwyxvuSqx34o3BqU7vdTYwWiLpGM~zU1~j9rHL7x60pVuYaXcFQDR4-QVy26b6Pt6BlAZoFmHhPcAuWfu-SFhjyZYsqzmEmHeYdAwa~HojSbofg0TMUgESRXMw6YThK1KXWeeJVeztGTz25sL8AAAA.i2p/announce.php=http://tracker.postman.i2p/"
|
||||
// , "eBook", "http://E71FRom6PZNEqTN2Lr8P-sr23b7HJVC32KoGnVQjaX6zJiXwhJy2HsXob36Qmj81TYFZdewFZa9mSJ533UZgGyQkXo2ahctg82JKYZfDe5uDxAn1E9YPjxZCWJaFJh0S~UwSs~9AZ7UcauSJIoNtpxrtbmRNVFLqnkEDdLZi26TeucfOmiFmIWnVblLniWv3tG1boE9Abd-6j3FmYVrRucYuepAILYt6katmVNOk6sXmno1Eynrp~~MBuFq0Ko6~jsc2E2CRVYXDhGHEMdt-j6JUz5D7S2RIVzDRqQyAZLKJ7OdQDmI31przzmne1vOqqqLC~1xUumZVIvF~yOeJUGNjJ1Vx0J8i2BQIusn1pQJ6UCB~ZtZZLQtEb8EPVCfpeRi2ri1M5CyOuxN0V5ekmPHrYIBNevuTCRC26NP7ZS5VDgx1~NaC3A-CzJAE6f1QXi0wMI9aywNG5KGzOPifcsih8eyGyytvgLtrZtV7ykzYpPCS-rDfITncpn5hliPUAAAA.i2p/pub/bt/announce.php=http://de-ebook-archiv.i2p/pub/bt/"
|
||||
// , "Gaytorrents", "http://uxPWHbK1OIj9HxquaXuhMiIvi21iK0~ZiG9d8G0840ZXIg0r6CbiV71xlsqmdnU6wm0T2LySriM0doW2gUigo-5BNkUquHwOjLROiETnB3ZR0Ml4IGa6QBPn1aAq2d9~g1r1nVjLE~pcFnXB~cNNS7kIhX1d6nLgYVZf0C2cZopEow2iWVUggGGnAA9mHjE86zLEnTvAyhbAMTqDQJhEuLa0ZYSORqzJDMkQt90MV4YMjX1ICY6RfUSFmxEqu0yWTrkHsTtRw48l~dz9wpIgc0a0T9C~eeWvmBFTqlJPtQZwntpNeH~jF7nlYzB58olgV2HHFYpVYD87DYNzTnmNWxCJ5AfDorm6AIUCV2qaE7tZtI1h6fbmGpGlPyW~Kw5GXrRfJwNvr6ajwAVi~bPVnrBwDZezHkfW4slOO8FACPR28EQvaTu9nwhAbqESxV2hCTq6vQSGjuxHeOuzBOEvRWkLKOHWTC09t2DbJ94FSqETmZopTB1ukEmaxRWbKSIaAAAA.i2p/announce.php=http://gaytorrents.i2p/"
|
||||
// , "NickyB", "http://9On6d3cZ27JjwYCtyJJbowe054d5tFnfMjv4PHsYs-EQn4Y4mk2zRixatvuAyXz2MmRfXG-NAUfhKr0KCxRNZbvHmlckYfT-WBzwwpiMAl0wDFY~Pl8cqXuhfikSG5WrqdPfDNNIBuuznS0dqaczf~OyVaoEOpvuP3qV6wKqbSSLpjOwwAaQPHjlRtNIW8-EtUZp-I0LT45HSoowp~6b7zYmpIyoATvIP~sT0g0MTrczWhbVTUZnEkZeLhOR0Duw1-IRXI2KHPbA24wLO9LdpKKUXed05RTz0QklW5ROgR6TYv7aXFufX8kC0-DaKvQ5JKG~h8lcoHvm1RCzNqVE-2aiZnO2xH08H-iCWoLNJE-Td2kT-Tsc~3QdQcnEUcL5BF-VT~QYRld2--9r0gfGl-yDrJZrlrihHGr5J7ImahelNn9PpkVp6eIyABRmJHf2iicrk3CtjeG1j9OgTSwaNmEpUpn4aN7Kx0zNLdH7z6uTgCGD9Kmh1MFYrsoNlTp4AAAA.i2p/bittorrent/announce.php=http://nickyb.i2p/bittorrent/"
|
||||
// , "Orion", "http://gKik1lMlRmuroXVGTZ~7v4Vez3L3ZSpddrGZBrxVriosCQf7iHu6CIk8t15BKsj~P0JJpxrofeuxtm7SCUAJEr0AIYSYw8XOmp35UfcRPQWyb1LsxUkMT4WqxAT3s1ClIICWlBu5An~q-Mm0VFlrYLIPBWlUFnfPR7jZ9uP5ZMSzTKSMYUWao3ejiykr~mtEmyls6g-ZbgKZawa9II4zjOy-hdxHgP-eXMDseFsrym4Gpxvy~3Fv9TuiSqhpgm~UeTo5YBfxn6~TahKtE~~sdCiSydqmKBhxAQ7uT9lda7xt96SS09OYMsIWxLeQUWhns-C~FjJPp1D~IuTrUpAFcVEGVL-BRMmdWbfOJEcWPZ~CBCQSO~VkuN1ebvIOr9JBerFMZSxZtFl8JwcrjCIBxeKPBmfh~xYh16BJm1BBBmN1fp2DKmZ2jBNkAmnUbjQOqWvUcehrykWk5lZbE7bjJMDFH48v3SXwRuDBiHZmSbsTY6zhGY~GkMQHNGxPMMSIAAAA.i2p/bt/announce.php=http://orion.i2p/bt/"
|
||||
// , "anonymity", "http://8EoJZIKrWgGuDrxA3nRJs1jsPfiGwmFWL91hBrf0HA7oKhEvAna4Ocx47VLUR9retVEYBAyWFK-eZTPcvhnz9XffBEiJQQ~kFSCqb1fV6IfPiV3HySqi9U5Caf6~hC46fRd~vYnxmaBLICT3N160cxBETqH3v2rdxdJpvYt8q4nMk9LUeVXq7zqCTFLLG5ig1uKgNzBGe58iNcsvTEYlnbYcE930ABmrzj8G1qQSgSwJ6wx3tUQNl1z~4wSOUMan~raZQD60lRK70GISjoX0-D0Po9WmPveN3ES3g72TIET3zc3WPdK2~lgmKGIs8GgNLES1cXTolvbPhdZK1gxddRMbJl6Y6IPFyQ9o4-6Rt3Lp-RMRWZ2TG7j2OMcNSiOmATUhKEFBDfv-~SODDyopGBmfeLw16F4NnYednvn4qP10dyMHcUASU6Zag4mfc2-WivrOqeWhD16fVAh8MoDpIIT~0r9XmwdaVFyLcjbXObabJczxCAW3fodQUnvuSkwzAAAA.i2p/anonymityTracker/announce.php=http://anonymityweb.i2p/anonymityTracker/"
|
||||
// , "The freak's tracker", "http://mHKva9x24E5Ygfey2llR1KyQHv5f8hhMpDMwJDg1U-hABpJ2NrQJd6azirdfaR0OKt4jDlmP2o4Qx0H598~AteyD~RJU~xcWYdcOE0dmJ2e9Y8-HY51ie0B1yD9FtIV72ZI-V3TzFDcs6nkdX9b81DwrAwwFzx0EfNvK1GLVWl59Ow85muoRTBA1q8SsZImxdyZ-TApTVlMYIQbdI4iQRwU9OmmtefrCe~ZOf4UBS9-KvNIqUL0XeBSqm0OU1jq-D10Ykg6KfqvuPnBYT1BYHFDQJXW5DdPKwcaQE4MtAdSGmj1epDoaEBUa9btQlFsM2l9Cyn1hzxqNWXELmx8dRlomQLlV4b586dRzW~fLlOPIGC13ntPXogvYvHVyEyptXkv890jC7DZNHyxZd5cyrKC36r9huKvhQAmNABT2Y~pOGwVrb~RpPwT0tBuPZ3lHYhBFYmD8y~AOhhNHKMLzea1rfwTvovBMByDdFps54gMN1mX4MbCGT4w70vIopS9yAAAA.i2p/bytemonsoon/announce.php"
|
||||
// , "mastertracker", "http://VzXD~stRKbL3MOmeTn1iaCQ0CFyTmuFHiKYyo0Rd~dFPZFCYH-22rT8JD7i-C2xzYFa4jT5U2aqHzHI-Jre4HL3Ri5hFtZrLk2ax3ji7Qfb6qPnuYkuiF2E2UDmKUOppI8d9Ye7tjdhQVCy0izn55tBaB-U7UWdcvSK2i85sauyw3G0Gfads1Rvy5-CAe2paqyYATcDmGjpUNLoxbfv9KH1KmwRTNH6k1v4PyWYYnhbT39WfKMbBjSxVQRdi19cyJrULSWhjxaQfJHeWx5Z8Ev4bSPByBeQBFl2~4vqy0S5RypINsRSa3MZdbiAAyn5tr5slWR6QdoqY3qBQgBJFZppy-3iWkFqqKgSxCPundF8gdDLC5ddizl~KYcYKl42y9SGFHIukH-TZs8~em0~iahzsqWVRks3zRG~tlBcX2U3M2~OJs~C33-NKhyfZT7-XFBREvb8Szmd~p66jDxrwOnKaku-G6DyoQipJqIz4VHmY9-y5T8RrUcJcM-5lVoMpAAAA.i2p/announce.php=http://tracker.mastertracker.i2p/"
|
||||
// , "Galen", "http://5jpwQMI5FT303YwKa5Rd38PYSX04pbIKgTaKQsWbqoWjIfoancFdWCShXHLI5G5ofOb0Xu11vl2VEMyPsg1jUFYSVnu4-VfMe3y4TKTR6DTpetWrnmEK6m2UXh91J5DZJAKlgmO7UdsFlBkQfR2rY853-DfbJtQIFl91tbsmjcA5CGQi4VxMFyIkBzv-pCsuLQiZqOwWasTlnzey8GcDAPG1LDcvfflGV~6F5no9mnuisZPteZKlrv~~TDoXTj74QjByWc4EOYlwqK8sbU9aOvz~s31XzErbPTfwiawiaZ0RUI-IDrKgyvmj0neuFTWgjRGVTH8bz7cBZIc3viy6ioD-eMQOrXaQL0TCWZUelRwHRvgdPiQrxdYQs7ixkajeHzxi-Pq0EMm5Vbh3j3Q9kfUFW3JjFDA-MLB4g6XnjCbM5J1rC0oOBDCIEfhQkszru5cyLjHiZ5yeA0VThgu~c7xKHybv~OMXION7V8pBKOgET7ZgAkw1xgYe3Kkyq5syAAAA.i2p/tr/announce.php=http://galen.i2p/tr/"
|
||||
"Postman", "http://tracker2.postman.i2p/announce.php=http://tracker2.postman.i2p/"
|
||||
,"Welterde", "http://tracker.welterde.i2p/a=http://tracker.welterde.i2p/stats?mode=top5"
|
||||
,"Diftracker", "http://n--XWjHjUPjnMNrSwXA2OYXpMIUL~u4FNXnrt2HtjK3y6j~4SOClyyeKzd0zRPlixxkCe2wfBIYye3bZsaqAD8bd0QMmowxbq91WpjsPfKMiphJbePKXtYAVARiy0cqyvh1d2LyDE-6wkvgaw45hknmS0U-Dg3YTJZbAQRU2SKXgIlAbWCv4R0kDFBLEVpReDiJef3rzAWHiW8yjmJuJilkYjMwlfRjw8xx1nl2s~yhlljk1pl13jGYb0nfawQnuOWeP-ASQWvAAyVgKvZRJE2O43S7iveu9piuv7plXWbt36ef7ndu2GNoNyPOBdpo9KUZ-NOXm4Kgh659YtEibL15dEPAOdxprY0sYUurVw8OIWqrpX7yn08nbi6qHVGqQwTpxH35vkL8qrCbm-ym7oQJQnNmSDrNTyWYRFSq5s5~7DAdFDzqRPW-pX~g0zEivWj5tzkhvG9rVFgFo0bpQX3X0PUAV9Xbyf8u~v8Zbr9K1pCPqBq9XEr4TqaLHw~bfAAAA.i2p/announce.php=http://diftracker.i2p/"
|
||||
// , "CRSTRACK", "http://b4G9sCdtfvccMAXh~SaZrPqVQNyGQbhbYMbw6supq2XGzbjU4NcOmjFI0vxQ8w1L05twmkOvg5QERcX6Mi8NQrWnR0stLExu2LucUXg1aYjnggxIR8TIOGygZVIMV3STKH4UQXD--wz0BUrqaLxPhrm2Eh9Hwc8TdB6Na4ShQUq5Xm8D4elzNUVdpM~RtChEyJWuQvoGAHY3ppX-EJJLkiSr1t77neS4Lc-KofMVmgI9a2tSSpNAagBiNI6Ak9L1T0F9uxeDfEG9bBSQPNMOSUbAoEcNxtt7xOW~cNOAyMyGydwPMnrQ5kIYPY8Pd3XudEko970vE0D6gO19yoBMJpKx6Dh50DGgybLQ9CpRaynh2zPULTHxm8rneOGRcQo8D3mE7FQ92m54~SvfjXjD2TwAVGI~ae~n9HDxt8uxOecAAvjjJ3TD4XM63Q9TmB38RmGNzNLDBQMEmJFpqQU8YeuhnS54IVdUoVQFqui5SfDeLXlSkh4vYoMU66pvBfWbAAAA.i2p/tracker/announce.php=http://crstrack.i2p/tracker/"
|
||||
// ,"Exotrack", "http://blbgywsjubw3d2zih2giokakhe3o2cko7jtte4risb3hohbcoyva.b32.i2p/announce.php=http://exotrack.i2p/"
|
||||
};
|
||||
|
||||
/** comma delimited list of name=announceURL=baseURL for the trackers to be displayed */
|
||||
public static final String PROP_TRACKERS = "i2psnark.trackers";
|
||||
private static Map<String, String> trackerMap = null;
|
||||
/** sorted map of name to announceURL=baseURL */
|
||||
public Map<String, String> getTrackers() {
|
||||
if (trackerMap != null) // only do this once, can't be updated while running
|
||||
return trackerMap;
|
||||
Map<String, String> rv = new TreeMap();
|
||||
return _trackerMap;
|
||||
}
|
||||
|
||||
/** @since 0.9 */
|
||||
private void initTrackerMap() {
|
||||
String trackers = _config.getProperty(PROP_TRACKERS);
|
||||
if ( (trackers == null) || (trackers.trim().length() <= 0) )
|
||||
trackers = _context.getProperty(PROP_TRACKERS);
|
||||
_trackerMap.clear();
|
||||
if ( (trackers == null) || (trackers.trim().length() <= 0) ) {
|
||||
for (int i = 0; i < DEFAULT_TRACKERS.length; i += 2)
|
||||
rv.put(DEFAULT_TRACKERS[i], DEFAULT_TRACKERS[i+1]);
|
||||
_trackerMap.put(DEFAULT_TRACKERS[i], DEFAULT_TRACKERS[i+1]);
|
||||
} else {
|
||||
StringTokenizer tok = new StringTokenizer(trackers, ",");
|
||||
while (tok.hasMoreTokens()) {
|
||||
String pair = tok.nextToken();
|
||||
int split = pair.indexOf('=');
|
||||
if (split <= 0)
|
||||
continue;
|
||||
String name = pair.substring(0, split).trim();
|
||||
String url = pair.substring(split+1).trim();
|
||||
String[] toks = trackers.split(",");
|
||||
for (int i = 0; i < toks.length; i += 2) {
|
||||
String name = toks[i].trim().replace(",", ",");
|
||||
String url = toks[i+1].trim().replace(",", ",");
|
||||
if ( (name.length() > 0) && (url.length() > 0) )
|
||||
rv.put(name, url);
|
||||
_trackerMap.put(name, url);
|
||||
}
|
||||
}
|
||||
|
||||
trackerMap = rv;
|
||||
return trackerMap;
|
||||
}
|
||||
|
||||
|
||||
/** @since 0.9 */
|
||||
public void setDefaultTrackerMap() {
|
||||
_trackerMap.clear();
|
||||
for (int i = 0; i < DEFAULT_TRACKERS.length; i += 2) {
|
||||
_trackerMap.put(DEFAULT_TRACKERS[i], DEFAULT_TRACKERS[i+1]);
|
||||
}
|
||||
if (_config.remove(PROP_TRACKERS) != null) {
|
||||
saveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 0.9 */
|
||||
public void saveTrackerMap() {
|
||||
StringBuilder buf = new StringBuilder(2048);
|
||||
boolean comma = false;
|
||||
for (Map.Entry<String, String> e : _trackerMap.entrySet()) {
|
||||
if (comma)
|
||||
buf.append(',');
|
||||
else
|
||||
comma = true;
|
||||
buf.append(e.getKey().replace(",", ",")).append(',').append(e.getValue().replace(",", ","));
|
||||
}
|
||||
_config.setProperty(PROP_TRACKERS, buf.toString());
|
||||
saveConfig();
|
||||
}
|
||||
|
||||
private static class TorrentFilenameFilter implements FilenameFilter {
|
||||
private static final TorrentFilenameFilter _filter = new TorrentFilenameFilter();
|
||||
public static TorrentFilenameFilter instance() { return _filter; }
|
||||
@@ -1426,4 +1461,14 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ignore case, current locale
|
||||
* @since 0.9
|
||||
*/
|
||||
private static class IgnoreCaseComparator implements Comparator<String> {
|
||||
public int compare(String l, String r) {
|
||||
return l.toLowerCase().compareTo(r.toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,8 @@ public class Storage
|
||||
* @param announce may be null
|
||||
* @param listener may be null
|
||||
*/
|
||||
public Storage(I2PSnarkUtil util, File baseFile, String announce, StorageListener listener)
|
||||
public Storage(I2PSnarkUtil util, File baseFile, String announce,
|
||||
boolean privateTorrent, StorageListener listener)
|
||||
throws IOException
|
||||
{
|
||||
_util = util;
|
||||
@@ -157,7 +158,7 @@ public class Storage
|
||||
|
||||
byte[] piece_hashes = fast_digestCreate();
|
||||
metainfo = new MetaInfo(announce, baseFile.getName(), null, files,
|
||||
lengthsList, piece_size, piece_hashes, total);
|
||||
lengthsList, piece_size, piece_hashes, total, privateTorrent);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ public class TrackerClient extends I2PAppThread
|
||||
primary = "";
|
||||
}
|
||||
List tlist = _util.getOpenTrackers();
|
||||
if (tlist != null) {
|
||||
if (tlist != null && (meta == null || !meta.isPrivate())) {
|
||||
for (int i = 0; i < tlist.size(); i++) {
|
||||
String url = (String)tlist.get(i);
|
||||
if (!isValidAnnounce(url)) {
|
||||
@@ -348,7 +348,7 @@ public class TrackerClient extends I2PAppThread
|
||||
} // *** end of trackers loop here
|
||||
|
||||
// Get peers from PEX
|
||||
if (left > 0 && coordinator.needPeers() && !stop) {
|
||||
if (left > 0 && coordinator.needPeers() && (!meta.isPrivate()) && !stop) {
|
||||
Set<PeerID> pids = coordinator.getPEXPeers();
|
||||
if (!pids.isEmpty()) {
|
||||
_util.debug("Got " + pids.size() + " from PEX", Snark.INFO);
|
||||
@@ -370,7 +370,7 @@ public class TrackerClient extends I2PAppThread
|
||||
|
||||
// Get peers from DHT
|
||||
// FIXME this needs to be in its own thread
|
||||
if (_util.getDHT() != null && !stop) {
|
||||
if (_util.getDHT() != null && (!meta.isPrivate()) && !stop) {
|
||||
int numwant;
|
||||
if (left == 0 || event.equals(STOPPED_EVENT) || !coordinator.needPeers())
|
||||
numwant = 1;
|
||||
@@ -444,22 +444,33 @@ public class TrackerClient extends I2PAppThread
|
||||
long downloaded, long left, String event)
|
||||
throws IOException
|
||||
{
|
||||
// What do we send for left in magnet mode? Can we omit it?
|
||||
long tleft = left >= 0 ? left : 1;
|
||||
String s = tr.announce
|
||||
+ "?info_hash=" + infoHash
|
||||
+ "&peer_id=" + peerID
|
||||
+ "&port=" + port
|
||||
+ "&ip=" + _util.getOurIPString() + ".i2p"
|
||||
+ "&uploaded=" + uploaded
|
||||
+ "&downloaded=" + downloaded
|
||||
+ "&left=" + tleft
|
||||
+ "&compact=1" // NOTE: opentracker will return 400 for &compact alone
|
||||
+ ((! event.equals(NO_EVENT)) ? ("&event=" + event) : "");
|
||||
if (left == 0 || event.equals(STOPPED_EVENT) || !coordinator.needPeers())
|
||||
s += "&numwant=0";
|
||||
StringBuilder buf = new StringBuilder(512);
|
||||
buf.append(tr.announce);
|
||||
if (tr.announce.contains("?"))
|
||||
buf.append('&');
|
||||
else
|
||||
s += "&numwant=" + _util.getMaxConnections();
|
||||
buf.append('?');
|
||||
buf.append("info_hash=").append(infoHash)
|
||||
.append("&peer_id=").append(peerID)
|
||||
.append("&port=").append(port)
|
||||
.append("&ip=" ).append(_util.getOurIPString()).append(".i2p")
|
||||
.append("&uploaded=").append(uploaded)
|
||||
.append("&downloaded=").append(downloaded)
|
||||
.append("&left=");
|
||||
// What do we send for left in magnet mode? Can we omit it?
|
||||
if (left >= 0)
|
||||
buf.append(left);
|
||||
else
|
||||
buf.append('1');
|
||||
buf.append("&compact=1"); // NOTE: opentracker will return 400 for &compact alone
|
||||
if (! event.equals(NO_EVENT))
|
||||
buf.append("&event=").append(event);
|
||||
buf.append("&numwant=");
|
||||
if (left == 0 || event.equals(STOPPED_EVENT) || !coordinator.needPeers())
|
||||
buf.append('0');
|
||||
else
|
||||
buf.append(_util.getMaxConnections());
|
||||
String s = buf.toString();
|
||||
_util.debug("Sending TrackerClient request: " + s, Snark.INFO);
|
||||
|
||||
tr.lastRequestTime = System.currentTimeMillis();
|
||||
|
||||
@@ -43,17 +43,16 @@ import org.klomp.snark.SnarkManager;
|
||||
import org.klomp.snark.Storage;
|
||||
import org.klomp.snark.TrackerClient;
|
||||
|
||||
import org.mortbay.http.HttpResponse;
|
||||
import org.mortbay.jetty.servlet.Default;
|
||||
import org.mortbay.util.Resource;
|
||||
import org.mortbay.util.URI;
|
||||
import org.mortbay.jetty.servlet.DefaultServlet;
|
||||
import org.mortbay.resource.Resource;
|
||||
import org.mortbay.util.URIUtil;
|
||||
|
||||
/**
|
||||
* We extend Default instead of HTTPServlet so we can handle
|
||||
* i2psnark/ file requests with http:// instead of the flaky and
|
||||
* often-blocked-by-the-browser file://
|
||||
*/
|
||||
public class I2PSnarkServlet extends Default {
|
||||
public class I2PSnarkServlet extends DefaultServlet {
|
||||
private I2PAppContext _context;
|
||||
private Log _log;
|
||||
private SnarkManager _manager;
|
||||
@@ -99,13 +98,17 @@ public class I2PSnarkServlet extends Default {
|
||||
* and we can't get any resources (like icons) out of the .war
|
||||
*/
|
||||
@Override
|
||||
protected Resource getResource(String pathInContext) throws IOException
|
||||
public Resource getResource(String pathInContext)
|
||||
{
|
||||
if (pathInContext == null || pathInContext.equals("/") || pathInContext.equals("/index.jsp") ||
|
||||
pathInContext.equals("/index.html") || pathInContext.startsWith("/_icons/"))
|
||||
pathInContext.equals("/index.html") || pathInContext.startsWith("/.icons/"))
|
||||
return super.getResource(pathInContext);
|
||||
// files in the i2psnark/ directory
|
||||
return _resourceBase.addPath(pathInContext);
|
||||
try {
|
||||
return _resourceBase.addPath(pathInContext);
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,10 +116,8 @@ public class I2PSnarkServlet extends Default {
|
||||
* @since 0.8.3
|
||||
*/
|
||||
@Override
|
||||
public void handleGet(HttpServletRequest request, HttpServletResponse response, String pathInContext, Resource resource, boolean endsWithSlash) throws ServletException, IOException {
|
||||
if (resource.getName().startsWith("jar:file:"))
|
||||
response.setHeader("Cache-Control", "max-age=86400"); // cache for a day
|
||||
super.handleGet(request, response, pathInContext, resource, endsWithSlash);
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
super.doGet(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,33 +145,46 @@ public class I2PSnarkServlet extends Default {
|
||||
// since we are not overriding handle*(), do this here
|
||||
String method = req.getMethod();
|
||||
if (!(method.equals("GET") || method.equals("HEAD") || method.equals("POST"))) {
|
||||
resp.sendError(HttpResponse.__405_Method_Not_Allowed);
|
||||
resp.sendError(405);
|
||||
return;
|
||||
}
|
||||
_themePath = "/themes/snark/" + _manager.getTheme() + '/';
|
||||
_imgPath = _themePath + "images/";
|
||||
// this is the part after /i2psnark
|
||||
String path = req.getServletPath();
|
||||
|
||||
// AJAX for mainsection
|
||||
if ("/.ajax/xhr1.html".equals(path)) {
|
||||
resp.setCharacterEncoding("UTF-8");
|
||||
resp.setContentType("text/html; charset=UTF-8");
|
||||
PrintWriter out = resp.getWriter();
|
||||
//if (_log.shouldLog(Log.DEBUG))
|
||||
// _manager.addMessage((_context.clock().now() / 1000) + " xhr1 p=" + req.getParameter("p"));
|
||||
writeMessages(out);
|
||||
writeTorrents(out, req);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isConfigure = "/configure".equals(path);
|
||||
// index.jsp doesn't work, it is grabbed by the war handler before here
|
||||
if (!(path == null || path.equals("/") || path.equals("/index.jsp") || path.equals("/index.html") || path.equals("/_post") || isConfigure)) {
|
||||
if (path.endsWith("/")) {
|
||||
// bypass the horrid Resource.getListHTML()
|
||||
String pathInfo = req.getPathInfo();
|
||||
String pathInContext = URI.addPaths(path, pathInfo);
|
||||
String pathInContext = URIUtil.addPaths(path, pathInfo);
|
||||
req.setCharacterEncoding("UTF-8");
|
||||
resp.setCharacterEncoding("UTF-8");
|
||||
resp.setContentType("text/html; charset=UTF-8");
|
||||
Resource resource = getResource(pathInContext);
|
||||
if (resource == null || (!resource.exists())) {
|
||||
resp.sendError(HttpResponse.__404_Not_Found);
|
||||
resp.sendError(404);
|
||||
} else {
|
||||
String base = URI.addPaths(req.getRequestURI(), "/");
|
||||
String base = URIUtil.addPaths(req.getRequestURI(), "/");
|
||||
String listing = getListHTML(resource, base, true, method.equals("POST") ? req.getParameterMap() : null);
|
||||
if (listing != null)
|
||||
resp.getWriter().write(listing);
|
||||
else // shouldn't happen
|
||||
resp.sendError(HttpResponse.__404_Not_Found);
|
||||
resp.sendError(404);
|
||||
}
|
||||
} else {
|
||||
super.service(req, resp);
|
||||
@@ -192,7 +206,8 @@ public class I2PSnarkServlet extends Default {
|
||||
|
||||
String peerParam = req.getParameter("p");
|
||||
String peerString;
|
||||
if (peerParam == null || !_manager.util().connected()) {
|
||||
if (peerParam == null || (!_manager.util().connected()) ||
|
||||
peerParam.replaceAll("[a-zA-Z0-9~=-]", "").length() > 0) { // XSS
|
||||
peerString = "";
|
||||
} else {
|
||||
peerString = "?p=" + peerParam;
|
||||
@@ -208,13 +223,24 @@ public class I2PSnarkServlet extends Default {
|
||||
out.write("</title>\n");
|
||||
|
||||
// we want it to go to the base URI so we don't refresh with some funky action= value
|
||||
int delay = 0;
|
||||
if (!isConfigure) {
|
||||
int delay = _manager.getRefreshDelaySeconds();
|
||||
if (delay > 0)
|
||||
out.write("<meta http-equiv=\"refresh\" content=\"" + delay + ";/i2psnark/" + peerString + "\">\n");
|
||||
delay = _manager.getRefreshDelaySeconds();
|
||||
if (delay > 0) {
|
||||
//out.write("<meta http-equiv=\"refresh\" content=\"" + delay + ";/i2psnark/" + peerString + "\">\n");
|
||||
out.write("<script src=\"/js/ajax.js\" type=\"text/javascript\"></script>\n" +
|
||||
"<script type=\"text/javascript\">\n" +
|
||||
"var failMessage = \"<b>" + _("Router is down") + "<\\/b>\";\n" +
|
||||
"function requestAjax1() { ajax(\"/i2psnark/.ajax/xhr1.html" + peerString + "\", \"mainsection\", " + (delay*1000) + "); }\n" +
|
||||
"function initAjax(delayMs) { setTimeout(requestAjax1, " + (delay*1000) +"); }\n" +
|
||||
"</script>\n");
|
||||
}
|
||||
}
|
||||
out.write(HEADER_A + _themePath + HEADER_B);
|
||||
out.write("</head><body>");
|
||||
out.write(HEADER_A + _themePath + HEADER_B + "</head>\n");
|
||||
if (isConfigure || delay <= 0)
|
||||
out.write("<body>");
|
||||
else
|
||||
out.write("<body onload=\"initAjax()\">");
|
||||
out.write("<center>");
|
||||
if (isConfigure) {
|
||||
out.write("<div class=\"snarknavbar\"><a href=\"/i2psnark/\" title=\"");
|
||||
@@ -249,25 +275,36 @@ public class I2PSnarkServlet extends Default {
|
||||
String newURL = req.getParameter("newURL");
|
||||
if (newURL != null && newURL.trim().length() > 0 && req.getMethod().equals("GET"))
|
||||
_manager.addMessage(_("Click \"Add torrent\" button to fetch torrent"));
|
||||
out.write("<div class=\"page\"><div class=\"mainsection\"><div class=\"snarkMessages\"><table><tr><td align=\"left\"><pre>");
|
||||
out.write("<div class=\"page\"><div id=\"mainsection\" class=\"mainsection\">");
|
||||
|
||||
writeMessages(out);
|
||||
|
||||
if (isConfigure) {
|
||||
// end of mainsection div
|
||||
out.write("<div class=\"logshim\"></div></div>\n");
|
||||
writeConfigForm(out, req);
|
||||
writeTrackerForm(out, req);
|
||||
} else {
|
||||
writeTorrents(out, req);
|
||||
// end of mainsection div
|
||||
out.write("</div><div id=\"lowersection\">\n");
|
||||
writeAddForm(out, req);
|
||||
writeSeedForm(out, req);
|
||||
writeConfigLink(out);
|
||||
// end of lowersection div
|
||||
out.write("</div>\n");
|
||||
}
|
||||
out.write(FOOTER);
|
||||
}
|
||||
|
||||
private void writeMessages(PrintWriter out) throws IOException {
|
||||
out.write("<div class=\"snarkMessages\"><table><tr><td align=\"left\"><pre>");
|
||||
List msgs = _manager.getMessages();
|
||||
for (int i = msgs.size()-1; i >= 0; i--) {
|
||||
String msg = (String)msgs.get(i);
|
||||
out.write(msg + "\n");
|
||||
}
|
||||
out.write("</pre></td></tr></table></div>");
|
||||
|
||||
if (isConfigure) {
|
||||
out.write("<div class=\"logshim\"></div></div>\n");
|
||||
writeConfigForm(out, req);
|
||||
} else {
|
||||
writeTorrents(out, req);
|
||||
out.write("</div>\n");
|
||||
writeAddForm(out, req);
|
||||
writeSeedForm(out, req);
|
||||
writeConfigLink(out);
|
||||
}
|
||||
out.write(FOOTER);
|
||||
}
|
||||
|
||||
private void writeTorrents(PrintWriter out, HttpServletRequest req) throws IOException {
|
||||
@@ -276,7 +313,6 @@ public class I2PSnarkServlet extends Default {
|
||||
String peerParam = req.getParameter("p");
|
||||
|
||||
List snarks = getSortedSnarks(req);
|
||||
String uri = req.getRequestURI();
|
||||
boolean isForm = _manager.util().connected() || !snarks.isEmpty();
|
||||
if (isForm) {
|
||||
out.write("<form action=\"_post\" method=\"POST\">\n");
|
||||
@@ -390,6 +426,7 @@ public class I2PSnarkServlet extends Default {
|
||||
out.write(" ");
|
||||
}
|
||||
out.write("</th></tr></thead>\n");
|
||||
String uri = "/i2psnark/";
|
||||
for (int i = 0; i < snarks.size(); i++) {
|
||||
Snark snark = (Snark)snarks.get(i);
|
||||
boolean showDebug = "2".equals(peerParam);
|
||||
@@ -650,14 +687,19 @@ public class I2PSnarkServlet extends Default {
|
||||
_manager.updateConfig(dataDir, filesPublic, autoStart, refreshDel, startupDel,
|
||||
seedPct, eepHost, eepPort, i2cpHost, i2cpPort, i2cpOpts,
|
||||
upLimit, upBW, useOpenTrackers, openTrackers, theme);
|
||||
} else if ("Save2".equals(action)) {
|
||||
String taction = req.getParameter("taction");
|
||||
if (taction != null)
|
||||
processTrackerForm(taction, req);
|
||||
} else if ("Create".equals(action)) {
|
||||
String baseData = req.getParameter("baseFile");
|
||||
if (baseData != null && baseData.trim().length() > 0) {
|
||||
File baseFile = new File(_manager.getDataDir(), baseData);
|
||||
String announceURL = req.getParameter("announceURL");
|
||||
String announceURLOther = req.getParameter("announceURLOther");
|
||||
if ( (announceURLOther != null) && (announceURLOther.trim().length() > "http://.i2p/announce".length()) )
|
||||
announceURL = announceURLOther;
|
||||
// make the user add a tracker on the config form now
|
||||
//String announceURLOther = req.getParameter("announceURLOther");
|
||||
//if ( (announceURLOther != null) && (announceURLOther.trim().length() > "http://.i2p/announce".length()) )
|
||||
// announceURL = announceURLOther;
|
||||
|
||||
if (announceURL == null || announceURL.length() <= 0)
|
||||
_manager.addMessage(_("Error creating torrent - you must select a tracker"));
|
||||
@@ -668,7 +710,7 @@ public class I2PSnarkServlet extends Default {
|
||||
try {
|
||||
// This may take a long time to check the storage, but since it already exists,
|
||||
// it shouldn't be THAT bad, so keep it in this thread.
|
||||
Storage s = new Storage(_manager.util(), baseFile, announceURL, null);
|
||||
Storage s = new Storage(_manager.util(), baseFile, announceURL, req.getParameter("private") != null, null);
|
||||
s.close(); // close the files... maybe need a way to pass this Storage to addTorrent rather than starting over
|
||||
MetaInfo info = s.getMetaInfo();
|
||||
File torrentFile = new File(_manager.getDataDir(), s.getBaseName() + ".torrent");
|
||||
@@ -713,6 +755,54 @@ public class I2PSnarkServlet extends Default {
|
||||
_manager.addMessage("Unknown POST action: \"" + action + '\"');
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 0.9 */
|
||||
private void processTrackerForm(String action, HttpServletRequest req) {
|
||||
if (action.equals(_("Delete selected"))) {
|
||||
boolean changed = false;
|
||||
Map<String, String> trackers = _manager.getTrackers();
|
||||
Enumeration e = req.getParameterNames();
|
||||
while (e.hasMoreElements()) {
|
||||
Object o = e.nextElement();
|
||||
if (!(o instanceof String))
|
||||
continue;
|
||||
String k = (String) o;
|
||||
if (!k.startsWith("delete_"))
|
||||
continue;
|
||||
k = k.substring(7);
|
||||
if (trackers.remove(k) != null) {
|
||||
_manager.addMessage(_("Removed") + ": " + k);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
_manager.saveTrackerMap();
|
||||
}
|
||||
} else if (action.equals(_("Add tracker"))) {
|
||||
String name = req.getParameter("tname");
|
||||
String hurl = req.getParameter("thurl");
|
||||
String aurl = req.getParameter("taurl");
|
||||
if (name != null && hurl != null && aurl != null) {
|
||||
name = name.trim();
|
||||
hurl = hurl.trim();
|
||||
aurl = aurl.trim().replace("=", "=");
|
||||
if (name.length() > 0 && hurl.startsWith("http://") && aurl.startsWith("http://")) {
|
||||
Map<String, String> trackers = _manager.getTrackers();
|
||||
trackers.put(name, aurl + '=' + hurl);
|
||||
_manager.saveTrackerMap();
|
||||
} else {
|
||||
_manager.addMessage(_("Enter valid tracker name and URLs"));
|
||||
}
|
||||
} else {
|
||||
_manager.addMessage(_("Enter valid tracker name and URLs"));
|
||||
}
|
||||
} else if (action.equals(_("Restore defaults"))) {
|
||||
_manager.setDefaultTrackerMap();
|
||||
_manager.addMessage(_("Restored default trackers"));
|
||||
} else {
|
||||
_manager.addMessage("Unknown POST action: \"" + action + '\"');
|
||||
}
|
||||
}
|
||||
|
||||
private static final String iopts[] = {"inbound.length", "inbound.quantity",
|
||||
"outbound.length", "outbound.quantity" };
|
||||
@@ -1222,7 +1312,7 @@ public class I2PSnarkServlet extends Default {
|
||||
out.write("\"> \n");
|
||||
// not supporting from file at the moment, since the file name passed isn't always absolute (so it may not resolve)
|
||||
//out.write("From file: <input type=\"file\" name=\"newFile\" size=\"50\" value=\"" + newFile + "\" /><br>");
|
||||
out.write("<input type=\"submit\" value=\"");
|
||||
out.write("<input type=\"submit\" class=\"add\" value=\"");
|
||||
out.write(_("Add torrent"));
|
||||
out.write("\" name=\"foo\" ><br>\n");
|
||||
out.write("<tr><td> <td><span class=\"snarkAddInfo\">");
|
||||
@@ -1269,31 +1359,40 @@ public class I2PSnarkServlet extends Default {
|
||||
//out.write(_("Open trackers and DHT only"));
|
||||
out.write(_("Open trackers only"));
|
||||
out.write("</option>\n");
|
||||
Map trackers = _manager.getTrackers();
|
||||
for (Iterator iter = trackers.entrySet().iterator(); iter.hasNext(); ) {
|
||||
Map.Entry entry = (Map.Entry)iter.next();
|
||||
String name = (String)entry.getKey();
|
||||
String announceURL = (String)entry.getValue();
|
||||
Map<String, String> trackers = _manager.getTrackers();
|
||||
for (Map.Entry<String, String> entry : trackers.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
String announceURL = entry.getValue();
|
||||
int e = announceURL.indexOf('=');
|
||||
if (e > 0)
|
||||
announceURL = announceURL.substring(0, e);
|
||||
announceURL = announceURL.substring(0, e).replace("=", "=");
|
||||
if (announceURL.equals(_lastAnnounceURL))
|
||||
announceURL += "\" selected=\"selected";
|
||||
out.write("\t<option value=\"" + announceURL + "\">" + name + "</option>\n");
|
||||
}
|
||||
out.write("</select>\n");
|
||||
out.write(_("or"));
|
||||
out.write(" <input type=\"text\" name=\"announceURLOther\" size=\"57\" value=\"http://\" " +
|
||||
"title=\"");
|
||||
out.write(_("Specify custom tracker announce URL"));
|
||||
out.write("\" > " +
|
||||
"<input type=\"submit\" value=\"");
|
||||
// make the user add a tracker on the config form now
|
||||
//out.write(_("or"));
|
||||
//out.write(" <input type=\"text\" name=\"announceURLOther\" size=\"57\" value=\"http://\" " +
|
||||
// "title=\"");
|
||||
//out.write(_("Specify custom tracker announce URL"));
|
||||
//out.write("\" > " +
|
||||
out.write(" <input type=\"submit\" class=\"create\" value=\"");
|
||||
out.write(_("Create torrent"));
|
||||
out.write("\" name=\"foo\" ></table>\n" +
|
||||
out.write("\" name=\"foo\" >\n" +
|
||||
"</td></tr><tr><td>");
|
||||
out.write(_("Private?"));
|
||||
out.write(" </td><td> <input type=\"checkbox\" class=\"optbox\" name=\"private\" value=\"true\" title=\"");
|
||||
out.write(_("Use for private trackers"));
|
||||
out.write("\"");
|
||||
if (req.getParameter("private") != null)
|
||||
out.write(" checked");
|
||||
out.write("></td></tr>" +
|
||||
"</table>\n" +
|
||||
"</form></div></div>");
|
||||
}
|
||||
|
||||
private static final int[] times = { 30, 60, 2*60, 5*60, 10*60, 30*60, -1 };
|
||||
private static final int[] times = { 5, 15, 30, 60, 2*60, 5*60, 10*60, 30*60, -1 };
|
||||
|
||||
private void writeConfigForm(PrintWriter out, HttpServletRequest req) throws IOException {
|
||||
String dataDir = _manager.getDataDir().getAbsolutePath();
|
||||
@@ -1356,7 +1455,7 @@ public class I2PSnarkServlet extends Default {
|
||||
out.write(Integer.toString(times[i]));
|
||||
out.write("\"");
|
||||
if (times[i] == delay)
|
||||
out.write(" selected=\"true\"");
|
||||
out.write(" selected=\"selected\"");
|
||||
out.write(">");
|
||||
if (times[i] > 0)
|
||||
out.write(DataHelper.formatDuration2(times[i] * 1000));
|
||||
@@ -1379,15 +1478,15 @@ public class I2PSnarkServlet extends Default {
|
||||
/*
|
||||
out.write("Seed percentage: <select name=\"seedPct\" disabled=\"true\" >\n\t");
|
||||
if (seedPct <= 0)
|
||||
out.write("<option value=\"0\" selected=\"true\">Unlimited</option>\n\t");
|
||||
out.write("<option value=\"0\" selected=\"selected\">Unlimited</option>\n\t");
|
||||
else
|
||||
out.write("<option value=\"0\">Unlimited</option>\n\t");
|
||||
if (seedPct == 100)
|
||||
out.write("<option value=\"100\" selected=\"true\">100%</option>\n\t");
|
||||
out.write("<option value=\"100\" selected=\"selected\">100%</option>\n\t");
|
||||
else
|
||||
out.write("<option value=\"100\">100%</option>\n\t");
|
||||
if (seedPct == 150)
|
||||
out.write("<option value=\"150\" selected=\"true\">150%</option>\n\t");
|
||||
out.write("<option value=\"150\" selected=\"selected\">150%</option>\n\t");
|
||||
else
|
||||
out.write("<option value=\"150\">150%</option>\n\t");
|
||||
out.write("</select><br>\n");
|
||||
@@ -1473,6 +1572,57 @@ public class I2PSnarkServlet extends Default {
|
||||
"</table></div></div></form>");
|
||||
}
|
||||
|
||||
/** @since 0.9 */
|
||||
private void writeTrackerForm(PrintWriter out, HttpServletRequest req) throws IOException {
|
||||
StringBuilder buf = new StringBuilder(1024);
|
||||
buf.append("<form action=\"/i2psnark/configure\" method=\"POST\">\n" +
|
||||
"<div class=\"configsectionpanel\"><div class=\"snarkConfig\">\n" +
|
||||
"<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n" +
|
||||
"<input type=\"hidden\" name=\"action\" value=\"Save2\" >\n" +
|
||||
"<span class=\"snarkConfigTitle\">" +
|
||||
"<img alt=\"\" border=\"0\" src=\"" + _imgPath + "config.png\"> ");
|
||||
buf.append(_("Trackers"));
|
||||
buf.append("</span><hr>\n" +
|
||||
"<table><tr><th>")
|
||||
//.append(_("Remove"))
|
||||
.append("</th><th>")
|
||||
.append(_("Name"))
|
||||
.append("</th><th>")
|
||||
.append(_("Website URL"))
|
||||
.append("</th><th>")
|
||||
.append(_("Announce URL"))
|
||||
.append("</th></tr>\n");
|
||||
Map<String, String> trackers = _manager.getTrackers();
|
||||
for (Map.Entry<String, String> entry : trackers.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
String announceURL = entry.getValue();
|
||||
int e = announceURL.indexOf('=');
|
||||
if (e <= 0)
|
||||
continue;
|
||||
String homeURL = announceURL.substring(e + 1);
|
||||
announceURL = announceURL.substring(0, e).replace("=", "=");
|
||||
buf.append("<tr><td align=\"center\"><input type=\"checkbox\" class=\"optbox\" name=\"delete_")
|
||||
.append(name).append("\">" +
|
||||
"</td><td align=\"left\">").append(name)
|
||||
.append("</td><td align=\"left\">").append(urlify(homeURL, 35))
|
||||
.append("</td><td align=\"left\">").append(urlify(announceURL, 35))
|
||||
.append("</td></tr>\n");
|
||||
}
|
||||
buf.append("<tr><td align=\"center\"><b>")
|
||||
.append(_("Add")).append(":</b></td>" +
|
||||
"<td align=\"left\"><input type=\"text\" size=\"16\" name=\"tname\"></td>" +
|
||||
"<td align=\"left\"><input type=\"text\" size=\"40\" name=\"thurl\"></td>" +
|
||||
"<td align=\"left\"><input type=\"text\" size=\"40\" name=\"taurl\"></td></tr>\n" +
|
||||
"<tr><td colspan=\"2\"></td><td colspan=\"2\" align=\"left\">\n" +
|
||||
"<input type=\"submit\" name=\"taction\" class=\"default\" value=\"").append(_("Add tracker")).append("\">\n" +
|
||||
"<input type=\"submit\" name=\"taction\" class=\"delete\" value=\"").append(_("Delete selected")).append("\">\n" +
|
||||
// "<input type=\"reset\" class=\"cancel\" value=\"").append(_("Cancel")).append("\">\n" +
|
||||
"<input type=\"submit\" name=\"taction\" class=\"reload\" value=\"").append(_("Restore defaults")).append("\">\n" +
|
||||
"<input type=\"submit\" name=\"taction\" class=\"add\" value=\"").append(_("Add tracker")).append("\">\n" +
|
||||
"</td></tr></table></div></div></form>\n");
|
||||
out.write(buf.toString());
|
||||
}
|
||||
|
||||
private void writeConfigLink(PrintWriter out) throws IOException {
|
||||
out.write("<div class=\"configsection\"><span class=\"snarkConfig\">\n" +
|
||||
"<span class=\"snarkConfigTitle\"><a href=\"configure\">" +
|
||||
@@ -1574,7 +1724,7 @@ public class I2PSnarkServlet extends Default {
|
||||
for (int i = min; i <= max; i++) {
|
||||
buf.append("<option value=\"").append(i).append("\" ");
|
||||
if (i == now)
|
||||
buf.append("selected=\"true\" ");
|
||||
buf.append("selected=\"selected\" ");
|
||||
// constants to prevent tagging
|
||||
buf.append(">").append(ngettext(DUMMY1 + name, DUMMY0 + name + 's', i));
|
||||
buf.append("</option>\n");
|
||||
@@ -1622,16 +1772,26 @@ public class I2PSnarkServlet extends Default {
|
||||
|
||||
/** @since 0.7.14 */
|
||||
private static String urlify(String s) {
|
||||
return urlify(s, 100);
|
||||
}
|
||||
|
||||
/** @since 0.9 */
|
||||
private static String urlify(String s, int max) {
|
||||
StringBuilder buf = new StringBuilder(256);
|
||||
// browsers seem to work without doing this but let's be strict
|
||||
String link = urlEncode(s);
|
||||
buf.append("<a href=\"").append(link).append("\">").append(link).append("</a>");
|
||||
String display;
|
||||
if (s.length() <= max)
|
||||
display = link;
|
||||
else
|
||||
display = urlEncode(s.substring(0, max)) + "…";
|
||||
buf.append("<a href=\"").append(link).append("\">").append(display).append("</a>");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/** @since 0.8.13 */
|
||||
private static String urlEncode(String s) {
|
||||
return s.replace("&", "&").replace(" ", "%20").replace(":", "%3A").replace("/", "%2F").replace(";", "%3B");
|
||||
return s.replace(";", "%3B").replace("&", "&").replace(" ", "%20");
|
||||
}
|
||||
|
||||
private static final String DOCTYPE = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
|
||||
@@ -1686,7 +1846,7 @@ public class I2PSnarkServlet extends Default {
|
||||
|
||||
StringBuilder buf=new StringBuilder(4096);
|
||||
buf.append(DOCTYPE + "<HTML><HEAD><TITLE>");
|
||||
String title = URI.decodePath(base);
|
||||
String title = URIUtil.decodePath(base);
|
||||
if (title.startsWith("/i2psnark/"))
|
||||
title = title.substring("/i2psnark/".length());
|
||||
|
||||
@@ -1795,7 +1955,7 @@ public class I2PSnarkServlet extends Default {
|
||||
.append(_("Priority")).append("</th>");
|
||||
buf.append("</tr></thead>\n");
|
||||
buf.append("<tr><td colspan=\"" + (showPriority ? '4' : '3') + "\" class=\"ParentDir\"><A HREF=\"");
|
||||
buf.append(URI.addPaths(base,"../"));
|
||||
buf.append(URIUtil.addPaths(base,"../"));
|
||||
buf.append("\"><img alt=\"\" border=\"0\" src=\"" + _imgPath + "up.png\"> ")
|
||||
.append(_("Up to higher level directory")).append("</A></td></tr>\n");
|
||||
|
||||
@@ -1805,7 +1965,7 @@ public class I2PSnarkServlet extends Default {
|
||||
boolean showSaveButton = false;
|
||||
for (int i=0 ; i< ls.length ; i++)
|
||||
{
|
||||
String encoded=URI.encodePath(ls[i]);
|
||||
String encoded=URIUtil.encodePath(ls[i]);
|
||||
// bugfix for I2P - Backport from Jetty 6 (zero file lengths and last-modified times)
|
||||
// http://jira.codehaus.org/browse/JETTY-361?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel#issue-tabs
|
||||
// See resource.diff attachment
|
||||
@@ -1861,9 +2021,9 @@ public class I2PSnarkServlet extends Default {
|
||||
}
|
||||
}
|
||||
|
||||
String path=URI.addPaths(base,encoded);
|
||||
String path=URIUtil.addPaths(base,encoded);
|
||||
if (item.isDirectory() && !path.endsWith("/"))
|
||||
path=URI.addPaths(path,"/");
|
||||
path=URIUtil.addPaths(path,"/");
|
||||
String icon = toIcon(item);
|
||||
|
||||
if (complete) {
|
||||
@@ -1991,12 +2151,12 @@ public class I2PSnarkServlet extends Default {
|
||||
|
||||
/** @since 0.7.14 */
|
||||
private static String toImg(String icon) {
|
||||
return "<img alt=\"\" height=\"16\" width=\"16\" src=\"/i2psnark/_icons/" + icon + ".png\">";
|
||||
return "<img alt=\"\" height=\"16\" width=\"16\" src=\"/i2psnark/.icons/" + icon + ".png\">";
|
||||
}
|
||||
|
||||
/** @since 0.8.2 */
|
||||
private static String toImg(String icon, String altText) {
|
||||
return "<img alt=\"" + altText + "\" height=\"16\" width=\"16\" src=\"/i2psnark/_icons/" + icon + ".png\">";
|
||||
return "<img alt=\"" + altText + "\" height=\"16\" width=\"16\" src=\"/i2psnark/.icons/" + icon + ".png\">";
|
||||
}
|
||||
|
||||
/** @since 0.8.1 */
|
||||
@@ -2080,8 +2240,8 @@ private static class FetchAndAdd implements Runnable {
|
||||
//if (peerParam != null)
|
||||
// buf.append("<input type=\"hidden\" name=\"p\" value=\"").append(peerParam).append("\" >\n");
|
||||
buf.append(_("Torrent was not retrieved from {0}", urlify(_url)));
|
||||
String link = urlEncode(_url);
|
||||
/**** FIXME ticket #575
|
||||
String link = urlEncode(_url).replace(":", "%3A").replace("/", "%2F");
|
||||
buf.append(" - [<a href=\"/i2psnark/?newURL=").append(link).append("#add\" >");
|
||||
buf.append(_("Retry"));
|
||||
buf.append("</a>]");
|
||||
|
||||
@@ -31,6 +31,8 @@ public class RunStandalone {
|
||||
if (!workDirCreated)
|
||||
System.err.println("ERROR: Unable to create Jetty temporary work directory");
|
||||
|
||||
throw new RuntimeException("unsupported");
|
||||
/****
|
||||
try {
|
||||
_server = new Server("jetty-i2psnark.xml");
|
||||
// just blow up NPE if we don't have a context
|
||||
@@ -39,13 +41,17 @@ public class RunStandalone {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
****/
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
throw new RuntimeException("unsupported");
|
||||
/****
|
||||
try {
|
||||
_server.stop();
|
||||
} catch (InterruptedException ie) {
|
||||
ie.printStackTrace();
|
||||
}
|
||||
****/
|
||||
}
|
||||
}
|
||||
|
||||
988
apps/i2psnark/locale/messages_cs.po
Normal file
@@ -0,0 +1,988 @@
|
||||
# I2P
|
||||
# Copyright (C) 2009 The I2P Project
|
||||
# This file is distributed under the same license as the i2psnark package.
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2012-02-17 11:41+0000\n"
|
||||
"PO-Revision-Date: 2012-02-12 20:06+0000\n"
|
||||
"Last-Translator: Waseihou Watashi <waseihou@gmail.com>\n"
|
||||
"Language-Team: Czech (http://www.transifex.net/projects/p/I2P/language/cs/)\n"
|
||||
"Language: cs\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:355
|
||||
#, java-format
|
||||
msgid "Total uploaders limit changed to {0}"
|
||||
msgstr "Celkový limit sdílečů změněn na {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:357
|
||||
#, java-format
|
||||
msgid "Minimum total uploaders limit is {0}"
|
||||
msgstr "Nejmenší celkový limit sdílečů je {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:369
|
||||
#, java-format
|
||||
msgid "Up BW limit changed to {0}KBps"
|
||||
msgstr "Horní BW limit změněn na {0}KBps"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:371
|
||||
#, java-format
|
||||
msgid "Minimum up bandwidth limit is {0}KBps"
|
||||
msgstr "Nejmenší horní limit přenosové rychlist je {0}KBps"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:383
|
||||
#, java-format
|
||||
msgid "Startup delay changed to {0}"
|
||||
msgstr "Prodleva při startu změněna na {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:394
|
||||
#, java-format
|
||||
msgid "Refresh time changed to {0}"
|
||||
msgstr "Doba aktualizace stavu (refresh time) změněna na {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:396
|
||||
msgid "Refresh disabled"
|
||||
msgstr "Aktualizace stavu vypnuta"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:451
|
||||
msgid "I2CP and tunnel changes will take effect after stopping all torrents"
|
||||
msgstr "Změny I2CP a tunelu se projeví až po zastavení všech torrentů"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:455
|
||||
#, java-format
|
||||
msgid "I2CP options changed to {0}"
|
||||
msgstr "Nastavení (options) I2CP změněno na {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:460
|
||||
msgid "Disconnecting old I2CP destination"
|
||||
msgstr "Odpojuji se od starého I2CP cíle"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:462
|
||||
#, java-format
|
||||
msgid "I2CP settings changed to {0}"
|
||||
msgstr "Nastavení (settings) I2CP změněno na {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:467
|
||||
msgid ""
|
||||
"Unable to connect with the new settings, reverting to the old I2CP settings"
|
||||
msgstr "Nemůžu se připojit s novým nastavením I2CP, vracím se k předhozímu."
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:471
|
||||
msgid "Unable to reconnect with the old settings!"
|
||||
msgstr "Nemohu se opětovně připojit ani s předchozím nastavením!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:473
|
||||
msgid "Reconnected on the new I2CP destination"
|
||||
msgstr "Opětovně připojeno k novému I2CP cíli"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:480
|
||||
#, java-format
|
||||
msgid "I2CP listener restarted for \"{0}\""
|
||||
msgstr "I2CP listener restartován pro \"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:492
|
||||
msgid "New files will be publicly readable"
|
||||
msgstr "Nové soubory budou veřejně přístupné"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:494
|
||||
msgid "New files will not be publicly readable"
|
||||
msgstr "Nové soubory nebudou veřejně přístupné"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:501
|
||||
msgid "Enabled autostart"
|
||||
msgstr "Automatické spuštění zapnuto"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:503
|
||||
msgid "Disabled autostart"
|
||||
msgstr "Automatické spuštění vypnuto"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:509
|
||||
msgid "Enabled open trackers - torrent restart required to take effect."
|
||||
msgstr "Zapnuto automatické spuštění"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:511
|
||||
msgid "Disabled open trackers - torrent restart required to take effect."
|
||||
msgstr ""
|
||||
"Otevřené trackery vypnuty - aby se změna projevila je nutné restartovat "
|
||||
"všechny torrenty"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:519
|
||||
msgid "Open Tracker list changed - torrent restart required to take effect."
|
||||
msgstr ""
|
||||
"Seznam otevřených trackerů změněn - aby se změna projevila je nutné "
|
||||
"restartovat všechny torrenty"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:526
|
||||
#, java-format
|
||||
msgid "{0} theme loaded, return to main i2psnark page to view."
|
||||
msgstr "Téma {0} bylo nahráno, přejděte prosím na hlavní stránku i2snark"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:533
|
||||
msgid "Configuration unchanged."
|
||||
msgstr "Nastavení nebylo změněno."
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:543
|
||||
#, java-format
|
||||
msgid "Unable to save the config to {0}"
|
||||
msgstr "Nemůžu uložit soubor s nastavením do souboru {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:608
|
||||
msgid "Connecting to I2P"
|
||||
msgstr "Připojuji se k I2P"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:611
|
||||
msgid "Error connecting to I2P - check your I2CP settings!"
|
||||
msgstr ""
|
||||
"Při připojování k I2P nastala chyba, zkontrolujte prosím nastavení I2CP!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:620
|
||||
#, java-format
|
||||
msgid "Error: Could not add the torrent {0}"
|
||||
msgstr "Chyba: nepodařilo se přidat torrent {0}"
|
||||
|
||||
#. catch this here so we don't try do delete it below
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:642
|
||||
#, java-format
|
||||
msgid "Cannot open \"{0}\""
|
||||
msgstr "Nejde otevřít \"{0}\""
|
||||
|
||||
#. TODO - if the existing one is a magnet, delete it and add the metainfo instead?
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:661
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:737
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:792
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2048
|
||||
#, java-format
|
||||
msgid "Torrent with this info hash is already running: {0}"
|
||||
msgstr "Torrent s tímto infohašišem již běží: {0}"
|
||||
|
||||
#. addMessage(_("Warning - No I2P trackers in \"{0}\", will announce to I2P open trackers and DHT only.", info.getName()));
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:668
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Warning - No I2P trackers in \"{0}\", will announce to I2P open trackers "
|
||||
"only."
|
||||
msgstr ""
|
||||
"Varování - v \"{0}\" nebyly nalezeny žádné I2P trackery, budou použity pouze "
|
||||
"otevrené I2P trackery."
|
||||
|
||||
#. addMessage(_("Warning - No I2P trackers in \"{0}\", and DHT and open trackers are disabled, you should enable open trackers or DHT before starting the torrent.", info.getName()));
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:673
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Warning - No I2P Trackers found in \"{0}\". Make sure Open Tracker is "
|
||||
"enabled before starting this torrent."
|
||||
msgstr ""
|
||||
"Varování - v \"{0}\" nebyly nalezeny žádné I2P trackery, před spuštěním "
|
||||
"tohoto torrentu se ujistěte že otevřené trackery jsou povoleny."
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:694
|
||||
#, java-format
|
||||
msgid "Torrent in \"{0}\" is invalid"
|
||||
msgstr "Torrent v \"{0}\" je chybný"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:699
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2070
|
||||
#, java-format
|
||||
msgid "ERROR - Out of memory, cannot create torrent from {0}"
|
||||
msgstr "CHYBA - nedostatek paměti, nemohu vytvořit torrent z {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:711
|
||||
#, java-format
|
||||
msgid "Torrent added and started: \"{0}\""
|
||||
msgstr "Torrent přidán a spuštěn: \"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:713
|
||||
#, java-format
|
||||
msgid "Torrent added: \"{0}\""
|
||||
msgstr "Torrent přidán: \"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:748
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:499
|
||||
#, java-format
|
||||
msgid "Fetching {0}"
|
||||
msgstr "Získávám {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:751
|
||||
#, java-format
|
||||
msgid ""
|
||||
"We have no saved peers and no other torrents are running. Fetch of {0} will "
|
||||
"not succeed until you start another torrent."
|
||||
msgstr ""
|
||||
"Nejsou uloženi žádní sdíleči a žádné další torrenty neběží. Získání {0} "
|
||||
"neuspěje dokud nespustíte nějaký další torrent."
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:755
|
||||
#, java-format
|
||||
msgid "Adding {0}"
|
||||
msgstr "Přídávám {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:802
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:825
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1260
|
||||
#, java-format
|
||||
msgid "Failed to copy torrent file to {0}"
|
||||
msgstr "Chyba: nepodařilo se zkopírovat soubor torrentu do {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1052
|
||||
#, java-format
|
||||
msgid "Too many files in \"{0}\" ({1}), deleting it!"
|
||||
msgstr "V \"{0}\" ({1}) je příliš mnoho souborů, mažu je!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1054
|
||||
#, java-format
|
||||
msgid "Torrent file \"{0}\" cannot end in \".torrent\", deleting it!"
|
||||
msgstr "Jméno souboru torrentu \"{0}\" nemůže končit na \".torrent\", mažu ho!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1056
|
||||
#, java-format
|
||||
msgid "No pieces in \"{0}\", deleting it!"
|
||||
msgstr "\"{0}\" neobsahuje žádné části, mažu to!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1058
|
||||
#, java-format
|
||||
msgid "Too many pieces in \"{0}\", limit is {1}, deleting it!"
|
||||
msgstr "Příliš mnoho částí v \"{0}\", maximum je {1}, mažu to!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1060
|
||||
#, java-format
|
||||
msgid "Pieces are too large in \"{0}\" ({1}B), deleting it."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1061
|
||||
#, java-format
|
||||
msgid "Limit is {0}B"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1063
|
||||
#, java-format
|
||||
msgid "Torrent \"{0}\" has no data, deleting it!"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1071
|
||||
#, java-format
|
||||
msgid "Torrents larger than {0}B are not supported yet, deleting \"{1}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1087
|
||||
#, java-format
|
||||
msgid "Error: Could not remove the torrent {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1108
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1126
|
||||
#, java-format
|
||||
msgid "Torrent stopped: \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1147
|
||||
#, java-format
|
||||
msgid "Torrent removed: \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1155
|
||||
#, java-format
|
||||
msgid "Adding torrents in {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1208
|
||||
#, java-format
|
||||
msgid "Download finished: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1256
|
||||
#, java-format
|
||||
msgid "Metainfo received for {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1257
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:534
|
||||
#, java-format
|
||||
msgid "Starting up torrent {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1313
|
||||
msgid "Unable to connect to I2P!"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1319
|
||||
#, java-format
|
||||
msgid "Unable to add {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:205
|
||||
msgid "I2PSnark - Anonymous BitTorrent Client"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:221
|
||||
msgid "Torrents"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:224
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:231
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1053
|
||||
msgid "I2PSnark"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:228
|
||||
msgid "Refresh page"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:233
|
||||
msgid "Forum"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:251
|
||||
msgid "Click \"Add torrent\" button to fetch torrent"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:290
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1791
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:296
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:298
|
||||
msgid "Hide Peers"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:303
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:305
|
||||
msgid "Show Peers"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:312
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1708
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1724
|
||||
msgid "Torrent"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:316
|
||||
msgid "Estimated time remaining"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: Please keep short or translate as " "
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:319
|
||||
msgid "ETA"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:323
|
||||
msgid "Downloaded"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: Please keep short or translate as " "
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:326
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:340
|
||||
msgid "RX"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:330
|
||||
msgid "Uploaded"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: Please keep short or translate as " "
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:333
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:350
|
||||
msgid "TX"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:338
|
||||
msgid "Down Rate"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: Please keep short or translate as " "
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:343
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:352
|
||||
msgid "Rate"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:348
|
||||
msgid "Up Rate"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:372
|
||||
msgid "Stop all torrents and the I2P tunnel"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:374
|
||||
msgid "Stop All"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:383
|
||||
msgid "Start all torrents and the I2P tunnel"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:385
|
||||
msgid "Start All"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:404
|
||||
msgid "No torrents loaded."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:409
|
||||
msgid "Totals"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:411
|
||||
#, java-format
|
||||
msgid "1 torrent"
|
||||
msgid_plural "{0} torrents"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[2] ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:414
|
||||
#, java-format
|
||||
msgid "1 connected peer"
|
||||
msgid_plural "{0} connected peers"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[2] ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:498
|
||||
msgid "Opening the I2P tunnel"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:505
|
||||
#, java-format
|
||||
msgid "Invalid URL: Must start with \"http://\", \"{0}\", or \"{1}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:553
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:580
|
||||
#, java-format
|
||||
msgid "Magnet deleted: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:561
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:586
|
||||
#, java-format
|
||||
msgid "Torrent file deleted: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:592
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:603
|
||||
#, java-format
|
||||
msgid "Data file deleted: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:594
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:605
|
||||
#, java-format
|
||||
msgid "Data file could not be deleted: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:617
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:624
|
||||
#, java-format
|
||||
msgid "Data dir deleted: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:663
|
||||
msgid "Error creating torrent - you must select a tracker"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:678
|
||||
#, java-format
|
||||
msgid "Torrent created for \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:680
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Many I2P trackers require you to register new torrents before seeding - "
|
||||
"please do so before starting \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:682
|
||||
#, java-format
|
||||
msgid "Error creating a torrent for \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:685
|
||||
#, java-format
|
||||
msgid "Cannot create a torrent for the nonexistent data: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:688
|
||||
msgid "Error creating torrent - you must enter a file or directory"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:691
|
||||
msgid "Stopping all torrents and closing the I2P tunnel."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:702
|
||||
msgid "I2P tunnel closed."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:705
|
||||
msgid "Opening the I2P tunnel and starting all torrents."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:827
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:832
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:838
|
||||
msgid "Tracker Error"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:830
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:834
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:846
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:850
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:858
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:862
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:867
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:871
|
||||
#, java-format
|
||||
msgid "1 peer"
|
||||
msgid_plural "{0} peers"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[2] ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:843
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:848
|
||||
msgid "Seeding"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:852
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1730
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1842
|
||||
msgid "Complete"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:855
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:860
|
||||
msgid "OK"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:864
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:869
|
||||
msgid "Stalled"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:873
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:876
|
||||
msgid "No Peers"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:878
|
||||
msgid "Stopped"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:911
|
||||
msgid "Torrent details"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:923
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1187
|
||||
msgid "Info"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:938
|
||||
msgid "View files"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:940
|
||||
msgid "Open file"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:982
|
||||
msgid "Stop the torrent"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:984
|
||||
msgid "Stop"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:994
|
||||
msgid "Start the torrent"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:996
|
||||
msgid "Start"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1007
|
||||
msgid "Remove the torrent from the active list, deleting the .torrent file"
|
||||
msgstr ""
|
||||
|
||||
#. Can't figure out how to escape double quotes inside the onclick string.
|
||||
#. Single quotes in translate strings with parameters must be doubled.
|
||||
#. Then the remaining single quite must be escaped
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1012
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Are you sure you want to delete the file \\''{0}.torrent\\'' (downloaded "
|
||||
"data will not be deleted) ?"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1015
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1026
|
||||
msgid "Delete the .torrent file and the associated data file(s)"
|
||||
msgstr ""
|
||||
|
||||
#. Can't figure out how to escape double quotes inside the onclick string.
|
||||
#. Single quotes in translate strings with parameters must be doubled.
|
||||
#. Then the remaining single quite must be escaped
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1031
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Are you sure you want to delete the torrent \\''{0}\\'' and all downloaded "
|
||||
"data?"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1034
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1069
|
||||
msgid "Unknown"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1081
|
||||
msgid "Seed"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1104
|
||||
msgid "Uninteresting (The peer has no pieces we need)"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1106
|
||||
msgid "Choked (The peer is not allowing us to request pieces)"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1126
|
||||
msgid "Uninterested (We have no pieces the peer needs)"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1128
|
||||
msgid "Choking (We are not allowing the peer to request pieces)"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1186
|
||||
#, java-format
|
||||
msgid "Details at {0} tracker"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1216
|
||||
msgid "Add Torrent"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1218
|
||||
msgid "From URL"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1221
|
||||
msgid ""
|
||||
"Enter the torrent file download URL (I2P only), magnet link, or maggot link"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1226
|
||||
msgid "Add torrent"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1229
|
||||
#, java-format
|
||||
msgid "You can also copy .torrent files to: {0}."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1231
|
||||
msgid "Removing a .torrent will cause it to stop."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1254
|
||||
msgid "Create Torrent"
|
||||
msgstr ""
|
||||
|
||||
#. out.write("From file: <input type=\"file\" name=\"newFile\" size=\"50\" value=\"" + newFile + "\" /><br>\n");
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1257
|
||||
msgid "Data to seed"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1261
|
||||
msgid "File or directory to seed (must be within the specified path)"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1263
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1749
|
||||
msgid "Tracker"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1265
|
||||
msgid "Select a tracker"
|
||||
msgstr ""
|
||||
|
||||
#. out.write(_("Open trackers and DHT only"));
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1270
|
||||
msgid "Open trackers only"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1285
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1288
|
||||
msgid "Specify custom tracker announce URL"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1291
|
||||
msgid "Create torrent"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1312
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1480
|
||||
msgid "Configuration"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1316
|
||||
msgid "Data directory"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1318
|
||||
msgid "Edit i2psnark.config and restart to change"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1322
|
||||
msgid "Files readable by all"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1326
|
||||
msgid "If checked, other users may access the downloaded files"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1330
|
||||
msgid "Auto start"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1334
|
||||
msgid "If checked, automatically start torrents that are added"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1338
|
||||
msgid "Theme"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1351
|
||||
msgid "Refresh time"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1364
|
||||
msgid "Never"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1370
|
||||
msgid "Startup delay"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1372
|
||||
msgid "minutes"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1396
|
||||
msgid "Total uploader limit"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1399
|
||||
msgid "peers"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1403
|
||||
msgid "Up bandwidth limit"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1406
|
||||
msgid "Half available bandwidth recommended."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1408
|
||||
msgid "View or change router bandwidth"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1412
|
||||
msgid "Use open trackers also"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1416
|
||||
msgid ""
|
||||
"If checked, announce torrents to open trackers as well as the tracker listed "
|
||||
"in the torrent file"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1420
|
||||
msgid "Open tracker announce URLs"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1432
|
||||
msgid "Inbound Settings"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1438
|
||||
msgid "Outbound Settings"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1446
|
||||
msgid "I2CP host"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1451
|
||||
msgid "I2CP port"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1466
|
||||
msgid "I2CP options"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1471
|
||||
msgid "Save configuration"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1496
|
||||
#, java-format
|
||||
msgid "Invalid magnet URL {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1530
|
||||
#, java-format
|
||||
msgid "Invalid info hash in magnet URL {0}"
|
||||
msgstr ""
|
||||
|
||||
#. * dummies for translation
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1560
|
||||
#, java-format
|
||||
msgid "1 hop"
|
||||
msgid_plural "{0} hops"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[2] ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1561
|
||||
#, java-format
|
||||
msgid "1 tunnel"
|
||||
msgid_plural "{0} tunnels"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[2] ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1728
|
||||
msgid "Completion"
|
||||
msgstr ""
|
||||
|
||||
#. else unknown
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1732
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1788
|
||||
msgid "Size"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1737
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1739
|
||||
msgid "Pieces"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1740
|
||||
msgid "Piece size"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1762
|
||||
msgid "Magnet link"
|
||||
msgstr ""
|
||||
|
||||
#. We don't have the hash of the torrent file
|
||||
#. buf.append("<br>").append(_("Maggot link")).append(": <a href=\"").append(MAGGOT).append(hex).append(':').append(hex).append("\">")
|
||||
#. .append(MAGGOT).append(hex).append(':').append(hex).append("</a>");
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1768
|
||||
msgid "Torrent file"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1786
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1825
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1795
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1800
|
||||
msgid "Up to higher level directory"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1830
|
||||
msgid "Torrent not found?"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1839
|
||||
msgid "File not found in torrent?"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1852
|
||||
msgid "complete"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1853
|
||||
msgid "bytes remaining"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1878
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1904
|
||||
msgid "High"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1909
|
||||
msgid "Normal"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1914
|
||||
msgid "Skip"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1923
|
||||
msgid "Save priorities"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2039
|
||||
#, java-format
|
||||
msgid "Torrent fetched from {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2060
|
||||
#, java-format
|
||||
msgid "Torrent already running: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2062
|
||||
#, java-format
|
||||
msgid "Torrent already in the queue: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2068
|
||||
#, java-format
|
||||
msgid "Torrent at {0} was not valid"
|
||||
msgstr ""
|
||||
|
||||
#. FIXME don't lose peer setting
|
||||
#. String peerParam = req.getParameter("p");
|
||||
#. if (peerParam != null)
|
||||
#. buf.append("<input type=\"hidden\" name=\"p\" value=\"").append(peerParam).append("\" >\n");
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2082
|
||||
#, java-format
|
||||
msgid "Torrent was not retrieved from {0}"
|
||||
msgstr ""
|
||||
@@ -52,22 +52,22 @@
|
||||
</target>
|
||||
|
||||
|
||||
<!-- TODO: Move the web classes from the jar to the war - they are not part of the API
|
||||
- This will require sponge to rewrite some seedless stuff that uses it.
|
||||
-->
|
||||
<!-- The web classes are now in the war not the jar - they are not part of the API -->
|
||||
<target name="jar" depends="builddep, compile, jarUpToDate, listChangedFiles" unless="jar.uptodate" >
|
||||
<!-- set if unset -->
|
||||
<property name="workspace.changes.j.tr" value="" />
|
||||
<jar destfile="./build/i2ptunnel.jar" basedir="./build/obj" includes="**/*.class">
|
||||
<jar destfile="./build/i2ptunnel.jar" basedir="./build/obj" includes="**/*.class" excludes="**/EditBean.class **/IndexBean.class" >
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="net.i2p.i2ptunnel.I2PTunnel" />
|
||||
<attribute name="Class-Path" value="i2p.jar mstreaming.jar" />
|
||||
<attribute name="Implementation-Version" value="${full.version}" />
|
||||
<attribute name="Built-By" value="${build.built-by}" />
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.j.tr}" />
|
||||
</manifest>
|
||||
</jar>
|
||||
<jar destfile="./build/temp-beans.jar" basedir="./build/obj" includes="**/EditBean.class **/IndexBean.class" />
|
||||
</target>
|
||||
|
||||
<target name="jarUpToDate">
|
||||
@@ -129,13 +129,17 @@
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<!-- The web classes are now in the war not the jar - they are not part of the API -->
|
||||
<target name="war" depends="precompilejsp, bundle, warUpToDate, listChangedFiles2" unless="war.uptodate" >
|
||||
<!-- set if unset -->
|
||||
<property name="workspace.changes.w.tr" value="" />
|
||||
<copy file="build/obj/net/i2p/i2ptunnel/web/EditBean.class" todir="../jsp/WEB-INF/classes/net/i2p/i2ptunnel/web" />
|
||||
<copy file="build/obj/net/i2p/i2ptunnel/web/IndexBean.class" todir="../jsp/WEB-INF/classes/net/i2p/i2ptunnel/web" />
|
||||
<war destfile="build/i2ptunnel.war" webxml="../jsp/web-out.xml"
|
||||
basedir="../jsp/" excludes="web.xml, web-fragment.xml, web-out.xml, **/*.java, *.jsp">
|
||||
<manifest>
|
||||
<attribute name="Implementation-Version" value="${full.version}" />
|
||||
<attribute name="Built-By" value="${build.built-by}" />
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.w.tr}" />
|
||||
@@ -171,11 +175,14 @@
|
||||
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
|
||||
<pathelement location="../../jetty/jettylib/commons-logging.jar" />
|
||||
<pathelement location="../../jetty/jettylib/commons-el.jar" />
|
||||
<pathelement location="../../jetty/jettylib/ant.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
|
||||
<pathelement location="${ant.home}/lib/ant.jar" />
|
||||
<pathelement location="build/i2ptunnel.jar" />
|
||||
<pathelement location="build/temp-beans.jar" />
|
||||
</classpath>
|
||||
<arg value="-d" />
|
||||
<arg value="../jsp/WEB-INF/classes" />
|
||||
<arg value="-v" />
|
||||
<arg value="-p" />
|
||||
<arg value="net.i2p.i2ptunnel.jsp" />
|
||||
<arg value="-webinc" />
|
||||
@@ -192,7 +199,9 @@
|
||||
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
|
||||
<pathelement location="../../jetty/jettylib/commons-logging.jar" />
|
||||
<pathelement location="../../jetty/jettylib/commons-el.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
|
||||
<pathelement location="build/i2ptunnel.jar" />
|
||||
<pathelement location="build/temp-beans.jar" />
|
||||
</classpath>
|
||||
</javac>
|
||||
<copy file="../jsp/web.xml" tofile="../jsp/web-out.xml" />
|
||||
|
||||
@@ -60,6 +60,14 @@ public abstract class I2PTunnelTask extends EventDispatcherImpl {
|
||||
|
||||
public abstract boolean close(boolean forced);
|
||||
|
||||
/**
|
||||
* For tasks that don't call I2PTunnel.addSession() directly
|
||||
* @since 0.8.13
|
||||
*/
|
||||
public void connected(I2PSession session) {
|
||||
getTunnel().addSession(session);
|
||||
}
|
||||
|
||||
public void disconnected(I2PSession session) {
|
||||
routerDisconnected();
|
||||
getTunnel().removeSession(session);
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
/* I2PTunnel is GPL'ed (with the exception mentioned in I2PTunnel.java)
|
||||
* (c) 2003 - 2004 mihi
|
||||
*/
|
||||
package net.i2p.i2ptunnel.localServer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.naming.NamingService;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.i2ptunnel.I2PTunnelHTTPClient;
|
||||
import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.Translate;
|
||||
|
||||
/**
|
||||
* Very simple web server.
|
||||
*
|
||||
* Serve local files in the docs/ directory, for CSS and images in
|
||||
* error pages, using the reserved address proxy.i2p
|
||||
* (similar to p.p in privoxy).
|
||||
* This solves the problems with including links to the router console,
|
||||
* as assuming the router console is at 127.0.0.1 leads to broken
|
||||
* links if it isn't.
|
||||
*
|
||||
* @since 0.7.6, moved from I2PTunnelHTTPClient in 0.9
|
||||
*/
|
||||
public abstract class LocalHTTPServer {
|
||||
|
||||
private final static byte[] ERR_404 =
|
||||
("HTTP/1.1 404 Not Found\r\n"+
|
||||
"Content-Type: text/plain\r\n"+
|
||||
"\r\n"+
|
||||
"HTTP Proxy local file not found")
|
||||
.getBytes();
|
||||
|
||||
private final static byte[] ERR_ADD =
|
||||
("HTTP/1.1 409 Bad\r\n"+
|
||||
"Content-Type: text/plain\r\n"+
|
||||
"\r\n"+
|
||||
"Add to addressbook failed - bad parameters")
|
||||
.getBytes();
|
||||
|
||||
/**
|
||||
* Very simple web server.
|
||||
*
|
||||
* Serve local files in the docs/ directory, for CSS and images in
|
||||
* error pages, using the reserved address proxy.i2p
|
||||
* (similar to p.p in privoxy).
|
||||
* This solves the problems with including links to the router console,
|
||||
* as assuming the router console is at 127.0.0.1 leads to broken
|
||||
* links if it isn't.
|
||||
*
|
||||
* Ignore all request headers (If-Modified-Since, etc.)
|
||||
*
|
||||
* There is basic protection here -
|
||||
* FileUtil.readFile() prevents traversal above the base directory -
|
||||
* but inproxy/gateway ops would be wise to block proxy.i2p to prevent
|
||||
* exposing the docs/ directory or perhaps other issues through
|
||||
* uncaught vulnerabilities.
|
||||
* Restrict to the /themes/ directory for now.
|
||||
*
|
||||
* @param targetRequest decoded path only, non-null
|
||||
* @param query raw (encoded), may be null
|
||||
*/
|
||||
public static void serveLocalFile(OutputStream out, String method, String targetRequest, String query, String proxyNonce) {
|
||||
//System.err.println("targetRequest: \"" + targetRequest + "\"");
|
||||
// a home page message for the curious...
|
||||
if (targetRequest.equals("/")) {
|
||||
try {
|
||||
out.write(("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nCache-Control: max-age=86400\r\n\r\nI2P HTTP proxy OK").getBytes());
|
||||
out.flush();
|
||||
} catch (IOException ioe) {}
|
||||
return;
|
||||
}
|
||||
if ((method.equals("GET") || method.equals("HEAD")) &&
|
||||
targetRequest.startsWith("/themes/") &&
|
||||
!targetRequest.contains("..")) {
|
||||
String filename = null;
|
||||
try {
|
||||
filename = targetRequest.substring(8); // "/themes/".length
|
||||
} catch (IndexOutOfBoundsException ioobe) {
|
||||
return;
|
||||
}
|
||||
// theme hack
|
||||
if (filename.startsWith("console/default/"))
|
||||
filename = filename.replaceFirst("default", I2PAppContext.getGlobalContext().getProperty("routerconsole.theme", "light"));
|
||||
File themesDir = new File(I2PAppContext.getGlobalContext().getBaseDir(), "docs/themes");
|
||||
File file = new File(themesDir, filename);
|
||||
if (file.exists() && !file.isDirectory()) {
|
||||
String type;
|
||||
if (filename.endsWith(".css"))
|
||||
type = "text/css";
|
||||
else if (filename.endsWith(".ico"))
|
||||
type = "image/x-icon";
|
||||
else if (filename.endsWith(".png"))
|
||||
type = "image/png";
|
||||
else if (filename.endsWith(".jpg"))
|
||||
type = "image/jpeg";
|
||||
else type = "text/html";
|
||||
try {
|
||||
out.write("HTTP/1.1 200 OK\r\nContent-Type: ".getBytes());
|
||||
out.write(type.getBytes());
|
||||
out.write("\r\nCache-Control: max-age=86400\r\n\r\n".getBytes());
|
||||
FileUtil.readFile(filename, themesDir.getAbsolutePath(), out);
|
||||
} catch (IOException ioe) {}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add to addressbook (form submit)
|
||||
// Parameters are url, host, dest, nonce, and master | router | private.
|
||||
// Do the add and redirect.
|
||||
if (targetRequest.equals("/add")) {
|
||||
Map<String, String> opts = new HashMap(8);
|
||||
// this only works if all keys are followed by =value
|
||||
StringTokenizer tok = new StringTokenizer(query, "=&;");
|
||||
while (tok.hasMoreTokens()) {
|
||||
String k = tok.nextToken();
|
||||
if (!tok.hasMoreTokens())
|
||||
break;
|
||||
String v = tok.nextToken();
|
||||
opts.put(decode(k), decode(v));
|
||||
}
|
||||
|
||||
String url = opts.get("url");
|
||||
String host = opts.get("host");
|
||||
String b64Dest = opts.get("dest");
|
||||
String nonce = opts.get("nonce");
|
||||
String book = "privatehosts.txt";
|
||||
if (opts.get("master") != null)
|
||||
book = "userhosts.txt";
|
||||
else if (opts.get("router") != null)
|
||||
book = "hosts.txt";
|
||||
Destination dest = null;
|
||||
if (b64Dest != null) {
|
||||
try {
|
||||
dest = new Destination(b64Dest);
|
||||
} catch (DataFormatException dfe) {
|
||||
System.err.println("Bad dest to save?" + b64Dest);
|
||||
}
|
||||
}
|
||||
//System.err.println("url : \"" + url + "\"");
|
||||
//System.err.println("host : \"" + host + "\"");
|
||||
//System.err.println("b64dest : \"" + b64Dest + "\"");
|
||||
//System.err.println("book : \"" + book + "\"");
|
||||
//System.err.println("nonce : \"" + nonce + "\"");
|
||||
if (proxyNonce.equals(nonce) && url != null && host != null && dest != null) {
|
||||
try {
|
||||
NamingService ns = I2PAppContext.getGlobalContext().namingService();
|
||||
Properties nsOptions = new Properties();
|
||||
nsOptions.setProperty("list", book);
|
||||
nsOptions.setProperty("s", _("Added via address helper"));
|
||||
boolean success = ns.put(host, dest, nsOptions);
|
||||
writeRedirectPage(out, success, host, book, url);
|
||||
return;
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
try {
|
||||
out.write(ERR_ADD);
|
||||
out.flush();
|
||||
} catch (IOException ioe) {}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
out.write(ERR_404);
|
||||
out.flush();
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
|
||||
/** @since 0.8.7 */
|
||||
private static void writeRedirectPage(OutputStream out, boolean success, String host, String book, String url) throws IOException {
|
||||
out.write(("HTTP/1.1 200 OK\r\n"+
|
||||
"Content-Type: text/html; charset=UTF-8\r\n"+
|
||||
"\r\n"+
|
||||
"<html><head>"+
|
||||
"<title>" + _("Redirecting to {0}", host) + "</title>\n" +
|
||||
"<link rel=\"shortcut icon\" href=\"http://proxy.i2p/themes/console/images/favicon.ico\" >\n" +
|
||||
"<link href=\"http://proxy.i2p/themes/console/default/console.css\" rel=\"stylesheet\" type=\"text/css\" >\n" +
|
||||
"<meta http-equiv=\"Refresh\" content=\"1; url=" + url + "\">\n" +
|
||||
"</head><body>\n" +
|
||||
"<div class=logo>\n" +
|
||||
"<a href=\"http://127.0.0.1:7657/\" title=\"" + _("Router Console") + "\"><img src=\"http://proxy.i2p/themes/console/images/i2plogo.png\" alt=\"I2P Router Console\" border=\"0\"></a><hr>\n" +
|
||||
"<a href=\"http://127.0.0.1:7657/config\">" + _("Configuration") + "</a> <a href=\"http://127.0.0.1:7657/help.jsp\">" + _("Help") + "</a> <a href=\"http://127.0.0.1:7657/susidns/index\">" + _("Addressbook") + "</a>\n" +
|
||||
"</div>" +
|
||||
"<div class=warning id=warning>\n" +
|
||||
"<h3>" +
|
||||
(success ?
|
||||
_("Saved {0} to the {1} addressbook, redirecting now.", host, book) :
|
||||
_("Failed to save {0} to the {1} addressbook, redirecting now.", host, book)) +
|
||||
"</h3>\n<p><a href=\"" + url + "\">" +
|
||||
_("Click here if you are not redirected automatically.") +
|
||||
"</a></p></div>").getBytes("UTF-8"));
|
||||
I2PTunnelHTTPClient.writeFooter(out);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode %xx encoding
|
||||
* @since 0.8.7
|
||||
*/
|
||||
public static String decode(String s) {
|
||||
if (!s.contains("%"))
|
||||
return s;
|
||||
StringBuilder buf = new StringBuilder(s.length());
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
if (c != '%') {
|
||||
buf.append(c);
|
||||
} else {
|
||||
try {
|
||||
buf.append((char) Integer.parseInt(s.substring(++i, (++i) + 1), 16));
|
||||
} catch (IndexOutOfBoundsException ioobe) {
|
||||
break;
|
||||
} catch (NumberFormatException nfe) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private static final String BUNDLE_NAME = "net.i2p.i2ptunnel.web.messages";
|
||||
|
||||
/** lang in routerconsole.lang property, else current locale */
|
||||
protected static String _(String key) {
|
||||
return Translate.getString(key, I2PAppContext.getGlobalContext(), BUNDLE_NAME);
|
||||
}
|
||||
|
||||
/** {0} */
|
||||
protected static String _(String key, Object o) {
|
||||
return Translate.getString(key, o, I2PAppContext.getGlobalContext(), BUNDLE_NAME);
|
||||
}
|
||||
|
||||
/** {0} and {1} */
|
||||
protected static String _(String key, Object o, Object o2) {
|
||||
return Translate.getString(key, o, o2, I2PAppContext.getGlobalContext(), BUNDLE_NAME);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -107,6 +107,7 @@ import net.i2p.util.Log;
|
||||
try {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(key);
|
||||
_session = client.createSession(in, tunnel.getClientOptions());
|
||||
connected(_session);
|
||||
} catch(Exception exc) {
|
||||
throw new RuntimeException("failed to create session", exc);
|
||||
}
|
||||
|
||||
@@ -103,6 +103,7 @@ public class I2PTunnelUDPServerBase extends I2PTunnelTask implements Source, Sin
|
||||
|
||||
try {
|
||||
_session = client.createSession(privData, getTunnel().getClientOptions());
|
||||
connected(_session);
|
||||
} catch(I2PSessionException exc) {
|
||||
throw new RuntimeException("failed to create session", exc);
|
||||
}
|
||||
|
||||
@@ -342,7 +342,8 @@ public class IndexBean {
|
||||
String pk = cur.getPrivKeyFile();
|
||||
if (pk == null)
|
||||
pk = _privKeyFile;
|
||||
if (pk != null && pk.startsWith("i2ptunnel") && pk.endsWith("-privKeys.dat")) {
|
||||
if (pk != null && pk.startsWith("i2ptunnel") && pk.endsWith("-privKeys.dat") &&
|
||||
((!isClient(cur.getType())) || cur.getPersistentClientKey())) {
|
||||
File pkf = new File(_context.getConfigDir(), pk);
|
||||
if (pkf.exists()) {
|
||||
String name = cur.getName();
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
package net.i2p.i2ptunnel.web;
|
||||
|
||||
/**
|
||||
* A temporary data holder for the wizard pages
|
||||
*
|
||||
* Warning - This class is not part of the i2ptunnel API, and at some point
|
||||
* it will be moved from the jar to the war.
|
||||
* Usage by classes outside of i2ptunnel.war is deprecated.
|
||||
*/
|
||||
public class WizardBean extends EditBean {
|
||||
private boolean _isClient;
|
||||
public WizardBean() { super(); }
|
||||
|
||||
/**
|
||||
* Whether the tunnel being set up is a client tunnel or not.
|
||||
* @since 0.8.13
|
||||
*/
|
||||
public void setIsClient(String isClient) {
|
||||
_isClient = Boolean.valueOf(isClient);
|
||||
}
|
||||
/** @since 0.8.13 */
|
||||
public boolean getIsClient() {
|
||||
return _isClient;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
// NOTE: Do the header carefully so there is no whitespace before the <?xml... line
|
||||
|
||||
%><%@page pageEncoding="UTF-8"
|
||||
%><%@page trimDirectiveWhitespaces="true"
|
||||
%><%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"
|
||||
%><%
|
||||
String tun = request.getParameter("tunnel");
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"%><?xml version="1.0" encoding="UTF-8"?>
|
||||
<%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"
|
||||
%><%@page trimDirectiveWhitespaces="true"
|
||||
%><?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.EditBean" id="editBean" scope="request" />
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.Messages" id="intl" scope="request" />
|
||||
@@ -355,11 +357,11 @@
|
||||
</label>
|
||||
<table border="0"><tr><!-- I give up -->
|
||||
<td><input value="1" type="radio" id="startOnLoad" name="newDest" title="New Destination"
|
||||
<%=(editBean.getNewDest(curTunnel) ? " checked=\"checked\"" : "")%> class="tickbox" />
|
||||
<td><%=intl._("Enable")%>
|
||||
<%=(editBean.getNewDest(curTunnel) ? " checked=\"checked\"" : "")%> class="tickbox" /></td>
|
||||
<td><%=intl._("Enable")%></td>
|
||||
<td><input value="0" type="radio" id="startOnLoad" name="newDest" title="New Destination"
|
||||
<%=(editBean.getNewDest(curTunnel) || editBean.getPersistentClientKey(curTunnel) ? "" : " checked=\"checked\"")%> class="tickbox" />
|
||||
<td><%=intl._("Disable")%>
|
||||
<%=(editBean.getNewDest(curTunnel) || editBean.getPersistentClientKey(curTunnel) ? "" : " checked=\"checked\"")%> class="tickbox" /></td>
|
||||
<td><%=intl._("Disable")%></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div id="portField" class="rowItem">
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"%><?xml version="1.0" encoding="UTF-8"?>
|
||||
<%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"
|
||||
%><%@page trimDirectiveWhitespaces="true"
|
||||
%><?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.EditBean" id="editBean" scope="request" />
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.Messages" id="intl" scope="request" />
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
request.setCharacterEncoding("UTF-8");
|
||||
|
||||
%><%@page pageEncoding="UTF-8"
|
||||
%><%@page trimDirectiveWhitespaces="true"
|
||||
%><%@page contentType="text/html" import="net.i2p.i2ptunnel.web.IndexBean"
|
||||
%><?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
<%
|
||||
// NOTE: Do the header carefully so there is no whitespace before the <?xml... line
|
||||
|
||||
// http://www.crazysquirrel.com/computing/general/form-encoding.jspx
|
||||
if (request.getCharacterEncoding() == null)
|
||||
request.setCharacterEncoding("UTF-8");
|
||||
|
||||
%><%@page pageEncoding="UTF-8"
|
||||
%><%@page contentType="text/html" import="net.i2p.i2ptunnel.web.WizardBean"
|
||||
%><%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"
|
||||
%><?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.WizardBean" id="wizardBean" scope="request" />
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.EditBean" id="editBean" scope="request" />
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.Messages" id="intl" scope="request" />
|
||||
<% String pageStr = request.getParameter("page");
|
||||
/* Get the number of the page we came from */
|
||||
@@ -45,14 +49,14 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title><%=intl._("I2P Tunnel Manager - Tunnel Creation Wizard")%></title>
|
||||
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
|
||||
<link href="/themes/console/images/favicon.ico" type="image/x-icon" rel="shortcut icon" />
|
||||
|
||||
<% if (wizardBean.allowCSS()) {
|
||||
%><link href="<%=wizardBean.getTheme()%>default.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<%=wizardBean.getTheme()%>i2ptunnel.css" rel="stylesheet" type="text/css" />
|
||||
|
||||
<% if (editBean.allowCSS()) {
|
||||
%><link href="<%=editBean.getTheme()%>default.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<%=editBean.getTheme()%>i2ptunnel.css" rel="stylesheet" type="text/css" />
|
||||
<% }
|
||||
%>
|
||||
</head>
|
||||
@@ -82,7 +86,7 @@
|
||||
} %>
|
||||
<input type="hidden" name="page" value="<%=curPage%>" />
|
||||
<input type="hidden" name="tunnel" value="null" />
|
||||
<input type="hidden" name="nonce" value="<%=wizardBean.getNextNonce()%>" />
|
||||
<input type="hidden" name="nonce" value="<%=editBean.getNextNonce()%>" />
|
||||
</div>
|
||||
|
||||
<div class="separator">
|
||||
@@ -93,12 +97,12 @@
|
||||
|
||||
if (curPage == 1) {
|
||||
%><p>
|
||||
<%=intl._("This wizard will take you through the various basic options available for manually creating tunnels in I2P.")%>
|
||||
<%=intl._("This wizard will take you through the various options available for creating tunnels in I2P.")%>
|
||||
</p>
|
||||
<p>
|
||||
<%=intl._("The first thing to decide is whether you want to create a client or server tunnel.")%>
|
||||
<%=intl._("If you are trying to connect to a remote service (such as an IRC server inside I2P, or a code repository) then you will require a client tunnel.")%>
|
||||
<%=intl._("Server tunnels are what client tunnels will connect to, and you will need to create one if you want to host a service - e.g. more eepsites, or an outproxy.")%>
|
||||
<%=intl._("The first thing to decide is whether you want to create a server or a client tunnel.")%>
|
||||
<%=intl._("If you need to connect to a remote service, such as an IRC server inside I2P or a code repository, then you will require a CLIENT tunnel.")%>
|
||||
<%=intl._("On the other hand, if you wish to host a service for others to connect to you'll need to create a SERVER tunnel.")%>
|
||||
</p>
|
||||
<div id="typeField" class="rowItem">
|
||||
<label><%=intl._("Server Tunnel")%></label>
|
||||
@@ -122,21 +126,21 @@
|
||||
if (tunnelIsClient) {
|
||||
%>
|
||||
<tr><td><%=intl._("Standard")%></td><td>
|
||||
<%=intl._("A basic client tunnel for connecting to a single service inside I2P.")%>
|
||||
<%=intl._("If none of the tunnel types below seem to fit your requirements, or you don't know what type of tunnel you need, try this one.")%>
|
||||
<%=intl._("Basic tunnel for connecting to a single service inside I2P.")%>
|
||||
<%=intl._("Try this if none of the tunnel types below fit your requirements, or you don't know what type of tunnel you need.")%>
|
||||
</td></tr>
|
||||
<tr><td>HTTP</td><td>
|
||||
<%=intl._("A client tunnel that acts as an HTTP proxy.")%>
|
||||
<%=intl._("With this tunnel type, you can connect to eepsites inside I2P by setting your browser to use the tunnel as a proxy, or setting the http_proxy environment variable for command-line applications in GNU/Linux.")%>
|
||||
<%=intl._("Tunnel that acts as an HTTP proxy for reaching eepsites inside I2P.")%>
|
||||
<%=intl._("Set your browser to use this tunnel as an http proxy, or set your \"http_proxy\" environment variable for command-line applications in GNU/Linux.")%>
|
||||
<%=intl._("Websites outside I2P can also be reached if an HTTP proxy within I2P is known.")%>
|
||||
</td></tr>
|
||||
<tr><td>IRC</td><td>
|
||||
<%=intl._("A customised client tunnel for connecting to a single IRC network inside I2P.")%>
|
||||
<%=intl._("With this tunnel type, you would configure your IRC client to connect to a local port on your computer.")%>
|
||||
<%=intl._("Each IRC network in I2P that you wish to connect to requires a separate tunnel.")%>
|
||||
<%=intl._("Customised client tunnel specific for IRC connections.")%>
|
||||
<%=intl._("With this tunnel type, your IRC client will be able to connect to an IRC network inside I2P.")%>
|
||||
<%=intl._("Each IRC network in I2P that you wish to connect to will require its own tunnel. (See Also, SOCKS IRC)")%>
|
||||
</td></tr>
|
||||
<tr><td>SOCKS 4/4a/5</td><td>
|
||||
<%=intl._("A client tunnel that implements the SOCKS protocol.")%>
|
||||
<%=intl._("A tunnel that implements the SOCKS protocol.")%>
|
||||
<%=intl._("This enables both TCP and UDP connections to be made through a SOCKS outproxy within I2P.")%>
|
||||
</td></tr>
|
||||
<tr><td>SOCKS IRC</td><td>
|
||||
@@ -150,14 +154,14 @@
|
||||
<%=intl._("This enables TCP connections to be made through an HTTP outproxy, assuming the proxy supports the CONNECT command.")%>
|
||||
</td></tr>
|
||||
<tr><td>Streamr</td><td>
|
||||
<%=intl._("A customised client tunnel for Streamr.")%>
|
||||
<%=intl._("I have no idea what this is.")%>
|
||||
<%=intl._("A customised client tunnel for Streamr.")%><%
|
||||
//XXX TODO<%=intl._("I have no idea what this is.")%>
|
||||
</td></tr><%
|
||||
} else {
|
||||
%>
|
||||
<tr><td><%=intl._("Standard")%></td><td>
|
||||
<%=intl._("A basic server tunnel for hosting a generic service inside I2P.")%>
|
||||
<%=intl._("If none of the tunnel types below seem to fit your requirements, or you don't know what type of tunnel you need, try this one.")%>
|
||||
<%=intl._("Try this if none of the tunnel types below fit your requirements, or you don't know what type of tunnel you need.")%>
|
||||
</td></tr>
|
||||
<tr><td>HTTP</td><td>
|
||||
<%=intl._("A server tunnel that is customised for HTTP connections.")%>
|
||||
@@ -172,8 +176,8 @@
|
||||
<%=intl._("Usually, a separate tunnel needs to be created for each IRC server that is to be accessible inside I2P.")%>
|
||||
</td></tr>
|
||||
<tr><td>Streamr</td><td>
|
||||
<%=intl._("A customised server tunnel for Streamr.")%>
|
||||
<%=intl._("I have no idea what this is.")%>
|
||||
<%=intl._("A customised server tunnel for Streamr.")%><%
|
||||
//XXX TODO<%=intl._("I have no idea what this is.")%>
|
||||
</td></tr><%
|
||||
}
|
||||
%>
|
||||
@@ -276,8 +280,8 @@
|
||||
if ((tunnelIsClient && "streamrclient".equals(tunnelType)) || (!tunnelIsClient && !"streamrserver".equals(tunnelType))) {
|
||||
if (curPage == 5) {
|
||||
%><p>
|
||||
<%=intl._("Some blurb explaining that this is the IP that the service is running on, and that the tunnel should direct requests to.")%>
|
||||
<%=intl._("For some reason streamrclient also uses this.")%>
|
||||
<%=intl._("This is the IP that your service is running on, this is usually on the same machine so 127.0.0.1 is autofilled.")%><%
|
||||
//XXX TODO<%=intl._("For some reason streamrclient also uses this.")%>
|
||||
</p>
|
||||
<div id="hostField" class="rowItem">
|
||||
<label for="targetHost" accesskey="H">
|
||||
@@ -293,7 +297,7 @@
|
||||
if (!tunnelIsClient) {
|
||||
if (curPage == 5) {
|
||||
%><p>
|
||||
<%=intl._("Some blurb explaining that this is the port that the service is running on, and that the tunnel should direct requests to.")%>
|
||||
<%=intl._("This is the port that the service is accepting connections on.")%>
|
||||
</p>
|
||||
<div id="portField" class="rowItem">
|
||||
<label for="targetPort" accesskey="P">
|
||||
@@ -309,8 +313,8 @@
|
||||
if (tunnelIsClient || "httpbidirserver".equals(tunnelType)) {
|
||||
if (curPage == 5) {
|
||||
%><p>
|
||||
<%=intl._("Some blurb explaining that this is the port that the client tunnel will be accessed from locally.")%>
|
||||
<%=intl._("This is also the client port for the httpbidirserver tunnel.")%>
|
||||
<%=intl._("This is the port that the client tunnel will be accessed from locally.")%>
|
||||
<%=intl._("This is also the client port for the HTTPBidir server tunnel.")%>
|
||||
</p>
|
||||
<div id="portField" class="rowItem">
|
||||
<label for="port" accesskey="P">
|
||||
@@ -326,9 +330,10 @@
|
||||
if ((tunnelIsClient && !"streamrclient".equals(tunnelType)) || "httpbidirserver".equals(tunnelType) || "streamrserver".equals(tunnelType)) {
|
||||
if (curPage == 5) {
|
||||
%><p>
|
||||
<%=intl._("Some blurb explaining what Reachable By is.")%>
|
||||
<%=intl._("Note that it is relevant to most Client tunnels, and httpbidirserver and streamrserver tunnels.")%>
|
||||
<%=intl._("So the wording may need to change slightly for the client vs. server tunnels.")%>
|
||||
<%=intl._("How do you want this tunnel to be accessed? By just this machine, your entire subnet, or external internet?")%>
|
||||
<%=intl._("You will most likely want to just allow 127.0.0.1")%><%
|
||||
//XXX TODO<%=intl._("Note that it is relevant to most Client tunnels, and httpbidirserver and streamrserver tunnels.")%><%
|
||||
//XXX TODO<%=intl._("So the wording may need to change slightly for the client vs. server tunnels.")%>
|
||||
</p>
|
||||
<div id="reachField" class="rowItem">
|
||||
<label for="reachableBy" accesskey="r">
|
||||
@@ -340,7 +345,7 @@
|
||||
if ("null".equals(clientInterface)) {
|
||||
clientInterface = "127.0.0.1";
|
||||
}
|
||||
for (String ifc : wizardBean.interfaceSet()) {
|
||||
for (String ifc : editBean.interfaceSet()) {
|
||||
out.write("<option value=\"");
|
||||
out.write(ifc);
|
||||
out.write('\"');
|
||||
@@ -351,7 +356,7 @@
|
||||
out.write("</option>\n");
|
||||
}
|
||||
%>
|
||||
</select>
|
||||
</select>
|
||||
</div><%
|
||||
} else {
|
||||
%><input type="hidden" name="reachableBy" value="<%=request.getParameter("reachableBy")%>" /><%
|
||||
@@ -364,7 +369,7 @@
|
||||
|
||||
if (curPage == 6) {
|
||||
%><p>
|
||||
<%=intl._("The I2P router can optionally start the tunnel for you automatically when the router is started.")%>
|
||||
<%=intl._("The I2P router can automatically start this tunnel for you when the router is started.")%>
|
||||
<%=intl._("This can be useful for frequently-used tunnels (especially server tunnels), but for tunnels that are only used occassionally it would mean that the I2P router is creating and maintaining unnecessary tunnels.")%>
|
||||
</p>
|
||||
<div id="startupField" class="rowItem">
|
||||
@@ -397,6 +402,67 @@
|
||||
<%=intl._("You can do this by clicking the Start button on the main page which corresponds to the new tunnel.")%><%
|
||||
} %>
|
||||
</p>
|
||||
<p>
|
||||
<%=intl._("Below is a summary of the options you chose:")%>
|
||||
</p>
|
||||
<table>
|
||||
<tr><td><%=intl._("Server or client tunnel?")%></td><td>
|
||||
<%=(tunnelIsClient ? "Client" : "Server")%>
|
||||
</td></tr>
|
||||
<tr><td><%=intl._("Tunnel type")%></td><td><%
|
||||
if ("client".equals(tunnelType) || "server".equals(tunnelType)) { %>
|
||||
<%=intl._("Standard")%><%
|
||||
} else if ("httpclient".equals(tunnelType) || "httpserver".equals(tunnelType)) { %>
|
||||
HTTP<%
|
||||
} else if ("httpbidirserver".equals(tunnelType)) { %>
|
||||
HTTP bidir<%
|
||||
} else if ("ircclient".equals(tunnelType) || "ircserver".equals(tunnelType)) { %>
|
||||
IRC<%
|
||||
} else if ("sockstunnel".equals(tunnelType)) { %>
|
||||
SOCKS 4/4a/5<%
|
||||
} else if ("socksirctunnel".equals(tunnelType)) { %>
|
||||
SOCKS IRC<%
|
||||
} else if ("connectclient".equals(tunnelType)) { %>
|
||||
CONNECT<%
|
||||
} else if ("streamrclient".equals(tunnelType) || "streamrserver".equals(tunnelType)) { %>
|
||||
Streamr<%
|
||||
} %>
|
||||
</td></tr>
|
||||
<tr><td><%=intl._("Tunnel name and description")%></td><td>
|
||||
<%=request.getParameter("name")%><br />
|
||||
<%=request.getParameter("description")%>
|
||||
</td></tr><%
|
||||
if (tunnelIsClient) { %>
|
||||
<tr><td><%=intl._("Tunnel destination")%></td><td><%
|
||||
if ("httpclient".equals(tunnelType) || "connectclient".equals(tunnelType) || "sockstunnel".equals(tunnelType) || "socksirctunnel".equals(tunnelType)) { %>
|
||||
<%=request.getParameter("proxyList")%><%
|
||||
} else if ("client".equals(tunnelType) || "ircclient".equals(tunnelType) || "streamrclient".equals(tunnelType)) { %>
|
||||
<%=request.getParameter("targetDestination")%><%
|
||||
} %>
|
||||
</td></tr><%
|
||||
} %>
|
||||
<tr><td><%=intl._("Binding address and port")%></td><td><%
|
||||
if ((tunnelIsClient && "streamrclient".equals(tunnelType)) || (!tunnelIsClient && !"streamrserver".equals(tunnelType))) { %>
|
||||
<%=request.getParameter("targetHost")%><br /><%
|
||||
}
|
||||
if (!tunnelIsClient) { %>
|
||||
<%=request.getParameter("targetPort")%><br /><%
|
||||
}
|
||||
if (tunnelIsClient || "httpbidirserver".equals(tunnelType)) { %>
|
||||
<br /><%=request.getParameter("port")%><%
|
||||
}
|
||||
if ((tunnelIsClient && !"streamrclient".equals(tunnelType)) || "httpbidirserver".equals(tunnelType) || "streamrserver".equals(tunnelType)) { %>
|
||||
<br /><%=request.getParameter("reachableBy")%><%
|
||||
} %>
|
||||
</td></tr>
|
||||
<tr><td><%=intl._("Tunnel auto-start")%></td><td><%
|
||||
if ("1".equals(request.getParameter("startOnLoad"))) { %>
|
||||
Yes<%
|
||||
} else { %>
|
||||
No<%
|
||||
} %>
|
||||
</td></tr>
|
||||
</table>
|
||||
<p>
|
||||
<%=intl._("Alongside these basic settings, there are a number of advanced options for tunnel configuration.")%>
|
||||
<%=intl._("The wizard will set reasonably sensible default values for these, but you can view and/or edit these by clicking on the tunnel's name in the main I2PTunnel page.")%>
|
||||
@@ -456,7 +522,7 @@ http://i2jump.i2p/" /><%
|
||||
<div id="globalOperationsPanel" class="panel">
|
||||
<div class="header"></div>
|
||||
<div class="footer">
|
||||
<div class=toolbox">
|
||||
<div class="toolbox">
|
||||
<a class="control" href="list"><%=intl._("Cancel")%></a>
|
||||
<% if (curPage != 1 && curPage != 7) {
|
||||
%><button id="controlPrevious" accesskey="P" class="control" type="submit" name="action" value="Previous page" title="Previous Page"><%=intl._("Previous")%>(<span class="accessKey">P</span>)</button><%
|
||||
|
||||
1238
apps/i2ptunnel/locale/messages_cs.po
Normal file
@@ -2,122 +2,119 @@
|
||||
# Copyright (C) 2009 The I2P Project
|
||||
# This file is distributed under the same license as the i2ptunnel package.
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
#
|
||||
# Translators:
|
||||
# Martin Svensson <digitalmannen@gmail.com>, 2011, 2012.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-12-15 20:14+0000\n"
|
||||
"PO-Revision-Date: 2011-08-26 09:28+0000\n"
|
||||
"Last-Translator: digitalmannen <digitalmannen@gmail.com>\n"
|
||||
"Language-Team: Swedish (Sweden) (http://www.transifex.net/projects/p/I2P/"
|
||||
"team/sv_SE/)\n"
|
||||
"Language: sv_SE\n"
|
||||
"Report-Msgid-Bugs-To: https://trac.i2p2.de/\n"
|
||||
"POT-Creation-Date: 2012-02-17 11:25+0000\n"
|
||||
"PO-Revision-Date: 2012-02-20 15:28+0000\n"
|
||||
"Last-Translator: Martin Svensson <digitalmannen@gmail.com>\n"
|
||||
"Language-Team: Swedish (Sweden) (http://www.transifex.net/projects/p/I2P/language/sv_SE/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: sv_SE\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:487
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:492
|
||||
msgid "This seems to be a bad destination:"
|
||||
msgstr "Detta verkar vara ett felaktigt mål"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:487
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:492
|
||||
msgid "i2paddresshelper cannot help you with a destination like that!"
|
||||
msgstr "i2padresshjälp kan inte hjälpa dig med ett sådant mål!"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:556
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:561
|
||||
#, java-format
|
||||
msgid ""
|
||||
"To visit the destination in your host database, click <a href=\"{0}\">here</"
|
||||
"a>. To visit the conflicting addresshelper destination, click <a href="
|
||||
"\"{1}\">here</a>."
|
||||
msgstr ""
|
||||
"För att besöka målet i din värd databas href=\"{0}\"> klicka <a här </ a>. "
|
||||
"För att besöka de motstridiga hjälpaddresserna,<a href=\"{1}\"> klicka <a "
|
||||
"här </ a>."
|
||||
"To visit the destination in your host database, click <a "
|
||||
"href=\"{0}\">here</a>. To visit the conflicting addresshelper destination, "
|
||||
"click <a href=\"{1}\">here</a>."
|
||||
msgstr "För att besöka målet i din värd databas href=\"{0}\"> klicka <a här </ a>. För att besöka de motstridiga hjälpaddresserna,<a href=\"{1}\"> klicka <a här </ a>."
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:932
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:937
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:398
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:142
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:401
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:391
|
||||
msgid "Host"
|
||||
msgstr "Värd"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:933
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:370
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:938
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:372
|
||||
msgid "Destination"
|
||||
msgstr "Mål"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:938
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:943
|
||||
#, java-format
|
||||
msgid "Continue to {0} without saving"
|
||||
msgstr "Fortsätt till {0} utan att spara"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:943
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:948
|
||||
#, java-format
|
||||
msgid "Save {0} to router address book and continue to eepsite"
|
||||
msgstr "Spara {0} till routeradressboken och fortsätt till eepsite "
|
||||
|
||||
#. only blockfile supports multiple books
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:946
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:951
|
||||
#, java-format
|
||||
msgid "Save {0} to master address book and continue to eepsite"
|
||||
msgstr "Spara {0} till huvudadressboken och fortsätt till eepsite "
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:947
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:952
|
||||
#, java-format
|
||||
msgid "Save {0} to private address book and continue to eepsite"
|
||||
msgstr "Spara {0} till privatadressbok och fortsätt till eepsite "
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1102
|
||||
#, fuzzy
|
||||
msgid "HTTP Outproxy"
|
||||
msgstr "Utproxy"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1107
|
||||
msgid ""
|
||||
"Click a link below to look for an address helper by using a \"jump\" service:"
|
||||
msgstr ""
|
||||
"Klicka på en länk nedan för att söka efter en hjälpaddress genom att använda "
|
||||
"en \"hopp\" tjänst"
|
||||
msgid "HTTP Outproxy"
|
||||
msgstr "HTTP Utproxy"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1325
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1112
|
||||
msgid ""
|
||||
"Click a link below to look for an address helper by using a \"jump\" "
|
||||
"service:"
|
||||
msgstr "Klicka på en länk nedan för att söka efter en hjälpaddress genom att använda en \"hopp\" tjänst"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1330
|
||||
msgid "Added via address helper"
|
||||
msgstr "Tillagd via adresshjälpen "
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1349
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1354
|
||||
#, java-format
|
||||
msgid "Redirecting to {0}"
|
||||
msgstr "Om dirigerar till {0}"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1355
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1360
|
||||
msgid "Router Console"
|
||||
msgstr "Router konsol "
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1356
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1361
|
||||
msgid "Addressbook"
|
||||
msgstr "Adressbok"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1356
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1361
|
||||
msgid "Configuration"
|
||||
msgstr "Konfiguration"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1356
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1361
|
||||
msgid "Help"
|
||||
msgstr "Hjälp"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1361
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1366
|
||||
#, java-format
|
||||
msgid "Saved {0} to the {1} addressbook, redirecting now."
|
||||
msgstr "Spara {0} till {1}adressboken, omdirigerar nu "
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1362
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1367
|
||||
#, java-format
|
||||
msgid "Failed to save {0} to the {1} addressbook, redirecting now."
|
||||
msgstr "Misslyckades med att spara {0} till {1}adressboken, omdirigerar nu "
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1364
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1369
|
||||
msgid "Click here if you are not redirected automatically."
|
||||
msgstr "Klicka här om du inte omdirigeras automatiskt "
|
||||
|
||||
@@ -130,9 +127,7 @@ msgstr "Intern "
|
||||
msgid ""
|
||||
"Invalid form submission, probably because you used the 'back' or 'reload' "
|
||||
"button on your browser. Please resubmit."
|
||||
msgstr ""
|
||||
"Ogiltigt formulärbegäran, beror troligtvis på attt du använde 'tillbaka' "
|
||||
"eller 'uppdatera' knappen. Försök att skicka igen"
|
||||
msgstr "Ogiltigt formulärbegäran, beror troligtvis på attt du använde 'tillbaka' eller 'uppdatera' knappen. Försök att skicka igen"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:222
|
||||
msgid "Configuration reloaded for all tunnels"
|
||||
@@ -209,12 +204,12 @@ msgid "HTTP bidir"
|
||||
msgstr "HTTP bidir"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:555
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:293
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:295
|
||||
msgid "Host not set"
|
||||
msgstr "Ingen värd angiven"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:559
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:275
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:277
|
||||
msgid "Port not set"
|
||||
msgstr "Ingen port angiven"
|
||||
|
||||
@@ -232,24 +227,26 @@ msgstr "Inställningar för ny proxy "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:112
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:112
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:110
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:124
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:245
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:260
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:112
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:126
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:247
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:262
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:307
|
||||
msgid "Name"
|
||||
msgstr "Namn"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:116
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:116
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:249
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:282
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:251
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:284
|
||||
msgid "Type"
|
||||
msgstr "Typ"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:120
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:120
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:229
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:389
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:231
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:391
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:311
|
||||
msgid "Description"
|
||||
msgstr "Beskrivning"
|
||||
|
||||
@@ -275,22 +272,27 @@ msgstr "krävs"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:159
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:178
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:460
|
||||
msgid "Reachable by"
|
||||
msgstr "Nåbar via"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:180
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:339
|
||||
msgid "Outproxies"
|
||||
msgstr "utgående proxy"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:187
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:359
|
||||
msgid "Tunnel Destination"
|
||||
msgstr "Tunnel mål"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:199
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:363
|
||||
msgid "name or destination"
|
||||
msgstr "namn eller mål"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:202
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:366
|
||||
msgid "b32 not recommended"
|
||||
msgstr "b32 rekommenderas ej"
|
||||
|
||||
@@ -302,18 +304,18 @@ msgstr "Delad klient"
|
||||
msgid ""
|
||||
"(Share tunnels with other clients and irc/httpclients? Change requires "
|
||||
"restart of client proxy)"
|
||||
msgstr ""
|
||||
"(Dela tunnlarna med andra klienter och irc/HTTP-klienter? Ändring kräver "
|
||||
"omstart av klientproxyn)"
|
||||
msgstr "(Dela tunnlarna med andra klienter och irc/HTTP-klienter? Ändring kräver omstart av klientproxyn)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:216
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:124
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:500
|
||||
msgid "Auto Start"
|
||||
msgstr "Starta automatiskt"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:220
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:228
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:128
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:504
|
||||
msgid "(Check the Box for 'YES')"
|
||||
msgstr "(Markera i boxen för 'Ja')"
|
||||
|
||||
@@ -330,9 +332,7 @@ msgstr "Avancerade nätverks instälningar"
|
||||
msgid ""
|
||||
"(NOTE: when this client proxy is configured to share tunnels, then these "
|
||||
"options are for all the shared proxy clients!)"
|
||||
msgstr ""
|
||||
"(OBS: när denna klientproxyn är konfigurerad för att dela tunnlar, då gäller "
|
||||
"dessa alternativ för alla delade proxyklienter!)"
|
||||
msgstr "(OBS: när denna klientproxyn är konfigurerad för att dela tunnlar, då gäller dessa alternativ för alla delade proxyklienter!)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:236
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:245
|
||||
@@ -414,26 +414,20 @@ msgstr "Antal"
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:318
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:327
|
||||
msgid "1 inbound, 1 outbound tunnel (low bandwidth usage, less reliability)"
|
||||
msgstr ""
|
||||
"1 inkommande, 1 utgående tunnlar (låg bandbreddsanvändning, låg "
|
||||
"tillförlitlighet)"
|
||||
msgstr "1 inkommande, 1 utgående tunnlar (låg bandbreddsanvändning, låg tillförlitlighet)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:322
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:331
|
||||
msgid ""
|
||||
"2 inbound, 2 outbound tunnels (standard bandwidth usage, standard "
|
||||
"reliability)"
|
||||
msgstr ""
|
||||
"2 inkommande, 2 utgående tunnlar (normal bandbreddsanvändning, normal "
|
||||
"tillförlitlighet)"
|
||||
msgstr "2 inkommande, 2 utgående tunnlar (normal bandbreddsanvändning, normal tillförlitlighet)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:326
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:335
|
||||
msgid ""
|
||||
"3 inbound, 3 outbound tunnels (higher bandwidth usage, higher reliability)"
|
||||
msgstr ""
|
||||
"3 inkommande, 3 utgående tunnlar (Högre bandbreddsanvändning, högre "
|
||||
"tillförlitlighet)"
|
||||
msgstr "3 inkommande, 3 utgående tunnlar (Högre bandbreddsanvändning, högre tillförlitlighet)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:335
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:344
|
||||
@@ -448,8 +442,7 @@ msgstr "Antal reserver"
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:347
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:356
|
||||
msgid "0 backup tunnels (0 redundancy, no added resource usage)"
|
||||
msgstr ""
|
||||
"0 reserv tunnlar i varje riktning (ingen redundans, ingen resursanvändning)"
|
||||
msgstr "0 reserv tunnlar i varje riktning (ingen redundans, ingen resursanvändning)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:351
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:360
|
||||
@@ -460,15 +453,12 @@ msgstr "1 reserv tunnel i varje riktning (låg redundans, låg resursanvändning
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:364
|
||||
msgid ""
|
||||
"2 backup tunnels each direction (medium redundancy, medium resource usage)"
|
||||
msgstr ""
|
||||
"2 reserv tunnlar i varje riktning (medel hög redundans, medel hög "
|
||||
"resursanvändning)"
|
||||
msgstr "2 reserv tunnlar i varje riktning (medel hög redundans, medel hög resursanvändning)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:359
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:368
|
||||
msgid "3 backup tunnels each direction (high redundancy, high resource usage)"
|
||||
msgstr ""
|
||||
"3 reserv tunnlar i varje riktning (hög redundans, hög resursanvändning)"
|
||||
msgstr "3 reserv tunnlar i varje riktning (hög redundans, hög resursanvändning)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:368
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:377
|
||||
@@ -506,8 +496,9 @@ msgstr "I2CP Routeradress"
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:406
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:148
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:409
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:247
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:269
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:249
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:271
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:412
|
||||
msgid "Port"
|
||||
msgstr "Port"
|
||||
|
||||
@@ -605,12 +596,11 @@ msgstr "Anpassade alternativ"
|
||||
msgid ""
|
||||
"NOTE: If tunnel is currently running, most changes will not take effect "
|
||||
"until tunnel is stopped and restarted."
|
||||
msgstr ""
|
||||
"OBS: Om tunneln är igång, kommer de flesta ändringarna inte att träda i "
|
||||
"kraft förrän tunneln stoppats och startats om."
|
||||
msgstr "OBS: Om tunneln är igång, kommer de flesta ändringarna inte att träda i kraft förrän tunneln stoppats och startats om."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:524
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:531
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:678
|
||||
msgid "Cancel"
|
||||
msgstr "Avbryt"
|
||||
|
||||
@@ -769,115 +759,466 @@ msgstr "Status meddelande "
|
||||
msgid "Refresh"
|
||||
msgstr "Uppdatera"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:94
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:92
|
||||
msgid "Tunnel Wizard"
|
||||
msgstr "Tunnel guide"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:96
|
||||
msgid "Stop All"
|
||||
msgstr "Stoppa alla"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:98
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:100
|
||||
msgid "Start All"
|
||||
msgstr "Starta alla"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:102
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:104
|
||||
msgid "Restart All"
|
||||
msgstr "Starta om alla"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:106
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:108
|
||||
msgid "Reload Config"
|
||||
msgstr "Uppdatera konfigurationen"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:108
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:110
|
||||
msgid "I2P Server Tunnels"
|
||||
msgstr "I2P Servertunnlel"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:112
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:133
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:114
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:135
|
||||
msgid "Points at"
|
||||
msgstr "Pekar på"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:114
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:156
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:160
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:116
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:158
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:162
|
||||
msgid "Preview"
|
||||
msgstr "förhandsvisning"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:116
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:180
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:253
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:300
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:118
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:182
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:255
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:302
|
||||
msgid "Status"
|
||||
msgstr "Status"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:166
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:168
|
||||
msgid "Base32 Address"
|
||||
msgstr "Bas32 adress"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:174
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:176
|
||||
msgid "No Preview"
|
||||
msgstr "Ingen förhandsvisning"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:187
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:307
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:189
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:309
|
||||
msgid "Starting..."
|
||||
msgstr "Startar..."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:194
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:208
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:314
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:328
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:342
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:196
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:210
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:316
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:330
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:344
|
||||
msgid "Stop"
|
||||
msgstr "Stopp"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:201
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:335
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:203
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:337
|
||||
msgid "Running"
|
||||
msgstr "Kör"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:215
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:349
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:217
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:351
|
||||
msgid "Stopped"
|
||||
msgstr "Stoppad"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:222
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:356
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:224
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:358
|
||||
msgid "Start"
|
||||
msgstr "Start"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:237
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:239
|
||||
msgid "New server tunnel"
|
||||
msgstr "Ny severtunnel "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:239
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:399
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:241
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:401
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:204
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:246
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:276
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:282
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:554
|
||||
msgid "Standard"
|
||||
msgstr "Standard"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:241
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:401
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:243
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:403
|
||||
msgid "Create"
|
||||
msgstr "Skapa"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:243
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:245
|
||||
msgid "I2P Client Tunnels"
|
||||
msgstr "I2P Klienttunnel"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:251
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:286
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:253
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:288
|
||||
msgid "Interface"
|
||||
msgstr "Gränssnitt "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:321
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:323
|
||||
msgid "Standby"
|
||||
msgstr "Standby"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:366
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:368
|
||||
msgid "Outproxy"
|
||||
msgstr "Utproxy"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:384
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:386
|
||||
msgid "none"
|
||||
msgstr "Ingen"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:397
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:399
|
||||
msgid "New client tunnel"
|
||||
msgstr "Ny klienttunnel"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:102
|
||||
msgid "I2P Tunnel Manager - Tunnel Creation Wizard"
|
||||
msgstr "I2P Tunnelhanterare - Guide för skapande av tunnlar "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:120
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:545
|
||||
msgid "Server or client tunnel?"
|
||||
msgstr "Server- eller klient-tunnel"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:126
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:549
|
||||
msgid "Tunnel type"
|
||||
msgstr "Tunnel typ"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:132
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:579
|
||||
msgid "Tunnel name and description"
|
||||
msgstr "Tunnelnamn och beskrivning "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:138
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:588
|
||||
msgid "Tunnel destination"
|
||||
msgstr "Mål för tunnel"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:144
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:604
|
||||
msgid "Binding address and port"
|
||||
msgstr "Adress och port"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:150
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:630
|
||||
msgid "Tunnel auto-start"
|
||||
msgstr "Tunnel auto-start"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:156
|
||||
msgid "Wizard completed"
|
||||
msgstr "Guiden färdig "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:170
|
||||
msgid ""
|
||||
"This wizard will take you through the various options available for creating"
|
||||
" tunnels in I2P."
|
||||
msgstr "Guiden tar dig igenom de olika inställningsmöjligheterna för att skapa tunnlar."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:172
|
||||
msgid ""
|
||||
"The first thing to decide is whether you want to create a server or a client"
|
||||
" tunnel."
|
||||
msgstr "Det första är att bestämma om det skall vara en server- eller klient-tunnel. "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:174
|
||||
msgid ""
|
||||
"If you need to connect to a remote service, such as an IRC server inside I2P"
|
||||
" or a code repository, then you will require a CLIENT tunnel."
|
||||
msgstr "Om du ansluter till en fjärrtjänst så som tex en IRC-server inom I2P, behövs en KLIENT-tunnel. "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:176
|
||||
msgid ""
|
||||
"On the other hand, if you wish to host a service for others to connect to "
|
||||
"you'll need to create a SERVER tunnel."
|
||||
msgstr "Men om du vill göra en tjänst tillgänglig för andra behövs en SERVER-tunnel."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:178
|
||||
msgid "Server Tunnel"
|
||||
msgstr "Server-tunnel"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:180
|
||||
msgid "Client Tunnel"
|
||||
msgstr "Klient-tunnel"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:198
|
||||
msgid "There are several types of tunnels to choose from:"
|
||||
msgstr "Det finns flera typer av tunnlar att välja på:"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:206
|
||||
msgid "Basic tunnel for connecting to a single service inside I2P."
|
||||
msgstr "Grundläggande tunnel för anslutning till en snigel tjänst innanför I2P. "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:208
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:250
|
||||
msgid ""
|
||||
"Try this if none of the tunnel types below fit your requirements, or you "
|
||||
"don't know what type of tunnel you need."
|
||||
msgstr "Prova detta om ingen av valen passar eller du inte vet vilken typ av tunnel som behövs."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:210
|
||||
msgid "Tunnel that acts as an HTTP proxy for reaching eepsites inside I2P."
|
||||
msgstr "Tunneln agerar som en HTTP-proxy för att komma åt eepsites innanför I2P. "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:212
|
||||
msgid ""
|
||||
"Set your browser to use this tunnel as an http proxy, or set your "
|
||||
"\"http_proxy\" environment variable for command-line applications in "
|
||||
"GNU/Linux."
|
||||
msgstr "Peka din webbläsare på denna tunnel som en http-proxy eller ställ in miljövariabeln \"http_proxy\" för terminal baserade applikationer i GNU/Linux."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:214
|
||||
msgid ""
|
||||
"Websites outside I2P can also be reached if an HTTP proxy within I2P is "
|
||||
"known."
|
||||
msgstr "Webbplats utanför I2P kan nås om en HTTP-proxy innanför I2P är känd."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:216
|
||||
msgid "Customised client tunnel specific for IRC connections."
|
||||
msgstr "Specialiserad tunnel för IRC anslutningar. "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:218
|
||||
msgid ""
|
||||
"With this tunnel type, your IRC client will be able to connect to an IRC "
|
||||
"network inside I2P."
|
||||
msgstr "Med denna tunneltyp kan IRC-klienter ansluta till IRC-nät inom I2P "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:220
|
||||
msgid ""
|
||||
"Each IRC network in I2P that you wish to connect to will require its own "
|
||||
"tunnel. (See Also, SOCKS IRC)"
|
||||
msgstr "Varje IRC-nät inom I2P som du vill ansluta till kräver en egen tunnel (Se även: SOCKS IRC) "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:222
|
||||
msgid "A tunnel that implements the SOCKS protocol."
|
||||
msgstr "En tunnel som implementerar SOCKS protokollet."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:224
|
||||
msgid ""
|
||||
"This enables both TCP and UDP connections to be made through a SOCKS "
|
||||
"outproxy within I2P."
|
||||
msgstr "Detta möjliggör både TCP och UDP anslutningar genom SOCKS utgående-proxy innanför I2P "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:226
|
||||
msgid ""
|
||||
"A client tunnel implementing the SOCKS protocol, which is customised for "
|
||||
"connecting to IRC networks."
|
||||
msgstr "En klient tunnel för SOCKS protokollet som är anpassad för IRC-nät."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:228
|
||||
msgid ""
|
||||
"With this tunnel type, IRC networks in I2P can be reached by typing the I2P "
|
||||
"address into your IRC client, and configuring the IRC client to use this "
|
||||
"SOCKS tunnel."
|
||||
msgstr "Med denna tunnel typen kan IRC-nät inom I2P nås genom att skriva in I2P adressen i IRC-klienten och konfigurera IRC-klienten att använda denna SOCKS-tunneln."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:230
|
||||
msgid ""
|
||||
"This means that only one I2P tunnel is required rather than a separate "
|
||||
"tunnel per IRC network."
|
||||
msgstr "Detta innebär att enbart en I2P-tunnel behövs istället för en tunnel per IRC-nät."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:232
|
||||
msgid ""
|
||||
"IRC networks outside I2P can also be reached if a SOCKS outproxy within I2P "
|
||||
"is known, though it depends on whether or not the outproxy has been blocked "
|
||||
"by the IRC network."
|
||||
msgstr "IRC-nät utanför I2P kan nås om en SOCKS-proxy innanför I2P är känd, men det bror på om utgående-proxy har blockerats av IRC-nätet."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:234
|
||||
msgid "A client tunnel that implements the HTTP CONNECT command."
|
||||
msgstr "En klient-tunnel som implementerar HTTP CONNECT kommandot. "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:236
|
||||
msgid ""
|
||||
"This enables TCP connections to be made through an HTTP outproxy, assuming "
|
||||
"the proxy supports the CONNECT command."
|
||||
msgstr "Detta möjliggör TCP anslutningar genom en HTTP utgående-proxy om proxyn stödjer CONNECT kommandot"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:238
|
||||
msgid "A customised client tunnel for Streamr."
|
||||
msgstr "En anpassad tunnel för Streamr."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:248
|
||||
msgid "A basic server tunnel for hosting a generic service inside I2P."
|
||||
msgstr "En server-tunnel för en godtycklig tjänst innanför I2P."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:252
|
||||
msgid "A server tunnel that is customised for HTTP connections."
|
||||
msgstr "En server-tunnel anpassad för HTTP anslutningar."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:254
|
||||
msgid "Use this tunnel type if you want to host an eepsite."
|
||||
msgstr "Använd denna denna typ av tunnel om du vill köra en eepsite."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:256
|
||||
msgid ""
|
||||
"A customised server tunnel that can both serve HTTP data and connect to "
|
||||
"other server tunnels."
|
||||
msgstr "En anpassad server tunnel som hanterar både HTTP data och anslutningar till andra server-tunnlar."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:258
|
||||
msgid "This tunnel type is predominantly used when running a Seedless server."
|
||||
msgstr "Tunneltypen använd vanligtvis när en Seedless server körs."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:260
|
||||
msgid "A customised server tunnel for hosting IRC networks inside I2P."
|
||||
msgstr "En server-tunnel för IRC-Nät innanför I2P."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:262
|
||||
msgid ""
|
||||
"Usually, a separate tunnel needs to be created for each IRC server that is "
|
||||
"to be accessible inside I2P."
|
||||
msgstr "Vanligtvis behövs en separat tunnel för varje IRC-server som skall anslutas till innanför I2P."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:264
|
||||
msgid "A customised server tunnel for Streamr."
|
||||
msgstr "En server-tunnel för Streamr."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:303
|
||||
msgid "Choose a name and description for your tunnel."
|
||||
msgstr "Välj namn och beskrivning av tunneln."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:305
|
||||
msgid ""
|
||||
"These can be anything you want - they are just for ease of identifying the "
|
||||
"tunnel in the routerconsole."
|
||||
msgstr "Kan vad som helst, används enbart för att enkelt identifiera tunneln i routerkonsolen "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:335
|
||||
msgid ""
|
||||
"If you know of any outproxies for this type of tunnel (either HTTP or "
|
||||
"SOCKS), fill them in below."
|
||||
msgstr "Om du känner till några utgående proxies för denna typen av tunnlar (HTTP eller SOCKS), fyll i dem nedan. "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:337
|
||||
msgid "Separate multiple proxies with commas."
|
||||
msgstr "Separera flera proxyservrar med komma."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:355
|
||||
msgid ""
|
||||
"Type in the I2P destination of the service that this client tunnel should "
|
||||
"connect to."
|
||||
msgstr "Ange I2P destinationen för tjänsten som tunneln skall ansluta till."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:357
|
||||
msgid ""
|
||||
"This could be the full base 64 destination key, or an I2P URL from your "
|
||||
"address book."
|
||||
msgstr "Kan vara hela base 64 målsnyckeln eller en I2P URL från adressboken."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:387
|
||||
msgid ""
|
||||
"This is the IP that your service is running on, this is usually on the same "
|
||||
"machine so 127.0.0.1 is autofilled."
|
||||
msgstr "Detta är IP-adressen som tjänsten körs på, detta är vanligtvis på samma maskin så 127.0.0.1 fylls i automatiskt. "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:410
|
||||
msgid "This is the port that the service is accepting connections on."
|
||||
msgstr "Porten som tjänsten accepterar anslutningar via."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:431
|
||||
msgid "This is the port that the client tunnel will be accessed from locally."
|
||||
msgstr "Porten som klient-tunneln kommer att ansluta till lokalt."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:433
|
||||
msgid "This is also the client port for the HTTPBidir server tunnel."
|
||||
msgstr "Detta är också en klient-port för HTTPBidir server-tunneln."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:452
|
||||
msgid ""
|
||||
"How do you want this tunnel to be accessed? By just this machine, your "
|
||||
"entire subnet, or external internet?"
|
||||
msgstr "Hur du vill att tunneln ska nås? Enbart denna maskinen, ditt lokala nät eller hela internet? "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:454
|
||||
msgid "You will most likely want to just allow 127.0.0.1"
|
||||
msgstr "Med största sannolikhet vill du enbart tillåta 127.0.0.1"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:496
|
||||
msgid ""
|
||||
"The I2P router can automatically start this tunnel for you when the router "
|
||||
"is started."
|
||||
msgstr "I2P routern kan starta denna tunneln automatiskt vid uppstart."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:498
|
||||
msgid ""
|
||||
"This can be useful for frequently-used tunnels (especially server tunnels), "
|
||||
"but for tunnels that are only used occassionally it would mean that the I2P "
|
||||
"router is creating and maintaining unnecessary tunnels."
|
||||
msgstr "Detta kan vara användbart för tunnlar som används ofta (tex server-tunnlar) men för tunnlar som används sällan innebär det att onödiga tunnlar upprättas. "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:524
|
||||
msgid "The wizard has now collected enough information to create your tunnel."
|
||||
msgstr "Guiden hat samlat tillräckligt med information för att skapa tunneln. "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:526
|
||||
msgid ""
|
||||
"Upon clicking the Save button below, the wizard will set up the tunnel, and "
|
||||
"take you back to the main I2PTunnel page."
|
||||
msgstr "När du klickar på \"spara\" kommer guiden att skapa tunneln och sedan ta dig till sidan för tunnlar."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:531
|
||||
msgid ""
|
||||
"Because you chose to automatically start the tunnel when the router starts, "
|
||||
"you don't have to do anything further."
|
||||
msgstr "Efter som du valt att starta tunneln samtidigt som routern startas behövs inget mer göras. "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:533
|
||||
msgid "The router will start the tunnel once it has been set up."
|
||||
msgstr "Routern starta tunneln när den skapats. "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:537
|
||||
msgid ""
|
||||
"Because you chose not to automatically start the tunnel, you will have to "
|
||||
"manually start it."
|
||||
msgstr "Efter som du valt att inte starta tunneln samtidigt som routern startas, behövs den startas manuellt."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:539
|
||||
msgid ""
|
||||
"You can do this by clicking the Start button on the main page which "
|
||||
"corresponds to the new tunnel."
|
||||
msgstr "Du gör det genom att klicka på startknappen vid tunneln på huvudsidan."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:543
|
||||
msgid "Below is a summary of the options you chose:"
|
||||
msgstr "Nedan är en sammanfattning över valen du kan göra:"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:641
|
||||
msgid ""
|
||||
"Alongside these basic settings, there are a number of advanced options for "
|
||||
"tunnel configuration."
|
||||
msgstr "Vid sidan om dessa grundägande inställningar finns att par avancerade val för tunneln. "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:643
|
||||
msgid ""
|
||||
"The wizard will set reasonably sensible default values for these, but you "
|
||||
"can view and/or edit these by clicking on the tunnel's name in the main "
|
||||
"I2PTunnel page."
|
||||
msgstr "Guiden väljer lämpliga värden för dessa. Men du kan ändra/se värdena på huvudsidan för I2P-tunnlar."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:683
|
||||
msgid "Previous"
|
||||
msgstr "Föregående"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:691
|
||||
msgid "Save Tunnel"
|
||||
msgstr "Spara tunnel"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:697
|
||||
msgid "Finish"
|
||||
msgstr "Färdig"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:703
|
||||
msgid "Next"
|
||||
msgstr "Nästa"
|
||||
|
||||
@@ -5,123 +5,117 @@
|
||||
#
|
||||
# Translators:
|
||||
# Denis <gribua@gmail.com>, 2011.
|
||||
# Denis Lysenko <gribua@gmail.com>, 2012.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: https://trac.i2p2.de/\n"
|
||||
"POT-Creation-Date: 2011-12-12 11:18+0000\n"
|
||||
"PO-Revision-Date: 2011-12-16 22:15+0000\n"
|
||||
"Last-Translator: Denis <gribua@gmail.com>\n"
|
||||
"Language-Team: Ukrainian (Ukraine) (http://www.transifex.net/projects/p/I2P/team/uk_UA/)\n"
|
||||
"POT-Creation-Date: 2012-02-17 11:25+0000\n"
|
||||
"PO-Revision-Date: 2012-02-17 12:01+0000\n"
|
||||
"Last-Translator: Denis Lysenko <gribua@gmail.com>\n"
|
||||
"Language-Team: Ukrainian (Ukraine) (http://www.transifex.net/projects/p/I2P/language/uk_UA/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: uk_UA\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:487
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:492
|
||||
msgid "This seems to be a bad destination:"
|
||||
msgstr "Скоріше всього це поганий адрес призначення:"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:487
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:492
|
||||
msgid "i2paddresshelper cannot help you with a destination like that!"
|
||||
msgstr "i2paddresshelper не може допомогти Вам з місцем призначення як це!"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:556
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:561
|
||||
#, java-format
|
||||
msgid ""
|
||||
"To visit the destination in your host database, click <a "
|
||||
"href=\"{0}\">here</a>. To visit the conflicting addresshelper destination, "
|
||||
"click <a href=\"{1}\">here</a>."
|
||||
msgstr ""
|
||||
"Для того щоб перейти по локальному посиланню з локальної адресної книги, "
|
||||
"натисніть ось<a href=\"{0}\">тут</a>. Для переходу по новому addresshelper-"
|
||||
"посиланню, натисніть будь-ласка <a href=\"{1}\">тут</a>."
|
||||
msgstr "Для того щоб перейти по локальному посиланню з локальної адресної книги, натисніть ось<a href=\"{0}\">тут</a>. Для переходу по новому addresshelper-посиланню, натисніть будь-ласка <a href=\"{1}\">тут</a>."
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:932
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:937
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:398
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:142
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:401
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:391
|
||||
msgid "Host"
|
||||
msgstr "Адрес"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:933
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:370
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:938
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:372
|
||||
msgid "Destination"
|
||||
msgstr "Адреса призначення"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:938
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:943
|
||||
#, java-format
|
||||
msgid "Continue to {0} without saving"
|
||||
msgstr "Продовжити до {0} без збереження"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:943
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:948
|
||||
#, java-format
|
||||
msgid "Save {0} to router address book and continue to eepsite"
|
||||
msgstr ""
|
||||
"Зберегти {0} в адресну книгу роутера и продовжити перехід до eep-сайту"
|
||||
msgstr "Зберегти {0} в адресну книгу роутера и продовжити перехід до eep-сайту"
|
||||
|
||||
#. only blockfile supports multiple books
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:946
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:951
|
||||
#, java-format
|
||||
msgid "Save {0} to master address book and continue to eepsite"
|
||||
msgstr ""
|
||||
"Зберегти {0} в основну адресну книгу і продовжити перехід до еер-сайту"
|
||||
msgstr "Зберегти {0} в основну адресну книгу і продовжити перехід до еер-сайту"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:947
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:952
|
||||
#, java-format
|
||||
msgid "Save {0} to private address book and continue to eepsite"
|
||||
msgstr ""
|
||||
"Зберегти {0} в приватну адресну книгу і продовжити перехід до еер-сайту."
|
||||
msgstr "Зберегти {0} в приватну адресну книгу і продовжити перехід до еер-сайту."
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1102
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1107
|
||||
msgid "HTTP Outproxy"
|
||||
msgstr "Вихідний HTTP проксі"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1107
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1112
|
||||
msgid ""
|
||||
"Click a link below to look for an address helper by using a \"jump\" "
|
||||
"service:"
|
||||
msgstr ""
|
||||
"\"Jump\" сервіси, які, можливо, знають необхідне Вам addresshelper-"
|
||||
"посилання."
|
||||
msgstr "\"Jump\" сервіси, які, можливо, знають необхідне Вам addresshelper-посилання."
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1325
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1330
|
||||
msgid "Added via address helper"
|
||||
msgstr "Додано через address helper"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1349
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1354
|
||||
#, java-format
|
||||
msgid "Redirecting to {0}"
|
||||
msgstr "Перенаправляємо до {0}"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1355
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1360
|
||||
msgid "Router Console"
|
||||
msgstr "Консоль роутера"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1356
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1361
|
||||
msgid "Addressbook"
|
||||
msgstr "Адресна книга"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1356
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1361
|
||||
msgid "Configuration"
|
||||
msgstr "Настройки"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1356
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1361
|
||||
msgid "Help"
|
||||
msgstr "Допомога"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1361
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1366
|
||||
#, java-format
|
||||
msgid "Saved {0} to the {1} addressbook, redirecting now."
|
||||
msgstr "{0} збережено в {1} адресної книги, перенапрявляємо."
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1362
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1367
|
||||
#, java-format
|
||||
msgid "Failed to save {0} to the {1} addressbook, redirecting now."
|
||||
msgstr "Не вдалось зберегти {0} в {1} адресної книги, перенаправляємо."
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1364
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1369
|
||||
msgid "Click here if you are not redirected automatically."
|
||||
msgstr "Клацніть тут якщо вас не перенаправило автоматично."
|
||||
|
||||
@@ -134,9 +128,7 @@ msgstr "внутрішній"
|
||||
msgid ""
|
||||
"Invalid form submission, probably because you used the 'back' or 'reload' "
|
||||
"button on your browser. Please resubmit."
|
||||
msgstr ""
|
||||
"Неправильно передана форма, можливо ви використовуєте дію браузера \"назад\""
|
||||
" або \"оновити\". Будь-ласка повторіть спробу."
|
||||
msgstr "Неправильно передана форма, можливо ви використовуєте дію браузера \"назад\" або \"оновити\". Будь-ласка повторіть спробу."
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:222
|
||||
msgid "Configuration reloaded for all tunnels"
|
||||
@@ -210,17 +202,15 @@ msgstr "Streamr сервер"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:467
|
||||
msgid "HTTP bidir"
|
||||
msgstr ""
|
||||
"HTTP bidir (експерементальний двухнаправлений режим, інструкцію запитуйте у "
|
||||
"sponge)"
|
||||
msgstr "HTTP bidir (експерементальний двухнаправлений режим, інструкцію запитуйте у sponge)"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:555
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:293
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:295
|
||||
msgid "Host not set"
|
||||
msgstr "Хост не заданий"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:559
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:275
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:277
|
||||
msgid "Port not set"
|
||||
msgstr "Порт не заданий"
|
||||
|
||||
@@ -238,24 +228,26 @@ msgstr "Нові налаштування проксі"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:112
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:112
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:110
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:124
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:245
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:260
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:112
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:126
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:247
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:262
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:307
|
||||
msgid "Name"
|
||||
msgstr "Назва"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:116
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:116
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:249
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:282
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:251
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:284
|
||||
msgid "Type"
|
||||
msgstr "Тип"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:120
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:120
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:229
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:389
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:231
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:391
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:311
|
||||
msgid "Description"
|
||||
msgstr "Опис"
|
||||
|
||||
@@ -281,22 +273,27 @@ msgstr "необхідно"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:159
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:178
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:460
|
||||
msgid "Reachable by"
|
||||
msgstr "Доступно цим"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:180
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:339
|
||||
msgid "Outproxies"
|
||||
msgstr "Список вихідних проксі (Outproxies)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:187
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:359
|
||||
msgid "Tunnel Destination"
|
||||
msgstr "Адреса Призначення Тунелю"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:199
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:363
|
||||
msgid "name or destination"
|
||||
msgstr "ім'я або призначення"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:202
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:366
|
||||
msgid "b32 not recommended"
|
||||
msgstr "b32 не рекомендується"
|
||||
|
||||
@@ -308,18 +305,18 @@ msgstr "Колективний Клієнт"
|
||||
msgid ""
|
||||
"(Share tunnels with other clients and irc/httpclients? Change requires "
|
||||
"restart of client proxy)"
|
||||
msgstr ""
|
||||
"(Використовувати тунелі спільно з іншими клієнтами і irc/httpclients? Зміна"
|
||||
" налаштування потребує перезапуску тунелю)"
|
||||
msgstr "(Використовувати тунелі спільно з іншими клієнтами і irc/httpclients? Зміна налаштування потребує перезапуску тунелю)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:216
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:124
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:500
|
||||
msgid "Auto Start"
|
||||
msgstr "Автозапуск"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:220
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:228
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:128
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:504
|
||||
msgid "(Check the Box for 'YES')"
|
||||
msgstr "(Виберіть чекбокс 'ТАК')"
|
||||
|
||||
@@ -336,9 +333,7 @@ msgstr "Розширені мережеві опції"
|
||||
msgid ""
|
||||
"(NOTE: when this client proxy is configured to share tunnels, then these "
|
||||
"options are for all the shared proxy clients!)"
|
||||
msgstr ""
|
||||
"(Зверніть увагу: коли цей клієнтський проксі настроєний ділитись тунелями, "
|
||||
"то ці опції будуть дійсні для всіх проксі клієнтів з якими ви ділитесь!)"
|
||||
msgstr "(Зверніть увагу: коли цей клієнтський проксі настроєний ділитись тунелями, то ці опції будуть дійсні для всіх проксі клієнтів з якими ви ділитесь!)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:236
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:245
|
||||
@@ -368,8 +363,7 @@ msgstr "2 хоп тунель (висока анонімність, велики
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:257
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:266
|
||||
msgid "3 hop tunnel (very high anonymity, poor performance)"
|
||||
msgstr ""
|
||||
"3 хоп тунель (дуже висока анонімність, погана продуктивність (комп'ютера))"
|
||||
msgstr "3 хоп тунель (дуже висока анонімність, погана продуктивність (комп'ютера))"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:266
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:275
|
||||
@@ -390,21 +384,18 @@ msgstr "0 хоп розкид (без рандомізації, фіксован
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:291
|
||||
msgid ""
|
||||
"+ 0-1 hop variance (medium additive randomisation, subtractive performance)"
|
||||
msgstr ""
|
||||
"+0-1 хоп розкид (помірна збільшена рандомізація, понижена продуктивність)"
|
||||
msgstr "+0-1 хоп розкид (помірна збільшена рандомізація, понижена продуктивність)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:286
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:295
|
||||
msgid ""
|
||||
"+ 0-2 hop variance (high additive randomisation, subtractive performance)"
|
||||
msgstr ""
|
||||
"+0-2 хоп розкид (дуже збільшена рандомізація, понижена продуктивність)"
|
||||
msgstr "+0-2 хоп розкид (дуже збільшена рандомізація, понижена продуктивність)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:290
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:299
|
||||
msgid "+/- 0-1 hop variance (standard randomisation, standard performance)"
|
||||
msgstr ""
|
||||
"+/- 0-1 хоп розкид (стандартна рандомізація, стандартна продуктивнсть)"
|
||||
msgstr "+/- 0-1 хоп розкид (стандартна рандомізація, стандартна продуктивнсть)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:294
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:303
|
||||
@@ -424,26 +415,20 @@ msgstr "Кількість"
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:318
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:327
|
||||
msgid "1 inbound, 1 outbound tunnel (low bandwidth usage, less reliability)"
|
||||
msgstr ""
|
||||
"1 вхідний, 1 вихідний тунель (низька пропускна спроможність, низька "
|
||||
"надійність)"
|
||||
msgstr "1 вхідний, 1 вихідний тунель (низька пропускна спроможність, низька надійність)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:322
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:331
|
||||
msgid ""
|
||||
"2 inbound, 2 outbound tunnels (standard bandwidth usage, standard "
|
||||
"reliability)"
|
||||
msgstr ""
|
||||
"2 вхідні, 2 вихідні тунелі (стандартна пропускна спроможність, стандартна "
|
||||
"надійність)"
|
||||
msgstr "2 вхідні, 2 вихідні тунелі (стандартна пропускна спроможність, стандартна надійність)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:326
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:335
|
||||
msgid ""
|
||||
"3 inbound, 3 outbound tunnels (higher bandwidth usage, higher reliability)"
|
||||
msgstr ""
|
||||
"3 вхідні, 3 вихідні тунелі (висока пропускна спроможність, висока "
|
||||
"надійність)"
|
||||
msgstr "3 вхідні, 3 вихідні тунелі (висока пропускна спроможність, висока надійність)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:335
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:344
|
||||
@@ -458,31 +443,23 @@ msgstr "Резервна кількість"
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:347
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:356
|
||||
msgid "0 backup tunnels (0 redundancy, no added resource usage)"
|
||||
msgstr ""
|
||||
"0 резервних тунелів (0 надлишок, відсутність додаткового навантаження на "
|
||||
"систему) "
|
||||
msgstr "0 резервних тунелів (0 надлишок, відсутність додаткового навантаження на систему) "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:351
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:360
|
||||
msgid "1 backup tunnel each direction (low redundancy, low resource usage)"
|
||||
msgstr ""
|
||||
"1 резервний тунель в кожному напрямку (низька надлишковість, низьке "
|
||||
"використання ресурсів системи)"
|
||||
msgstr "1 резервний тунель в кожному напрямку (низька надлишковість, низьке використання ресурсів системи)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:355
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:364
|
||||
msgid ""
|
||||
"2 backup tunnels each direction (medium redundancy, medium resource usage)"
|
||||
msgstr ""
|
||||
"2 резервні тунелі в кожному напрямку (середня надмірність, середнє "
|
||||
"навантаження на систему)"
|
||||
msgstr "2 резервні тунелі в кожному напрямку (середня надмірність, середнє навантаження на систему)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:359
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:368
|
||||
msgid "3 backup tunnels each direction (high redundancy, high resource usage)"
|
||||
msgstr ""
|
||||
"3 резервні тунелі в кожному напрямку (висока надмірність, високе "
|
||||
"навантаження на систему)"
|
||||
msgstr "3 резервні тунелі в кожному напрямку (висока надмірність, високе навантаження на систему)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:368
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:377
|
||||
@@ -502,8 +479,7 @@ msgstr "оптимізувати для малих затримок (irc)"
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:386
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:395
|
||||
msgid "bulk connection (downloads/websites/BT)"
|
||||
msgstr ""
|
||||
"оптимізувати для великого об'єму (завантаження/веб-серфінг/Бітторрент)"
|
||||
msgstr "оптимізувати для великого об'єму (завантаження/веб-серфінг/Бітторрент)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:388
|
||||
msgid "Delay Connect"
|
||||
@@ -511,9 +487,7 @@ msgstr "Затримка Зєднання"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:392
|
||||
msgid "for request/response connections"
|
||||
msgstr ""
|
||||
"оптимізація для з'єднань, які починаються з запиту клієнта/відповіді "
|
||||
"сервера. "
|
||||
msgstr "оптимізація для з'єднань, які починаються з запиту клієнта/відповіді сервера. "
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:396
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:399
|
||||
@@ -523,8 +497,9 @@ msgstr "I2CP Адрес Роутера"
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:406
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:148
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:409
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:247
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:269
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:249
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:271
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:412
|
||||
msgid "Port"
|
||||
msgstr "Порт"
|
||||
|
||||
@@ -622,12 +597,11 @@ msgstr "Вибіркові параметри"
|
||||
msgid ""
|
||||
"NOTE: If tunnel is currently running, most changes will not take effect "
|
||||
"until tunnel is stopped and restarted."
|
||||
msgstr ""
|
||||
"Примітка: Якщо тунель зараз активний, то більшість змін не почнуть діяти до "
|
||||
"того моменту поки тунель не зупинять і перезапустять."
|
||||
msgstr "Примітка: Якщо тунель зараз активний, то більшість змін не почнуть діяти до того моменту поки тунель не зупинять і перезапустять."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:524
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:531
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:678
|
||||
msgid "Cancel"
|
||||
msgstr "Відмінити"
|
||||
|
||||
@@ -786,117 +760,466 @@ msgstr "Повідомлення про стан"
|
||||
msgid "Refresh"
|
||||
msgstr "Оновити"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:94
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:92
|
||||
msgid "Tunnel Wizard"
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:96
|
||||
msgid "Stop All"
|
||||
msgstr "Зупинити все"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:98
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:100
|
||||
msgid "Start All"
|
||||
msgstr "Запустити все"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:102
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:104
|
||||
msgid "Restart All"
|
||||
msgstr "Перезапустити все"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:106
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:108
|
||||
msgid "Reload Config"
|
||||
msgstr "Перезапустити настройки"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:108
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:110
|
||||
msgid "I2P Server Tunnels"
|
||||
msgstr "Серверні I2P тунелі"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:112
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:133
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:114
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:135
|
||||
msgid "Points at"
|
||||
msgstr "Вказує на"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:114
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:156
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:160
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:116
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:158
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:162
|
||||
msgid "Preview"
|
||||
msgstr "Попередній перегляд"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:116
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:180
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:253
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:300
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:118
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:182
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:255
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:302
|
||||
msgid "Status"
|
||||
msgstr "Статус"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:166
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:168
|
||||
msgid "Base32 Address"
|
||||
msgstr "Base32-адрес"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:174
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:176
|
||||
msgid "No Preview"
|
||||
msgstr "Попередній перегляд недоступний"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:187
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:307
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:189
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:309
|
||||
msgid "Starting..."
|
||||
msgstr "Запускається..."
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:194
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:208
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:314
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:328
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:342
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:196
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:210
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:316
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:330
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:344
|
||||
msgid "Stop"
|
||||
msgstr "Зупинити"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:201
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:335
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:203
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:337
|
||||
msgid "Running"
|
||||
msgstr "Працює"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:215
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:349
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:217
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:351
|
||||
msgid "Stopped"
|
||||
msgstr "Зупинений"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:222
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:356
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:224
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:358
|
||||
msgid "Start"
|
||||
msgstr "Запустити"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:237
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:239
|
||||
msgid "New server tunnel"
|
||||
msgstr "Новий серверний тунель"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:239
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:399
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:241
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:401
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:204
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:246
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:276
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:282
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:554
|
||||
msgid "Standard"
|
||||
msgstr "Стандартний"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:241
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:401
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:243
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:403
|
||||
msgid "Create"
|
||||
msgstr "Створити"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:243
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:245
|
||||
msgid "I2P Client Tunnels"
|
||||
msgstr "Клієнтскі I2P тунелі"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:251
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:286
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:253
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:288
|
||||
msgid "Interface"
|
||||
msgstr "Мережевий інтерфейс"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:321
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:323
|
||||
msgid "Standby"
|
||||
msgstr "Режим очікування"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:366
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:368
|
||||
msgid "Outproxy"
|
||||
msgstr "Outproxy (зовнішній проксі)"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:384
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:386
|
||||
msgid "none"
|
||||
msgstr "ні"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:397
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:399
|
||||
msgid "New client tunnel"
|
||||
msgstr "Новий клієнтський тунель"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:102
|
||||
msgid "I2P Tunnel Manager - Tunnel Creation Wizard"
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:120
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:545
|
||||
msgid "Server or client tunnel?"
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:126
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:549
|
||||
msgid "Tunnel type"
|
||||
msgstr "Тип тунелю"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:132
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:579
|
||||
msgid "Tunnel name and description"
|
||||
msgstr "Ім'я і опис тунелю"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:138
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:588
|
||||
msgid "Tunnel destination"
|
||||
msgstr "Місце призначення тунелю"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:144
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:604
|
||||
msgid "Binding address and port"
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:150
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:630
|
||||
msgid "Tunnel auto-start"
|
||||
msgstr "Авто-старт тунелю"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:156
|
||||
msgid "Wizard completed"
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:170
|
||||
msgid ""
|
||||
"This wizard will take you through the various options available for creating"
|
||||
" tunnels in I2P."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:172
|
||||
msgid ""
|
||||
"The first thing to decide is whether you want to create a server or a client"
|
||||
" tunnel."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:174
|
||||
msgid ""
|
||||
"If you need to connect to a remote service, such as an IRC server inside I2P"
|
||||
" or a code repository, then you will require a CLIENT tunnel."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:176
|
||||
msgid ""
|
||||
"On the other hand, if you wish to host a service for others to connect to "
|
||||
"you'll need to create a SERVER tunnel."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:178
|
||||
msgid "Server Tunnel"
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:180
|
||||
msgid "Client Tunnel"
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:198
|
||||
msgid "There are several types of tunnels to choose from:"
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:206
|
||||
msgid "Basic tunnel for connecting to a single service inside I2P."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:208
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:250
|
||||
msgid ""
|
||||
"Try this if none of the tunnel types below fit your requirements, or you "
|
||||
"don't know what type of tunnel you need."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:210
|
||||
msgid "Tunnel that acts as an HTTP proxy for reaching eepsites inside I2P."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:212
|
||||
msgid ""
|
||||
"Set your browser to use this tunnel as an http proxy, or set your "
|
||||
"\"http_proxy\" environment variable for command-line applications in "
|
||||
"GNU/Linux."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:214
|
||||
msgid ""
|
||||
"Websites outside I2P can also be reached if an HTTP proxy within I2P is "
|
||||
"known."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:216
|
||||
msgid "Customised client tunnel specific for IRC connections."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:218
|
||||
msgid ""
|
||||
"With this tunnel type, your IRC client will be able to connect to an IRC "
|
||||
"network inside I2P."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:220
|
||||
msgid ""
|
||||
"Each IRC network in I2P that you wish to connect to will require its own "
|
||||
"tunnel. (See Also, SOCKS IRC)"
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:222
|
||||
msgid "A tunnel that implements the SOCKS protocol."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:224
|
||||
msgid ""
|
||||
"This enables both TCP and UDP connections to be made through a SOCKS "
|
||||
"outproxy within I2P."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:226
|
||||
msgid ""
|
||||
"A client tunnel implementing the SOCKS protocol, which is customised for "
|
||||
"connecting to IRC networks."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:228
|
||||
msgid ""
|
||||
"With this tunnel type, IRC networks in I2P can be reached by typing the I2P "
|
||||
"address into your IRC client, and configuring the IRC client to use this "
|
||||
"SOCKS tunnel."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:230
|
||||
msgid ""
|
||||
"This means that only one I2P tunnel is required rather than a separate "
|
||||
"tunnel per IRC network."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:232
|
||||
msgid ""
|
||||
"IRC networks outside I2P can also be reached if a SOCKS outproxy within I2P "
|
||||
"is known, though it depends on whether or not the outproxy has been blocked "
|
||||
"by the IRC network."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:234
|
||||
msgid "A client tunnel that implements the HTTP CONNECT command."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:236
|
||||
msgid ""
|
||||
"This enables TCP connections to be made through an HTTP outproxy, assuming "
|
||||
"the proxy supports the CONNECT command."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:238
|
||||
msgid "A customised client tunnel for Streamr."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:248
|
||||
msgid "A basic server tunnel for hosting a generic service inside I2P."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:252
|
||||
msgid "A server tunnel that is customised for HTTP connections."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:254
|
||||
msgid "Use this tunnel type if you want to host an eepsite."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:256
|
||||
msgid ""
|
||||
"A customised server tunnel that can both serve HTTP data and connect to "
|
||||
"other server tunnels."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:258
|
||||
msgid "This tunnel type is predominantly used when running a Seedless server."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:260
|
||||
msgid "A customised server tunnel for hosting IRC networks inside I2P."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:262
|
||||
msgid ""
|
||||
"Usually, a separate tunnel needs to be created for each IRC server that is "
|
||||
"to be accessible inside I2P."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:264
|
||||
msgid "A customised server tunnel for Streamr."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:303
|
||||
msgid "Choose a name and description for your tunnel."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:305
|
||||
msgid ""
|
||||
"These can be anything you want - they are just for ease of identifying the "
|
||||
"tunnel in the routerconsole."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:335
|
||||
msgid ""
|
||||
"If you know of any outproxies for this type of tunnel (either HTTP or "
|
||||
"SOCKS), fill them in below."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:337
|
||||
msgid "Separate multiple proxies with commas."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:355
|
||||
msgid ""
|
||||
"Type in the I2P destination of the service that this client tunnel should "
|
||||
"connect to."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:357
|
||||
msgid ""
|
||||
"This could be the full base 64 destination key, or an I2P URL from your "
|
||||
"address book."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:387
|
||||
msgid ""
|
||||
"This is the IP that your service is running on, this is usually on the same "
|
||||
"machine so 127.0.0.1 is autofilled."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:410
|
||||
msgid "This is the port that the service is accepting connections on."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:431
|
||||
msgid "This is the port that the client tunnel will be accessed from locally."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:433
|
||||
msgid "This is also the client port for the HTTPBidir server tunnel."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:452
|
||||
msgid ""
|
||||
"How do you want this tunnel to be accessed? By just this machine, your "
|
||||
"entire subnet, or external internet?"
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:454
|
||||
msgid "You will most likely want to just allow 127.0.0.1"
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:496
|
||||
msgid ""
|
||||
"The I2P router can automatically start this tunnel for you when the router "
|
||||
"is started."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:498
|
||||
msgid ""
|
||||
"This can be useful for frequently-used tunnels (especially server tunnels), "
|
||||
"but for tunnels that are only used occassionally it would mean that the I2P "
|
||||
"router is creating and maintaining unnecessary tunnels."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:524
|
||||
msgid "The wizard has now collected enough information to create your tunnel."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:526
|
||||
msgid ""
|
||||
"Upon clicking the Save button below, the wizard will set up the tunnel, and "
|
||||
"take you back to the main I2PTunnel page."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:531
|
||||
msgid ""
|
||||
"Because you chose to automatically start the tunnel when the router starts, "
|
||||
"you don't have to do anything further."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:533
|
||||
msgid "The router will start the tunnel once it has been set up."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:537
|
||||
msgid ""
|
||||
"Because you chose not to automatically start the tunnel, you will have to "
|
||||
"manually start it."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:539
|
||||
msgid ""
|
||||
"You can do this by clicking the Start button on the main page which "
|
||||
"corresponds to the new tunnel."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:543
|
||||
msgid "Below is a summary of the options you chose:"
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:641
|
||||
msgid ""
|
||||
"Alongside these basic settings, there are a number of advanced options for "
|
||||
"tunnel configuration."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:643
|
||||
msgid ""
|
||||
"The wizard will set reasonably sensible default values for these, but you "
|
||||
"can view and/or edit these by clicking on the tunnel's name in the main "
|
||||
"I2PTunnel page."
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:683
|
||||
msgid "Previous"
|
||||
msgstr "Попередній"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:691
|
||||
msgid "Save Tunnel"
|
||||
msgstr "Зберегти тунель"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:697
|
||||
msgid "Finish"
|
||||
msgstr "Завершити"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:703
|
||||
msgid "Next"
|
||||
msgstr "Далі"
|
||||
|
||||
16
apps/jetty/apache-tomcat-deployer/NOTICE
Normal file
@@ -0,0 +1,16 @@
|
||||
Apache Tomcat
|
||||
Copyright 1999-2011 The Apache Software Foundation
|
||||
|
||||
This product includes software developed by
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
The Windows Installer is built with the Nullsoft
|
||||
Scriptable Install Sysem (NSIS), which is
|
||||
open source software. The original software and
|
||||
related information is available at
|
||||
http://nsis.sourceforge.net.
|
||||
|
||||
Java compilation software for JSP pages is provided by Eclipse,
|
||||
which is open source software. The original software and
|
||||
related information is available at
|
||||
http://www.eclipse.org.
|
||||
14
apps/jetty/apache-tomcat-deployer/README-i2p.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
This is Apache Tomcat 6.x, supporting Servlet 2.5 and JSP 2.1.
|
||||
The Glassfish JSP 2.1 bundled in Jetty 6 is way too old.
|
||||
|
||||
Retrieved from the file
|
||||
apache-tomcat-6.0.35-deployer.tar.gz
|
||||
|
||||
minus the following files and directores:
|
||||
|
||||
build.xml
|
||||
deployer-howto.html
|
||||
images/*
|
||||
lib/catalina*
|
||||
LICENSE (see ../../../licenses/LICENSE-Apache2.0.txt, it's also inside every jar)
|
||||
RELEASE-NOTES
|
||||
BIN
apps/jetty/apache-tomcat-deployer/lib/el-api.jar
Normal file
BIN
apps/jetty/apache-tomcat-deployer/lib/jasper-el.jar
Normal file
BIN
apps/jetty/apache-tomcat-deployer/lib/jasper.jar
Normal file
BIN
apps/jetty/apache-tomcat-deployer/lib/jsp-api.jar
Normal file
BIN
apps/jetty/apache-tomcat-deployer/lib/servlet-api.jar
Normal file
BIN
apps/jetty/apache-tomcat-deployer/lib/tomcat-juli.jar
Normal file
@@ -1,15 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project basedir="." default="all" name="jetty">
|
||||
|
||||
<property name="jetty.base" value="jetty-5.1.15" />
|
||||
<property name="jetty.sha1" value="3a7a3de50f86f0cdb23c33aec632ea7f44132c5e" />
|
||||
<property name="jetty.filename" value="${jetty.base}.tgz" />
|
||||
<property name="jetty.url" value="http://dist.codehaus.org/jetty/jetty-5.1.x/${jetty.filename}" />
|
||||
<property name="jetty.ver" value="6.1.26" />
|
||||
<property name="jetty.base" value="jetty-${jetty.ver}" />
|
||||
<property name="jetty.sha1" value="9485913f1a1945a849a90f1a34853d22350bc524" />
|
||||
<property name="jetty.filename" value="${jetty.base}.zip" />
|
||||
<property name="jetty.url" value="http://dist.codehaus.org/jetty/${jetty.base}/${jetty.filename}" />
|
||||
<property name="verified.filename" value="verified.txt" />
|
||||
<property name="javac.compilerargs" value="" />
|
||||
<property name="tomcat.lib" value="apache-tomcat-deployer/lib" />
|
||||
|
||||
<target name="all" depends="build" />
|
||||
|
||||
<!--
|
||||
<target name="ensureJettylib" >
|
||||
<available property="jetty.zip.available" file="${jetty.filename}" type="file" />
|
||||
<available property="jetty.zip.extracted" file="jettylib" type="dir" />
|
||||
@@ -17,6 +20,8 @@
|
||||
<ant target="verifyJettylib" />
|
||||
<ant target="extractJettylib" />
|
||||
</target>
|
||||
-->
|
||||
<target name="ensureJettylib" depends="extractJettylib" />
|
||||
|
||||
<target name="fetchJettylib" unless="jetty.zip.available" >
|
||||
<echo message="It seems that you don't have '${jetty.filename}' deployed." />
|
||||
@@ -63,27 +68,92 @@
|
||||
<touch file="${verified.filename}" />
|
||||
</target>
|
||||
|
||||
<!--
|
||||
<target name="extractJettylib" unless="jetty.zip.extracted" >
|
||||
-->
|
||||
<target name="extractJettylib" >
|
||||
<!-- for .tgz -->
|
||||
<!--
|
||||
<gunzip src="${jetty.filename}" dest="jetty.tar" />
|
||||
<untar src="jetty.tar" dest="." />
|
||||
-->
|
||||
<!-- for .zip -->
|
||||
<!--
|
||||
<unzip src="${jetty.filename}" dest="." />
|
||||
-->
|
||||
<mkdir dir="jettylib" />
|
||||
<copy todir="jettylib" preservelastmodified="true" >
|
||||
<fileset dir="${jetty.base}/lib">
|
||||
<include name="*.jar" />
|
||||
</fileset>
|
||||
<fileset dir="${jetty.base}/ext">
|
||||
<include name="ant.jar" />
|
||||
<include name="commons-el.jar" />
|
||||
<include name="commons-logging.jar" />
|
||||
<include name="jasper-compiler.jar" />
|
||||
<include name="jasper-runtime.jar" />
|
||||
</fileset>
|
||||
</copy>
|
||||
<!-- We copy everything to names without the version numbers so we
|
||||
can update them later. Where there was something similar in Jetty 5,
|
||||
we use the same names so they will overwrite the Jetty 5 jar on upgrade.
|
||||
Otherwise we use the same name as the symlink in Ubuntu /usr/share/java.
|
||||
Reasons for inclusion:
|
||||
start.jar: Needed for clients.config startup of eepsites
|
||||
jetty-util-xxx.jar: LifeCycle (base class for stuff), URIUtil (used in i2psnark)
|
||||
jetty-sslengine-xxx.jar: SSL NIO Connector for console
|
||||
jetty-java5-threadpool-xxx.jar: Concurrent thread pool for eepsite
|
||||
glassfish 2.1: Not used, too old, see Tomcat below.
|
||||
jetty-rewrite-handler: Not used by I2P, but only 20KB and could be useful for eepsites
|
||||
jetty-management: Not used by I2P, but only 34KB and could be useful for eepsites, and we bundled it with Jetty 5
|
||||
All of these are available in the Ubuntu packages libjetty-java and libjetty-extra-java
|
||||
-->
|
||||
<copy preservelastmodified="true" file="${jetty.base}/start.jar" tofile="jettylib/jetty-start.jar" />
|
||||
<copy file="${jetty.base}/lib/${jetty.base}.jar" tofile="jettylib/org.mortbay.jetty.jar" />
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-util-${jetty.ver}.jar" tofile="jettylib/jetty-util.jar" />
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/ext/jetty-java5-threadpool-${jetty.ver}.jar" tofile="jettylib/jetty-java5-threadpool.jar" />
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/ext/jetty-rewrite-handler-${jetty.ver}.jar" tofile="jettylib/jetty-rewrite-handler.jar" />
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/ext/jetty-sslengine-${jetty.ver}.jar" tofile="jettylib/jetty-sslengine.jar" />
|
||||
<copy preservelastmodified="true" file="${jetty.base}/lib/management/jetty-management-${jetty.ver}.jar" tofile="jettylib/org.mortbay.jmx.jar" />
|
||||
<delete file="jetty.tar" />
|
||||
<!--
|
||||
<delete dir="${jetty.base}" />
|
||||
-->
|
||||
<!-- commons-logging.jar not in Jetty 6 but we have it in launch4j so copy it over,
|
||||
needed for old plugins and things. We add tomcat-juli below.
|
||||
-->
|
||||
<jar destfile="jettylib/commons-logging.jar" filesetmanifest="mergewithoutmain" >
|
||||
<zipfileset excludes="META-INF/LICENSE.txt META-INF/NOTICE.txt" src="../../installer/lib/launch4j/lib/commons-logging.jar" />
|
||||
</jar>
|
||||
<ant target="copyTomcatLib" />
|
||||
</target>
|
||||
|
||||
<!-- Tomcat.
|
||||
The glassfish jars bundled in Jetty 6 are way too old.
|
||||
For compatibility with very old I2P installations where the classpath
|
||||
was set individually in wrapper.config, we rename and combine the jars as follows:
|
||||
jasper.jar : jasper-runtime.jar
|
||||
jasper-el.jar + el-api.jar : commons-el.jar
|
||||
servlet-api.jar + jsp-api.jar : javax.servlet.jar
|
||||
tomcat-juli.jar : Add to commons-logging.jar
|
||||
empty jar : jasper-compiler.jar
|
||||
Also, take NOTICE and LICENSE out of each one, we bundle those separately.
|
||||
-->
|
||||
<target name="copyTomcatLib" >
|
||||
<jar destfile="jettylib/jasper-runtime.jar" filesetmanifest="merge" >
|
||||
<zipfileset excludes="META-INF/LICENSE META-INF/NOTICE" src="${tomcat.lib}/jasper.jar" />
|
||||
</jar>
|
||||
<jar destfile="jettylib/commons-el.jar" duplicate="preserve" filesetmanifest="merge" >
|
||||
<zipfileset excludes="META-INF/LICENSE META-INF/NOTICE" src="${tomcat.lib}/jasper-el.jar" />
|
||||
<zipfileset excludes="META-INF/**/*" src="${tomcat.lib}/el-api.jar" />
|
||||
</jar>
|
||||
<jar destfile="jettylib/javax.servlet.jar" duplicate="preserve" filesetmanifest="mergewithoutmain" >
|
||||
<zipfileset excludes="META-INF/LICENSE META-INF/NOTICE" src="${tomcat.lib}/servlet-api.jar" />
|
||||
<zipfileset excludes="META-INF/**/*" src="${tomcat.lib}/jsp-api.jar" />
|
||||
</jar>
|
||||
<!-- Ant bug, don't set update and filesetmanifest or the update doesn't happen,
|
||||
Their bug tracker claims fixed in 1.8.0 but broken for me in 1.8.1
|
||||
-->
|
||||
<jar destfile="jettylib/commons-logging.jar" update="true" >
|
||||
<zipfileset excludes="META-INF/LICENSE META-INF/NOTICE" src="${tomcat.lib}/tomcat-juli.jar" />
|
||||
</jar>
|
||||
<jar destfile="jettylib/jasper-compiler.jar" >
|
||||
<manifest>
|
||||
<attribute name="Note" value="Intentionally empty" />
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="build" depends="jar" />
|
||||
|
||||
<target name="builddep" />
|
||||
<target name="compile" depends="builddep, ensureJettylib" >
|
||||
<mkdir dir="./build" />
|
||||
@@ -93,7 +163,7 @@
|
||||
debug="true" source="1.5" target="1.5"
|
||||
destdir="./build/obj"
|
||||
includeAntRuntime="false"
|
||||
classpath="./jettylib/commons-logging.jar:./jettylib/javax.servlet.jar:./jettylib/org.mortbay.jetty.jar" >
|
||||
classpath="../../core/java/build/i2p.jar:./jettylib/commons-logging.jar:./jettylib/javax.servlet.jar:./jettylib/org.mortbay.jetty.jar:./jettylib/jetty-util.jar" >
|
||||
<compilerarg line="${javac.compilerargs}" />
|
||||
</javac>
|
||||
</target>
|
||||
@@ -112,11 +182,18 @@
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<!-- With Jetty 5 we replaced classes in the jar, but with Jetty 6 we
|
||||
put our stuff in its own jar so we can work with standard Jetty 6 packages
|
||||
-->
|
||||
<target name="jar" depends="compile, jarUpToDate, listChangedFiles" unless="jar.uptodate" >
|
||||
<!-- set if unset -->
|
||||
<property name="workspace.changes.tr" value="" />
|
||||
<jar destfile="./jettylib/org.mortbay.jetty.jar" basedir="./build/obj" includes="**/*.class" update="true" >
|
||||
<!-- old jetty 5 classes blow up the build if you forgot to do distclean -->
|
||||
<delete dir="build/obj/org" />
|
||||
<copy todir="build/obj" file="resources/log4j.properties" />
|
||||
<jar destfile="./jettylib/jetty-i2p.jar" basedir="./build/obj" includes="**/*.class log4j.properties" >
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${build.built-by}" />
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
|
||||
@@ -125,7 +202,7 @@
|
||||
</target>
|
||||
|
||||
<target name="jarUpToDate">
|
||||
<uptodate property="jar.uptodate" targetfile="jettylib/org.mortbay.jetty.jar" >
|
||||
<uptodate property="jar.uptodate" targetfile="jettylib/jetty-i2p.jar" >
|
||||
<srcfiles dir= "build/obj" includes="**/*.class" />
|
||||
</uptodate>
|
||||
<condition property="shouldListChanges" >
|
||||
@@ -145,7 +222,9 @@
|
||||
<target name="cleandep" depends="clean" />
|
||||
<target name="distclean" depends="clean">
|
||||
<delete dir="./jettylib" />
|
||||
<!--
|
||||
<echo message="Not actually deleting the jetty libs (since they're so large)" />
|
||||
-->
|
||||
</target>
|
||||
<target name="reallyclean" depends="distclean">
|
||||
</target>
|
||||
|
||||
186
apps/jetty/java/src/net/i2p/jetty/I2PLogger.java
Normal file
@@ -0,0 +1,186 @@
|
||||
// ========================================================================
|
||||
// Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ========================================================================
|
||||
|
||||
package net.i2p.jetty;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.log.Logger;
|
||||
|
||||
/**
|
||||
* Modified from Jetty 6.1.26 StdErrLog.java and Slf4jLog.java
|
||||
*
|
||||
* Usage: org.mortbay.log.Log.setLog(new I2PLogger(ctx));
|
||||
*
|
||||
* @since Jetty 6
|
||||
*/
|
||||
public class I2PLogger implements Logger
|
||||
{
|
||||
private final Log _log;
|
||||
|
||||
StringBuilder _buffer = new StringBuilder();
|
||||
|
||||
static {
|
||||
// So people don't wonder where the logs went
|
||||
System.out.println("INFO: Jetty " + Server.getVersion() + " logging to I2P logs using class " + Server.class.getName());
|
||||
}
|
||||
|
||||
public I2PLogger()
|
||||
{
|
||||
this(I2PAppContext.getGlobalContext());
|
||||
}
|
||||
|
||||
public I2PLogger(I2PAppContext ctx)
|
||||
{
|
||||
_log = ctx.logManager().getLog(Server.class);
|
||||
if (System.getProperty("DEBUG") != null)
|
||||
setDebugEnabled(true);
|
||||
}
|
||||
|
||||
public boolean isDebugEnabled()
|
||||
{
|
||||
return _log.shouldLog(Log.DEBUG);
|
||||
}
|
||||
|
||||
public void setDebugEnabled(boolean enabled)
|
||||
{
|
||||
if (enabled)
|
||||
_log.setMinimumPriority(Log.DEBUG);
|
||||
else
|
||||
// LogManager.getDefaultLimit() returns a String, not worth it
|
||||
_log.setMinimumPriority(Log.ERROR);
|
||||
}
|
||||
|
||||
public void info(String msg,Object arg0, Object arg1)
|
||||
{
|
||||
if (arg0 == null && arg1 == null) {
|
||||
_log.info(msg);
|
||||
} else if (arg0 != null && arg1 == null && arg0 instanceof Throwable) {
|
||||
_log.info(msg, (Throwable) arg0);
|
||||
} else if (_log.shouldLog(Log.INFO)) {
|
||||
synchronized(_buffer) {
|
||||
format(msg,arg0,arg1);
|
||||
_log.info(_buffer.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void debug(String msg,Throwable th)
|
||||
{
|
||||
_log.debug(msg,th);
|
||||
}
|
||||
|
||||
public void debug(String msg,Object arg0, Object arg1)
|
||||
{
|
||||
if (arg0 == null && arg1 == null) {
|
||||
_log.debug(msg);
|
||||
} else if (arg0 != null && arg1 == null && arg0 instanceof Throwable) {
|
||||
_log.debug(msg, (Throwable) arg0);
|
||||
} else if (_log.shouldLog(Log.DEBUG)) {
|
||||
synchronized(_buffer) {
|
||||
format(msg,arg0,arg1);
|
||||
_log.debug(_buffer.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void warn(String msg,Object arg0, Object arg1)
|
||||
{
|
||||
if (arg0 == null && arg1 == null) {
|
||||
_log.warn(msg);
|
||||
} else if (arg0 != null && arg1 == null && arg0 instanceof Throwable) {
|
||||
_log.error(msg, (Throwable) arg0);
|
||||
} else if (_log.shouldLog(Log.WARN)) {
|
||||
synchronized(_buffer) {
|
||||
format(msg,arg0,arg1);
|
||||
_log.warn(_buffer.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void warn(String msg, Throwable th)
|
||||
{
|
||||
// This doesn't cover ClassNotFoundException, etc.
|
||||
//if (th instanceof RuntimeException || th instanceof Error)
|
||||
_log.error(msg, th);
|
||||
//else
|
||||
// _log.warn(msg,th);
|
||||
}
|
||||
|
||||
private void format(String msg, Object arg0, Object arg1)
|
||||
{
|
||||
_buffer.setLength(0);
|
||||
int i0=msg==null?-1:msg.indexOf("{}");
|
||||
int i1=i0<0?-1:msg.indexOf("{}",i0+2);
|
||||
|
||||
if (i0>=0)
|
||||
{
|
||||
format(msg.substring(0,i0));
|
||||
format(String.valueOf(arg0==null?"null":arg0));
|
||||
|
||||
if (i1>=0)
|
||||
{
|
||||
format(msg.substring(i0+2,i1));
|
||||
format(String.valueOf(arg1==null?"null":arg1));
|
||||
format(msg.substring(i1+2));
|
||||
}
|
||||
else
|
||||
{
|
||||
format(msg.substring(i0+2));
|
||||
if (arg1!=null)
|
||||
{
|
||||
_buffer.append(' ');
|
||||
format(String.valueOf(arg1));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
format(msg);
|
||||
if (arg0!=null)
|
||||
{
|
||||
_buffer.append(' ');
|
||||
format(String.valueOf(arg0));
|
||||
}
|
||||
if (arg1!=null)
|
||||
{
|
||||
_buffer.append(' ');
|
||||
format(String.valueOf(arg1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void format(String msg)
|
||||
{
|
||||
if (msg == null)
|
||||
_buffer.append("null");
|
||||
else
|
||||
_buffer.append(msg);
|
||||
}
|
||||
|
||||
public Logger getLogger(String name)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "I2PLogger";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
513
apps/jetty/java/src/net/i2p/jetty/I2PRequestLog.java
Normal file
@@ -0,0 +1,513 @@
|
||||
//========================================================================
|
||||
//Copyright 1997-2006 Mort Bay Consulting Pty. Ltd.
|
||||
//------------------------------------------------------------------------
|
||||
//Licensed under the Apache License, Version 2.0 (the "License");
|
||||
//you may not use this file except in compliance with the License.
|
||||
//You may obtain a copy of the License at
|
||||
//http://www.apache.org/licenses/LICENSE-2.0
|
||||
//Unless required by applicable law or agreed to in writing, software
|
||||
//distributed under the License is distributed on an "AS IS" BASIS,
|
||||
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//See the License for the specific language governing permissions and
|
||||
//limitations under the License.
|
||||
//========================================================================
|
||||
|
||||
package net.i2p.jetty;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.mortbay.component.AbstractLifeCycle;
|
||||
import org.mortbay.jetty.HttpHeaders;
|
||||
import org.mortbay.jetty.Request;
|
||||
import org.mortbay.jetty.RequestLog;
|
||||
import org.mortbay.jetty.Response;
|
||||
import org.mortbay.jetty.servlet.PathMap;
|
||||
import org.mortbay.log.Log;
|
||||
import org.mortbay.util.DateCache;
|
||||
import org.mortbay.util.RolloverFileOutputStream;
|
||||
import org.mortbay.util.StringUtil;
|
||||
import org.mortbay.util.TypeUtil;
|
||||
import org.mortbay.util.Utf8StringBuffer;
|
||||
|
||||
/**
|
||||
* This {@link RequestLog} implementation outputs logs in the pseudo-standard NCSA common log format.
|
||||
* Configuration options allow a choice between the standard Common Log Format (as used in the 3 log format)
|
||||
* and the Combined Log Format (single log format).
|
||||
* This log format can be output by most web servers, and almost all web log analysis software can understand
|
||||
* these formats.
|
||||
*
|
||||
* ** I2P Mods **
|
||||
*
|
||||
* For Jetty 5, this extended NCSARequestLog to
|
||||
* override log() to put in the requestor's destination hash,
|
||||
* instead of 127.0.0.1,
|
||||
* which is placed in the X-I2P-DestHash field in the request headers
|
||||
* by I2PTunnelHTTPServer.
|
||||
* But we also had to modify NCSARequestLog to do so, to change private
|
||||
* fields to protected.
|
||||
*
|
||||
* So that we will work with system Jetty 6 packages, we just copy the whole thing
|
||||
* and modify log() as required.
|
||||
* We leave the package as org.mortbay.http for compatibility with old
|
||||
* jetty.xml files.
|
||||
*
|
||||
* @author Greg Wilkins
|
||||
* @author Nigel Canonizado
|
||||
*
|
||||
*/
|
||||
public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
|
||||
{
|
||||
private String _filename;
|
||||
private boolean _extended;
|
||||
private boolean _append;
|
||||
private int _retainDays;
|
||||
private boolean _closeOut;
|
||||
private boolean _preferProxiedForAddress;
|
||||
private String _logDateFormat="dd/MMM/yyyy:HH:mm:ss Z";
|
||||
private String _filenameDateFormat = null;
|
||||
private Locale _logLocale = Locale.getDefault();
|
||||
private String _logTimeZone = "GMT";
|
||||
private String[] _ignorePaths;
|
||||
private boolean _logLatency = false;
|
||||
private boolean _logCookies = false;
|
||||
private boolean _logServer = false;
|
||||
|
||||
private transient OutputStream _out;
|
||||
private transient OutputStream _fileOut;
|
||||
private transient DateCache _logDateCache;
|
||||
private transient PathMap _ignorePathMap;
|
||||
private transient Writer _writer;
|
||||
private transient ArrayList _buffers;
|
||||
private transient char[] _copy;
|
||||
|
||||
|
||||
public I2PRequestLog()
|
||||
{
|
||||
_extended = true;
|
||||
_append = true;
|
||||
_retainDays = 31;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param filename The filename for the request log. This may be in the format expected by {@link RolloverFileOutputStream}
|
||||
*/
|
||||
public I2PRequestLog(String filename)
|
||||
{
|
||||
_extended = true;
|
||||
_append = true;
|
||||
_retainDays = 31;
|
||||
setFilename(filename);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param filename The filename for the request log. This may be in the format expected by {@link RolloverFileOutputStream}
|
||||
*/
|
||||
public void setFilename(String filename)
|
||||
{
|
||||
if (filename != null)
|
||||
{
|
||||
filename = filename.trim();
|
||||
if (filename.length() == 0)
|
||||
filename = null;
|
||||
}
|
||||
_filename = filename;
|
||||
}
|
||||
|
||||
public String getFilename()
|
||||
{
|
||||
return _filename;
|
||||
}
|
||||
|
||||
public String getDatedFilename()
|
||||
{
|
||||
if (_fileOut instanceof RolloverFileOutputStream)
|
||||
return ((RolloverFileOutputStream)_fileOut).getDatedFilename();
|
||||
return null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param format Format for the timestamps in the log file. If not set,
|
||||
* the pre-formated request timestamp is used.
|
||||
*/
|
||||
public void setLogDateFormat(String format)
|
||||
{
|
||||
_logDateFormat = format;
|
||||
}
|
||||
|
||||
public String getLogDateFormat()
|
||||
{
|
||||
return _logDateFormat;
|
||||
}
|
||||
|
||||
public void setLogLocale(Locale logLocale)
|
||||
{
|
||||
_logLocale = logLocale;
|
||||
}
|
||||
|
||||
public Locale getLogLocale()
|
||||
{
|
||||
return _logLocale;
|
||||
}
|
||||
|
||||
public void setLogTimeZone(String tz)
|
||||
{
|
||||
_logTimeZone = tz;
|
||||
}
|
||||
|
||||
public String getLogTimeZone()
|
||||
{
|
||||
return _logTimeZone;
|
||||
}
|
||||
|
||||
public void setRetainDays(int retainDays)
|
||||
{
|
||||
_retainDays = retainDays;
|
||||
}
|
||||
|
||||
public int getRetainDays()
|
||||
{
|
||||
return _retainDays;
|
||||
}
|
||||
|
||||
public void setExtended(boolean extended)
|
||||
{
|
||||
_extended = extended;
|
||||
}
|
||||
|
||||
public boolean isExtended()
|
||||
{
|
||||
return _extended;
|
||||
}
|
||||
|
||||
public void setAppend(boolean append)
|
||||
{
|
||||
_append = append;
|
||||
}
|
||||
|
||||
public boolean isAppend()
|
||||
{
|
||||
return _append;
|
||||
}
|
||||
|
||||
public void setIgnorePaths(String[] ignorePaths)
|
||||
{
|
||||
_ignorePaths = ignorePaths;
|
||||
}
|
||||
|
||||
public String[] getIgnorePaths()
|
||||
{
|
||||
return _ignorePaths;
|
||||
}
|
||||
|
||||
public void setLogCookies(boolean logCookies)
|
||||
{
|
||||
_logCookies = logCookies;
|
||||
}
|
||||
|
||||
public boolean getLogCookies()
|
||||
{
|
||||
return _logCookies;
|
||||
}
|
||||
|
||||
public boolean getLogServer()
|
||||
{
|
||||
return _logServer;
|
||||
}
|
||||
|
||||
public void setLogServer(boolean logServer)
|
||||
{
|
||||
_logServer=logServer;
|
||||
}
|
||||
|
||||
public void setLogLatency(boolean logLatency)
|
||||
{
|
||||
_logLatency = logLatency;
|
||||
}
|
||||
|
||||
public boolean getLogLatency()
|
||||
{
|
||||
return _logLatency;
|
||||
}
|
||||
|
||||
public void setPreferProxiedForAddress(boolean preferProxiedForAddress)
|
||||
{
|
||||
_preferProxiedForAddress = preferProxiedForAddress;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void log(Request request, Response response)
|
||||
{
|
||||
if (!isStarted())
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
if (_ignorePathMap != null && _ignorePathMap.getMatch(request.getRequestURI()) != null)
|
||||
return;
|
||||
|
||||
if (_fileOut == null)
|
||||
return;
|
||||
|
||||
Utf8StringBuffer u8buf;
|
||||
StringBuffer buf;
|
||||
synchronized(_writer)
|
||||
{
|
||||
int size=_buffers.size();
|
||||
u8buf = size==0?new Utf8StringBuffer(160):(Utf8StringBuffer)_buffers.remove(size-1);
|
||||
buf = u8buf.getStringBuffer();
|
||||
}
|
||||
|
||||
synchronized(buf) // for efficiency until we can use StringBuilder
|
||||
{
|
||||
if (_logServer)
|
||||
{
|
||||
buf.append(request.getServerName());
|
||||
buf.append(' ');
|
||||
}
|
||||
|
||||
String addr = null;
|
||||
if (_preferProxiedForAddress)
|
||||
{
|
||||
addr = request.getHeader(HttpHeaders.X_FORWARDED_FOR);
|
||||
}
|
||||
|
||||
if (addr == null) {
|
||||
// TODO offer B32 option
|
||||
addr = request.getHeader("X-I2P-DestHash");
|
||||
if(addr != null)
|
||||
addr += ".i2p";
|
||||
else
|
||||
addr = request.getRemoteAddr();
|
||||
}
|
||||
|
||||
buf.append(addr);
|
||||
buf.append(" - ");
|
||||
String user = request.getRemoteUser();
|
||||
buf.append((user == null)? " - " : user);
|
||||
buf.append(" [");
|
||||
if (_logDateCache!=null)
|
||||
buf.append(_logDateCache.format(request.getTimeStamp()));
|
||||
else
|
||||
buf.append(request.getTimeStampBuffer().toString());
|
||||
|
||||
buf.append("] \"");
|
||||
buf.append(request.getMethod());
|
||||
buf.append(' ');
|
||||
|
||||
request.getUri().writeTo(u8buf);
|
||||
|
||||
buf.append(' ');
|
||||
buf.append(request.getProtocol());
|
||||
buf.append("\" ");
|
||||
int status = response.getStatus();
|
||||
if (status<=0)
|
||||
status=404;
|
||||
buf.append((char)('0'+((status/100)%10)));
|
||||
buf.append((char)('0'+((status/10)%10)));
|
||||
buf.append((char)('0'+(status%10)));
|
||||
|
||||
|
||||
long responseLength=response.getContentCount();
|
||||
if (responseLength >=0)
|
||||
{
|
||||
buf.append(' ');
|
||||
if (responseLength > 99999)
|
||||
buf.append(Long.toString(responseLength));
|
||||
else
|
||||
{
|
||||
if (responseLength > 9999)
|
||||
buf.append((char)('0' + ((responseLength / 10000)%10)));
|
||||
if (responseLength > 999)
|
||||
buf.append((char)('0' + ((responseLength /1000)%10)));
|
||||
if (responseLength > 99)
|
||||
buf.append((char)('0' + ((responseLength / 100)%10)));
|
||||
if (responseLength > 9)
|
||||
buf.append((char)('0' + ((responseLength / 10)%10)));
|
||||
buf.append((char)('0' + (responseLength)%10));
|
||||
}
|
||||
buf.append(' ');
|
||||
}
|
||||
else
|
||||
buf.append(" - ");
|
||||
|
||||
}
|
||||
|
||||
if (!_extended && !_logCookies && !_logLatency)
|
||||
{
|
||||
synchronized(_writer)
|
||||
{
|
||||
buf.append(StringUtil.__LINE_SEPARATOR);
|
||||
int l=buf.length();
|
||||
if (l>_copy.length)
|
||||
l=_copy.length;
|
||||
buf.getChars(0,l,_copy,0);
|
||||
_writer.write(_copy,0,l);
|
||||
_writer.flush();
|
||||
u8buf.reset();
|
||||
_buffers.add(u8buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
synchronized(_writer)
|
||||
{
|
||||
int l=buf.length();
|
||||
if (l>_copy.length)
|
||||
l=_copy.length;
|
||||
buf.getChars(0,l,_copy,0);
|
||||
_writer.write(_copy,0,l);
|
||||
u8buf.reset();
|
||||
_buffers.add(u8buf);
|
||||
|
||||
// TODO do outside synchronized scope
|
||||
if (_extended)
|
||||
logExtended(request, response, _writer);
|
||||
|
||||
// TODO do outside synchronized scope
|
||||
if (_logCookies)
|
||||
{
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if (cookies == null || cookies.length == 0)
|
||||
_writer.write(" -");
|
||||
else
|
||||
{
|
||||
_writer.write(" \"");
|
||||
for (int i = 0; i < cookies.length; i++)
|
||||
{
|
||||
if (i != 0)
|
||||
_writer.write(';');
|
||||
_writer.write(cookies[i].getName());
|
||||
_writer.write('=');
|
||||
_writer.write(cookies[i].getValue());
|
||||
}
|
||||
_writer.write('\"');
|
||||
}
|
||||
}
|
||||
|
||||
if (_logLatency)
|
||||
{
|
||||
_writer.write(' ');
|
||||
_writer.write(TypeUtil.toString(System.currentTimeMillis() - request.getTimeStamp()));
|
||||
}
|
||||
|
||||
_writer.write(StringUtil.__LINE_SEPARATOR);
|
||||
_writer.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
Log.warn(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected void logExtended(Request request,
|
||||
Response response,
|
||||
Writer writer) throws IOException
|
||||
{
|
||||
String referer = request.getHeader(HttpHeaders.REFERER);
|
||||
if (referer == null)
|
||||
writer.write("\"-\" ");
|
||||
else
|
||||
{
|
||||
writer.write('"');
|
||||
writer.write(referer);
|
||||
writer.write("\" ");
|
||||
}
|
||||
|
||||
String agent = request.getHeader(HttpHeaders.USER_AGENT);
|
||||
if (agent == null)
|
||||
writer.write("\"-\" ");
|
||||
else
|
||||
{
|
||||
writer.write('"');
|
||||
writer.write(agent);
|
||||
writer.write('"');
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
if (_logDateFormat!=null)
|
||||
{
|
||||
_logDateCache = new DateCache(_logDateFormat, _logLocale);
|
||||
_logDateCache.setTimeZoneID(_logTimeZone);
|
||||
}
|
||||
|
||||
if (_filename != null)
|
||||
{
|
||||
_fileOut = new RolloverFileOutputStream(_filename,_append,_retainDays,TimeZone.getTimeZone(_logTimeZone),_filenameDateFormat,null);
|
||||
_closeOut = true;
|
||||
Log.info("Opened "+getDatedFilename());
|
||||
}
|
||||
else
|
||||
_fileOut = System.err;
|
||||
|
||||
_out = _fileOut;
|
||||
|
||||
if (_ignorePaths != null && _ignorePaths.length > 0)
|
||||
{
|
||||
_ignorePathMap = new PathMap();
|
||||
for (int i = 0; i < _ignorePaths.length; i++)
|
||||
_ignorePathMap.put(_ignorePaths[i], _ignorePaths[i]);
|
||||
}
|
||||
else
|
||||
_ignorePathMap = null;
|
||||
|
||||
_writer = new OutputStreamWriter(_out);
|
||||
_buffers = new ArrayList();
|
||||
_copy = new char[1024];
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
super.doStop();
|
||||
try {if (_writer != null) _writer.flush();} catch (IOException e) {Log.ignore(e);}
|
||||
if (_out != null && _closeOut)
|
||||
try {_out.close();} catch (IOException e) {Log.ignore(e);}
|
||||
|
||||
_out = null;
|
||||
_fileOut = null;
|
||||
_closeOut = false;
|
||||
_logDateCache = null;
|
||||
_writer = null;
|
||||
_buffers = null;
|
||||
_copy = null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return the log File Date Format
|
||||
*/
|
||||
public String getFilenameDateFormat()
|
||||
{
|
||||
return _filenameDateFormat;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the log file date format.
|
||||
* see RolloverFileOutputStream(String, boolean, int, TimeZone, String, String)
|
||||
* @param logFileDateFormat the logFileDateFormat to pass to RolloverFileOutputStream
|
||||
*/
|
||||
public void setFilenameDateFormat(String logFileDateFormat)
|
||||
{
|
||||
_filenameDateFormat=logFileDateFormat;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
// ========================================================================
|
||||
// $Id: NCSARequestLog.java,v 1.35 2005/08/13 00:01:24 gregwilkins Exp $
|
||||
// Copyright 2000-2004 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ========================================================================
|
||||
|
||||
package org.mortbay.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.mortbay.log.LogFactory;
|
||||
import org.mortbay.util.DateCache;
|
||||
import org.mortbay.util.LogSupport;
|
||||
import org.mortbay.util.RolloverFileOutputStream;
|
||||
import org.mortbay.util.StringUtil;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** NCSA HTTP Request Log.
|
||||
*
|
||||
* Override log() to put in the requestor's destination hash,
|
||||
* instead of 127.0.0.1,
|
||||
* which is placed in the X-I2P-DestHash field in the request headers
|
||||
* by I2PTunnelHTTPServer.
|
||||
*
|
||||
* NCSA common or NCSA extended (combined) request log.
|
||||
* @version $Id: NCSARequestLog.java,v 1.35 2005/08/13 00:01:24 gregwilkins Exp $
|
||||
* @author Tony Thompson
|
||||
* @author Greg Wilkins
|
||||
*/
|
||||
public class I2PRequestLog extends NCSARequestLog
|
||||
{
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
*/
|
||||
public I2PRequestLog()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param filename Filename, which can be in
|
||||
* rolloverFileOutputStream format
|
||||
* @see org.mortbay.util.RolloverFileOutputStream
|
||||
* @exception IOException
|
||||
*/
|
||||
public I2PRequestLog(String filename)
|
||||
throws IOException
|
||||
{
|
||||
super(filename);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Log a request.
|
||||
* @param request The request
|
||||
* @param response The response to this request.
|
||||
* @param responseLength The bytes written to the response.
|
||||
*/
|
||||
public void log(HttpRequest request,
|
||||
HttpResponse response,
|
||||
int responseLength)
|
||||
{
|
||||
try{
|
||||
// ignore ignorables
|
||||
if (_ignorePathMap != null &&
|
||||
_ignorePathMap.getMatch(request.getPath()) != null)
|
||||
return;
|
||||
|
||||
// log the rest
|
||||
if (_fileOut==null)
|
||||
return;
|
||||
|
||||
StringBuilder buf = new StringBuilder(160);
|
||||
|
||||
String addr = request.getField("X-I2P-DestHash");
|
||||
if(addr != null)
|
||||
buf.append(addr).append(".i2p");
|
||||
else
|
||||
buf.append(request.getRemoteAddr());
|
||||
|
||||
buf.append(" - ");
|
||||
String user = request.getAuthUser();
|
||||
buf.append((user==null)?"-":user);
|
||||
buf.append(" [");
|
||||
buf.append(_logDateCache.format(request.getTimeStamp()));
|
||||
buf.append("] \"");
|
||||
buf.append(request.getMethod());
|
||||
buf.append(' ');
|
||||
buf.append(request.getURI());
|
||||
buf.append(' ');
|
||||
buf.append(request.getVersion());
|
||||
buf.append("\" ");
|
||||
int status=response.getStatus();
|
||||
buf.append((char)('0'+((status/100)%10)));
|
||||
buf.append((char)('0'+((status/10)%10)));
|
||||
buf.append((char)('0'+(status%10)));
|
||||
if (responseLength>=0)
|
||||
{
|
||||
buf.append(' ');
|
||||
if (responseLength>99999)
|
||||
buf.append(Integer.toString(responseLength));
|
||||
else
|
||||
{
|
||||
if (responseLength>9999)
|
||||
buf.append((char)('0'+((responseLength/10000)%10)));
|
||||
if (responseLength>999)
|
||||
buf.append((char)('0'+((responseLength/1000)%10)));
|
||||
if (responseLength>99)
|
||||
buf.append((char)('0'+((responseLength/100)%10)));
|
||||
if (responseLength>9)
|
||||
buf.append((char)('0'+((responseLength/10)%10)));
|
||||
buf.append((char)('0'+(responseLength%10)));
|
||||
}
|
||||
buf.append(' ');
|
||||
}
|
||||
else
|
||||
buf.append(" - ");
|
||||
|
||||
String log =buf.toString();
|
||||
synchronized(_writer)
|
||||
{
|
||||
_writer.write(log);
|
||||
if (isExtended())
|
||||
{
|
||||
logExtended(request,response,_writer);
|
||||
if (!getLogCookies())
|
||||
_writer.write(" -");
|
||||
}
|
||||
|
||||
if (getLogCookies())
|
||||
{
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if (cookies==null || cookies.length==0)
|
||||
_writer.write(" -");
|
||||
else
|
||||
{
|
||||
_writer.write(" \"");
|
||||
for (int i=0;i<cookies.length;i++)
|
||||
{
|
||||
if (i!=0)
|
||||
_writer.write(';');
|
||||
_writer.write(cookies[i].getName());
|
||||
_writer.write('=');
|
||||
_writer.write(cookies[i].getValue());
|
||||
}
|
||||
_writer.write("\"");
|
||||
}
|
||||
}
|
||||
|
||||
if (getLogLatency())
|
||||
_writer.write(" "+(System.currentTimeMillis()-request.getTimeStamp()));
|
||||
|
||||
_writer.write(StringUtil.__LINE_SEPARATOR);
|
||||
_writer.flush();
|
||||
}
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,505 +0,0 @@
|
||||
// ========================================================================
|
||||
// $Id: NCSARequestLog.java,v 1.35 2005/08/13 00:01:24 gregwilkins Exp $
|
||||
// Copyright 2000-2004 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ========================================================================
|
||||
|
||||
package org.mortbay.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.mortbay.log.LogFactory;
|
||||
import org.mortbay.util.DateCache;
|
||||
import org.mortbay.util.LogSupport;
|
||||
import org.mortbay.util.RolloverFileOutputStream;
|
||||
import org.mortbay.util.StringUtil;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** NCSA HTTP Request Log.
|
||||
* NCSA common or NCSA extended (combined) request log.
|
||||
*
|
||||
* Taken from 5.1.12 source and modded to change some private vars to protected
|
||||
* so we can extend it for I2P.
|
||||
*
|
||||
* @version $Id: NCSARequestLog.java,v 1.35 2005/08/13 00:01:24 gregwilkins Exp $
|
||||
* @author Tony Thompson
|
||||
* @author Greg Wilkins
|
||||
*/
|
||||
public class NCSARequestLog implements RequestLog
|
||||
{
|
||||
protected static Log log = LogFactory.getLog(NCSARequestLog.class);
|
||||
|
||||
private String _filename;
|
||||
private boolean _extended;
|
||||
private boolean _append;
|
||||
private int _retainDays;
|
||||
private boolean _closeOut;
|
||||
private boolean _preferProxiedForAddress;
|
||||
private String _logDateFormat="dd/MMM/yyyy:HH:mm:ss ZZZ";
|
||||
private Locale _logLocale=Locale.getDefault();
|
||||
private String _logTimeZone=TimeZone.getDefault().getID();
|
||||
private String[] _ignorePaths;
|
||||
private boolean _logLatency=false;
|
||||
private boolean _logCookies=false;
|
||||
|
||||
protected transient OutputStream _out;
|
||||
protected transient OutputStream _fileOut;
|
||||
protected transient DateCache _logDateCache;
|
||||
protected transient PathMap _ignorePathMap;
|
||||
protected transient Writer _writer;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
*/
|
||||
public NCSARequestLog()
|
||||
{
|
||||
_extended=true;
|
||||
_append=true;
|
||||
_retainDays=31;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param filename Filename, which can be in
|
||||
* rolloverFileOutputStream format
|
||||
* @see org.mortbay.util.RolloverFileOutputStream
|
||||
* @exception IOException
|
||||
*/
|
||||
public NCSARequestLog(String filename)
|
||||
throws IOException
|
||||
{
|
||||
_extended=true;
|
||||
_append=true;
|
||||
_retainDays=31;
|
||||
setFilename(filename);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the log filename.
|
||||
* @see NCSARequestLog#setRetainDays(int)
|
||||
* @param filename The filename to use. If the filename contains the
|
||||
* string "yyyy_mm_dd", then a RolloverFileOutputStream is used and the
|
||||
* log is rolled over nightly and aged according setRetainDays. If no
|
||||
* filename is set or a null filename
|
||||
* passed, then requests are logged to System.err.
|
||||
*/
|
||||
public void setFilename(String filename)
|
||||
{
|
||||
if (filename!=null)
|
||||
{
|
||||
filename=filename.trim();
|
||||
if (filename.length()==0)
|
||||
filename=null;
|
||||
}
|
||||
_filename=filename;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the log filename.
|
||||
* @see NCSARequestLog#getDatedFilename()
|
||||
* @return The log filename without any date expansion.
|
||||
*/
|
||||
public String getFilename()
|
||||
{
|
||||
return _filename;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the dated log filename.
|
||||
* @see NCSARequestLog#getFilename()
|
||||
* @return The log filename with any date encoding expanded.
|
||||
*/
|
||||
public String getDatedFilename()
|
||||
{
|
||||
if (_fileOut instanceof RolloverFileOutputStream)
|
||||
return ((RolloverFileOutputStream)_fileOut).getDatedFilename();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param format The date format to use within the log file.
|
||||
*/
|
||||
public void setLogDateFormat(String format)
|
||||
{
|
||||
_logDateFormat=format;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The date format to use within the log file.
|
||||
*/
|
||||
public String getLogDateFormat()
|
||||
{
|
||||
return _logDateFormat;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param tz The date format timezone to use within the log file.
|
||||
*/
|
||||
public void setLogTimeZone(String tz)
|
||||
{
|
||||
_logTimeZone=tz;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The date format timezone to use within the log file.
|
||||
*/
|
||||
public String getLogTimeZone()
|
||||
{
|
||||
return _logTimeZone;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The number of days to retain rollovered log files.
|
||||
*/
|
||||
public int getRetainDays()
|
||||
{
|
||||
return _retainDays;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param retainDays The number of days to retain rollovered log files.
|
||||
*/
|
||||
public void setRetainDays(int retainDays)
|
||||
{
|
||||
_retainDays = retainDays;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return True if NCSA extended format is to be used.
|
||||
*/
|
||||
public boolean isExtended()
|
||||
{
|
||||
return _extended;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param e True if NCSA extended format is to be used.
|
||||
*/
|
||||
public void setExtended(boolean e)
|
||||
{
|
||||
_extended=e;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return True if logs are appended to existing log files.
|
||||
*/
|
||||
public boolean isAppend()
|
||||
{
|
||||
return _append;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param a True if logs are appended to existing log files.
|
||||
*/
|
||||
public void setAppend(boolean a)
|
||||
{
|
||||
_append=a;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @deprecated ignored
|
||||
*/
|
||||
public void setBuffered(boolean b)
|
||||
{}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set which paths to ignore.
|
||||
*
|
||||
* @param ignorePaths Array of path specifications to ignore
|
||||
*/
|
||||
public void setIgnorePaths(String[] ignorePaths)
|
||||
{
|
||||
// Contributed by Martin Vilcans (martin@jadestone.se)
|
||||
_ignorePaths = ignorePaths;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String[] getIgnorePaths()
|
||||
{
|
||||
return _ignorePaths;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return Returns the logCookies.
|
||||
*/
|
||||
public boolean getLogCookies()
|
||||
{
|
||||
return _logCookies;
|
||||
}
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param logCookies The logCookies to set.
|
||||
*/
|
||||
public void setLogCookies(boolean logCookies)
|
||||
{
|
||||
_logCookies = logCookies;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return Returns true if logging latency
|
||||
*/
|
||||
public boolean getLogLatency()
|
||||
{
|
||||
return _logLatency;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param logLatency If true, latency is logged at the end of the log line
|
||||
*/
|
||||
public void setLogLatency(boolean logLatency)
|
||||
{
|
||||
_logLatency = logLatency;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Prefer to log the proxied-for IP address (if present in
|
||||
* the request header) over the native requester IP address.
|
||||
* Useful in reverse-proxy situations when you'd rather see
|
||||
* the IP address of the host before the most recent proxy
|
||||
* server, as opposed to your own proxy server(s) every time.
|
||||
*
|
||||
* jlrobins@socialserve.com, March 2004.
|
||||
**/
|
||||
public void setPreferProxiedForAddress(boolean value)
|
||||
{
|
||||
_preferProxiedForAddress = value;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void start()
|
||||
throws Exception
|
||||
{
|
||||
_logDateCache=new DateCache(_logDateFormat,_logLocale);
|
||||
_logDateCache.setTimeZoneID(_logTimeZone);
|
||||
|
||||
if (_filename != null)
|
||||
{
|
||||
_fileOut=new RolloverFileOutputStream(_filename,_append,_retainDays);
|
||||
_closeOut=true;
|
||||
}
|
||||
else
|
||||
_fileOut=System.err;
|
||||
|
||||
_out=_fileOut;
|
||||
|
||||
if (_ignorePaths!=null && _ignorePaths.length>0)
|
||||
{
|
||||
_ignorePathMap=new PathMap();
|
||||
for (int i=0;i<_ignorePaths.length;i++)
|
||||
_ignorePathMap.put(_ignorePaths[i],_ignorePaths[i]);
|
||||
}
|
||||
else
|
||||
_ignorePathMap=null;
|
||||
|
||||
_writer=new OutputStreamWriter(_out);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isStarted()
|
||||
{
|
||||
return _fileOut!=null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void stop()
|
||||
{
|
||||
try{if (_writer!=null)_writer.flush();} catch (IOException e){LogSupport.ignore(log,e);}
|
||||
if (_out!=null && _closeOut)
|
||||
try{_out.close();}catch(IOException e){LogSupport.ignore(log,e);}
|
||||
_out=null;
|
||||
_fileOut=null;
|
||||
_closeOut=false;
|
||||
_logDateCache=null;
|
||||
_writer=null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Log a request.
|
||||
* @param request The request
|
||||
* @param response The response to this request.
|
||||
* @param responseLength The bytes written to the response.
|
||||
*/
|
||||
public void log(HttpRequest request,
|
||||
HttpResponse response,
|
||||
int responseLength)
|
||||
{
|
||||
try{
|
||||
// ignore ignorables
|
||||
if (_ignorePathMap != null &&
|
||||
_ignorePathMap.getMatch(request.getPath()) != null)
|
||||
return;
|
||||
|
||||
// log the rest
|
||||
if (_fileOut==null)
|
||||
return;
|
||||
|
||||
StringBuffer buf = new StringBuffer(160);
|
||||
|
||||
String addr = null;
|
||||
if(_preferProxiedForAddress)
|
||||
{
|
||||
// If header is not present, addr will remain null ...
|
||||
addr = request.getField(HttpFields.__XForwardedFor);
|
||||
}
|
||||
if(addr == null)
|
||||
addr = request.getRemoteAddr();
|
||||
buf.append(addr);
|
||||
|
||||
buf.append(" - ");
|
||||
String user = request.getAuthUser();
|
||||
buf.append((user==null)?"-":user);
|
||||
buf.append(" [");
|
||||
buf.append(_logDateCache.format(request.getTimeStamp()));
|
||||
buf.append("] \"");
|
||||
buf.append(request.getMethod());
|
||||
buf.append(' ');
|
||||
buf.append(request.getURI());
|
||||
buf.append(' ');
|
||||
buf.append(request.getVersion());
|
||||
buf.append("\" ");
|
||||
int status=response.getStatus();
|
||||
buf.append((char)('0'+((status/100)%10)));
|
||||
buf.append((char)('0'+((status/10)%10)));
|
||||
buf.append((char)('0'+(status%10)));
|
||||
if (responseLength>=0)
|
||||
{
|
||||
buf.append(' ');
|
||||
if (responseLength>99999)
|
||||
buf.append(Integer.toString(responseLength));
|
||||
else
|
||||
{
|
||||
if (responseLength>9999)
|
||||
buf.append((char)('0'+((responseLength/10000)%10)));
|
||||
if (responseLength>999)
|
||||
buf.append((char)('0'+((responseLength/1000)%10)));
|
||||
if (responseLength>99)
|
||||
buf.append((char)('0'+((responseLength/100)%10)));
|
||||
if (responseLength>9)
|
||||
buf.append((char)('0'+((responseLength/10)%10)));
|
||||
buf.append((char)('0'+(responseLength%10)));
|
||||
}
|
||||
buf.append(' ');
|
||||
}
|
||||
else
|
||||
buf.append(" - ");
|
||||
|
||||
String log =buf.toString();
|
||||
synchronized(_writer)
|
||||
{
|
||||
_writer.write(log);
|
||||
if (_extended)
|
||||
{
|
||||
logExtended(request,response,_writer);
|
||||
if (!_logCookies)
|
||||
_writer.write(" -");
|
||||
}
|
||||
|
||||
if (_logCookies)
|
||||
{
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if (cookies==null || cookies.length==0)
|
||||
_writer.write(" -");
|
||||
else
|
||||
{
|
||||
_writer.write(" \"");
|
||||
for (int i=0;i<cookies.length;i++)
|
||||
{
|
||||
if (i!=0)
|
||||
_writer.write(';');
|
||||
_writer.write(cookies[i].getName());
|
||||
_writer.write('=');
|
||||
_writer.write(cookies[i].getValue());
|
||||
}
|
||||
_writer.write("\"");
|
||||
}
|
||||
}
|
||||
|
||||
if (_logLatency)
|
||||
_writer.write(" "+(System.currentTimeMillis()-request.getTimeStamp()));
|
||||
|
||||
_writer.write(StringUtil.__LINE_SEPARATOR);
|
||||
_writer.flush();
|
||||
}
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,e);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Log Extended fields.
|
||||
* This method can be extended by a derived class to add extened fields to
|
||||
* each log entry. It is called by the log method after all standard
|
||||
* fields have been added, but before the line terminator.
|
||||
* Derived implementations should write extra fields to the Writer
|
||||
* provided.
|
||||
* The default implementation writes the referer and user agent.
|
||||
* @param request The request to log.
|
||||
* @param response The response to log.
|
||||
* @param log The writer to write the extra fields to.
|
||||
* @exception IOException Problem writing log
|
||||
*/
|
||||
protected void logExtended(HttpRequest request,
|
||||
HttpResponse response,
|
||||
Writer log)
|
||||
throws IOException
|
||||
{
|
||||
String referer = request.getField(HttpFields.__Referer);
|
||||
if(referer==null)
|
||||
log.write("\"-\" ");
|
||||
else
|
||||
{
|
||||
log.write('"');
|
||||
log.write(referer);
|
||||
log.write("\" ");
|
||||
}
|
||||
|
||||
String agent = request.getField(HttpFields.__UserAgent);
|
||||
if(agent==null)
|
||||
log.write("\"-\"");
|
||||
else
|
||||
{
|
||||
log.write('"');
|
||||
log.write(agent);
|
||||
log.write('"');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,809 +0,0 @@
|
||||
// ========================================================================
|
||||
// $Id: ResourceHandler.java,v 1.66 2005/08/24 08:18:17 gregwilkins Exp $
|
||||
// Copyright 199-2004 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ========================================================================
|
||||
|
||||
package org.mortbay.http.handler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.mortbay.log.LogFactory;
|
||||
import org.mortbay.http.HttpException;
|
||||
import org.mortbay.http.HttpFields;
|
||||
import org.mortbay.http.HttpRequest;
|
||||
import org.mortbay.http.HttpResponse;
|
||||
import org.mortbay.http.InclusiveByteRange;
|
||||
import org.mortbay.http.MultiPartResponse;
|
||||
import org.mortbay.http.ResourceCache;
|
||||
import org.mortbay.util.CachedResource;
|
||||
import org.mortbay.util.IO;
|
||||
import org.mortbay.util.LogSupport;
|
||||
import org.mortbay.util.Resource;
|
||||
import org.mortbay.util.StringMap;
|
||||
import org.mortbay.util.TypeUtil;
|
||||
import org.mortbay.util.URI;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Handler to serve files and resources.
|
||||
* Serves files from a given resource URL base and implements
|
||||
* the GET, HEAD, DELETE, OPTIONS, PUT, MOVE methods and the
|
||||
* IfModifiedSince and IfUnmodifiedSince header fields.
|
||||
* A simple memory cache is also provided to reduce file I/O.
|
||||
* HTTP/1.1 ranges are supported.
|
||||
*
|
||||
* @version $Id: ResourceHandler.java,v 1.66 2005/08/24 08:18:17 gregwilkins Exp $
|
||||
* @author Nuno Pregui?a (sorry, wasn't UTF-8)
|
||||
* @author Greg Wilkins
|
||||
*/
|
||||
public class ResourceHandler extends AbstractHttpHandler
|
||||
{
|
||||
private static Log log = LogFactory.getLog(ResourceHandler.class);
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
private boolean _acceptRanges=true;
|
||||
private boolean _redirectWelcomeFiles ;
|
||||
private String[] _methods=null;
|
||||
private String _allowed;
|
||||
private boolean _dirAllowed=true;
|
||||
private int _minGzipLength =-1;
|
||||
private StringMap _methodMap = new StringMap();
|
||||
{
|
||||
setAllowedMethods(new String[]
|
||||
{
|
||||
HttpRequest.__GET,
|
||||
HttpRequest.__POST,
|
||||
HttpRequest.__HEAD,
|
||||
HttpRequest.__OPTIONS,
|
||||
HttpRequest.__TRACE
|
||||
});
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/** Construct a ResourceHandler.
|
||||
*/
|
||||
public ResourceHandler()
|
||||
{}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
public synchronized void start()
|
||||
throws Exception
|
||||
{
|
||||
super.start();
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
public void stop()
|
||||
throws InterruptedException
|
||||
{
|
||||
super.stop();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String[] getAllowedMethods()
|
||||
{
|
||||
return _methods;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setAllowedMethods(String[] methods)
|
||||
{
|
||||
StringBuffer b = new StringBuffer();
|
||||
_methods=methods;
|
||||
_methodMap.clear();
|
||||
for (int i=0;i<methods.length;i++)
|
||||
{
|
||||
_methodMap.put(methods[i],methods[i]);
|
||||
if (i>0)
|
||||
b.append(',');
|
||||
b.append(methods[i]);
|
||||
}
|
||||
_allowed=b.toString();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isMethodAllowed(String method)
|
||||
{
|
||||
return _methodMap.get(method)!=null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String getAllowedString()
|
||||
{
|
||||
return _allowed;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isDirAllowed()
|
||||
{
|
||||
return _dirAllowed;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setDirAllowed(boolean dirAllowed)
|
||||
{
|
||||
_dirAllowed = dirAllowed;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isAcceptRanges()
|
||||
{
|
||||
return _acceptRanges;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return True if welcome files are redirected to. False if forward is used.
|
||||
*/
|
||||
public boolean getRedirectWelcome()
|
||||
{
|
||||
return _redirectWelcomeFiles;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param redirectWelcome True if welcome files are redirected to. False
|
||||
* if forward is used.
|
||||
*/
|
||||
public void setRedirectWelcome(boolean redirectWelcome)
|
||||
{
|
||||
_redirectWelcomeFiles = redirectWelcome;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set if the handler accepts range requests.
|
||||
* Default is false;
|
||||
* @param ar True if the handler should accept ranges
|
||||
*/
|
||||
public void setAcceptRanges(boolean ar)
|
||||
{
|
||||
_acceptRanges=ar;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get minimum content length for GZIP encoding.
|
||||
* @return Minimum length of content for gzip encoding or -1 if disabled.
|
||||
*/
|
||||
public int getMinGzipLength()
|
||||
{
|
||||
return _minGzipLength;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set minimum content length for GZIP encoding.
|
||||
* @param minGzipLength If set to a positive integer, then static content
|
||||
* larger than this will be served as gzip content encoded
|
||||
* if a matching resource is found ending with ".gz"
|
||||
*/
|
||||
public void setMinGzipLength(int minGzipLength)
|
||||
{
|
||||
_minGzipLength = minGzipLength;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** get Resource to serve.
|
||||
* Map a path to a resource. The default implementation calls
|
||||
* HttpContext.getResource but derived handers may provide
|
||||
* their own mapping.
|
||||
* @param pathInContext The path to find a resource for.
|
||||
* @return The resource to serve.
|
||||
*/
|
||||
protected Resource getResource(String pathInContext)
|
||||
throws IOException
|
||||
{
|
||||
return getHttpContext().getResource(pathInContext);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void handle(String pathInContext,
|
||||
String pathParams,
|
||||
HttpRequest request,
|
||||
HttpResponse response)
|
||||
throws HttpException, IOException
|
||||
{
|
||||
Resource resource = getResource(pathInContext);
|
||||
if (resource==null)
|
||||
return;
|
||||
|
||||
// Is the method allowed?
|
||||
if (!isMethodAllowed(request.getMethod()))
|
||||
{
|
||||
if(log.isDebugEnabled())log.debug("Method not allowed: "+request.getMethod());
|
||||
if (resource.exists())
|
||||
{
|
||||
setAllowHeader(response);
|
||||
response.sendError(HttpResponse.__405_Method_Not_Allowed);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle the request
|
||||
try
|
||||
{
|
||||
if(log.isDebugEnabled())log.debug("PATH="+pathInContext+" RESOURCE="+resource);
|
||||
|
||||
// check filename
|
||||
String method=request.getMethod();
|
||||
if (method.equals(HttpRequest.__GET) ||
|
||||
method.equals(HttpRequest.__POST) ||
|
||||
method.equals(HttpRequest.__HEAD))
|
||||
handleGet(request, response, pathInContext, pathParams, resource);
|
||||
else if (method.equals(HttpRequest.__PUT))
|
||||
handlePut(request, response, pathInContext, resource);
|
||||
else if (method.equals(HttpRequest.__DELETE))
|
||||
handleDelete(request, response, pathInContext, resource);
|
||||
else if (method.equals(HttpRequest.__OPTIONS))
|
||||
handleOptions(response, pathInContext);
|
||||
else if (method.equals(HttpRequest.__MOVE))
|
||||
handleMove(request, response, pathInContext, resource);
|
||||
else if (method.equals(HttpRequest.__TRACE))
|
||||
handleTrace(request, response);
|
||||
else
|
||||
{
|
||||
if(log.isDebugEnabled())log.debug("Unknown action:"+method);
|
||||
// anything else...
|
||||
try{
|
||||
if (resource.exists())
|
||||
response.sendError(HttpResponse.__501_Not_Implemented);
|
||||
}
|
||||
catch(Exception e) {LogSupport.ignore(log,e);}
|
||||
}
|
||||
}
|
||||
catch(IllegalArgumentException e)
|
||||
{
|
||||
LogSupport.ignore(log,e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (resource!=null && !(resource instanceof CachedResource))
|
||||
resource.release();
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
public void handleGet(HttpRequest request,
|
||||
HttpResponse response,
|
||||
String pathInContext,
|
||||
String pathParams,
|
||||
Resource resource)
|
||||
throws IOException
|
||||
{
|
||||
if(log.isDebugEnabled())log.debug("Looking for "+resource);
|
||||
|
||||
if (resource!=null && resource.exists())
|
||||
{
|
||||
// check if directory
|
||||
if (resource.isDirectory())
|
||||
{
|
||||
if (!pathInContext.endsWith("/") && !pathInContext.equals("/"))
|
||||
{
|
||||
log.debug("Redirect to directory/");
|
||||
|
||||
String q=request.getQuery();
|
||||
|
||||
// Properly fix URI
|
||||
URI urifix = new URI(request.getRequestURL().toString());
|
||||
urifix.setPath(urifix.getPath());
|
||||
StringBuffer buf = new StringBuffer(urifix.toString());
|
||||
urifix = null;
|
||||
|
||||
if (q!=null&&q.length()!=0)
|
||||
{
|
||||
buf.append('?');
|
||||
buf.append(q);
|
||||
}
|
||||
response.setField(HttpFields.__Location, URI.addPaths(buf.toString(),"/"));
|
||||
response.setStatus(302);
|
||||
request.setHandled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// See if index file exists
|
||||
String welcome=getHttpContext().getWelcomeFile(resource);
|
||||
if (welcome!=null)
|
||||
{
|
||||
// Forward to the index
|
||||
String ipath=URI.addPaths(pathInContext,welcome);
|
||||
if (_redirectWelcomeFiles)
|
||||
{
|
||||
// Redirect to the index
|
||||
ipath=URI.addPaths(getHttpContext().getContextPath(),ipath);
|
||||
response.setContentLength(0);
|
||||
response.sendRedirect(ipath);
|
||||
}
|
||||
else
|
||||
{
|
||||
URI uri=request.getURI();
|
||||
uri.setPath(URI.addPaths(uri.getPath(),welcome));
|
||||
getHttpContext().handle(ipath,pathParams,request,response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Check modified dates
|
||||
if (!passConditionalHeaders(request,response,resource))
|
||||
return;
|
||||
// If we got here, no forward to index took place
|
||||
sendDirectory(request,response,resource,pathInContext.length()>1);
|
||||
}
|
||||
// check if it is a file
|
||||
else if (resource.exists())
|
||||
{
|
||||
// Check modified dates
|
||||
if (!passConditionalHeaders(request,response,resource))
|
||||
return;
|
||||
sendData(request,response,pathInContext,resource,true);
|
||||
}
|
||||
else
|
||||
// don't know what it is
|
||||
log.warn("Unknown file type");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* Check modification date headers.
|
||||
*/
|
||||
private boolean passConditionalHeaders(HttpRequest request,
|
||||
HttpResponse response,
|
||||
Resource resource)
|
||||
throws IOException
|
||||
{
|
||||
if (!request.getMethod().equals(HttpRequest.__HEAD))
|
||||
{
|
||||
// If we have meta data for the file
|
||||
// Try a direct match for most common requests. Avoids
|
||||
// parsing the date.
|
||||
ResourceCache.ResourceMetaData metaData =
|
||||
(ResourceCache.ResourceMetaData)resource.getAssociate();
|
||||
if (metaData!=null)
|
||||
{
|
||||
String ifms=request.getField(HttpFields.__IfModifiedSince);
|
||||
String mdlm=metaData.getLastModified();
|
||||
if (ifms!=null && mdlm!=null && ifms.equals(mdlm))
|
||||
{
|
||||
response.setStatus(HttpResponse.__304_Not_Modified);
|
||||
request.setHandled(true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
long date=0;
|
||||
// Parse the if[un]modified dates and compare to resource
|
||||
|
||||
if ((date=request.getDateField(HttpFields.__IfUnmodifiedSince))>0)
|
||||
{
|
||||
if (resource.lastModified()/1000 > date/1000)
|
||||
{
|
||||
response.sendError(HttpResponse.__412_Precondition_Failed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((date=request.getDateField(HttpFields.__IfModifiedSince))>0)
|
||||
{
|
||||
|
||||
if (resource.lastModified()/1000 <= date/1000)
|
||||
{
|
||||
response.setStatus(HttpResponse.__304_Not_Modified);
|
||||
request.setHandled(true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
void handlePut(HttpRequest request,
|
||||
HttpResponse response,
|
||||
String pathInContext,
|
||||
Resource resource)
|
||||
throws IOException
|
||||
{
|
||||
if(log.isDebugEnabled())log.debug("PUT "+pathInContext+" in "+resource);
|
||||
|
||||
boolean exists=resource!=null && resource.exists();
|
||||
if (exists &&
|
||||
!passConditionalHeaders(request,response,resource))
|
||||
return;
|
||||
|
||||
if (pathInContext.endsWith("/"))
|
||||
{
|
||||
if (!exists)
|
||||
{
|
||||
if (!resource.getFile().mkdirs())
|
||||
response.sendError(HttpResponse.__403_Forbidden, "Directories could not be created");
|
||||
else
|
||||
{
|
||||
request.setHandled(true);
|
||||
response.setStatus(HttpResponse.__201_Created);
|
||||
response.commit();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
request.setHandled(true);
|
||||
response.setStatus(HttpResponse.__200_OK);
|
||||
response.commit();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
int toRead = request.getContentLength();
|
||||
InputStream in = request.getInputStream();
|
||||
OutputStream out = resource.getOutputStream();
|
||||
if (toRead>=0)
|
||||
IO.copy(in,out,toRead);
|
||||
else
|
||||
IO.copy(in,out);
|
||||
out.close();
|
||||
request.setHandled(true);
|
||||
response.setStatus(exists
|
||||
?HttpResponse.__200_OK
|
||||
:HttpResponse.__201_Created);
|
||||
response.commit();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,ex);
|
||||
response.sendError(HttpResponse.__403_Forbidden,
|
||||
ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
void handleDelete(HttpRequest request,
|
||||
HttpResponse response,
|
||||
String pathInContext,
|
||||
Resource resource)
|
||||
throws IOException
|
||||
{
|
||||
if(log.isDebugEnabled())log.debug("DELETE "+pathInContext+" from "+resource);
|
||||
|
||||
if (!resource.exists() ||
|
||||
!passConditionalHeaders(request,response,resource))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
// delete the file
|
||||
if (resource.delete())
|
||||
response.setStatus(HttpResponse.__204_No_Content);
|
||||
else
|
||||
response.sendError(HttpResponse.__403_Forbidden);
|
||||
|
||||
// Send response
|
||||
request.setHandled(true);
|
||||
}
|
||||
catch (SecurityException sex)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,sex);
|
||||
response.sendError(HttpResponse.__403_Forbidden, sex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
void handleMove(HttpRequest request,
|
||||
HttpResponse response,
|
||||
String pathInContext,
|
||||
Resource resource)
|
||||
throws IOException
|
||||
{
|
||||
if (!resource.exists() || !passConditionalHeaders(request,response,resource))
|
||||
return;
|
||||
|
||||
|
||||
String newPath = URI.canonicalPath(request.getField("New-uri"));
|
||||
if (newPath==null)
|
||||
{
|
||||
response.sendError(HttpResponse.__405_Method_Not_Allowed,
|
||||
"Bad new uri");
|
||||
return;
|
||||
}
|
||||
|
||||
String contextPath = getHttpContext().getContextPath();
|
||||
if (contextPath!=null && !newPath.startsWith(contextPath))
|
||||
{
|
||||
response.sendError(HttpResponse.__405_Method_Not_Allowed,
|
||||
"Not in context");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Find path
|
||||
try
|
||||
{
|
||||
// TODO - Check this
|
||||
String newInfo=newPath;
|
||||
if (contextPath!=null)
|
||||
newInfo=newInfo.substring(contextPath.length());
|
||||
Resource newFile = getHttpContext().getBaseResource().addPath(newInfo);
|
||||
|
||||
if(log.isDebugEnabled())log.debug("Moving "+resource+" to "+newFile);
|
||||
resource.renameTo(newFile);
|
||||
|
||||
response.setStatus(HttpResponse.__204_No_Content);
|
||||
request.setHandled(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,ex);
|
||||
setAllowHeader(response);
|
||||
response.sendError(HttpResponse.__405_Method_Not_Allowed,
|
||||
"Error:"+ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
void handleOptions(HttpResponse response, String pathInContext)
|
||||
throws IOException
|
||||
{
|
||||
if ("*".equals(pathInContext))
|
||||
return;
|
||||
setAllowHeader(response);
|
||||
response.commit();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
void setAllowHeader(HttpResponse response)
|
||||
{
|
||||
response.setField(HttpFields.__Allow, getAllowedString());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void writeHeaders(HttpResponse response,Resource resource, long count)
|
||||
throws IOException
|
||||
{
|
||||
ResourceCache.ResourceMetaData metaData =
|
||||
(ResourceCache.ResourceMetaData)resource.getAssociate();
|
||||
|
||||
response.setContentType(metaData.getMimeType());
|
||||
if (count != -1)
|
||||
{
|
||||
if (count==resource.length())
|
||||
response.setField(HttpFields.__ContentLength,metaData.getLength());
|
||||
else
|
||||
response.setContentLength((int)count);
|
||||
}
|
||||
|
||||
response.setField(HttpFields.__LastModified,metaData.getLastModified());
|
||||
|
||||
if (_acceptRanges && response.getHttpRequest().getDotVersion()>0)
|
||||
response.setField(HttpFields.__AcceptRanges,"bytes");
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void sendData(HttpRequest request,
|
||||
HttpResponse response,
|
||||
String pathInContext,
|
||||
Resource resource,
|
||||
boolean writeHeaders)
|
||||
throws IOException
|
||||
{
|
||||
long resLength=resource.length();
|
||||
|
||||
// see if there are any range headers
|
||||
Enumeration reqRanges =
|
||||
request.getDotVersion()>0
|
||||
?request.getFieldValues(HttpFields.__Range)
|
||||
:null;
|
||||
|
||||
if (!writeHeaders || reqRanges == null || !reqRanges.hasMoreElements())
|
||||
{
|
||||
// look for a gziped content.
|
||||
Resource data=resource;
|
||||
if (_minGzipLength>0)
|
||||
{
|
||||
String accept=request.getField(HttpFields.__AcceptEncoding);
|
||||
if (accept!=null && resLength>_minGzipLength &&
|
||||
!pathInContext.endsWith(".gz"))
|
||||
{
|
||||
Resource gz = getHttpContext().getResource(pathInContext+".gz");
|
||||
if (gz.exists() && accept.indexOf("gzip")>=0)
|
||||
{
|
||||
if(log.isDebugEnabled())log.debug("gzip="+gz);
|
||||
response.setField(HttpFields.__ContentEncoding,"gzip");
|
||||
data=gz;
|
||||
resLength=data.length();
|
||||
}
|
||||
}
|
||||
}
|
||||
writeHeaders(response,resource,resLength);
|
||||
|
||||
request.setHandled(true);
|
||||
OutputStream out = response.getOutputStream();
|
||||
data.writeTo(out,0,resLength);
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the satisfiable ranges
|
||||
List ranges =InclusiveByteRange.satisfiableRanges(reqRanges,resLength);
|
||||
if(log.isDebugEnabled())log.debug("ranges: " + reqRanges + " == " + ranges);
|
||||
|
||||
// if there are no satisfiable ranges, send 416 response
|
||||
if (ranges==null || ranges.size()==0)
|
||||
{
|
||||
log.debug("no satisfiable ranges");
|
||||
writeHeaders(response, resource, resLength);
|
||||
response.setStatus(HttpResponse.__416_Requested_Range_Not_Satisfiable);
|
||||
response.setReason((String)HttpResponse.__statusMsg
|
||||
.get(TypeUtil.newInteger(HttpResponse.__416_Requested_Range_Not_Satisfiable)));
|
||||
|
||||
response.setField(HttpFields.__ContentRange,
|
||||
InclusiveByteRange.to416HeaderRangeString(resLength));
|
||||
|
||||
OutputStream out = response.getOutputStream();
|
||||
resource.writeTo(out,0,resLength);
|
||||
request.setHandled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// if there is only a single valid range (must be satisfiable
|
||||
// since were here now), send that range with a 216 response
|
||||
if ( ranges.size()== 1)
|
||||
{
|
||||
InclusiveByteRange singleSatisfiableRange =
|
||||
(InclusiveByteRange)ranges.get(0);
|
||||
if(log.isDebugEnabled())log.debug("single satisfiable range: " + singleSatisfiableRange);
|
||||
long singleLength = singleSatisfiableRange.getSize(resLength);
|
||||
writeHeaders(response,resource,singleLength);
|
||||
response.setStatus(HttpResponse.__206_Partial_Content);
|
||||
response.setReason((String)HttpResponse.__statusMsg
|
||||
.get(TypeUtil.newInteger(HttpResponse.__206_Partial_Content)));
|
||||
response.setField(HttpFields.__ContentRange,
|
||||
singleSatisfiableRange.toHeaderRangeString(resLength));
|
||||
OutputStream out = response.getOutputStream();
|
||||
resource.writeTo(out,
|
||||
singleSatisfiableRange.getFirst(resLength),
|
||||
singleLength);
|
||||
request.setHandled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// multiple non-overlapping valid ranges cause a multipart
|
||||
// 216 response which does not require an overall
|
||||
// content-length header
|
||||
//
|
||||
ResourceCache.ResourceMetaData metaData =
|
||||
(ResourceCache.ResourceMetaData)resource.getAssociate();
|
||||
String encoding = metaData.getMimeType();
|
||||
MultiPartResponse multi = new MultiPartResponse(response);
|
||||
response.setStatus(HttpResponse.__206_Partial_Content);
|
||||
response.setReason((String)HttpResponse.__statusMsg
|
||||
.get(TypeUtil.newInteger(HttpResponse.__206_Partial_Content)));
|
||||
|
||||
// If the request has a "Request-Range" header then we need to
|
||||
// send an old style multipart/x-byteranges Content-Type. This
|
||||
// keeps Netscape and acrobat happy. This is what Apache does.
|
||||
String ctp;
|
||||
if (request.containsField(HttpFields.__RequestRange))
|
||||
ctp = "multipart/x-byteranges; boundary=";
|
||||
else
|
||||
ctp = "multipart/byteranges; boundary=";
|
||||
response.setContentType(ctp+multi.getBoundary());
|
||||
|
||||
InputStream in=(resource instanceof CachedResource)
|
||||
?null:resource.getInputStream();
|
||||
OutputStream out = response.getOutputStream();
|
||||
long pos=0;
|
||||
|
||||
for (int i=0;i<ranges.size();i++)
|
||||
{
|
||||
InclusiveByteRange ibr = (InclusiveByteRange) ranges.get(i);
|
||||
String header=HttpFields.__ContentRange+": "+
|
||||
ibr.toHeaderRangeString(resLength);
|
||||
if(log.isDebugEnabled())log.debug("multi range: "+encoding+" "+header);
|
||||
multi.startPart(encoding,new String[]{header});
|
||||
|
||||
long start=ibr.getFirst(resLength);
|
||||
long size=ibr.getSize(resLength);
|
||||
if (in!=null)
|
||||
{
|
||||
// Handle non cached resource
|
||||
if (start<pos)
|
||||
{
|
||||
in.close();
|
||||
in=resource.getInputStream();
|
||||
pos=0;
|
||||
}
|
||||
if (pos<start)
|
||||
{
|
||||
in.skip(start-pos);
|
||||
pos=start;
|
||||
}
|
||||
IO.copy(in,out,size);
|
||||
pos+=size;
|
||||
}
|
||||
else
|
||||
// Handle cached resource
|
||||
resource.writeTo(out,start,size);
|
||||
|
||||
}
|
||||
if (in!=null)
|
||||
in.close();
|
||||
multi.close();
|
||||
|
||||
request.setHandled(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
void sendDirectory(HttpRequest request,
|
||||
HttpResponse response,
|
||||
Resource resource,
|
||||
boolean parent)
|
||||
throws IOException
|
||||
{
|
||||
if (!_dirAllowed)
|
||||
{
|
||||
response.sendError(HttpResponse.__403_Forbidden);
|
||||
return;
|
||||
}
|
||||
|
||||
request.setHandled(true);
|
||||
|
||||
if(log.isDebugEnabled())log.debug("sendDirectory: "+resource);
|
||||
byte[] data=null;
|
||||
if (resource instanceof CachedResource)
|
||||
data=((CachedResource)resource).getCachedData();
|
||||
|
||||
if (data==null)
|
||||
{
|
||||
String base = URI.addPaths(request.getPath(),"/");
|
||||
String dir = resource.getListHTML(URI.encodePath(base),parent);
|
||||
if (dir==null)
|
||||
{
|
||||
response.sendError(HttpResponse.__403_Forbidden,
|
||||
"No directory");
|
||||
return;
|
||||
}
|
||||
data=dir.getBytes("UTF8");
|
||||
if (resource instanceof CachedResource)
|
||||
((CachedResource)resource).setCachedData(data);
|
||||
}
|
||||
|
||||
response.setContentType("text/html; charset=UTF8");
|
||||
response.setContentLength(data.length);
|
||||
|
||||
if (request.getMethod().equals(HttpRequest.__HEAD))
|
||||
{
|
||||
response.commit();
|
||||
return;
|
||||
}
|
||||
|
||||
response.getOutputStream().write(data,0,data.length);
|
||||
response.commit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,617 +0,0 @@
|
||||
// ========================================================================
|
||||
// $Id: Server.java,v 1.40 2005/10/21 13:52:11 gregwilkins Exp $
|
||||
// Copyright 2002-2004 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ========================================================================
|
||||
|
||||
package org.mortbay.jetty;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.mortbay.log.LogFactory;
|
||||
import org.mortbay.http.HttpContext;
|
||||
import org.mortbay.http.HttpServer;
|
||||
import org.mortbay.jetty.servlet.ServletHttpContext;
|
||||
import org.mortbay.jetty.servlet.WebApplicationContext;
|
||||
import org.mortbay.util.LogSupport;
|
||||
import org.mortbay.util.Resource;
|
||||
import org.mortbay.xml.XmlConfiguration;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** The Jetty HttpServer.
|
||||
*
|
||||
* This specialization of org.mortbay.http.HttpServer adds knowledge
|
||||
* about servlets and their specialized contexts. It also included
|
||||
* support for initialization from xml configuration files
|
||||
* that follow the XmlConfiguration dtd.
|
||||
*
|
||||
* HttpContexts created by Server are of the type
|
||||
* org.mortbay.jetty.servlet.ServletHttpContext unless otherwise
|
||||
* specified.
|
||||
*
|
||||
* This class also provides a main() method which starts a server for
|
||||
* each config file passed on the command line. If the system
|
||||
* property JETTY_NO_SHUTDOWN_HOOK is not set to true, then a shutdown
|
||||
* hook is thread is registered to stop these servers.
|
||||
*
|
||||
* @see org.mortbay.xml.XmlConfiguration
|
||||
* @see org.mortbay.jetty.servlet.ServletHttpContext
|
||||
* @version $Revision: 1.40 $
|
||||
* @author Greg Wilkins (gregw)
|
||||
*/
|
||||
public class Server extends HttpServer
|
||||
{
|
||||
static Log log = LogFactory.getLog(Server.class);
|
||||
private String[] _webAppConfigurationClassNames =
|
||||
new String[]{"org.mortbay.jetty.servlet.XMLConfiguration", "org.mortbay.jetty.servlet.JettyWebConfiguration"};
|
||||
private String _configuration;
|
||||
private String _rootWebApp;
|
||||
private static ShutdownHookThread hookThread = new ShutdownHookThread();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
*/
|
||||
public Server()
|
||||
{
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param configuration The filename or URL of the XML
|
||||
* configuration file.
|
||||
*/
|
||||
public Server(String configuration)
|
||||
throws IOException
|
||||
{
|
||||
this(Resource.newResource(configuration).getURL());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param configuration The filename or URL of the XML
|
||||
* configuration file.
|
||||
*/
|
||||
public Server(Resource configuration)
|
||||
throws IOException
|
||||
{
|
||||
this(configuration.getURL());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param configuration The filename or URL of the XML
|
||||
* configuration file.
|
||||
*/
|
||||
public Server(URL configuration)
|
||||
throws IOException
|
||||
{
|
||||
_configuration=configuration.toString();
|
||||
Server.hookThread.add(this);
|
||||
try
|
||||
{
|
||||
XmlConfiguration config=new XmlConfiguration(configuration);
|
||||
config.configure(this);
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch(InvocationTargetException e)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,e.getTargetException());
|
||||
throw new IOException("Jetty configuration problem: "+e.getTargetException());
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,e);
|
||||
throw new IOException("Jetty configuration problem: "+e);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean getStopAtShutdown()
|
||||
{
|
||||
return hookThread.contains(this);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setStopAtShutdown(boolean stop)
|
||||
{
|
||||
if (stop)
|
||||
hookThread.add(this);
|
||||
else
|
||||
hookThread.remove(this);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the root webapp name.
|
||||
* @return The name of the root webapp (eg. "root" for root.war).
|
||||
*/
|
||||
public String getRootWebApp()
|
||||
{
|
||||
return _rootWebApp;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the root webapp name.
|
||||
* @param rootWebApp The name of the root webapp (eg. "root" for root.war).
|
||||
*/
|
||||
public void setRootWebApp(String rootWebApp)
|
||||
{
|
||||
_rootWebApp = rootWebApp;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Configure the server from an XML file.
|
||||
* @param configuration The filename or URL of the XML
|
||||
* configuration file.
|
||||
*/
|
||||
public void configure(String configuration)
|
||||
throws IOException
|
||||
{
|
||||
|
||||
URL url=Resource.newResource(configuration).getURL();
|
||||
if (_configuration!=null && _configuration.equals(url.toString()))
|
||||
return;
|
||||
if (_configuration!=null)
|
||||
throw new IllegalStateException("Already configured with "+_configuration);
|
||||
try
|
||||
{
|
||||
XmlConfiguration config=new XmlConfiguration(url);
|
||||
_configuration=url.toString();
|
||||
config.configure(this);
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,e);
|
||||
throw new IOException("Jetty configuration problem: "+e);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String getConfiguration()
|
||||
{
|
||||
return _configuration;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Create a new ServletHttpContext.
|
||||
* Ths method is called by HttpServer to creat new contexts. Thus
|
||||
* calls to addContext or getContext that result in a new Context
|
||||
* being created will return an
|
||||
* org.mortbay.jetty.servlet.ServletHttpContext instance.
|
||||
* @return ServletHttpContext
|
||||
*/
|
||||
protected HttpContext newHttpContext()
|
||||
{
|
||||
return new ServletHttpContext();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Create a new WebApplicationContext.
|
||||
* Ths method is called by Server to creat new contexts for web
|
||||
* applications. Thus calls to addWebApplication that result in
|
||||
* a new Context being created will return an correct class instance.
|
||||
* Derived class can override this method to create instance of its
|
||||
* own class derived from WebApplicationContext in case it needs more
|
||||
* functionality.
|
||||
* @param webApp The Web application directory or WAR file.
|
||||
* @return WebApplicationContext
|
||||
*/
|
||||
protected WebApplicationContext newWebApplicationContext(
|
||||
String webApp
|
||||
)
|
||||
{
|
||||
return new WebApplicationContext(webApp);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add Web Application.
|
||||
* @param contextPathSpec The context path spec. Which must be of
|
||||
* the form / or /path/*
|
||||
* @param webApp The Web application directory or WAR file.
|
||||
* @return The WebApplicationContext
|
||||
* @exception IOException
|
||||
*/
|
||||
public WebApplicationContext addWebApplication(String contextPathSpec,
|
||||
String webApp)
|
||||
throws IOException
|
||||
{
|
||||
return addWebApplication(null,contextPathSpec,webApp);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add Web Application.
|
||||
* @param virtualHost Virtual host name or null
|
||||
* @param contextPathSpec The context path spec. Which must be of
|
||||
* the form / or /path/*
|
||||
* @param webApp The Web application directory or WAR file.
|
||||
* @return The WebApplicationContext
|
||||
* @exception IOException
|
||||
*/
|
||||
public WebApplicationContext addWebApplication(String virtualHost,
|
||||
String contextPathSpec,
|
||||
String webApp)
|
||||
throws IOException
|
||||
{
|
||||
WebApplicationContext appContext =
|
||||
newWebApplicationContext(webApp);
|
||||
appContext.setContextPath(contextPathSpec);
|
||||
addContext(virtualHost,appContext);
|
||||
if(log.isDebugEnabled())log.debug("Web Application "+appContext+" added");
|
||||
return appContext;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add Web Applications.
|
||||
* Add auto webapplications to the server. The name of the
|
||||
* webapp directory or war is used as the context name. If a
|
||||
* webapp is called "root" it is added at "/".
|
||||
* @param webapps Directory file name or URL to look for auto webapplication.
|
||||
* @exception IOException
|
||||
*/
|
||||
public WebApplicationContext[] addWebApplications(String webapps)
|
||||
throws IOException
|
||||
{
|
||||
return addWebApplications(null,webapps,null,false);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add Web Applications.
|
||||
* Add auto webapplications to the server. The name of the
|
||||
* webapp directory or war is used as the context name. If the
|
||||
* webapp matches the rootWebApp it is added as the "/" context.
|
||||
* @param host Virtual host name or null
|
||||
* @param webapps Directory file name or URL to look for auto webapplication.
|
||||
* @exception IOException
|
||||
*/
|
||||
public WebApplicationContext[] addWebApplications(String host,
|
||||
String webapps)
|
||||
throws IOException
|
||||
{
|
||||
return addWebApplications(host,webapps,null,false);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add Web Applications.
|
||||
* Add auto webapplications to the server. The name of the
|
||||
* webapp directory or war is used as the context name. If the
|
||||
* webapp matches the rootWebApp it is added as the "/" context.
|
||||
* @param host Virtual host name or null
|
||||
* @param webapps Directory file name or URL to look for auto
|
||||
* webapplication.
|
||||
* @param extract If true, extract war files
|
||||
* @exception IOException
|
||||
*/
|
||||
public WebApplicationContext[] addWebApplications(String host,
|
||||
String webapps,
|
||||
boolean extract)
|
||||
throws IOException
|
||||
{
|
||||
return addWebApplications(host,webapps,null,extract);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add Web Applications.
|
||||
* Add auto webapplications to the server. The name of the
|
||||
* webapp directory or war is used as the context name. If the
|
||||
* webapp matches the rootWebApp it is added as the "/" context.
|
||||
* @param host Virtual host name or null
|
||||
* @param webapps Directory file name or URL to look for auto
|
||||
* webapplication.
|
||||
* @param defaults The defaults xml filename or URL which is
|
||||
* loaded before any in the web app. Must respect the web.dtd.
|
||||
* If null the default defaults file is used. If the empty string, then
|
||||
* no defaults file is used.
|
||||
* @param extract If true, extract war files
|
||||
* @exception IOException
|
||||
*/
|
||||
public WebApplicationContext[] addWebApplications(String host,
|
||||
String webapps,
|
||||
String defaults,
|
||||
boolean extract)
|
||||
throws IOException
|
||||
{
|
||||
return addWebApplications(host,webapps,defaults,extract,true,null);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add Web Applications.
|
||||
* Add auto webapplications to the server. The name of the
|
||||
* webapp directory or war is used as the context name. If the
|
||||
* webapp matches the rootWebApp it is added as the "/" context.
|
||||
* @param host Virtual host name or null
|
||||
* @param webapps Directory file name or URL to look for auto
|
||||
* webapplication.
|
||||
* @param defaults The defaults xml filename or URL which is
|
||||
* loaded before any in the web app. Must respect the web.dtd.
|
||||
* If null the default defaults file is used. If the empty string, then
|
||||
* no defaults file is used.
|
||||
* @param extract If true, extract war files
|
||||
* @param java2CompliantClassLoader True if java2 compliance is applied to all webapplications
|
||||
* @exception IOException
|
||||
*/
|
||||
public WebApplicationContext[] addWebApplications(String host,
|
||||
String webapps,
|
||||
String defaults,
|
||||
boolean extract,
|
||||
boolean java2CompliantClassLoader)
|
||||
throws IOException
|
||||
{
|
||||
return addWebApplications(host,webapps,defaults,extract,java2CompliantClassLoader,null);
|
||||
|
||||
}
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add Web Applications.
|
||||
* Add auto webapplications to the server. The name of the
|
||||
* webapp directory or war is used as the context name. If the
|
||||
* webapp matches the rootWebApp it is added as the "/" context.
|
||||
* @param host Virtual host name or null
|
||||
* @param webapps Directory file name or URL to look for auto
|
||||
* webapplication.
|
||||
* @param defaults The defaults xml filename or URL which is
|
||||
* loaded before any in the web app. Must respect the web.dtd.
|
||||
* If null the default defaults file is used. If the empty string, then
|
||||
* no defaults file is used.
|
||||
* @param extract If true, extract war files
|
||||
* @param java2CompliantClassLoader True if java2 compliance is applied to all webapplications
|
||||
* @param Attributes[] A set of attributes to pass to setAttribute, format is first item is the key, second item is the value.
|
||||
* @exception IOException
|
||||
*/
|
||||
public WebApplicationContext[] addWebApplications(String host,
|
||||
String webapps,
|
||||
String defaults,
|
||||
boolean extract,
|
||||
boolean java2CompliantClassLoader,
|
||||
String Attributes[])
|
||||
throws IOException
|
||||
{
|
||||
ArrayList wacs = new ArrayList();
|
||||
Resource r=Resource.newResource(webapps);
|
||||
if (!r.exists())
|
||||
throw new IllegalArgumentException("No such webapps resource "+r);
|
||||
|
||||
if (!r.isDirectory())
|
||||
throw new IllegalArgumentException("Not directory webapps resource "+r);
|
||||
if(Attributes != null) {
|
||||
if(((Attributes.length / 2) * 2) != Attributes.length) {
|
||||
throw new IllegalArgumentException("Attributes must be in pairs of key,value.");
|
||||
}
|
||||
}
|
||||
String[] files=r.list();
|
||||
|
||||
for (int f=0;files!=null && f<files.length;f++)
|
||||
{
|
||||
String context=files[f];
|
||||
|
||||
if (context.equalsIgnoreCase("CVS/") ||
|
||||
context.equalsIgnoreCase("CVS") ||
|
||||
context.startsWith("."))
|
||||
continue;
|
||||
|
||||
|
||||
String app = r.addPath(r.encode(files[f])).toString();
|
||||
if (context.toLowerCase().endsWith(".war") ||
|
||||
context.toLowerCase().endsWith(".jar"))
|
||||
{
|
||||
context=context.substring(0,context.length()-4);
|
||||
Resource unpacked=r.addPath(context);
|
||||
if (unpacked!=null && unpacked.exists() && unpacked.isDirectory())
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_rootWebApp!=null && (context.equals(_rootWebApp)||context.equals(_rootWebApp+"/")))
|
||||
context="/";
|
||||
else
|
||||
context="/"+context;
|
||||
|
||||
WebApplicationContext wac= addWebApplication(host,
|
||||
context,
|
||||
app);
|
||||
wac.setExtractWAR(extract);
|
||||
wac.setClassLoaderJava2Compliant(java2CompliantClassLoader);
|
||||
if (defaults!=null)
|
||||
{
|
||||
if (defaults.length()==0)
|
||||
wac.setDefaultsDescriptor(null);
|
||||
else
|
||||
wac.setDefaultsDescriptor(defaults);
|
||||
}
|
||||
if(Attributes != null) {
|
||||
for(int i = 0; i < Attributes.length; i++, i++) {
|
||||
wac.setAttribute(Attributes[i],Attributes[i + 1]);
|
||||
}
|
||||
}
|
||||
wacs.add(wac);
|
||||
}
|
||||
|
||||
return (WebApplicationContext[])wacs.toArray(new WebApplicationContext[wacs.size()]);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** setWebApplicationConfigurationClasses
|
||||
* Set up the list of classnames of WebApplicationContext.Configuration
|
||||
* implementations that will be applied to configure every webapp.
|
||||
* The list can be overridden by individual WebApplicationContexts.
|
||||
* @param configurationClasses
|
||||
*/
|
||||
public void setWebApplicationConfigurationClassNames (String[] configurationClassNames)
|
||||
{
|
||||
if (configurationClassNames != null)
|
||||
{
|
||||
_webAppConfigurationClassNames = new String[configurationClassNames.length];
|
||||
System.arraycopy(configurationClassNames, 0, _webAppConfigurationClassNames, 0, configurationClassNames.length);
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getWebApplicationConfigurationClassNames ()
|
||||
{
|
||||
return _webAppConfigurationClassNames;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
public static void main(String[] arg)
|
||||
{
|
||||
String[] dftConfig={"etc/jetty.xml"};
|
||||
|
||||
if (arg.length==0)
|
||||
{
|
||||
log.info("Using default configuration: etc/jetty.xml");
|
||||
arg=dftConfig;
|
||||
}
|
||||
|
||||
final Server[] servers=new Server[arg.length];
|
||||
|
||||
// create and start the servers.
|
||||
for (int i=0;i<arg.length;i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
servers[i] = new Server(arg[i]);
|
||||
servers[i].setStopAtShutdown(true);
|
||||
servers[i].start();
|
||||
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,e);
|
||||
}
|
||||
}
|
||||
|
||||
// create and start the servers.
|
||||
for (int i=0;i<arg.length;i++)
|
||||
{
|
||||
try{servers[i].join();}
|
||||
catch (Exception e){LogSupport.ignore(log,e);}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ShutdownHook thread for stopping all servers.
|
||||
*
|
||||
* Thread is hooked first time list of servers is changed.
|
||||
*/
|
||||
private static class ShutdownHookThread extends Thread {
|
||||
private boolean hooked = false;
|
||||
private ArrayList servers = new ArrayList();
|
||||
|
||||
/**
|
||||
* Hooks this thread for shutdown.
|
||||
* @see java.lang.Runtime#addShutdownHook(java.lang.Thread)
|
||||
*/
|
||||
private void createShutdownHook() {
|
||||
if (!Boolean.getBoolean("JETTY_NO_SHUTDOWN_HOOK") && !hooked) {
|
||||
try {
|
||||
Method shutdownHook = java.lang.Runtime.class.getMethod("addShutdownHook",
|
||||
new Class[] { java.lang.Thread.class });
|
||||
shutdownHook.invoke(Runtime.getRuntime(), new Object[] { this });
|
||||
this.hooked = true;
|
||||
} catch (Exception e) {
|
||||
if (log.isDebugEnabled()) log.debug("No shutdown hook in JVM ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Server to servers list.
|
||||
*/
|
||||
public boolean add(Server server) {
|
||||
createShutdownHook();
|
||||
return this.servers.add(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains Server in servers list?
|
||||
*/
|
||||
public boolean contains(Server server) {
|
||||
return this.servers.contains(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append all Servers from Collection
|
||||
*/
|
||||
public boolean addAll(Collection c) {
|
||||
createShutdownHook();
|
||||
return this.servers.addAll(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear list of Servers.
|
||||
*/
|
||||
public void clear() {
|
||||
createShutdownHook();
|
||||
this.servers.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove Server from list.
|
||||
*/
|
||||
public boolean remove(Server server) {
|
||||
createShutdownHook();
|
||||
return this.servers.remove(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all Servers in Collection from list.
|
||||
*/
|
||||
public boolean removeAll(Collection c) {
|
||||
createShutdownHook();
|
||||
return this.servers.removeAll(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop all Servers in list.
|
||||
*/
|
||||
public void run() {
|
||||
setName("Shutdown");
|
||||
log.info("Shutdown hook executing");
|
||||
Iterator it = servers.iterator();
|
||||
while (it.hasNext()) {
|
||||
Server svr = (Server) it.next();
|
||||
if (svr == null) continue;
|
||||
try {
|
||||
svr.stop();
|
||||
} catch (Exception e) {
|
||||
log.warn(LogSupport.EXCEPTION, e);
|
||||
}
|
||||
log.info("Shutdown hook complete");
|
||||
|
||||
// Try to avoid JVM crash
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (Exception e) {
|
||||
log.warn(LogSupport.EXCEPTION, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,352 +0,0 @@
|
||||
// ========================================================================
|
||||
// $Id: FileResource.java,v 1.31 2006/01/04 13:55:31 gregwilkins Exp $
|
||||
// Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ========================================================================
|
||||
package org.mortbay.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.security.Permission;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.mortbay.log.LogFactory;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** File Resource.
|
||||
*
|
||||
* Handle resources of implied or explicit file type.
|
||||
* This class can check for aliasing in the filesystem (eg case
|
||||
* insensitivity). By default this is turned on if the platform does
|
||||
* not have the "/" path separator, or it can be controlled with the
|
||||
* "org.mortbay.util.FileResource.checkAliases" system parameter.
|
||||
*
|
||||
* If alias checking is turned on, then aliased resources are
|
||||
* treated as if they do not exist, nor can they be created.
|
||||
*
|
||||
* @version $Revision: 1.31 $
|
||||
* @author Greg Wilkins (gregw)
|
||||
*/
|
||||
public class FileResource extends URLResource
|
||||
{
|
||||
private static Log log = LogFactory.getLog(Credential.class);
|
||||
private static boolean __checkAliases;
|
||||
static
|
||||
{
|
||||
__checkAliases=
|
||||
"true".equalsIgnoreCase
|
||||
(System.getProperty("org.mortbay.util.FileResource.checkAliases","true"));
|
||||
|
||||
if (__checkAliases)
|
||||
log.info("Checking Resource aliases");
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private File _file;
|
||||
private transient URL _alias=null;
|
||||
private transient boolean _aliasChecked=false;
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/** setCheckAliases.
|
||||
* @param checkAliases True of resource aliases are to be checked for (eg case insensitivity or 8.3 short names) and treated as not found.
|
||||
*/
|
||||
public static void setCheckAliases(boolean checkAliases)
|
||||
{
|
||||
__checkAliases=checkAliases;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/** getCheckAliases.
|
||||
* @return True of resource aliases are to be checked for (eg case insensitivity or 8.3 short names) and treated as not found.
|
||||
*/
|
||||
public static boolean getCheckAliases()
|
||||
{
|
||||
return __checkAliases;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
FileResource(URL url)
|
||||
throws IOException, URISyntaxException
|
||||
{
|
||||
super(url,null);
|
||||
|
||||
try
|
||||
{
|
||||
// Try standard API to convert URL to file.
|
||||
_file =new File(new URI(url.toString()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogSupport.ignore(log,e);
|
||||
try
|
||||
{
|
||||
// Assume that File.toURL produced unencoded chars. So try
|
||||
// encoding them.
|
||||
String urls=
|
||||
"file:"+org.mortbay.util.URI.encodePath(url.toString().substring(5));
|
||||
_file =new File(new URI(urls));
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
LogSupport.ignore(log,e2);
|
||||
|
||||
// Still can't get the file. Doh! try good old hack!
|
||||
checkConnection();
|
||||
Permission perm = _connection.getPermission();
|
||||
_file = new File(perm==null?url.getFile():perm.getName());
|
||||
}
|
||||
}
|
||||
|
||||
if (_file.isDirectory() && !_urlString.endsWith("/"))
|
||||
_urlString=_urlString+"/";
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
FileResource(URL url, URLConnection connection, File file)
|
||||
{
|
||||
super(url,connection);
|
||||
_file=file;
|
||||
if (_file.isDirectory() && !_urlString.endsWith("/"))
|
||||
_urlString=_urlString+"/";
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
public Resource addPath(String path)
|
||||
throws IOException,MalformedURLException
|
||||
{
|
||||
FileResource r=null;
|
||||
|
||||
if (!isDirectory())
|
||||
{
|
||||
r=(FileResource)super.addPath(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
path = org.mortbay.util.URI.canonicalPath(path);
|
||||
|
||||
// treat all paths being added as relative
|
||||
String rel=path;
|
||||
if (path.startsWith("/"))
|
||||
rel = path.substring(1);
|
||||
|
||||
File newFile = new File(_file,rel.replace('/', File.separatorChar));
|
||||
r=new FileResource(newFile.toURI().toURL(),null,newFile);
|
||||
}
|
||||
|
||||
String encoded=org.mortbay.util.URI.encodePath(path);
|
||||
int expected=r._urlString.length()-encoded.length();
|
||||
int index = r._urlString.lastIndexOf(encoded, expected);
|
||||
|
||||
if (expected!=index && ((expected-1)!=index || path.endsWith("/") || !r.isDirectory()))
|
||||
{
|
||||
r._alias=r._url;
|
||||
r._aliasChecked=true;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public URL getAlias()
|
||||
{
|
||||
if (__checkAliases) {
|
||||
if (!_aliasChecked)
|
||||
{
|
||||
try
|
||||
{
|
||||
String abs=_file.getAbsolutePath();
|
||||
String can=_file.getCanonicalPath();
|
||||
|
||||
if (abs.length()!=can.length() || !abs.equals(can))
|
||||
_alias=new File(can).toURI().toURL();
|
||||
|
||||
_aliasChecked=true;
|
||||
|
||||
if (_alias!=null && log.isDebugEnabled())
|
||||
{
|
||||
log.debug("ALIAS abs="+abs);
|
||||
log.debug("ALIAS can="+can);
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
log.warn(LogSupport.EXCEPTION,e);
|
||||
return getURL();
|
||||
}
|
||||
}
|
||||
} else return null;
|
||||
return _alias;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
/**
|
||||
* Returns true if the resource exists.
|
||||
*/
|
||||
public boolean exists()
|
||||
{
|
||||
return _file.exists();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
/**
|
||||
* Returns the last modified time
|
||||
*/
|
||||
public long lastModified()
|
||||
{
|
||||
return _file.lastModified();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
/**
|
||||
* Returns true if the respresenetd resource is a container/directory.
|
||||
*/
|
||||
public boolean isDirectory()
|
||||
{
|
||||
return _file.isDirectory();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/**
|
||||
* Return the length of the resource
|
||||
*/
|
||||
public long length()
|
||||
{
|
||||
return _file.length();
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/**
|
||||
* Returns the name of the resource
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return _file.getAbsolutePath();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns an File representing the given resource or NULL if this
|
||||
* is not possible.
|
||||
*/
|
||||
public File getFile()
|
||||
{
|
||||
return _file;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/**
|
||||
* Returns an input stream to the resource
|
||||
*/
|
||||
public InputStream getInputStream() throws IOException
|
||||
{
|
||||
return new FileInputStream(_file);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/**
|
||||
* Returns an output stream to the resource
|
||||
*/
|
||||
public OutputStream getOutputStream()
|
||||
throws java.io.IOException, SecurityException
|
||||
{
|
||||
return new FileOutputStream(_file);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/**
|
||||
* Deletes the given resource
|
||||
*/
|
||||
public boolean delete()
|
||||
throws SecurityException
|
||||
{
|
||||
return _file.delete();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/**
|
||||
* Rename the given resource
|
||||
*/
|
||||
public boolean renameTo( Resource dest)
|
||||
throws SecurityException
|
||||
{
|
||||
if( dest instanceof FileResource)
|
||||
return _file.renameTo( ((FileResource)dest)._file);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/**
|
||||
* Returns a list of resources contained in the given resource
|
||||
*/
|
||||
public String[] list()
|
||||
{
|
||||
String[] list =_file.list();
|
||||
if (list==null)
|
||||
return null;
|
||||
for (int i=list.length;i-->0;)
|
||||
{
|
||||
if (new File(_file,list[i]).isDirectory() &&
|
||||
!list[i].endsWith("/"))
|
||||
list[i]+="/";
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Encode according to this resource type.
|
||||
* File URIs are encoded.
|
||||
* @param uri URI to encode.
|
||||
* @return The uri unchanged.
|
||||
*/
|
||||
public String encode(String uri)
|
||||
{
|
||||
return uri;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public boolean equals( Object o)
|
||||
{
|
||||
if (this == o)
|
||||
return true;
|
||||
|
||||
if (null == o || ! (o instanceof FileResource))
|
||||
return false;
|
||||
|
||||
FileResource f=(FileResource)o;
|
||||
return f._file == _file || (null != _file && _file.equals(f._file));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return the hashcode.
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
return null == _file ? super.hashCode() : _file.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -1,253 +0,0 @@
|
||||
// ========================================================================
|
||||
// $Id: InetAddrPort.java,v 1.7 2004/10/23 09:03:22 gregwilkins Exp $
|
||||
// Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ========================================================================
|
||||
|
||||
package org.mortbay.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.InetAddress;
|
||||
|
||||
/* ======================================================================== */
|
||||
/** InetAddress and Port.
|
||||
*/
|
||||
public class InetAddrPort implements Serializable
|
||||
{
|
||||
/* ------------------------------------------------------------ */
|
||||
public final static String __0_0_0_0 = "0.0.0.0";
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private InetAddress _addr=null;
|
||||
private boolean _addrIsHost=false;
|
||||
private int _port=0;
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
public InetAddrPort()
|
||||
{}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor for a port on all local host address.
|
||||
* @param port
|
||||
*/
|
||||
public InetAddrPort(int port)
|
||||
{
|
||||
_port=port;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param addr
|
||||
* @param port
|
||||
*/
|
||||
public InetAddrPort(InetAddress addr, int port)
|
||||
{
|
||||
_addr=addr;
|
||||
_port=port;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param host
|
||||
* @param port
|
||||
*/
|
||||
public InetAddrPort(String host, int port)
|
||||
throws java.net.UnknownHostException
|
||||
{
|
||||
setHost(host);
|
||||
setPort(port);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* Patched to support [::1]:port for I2P
|
||||
*
|
||||
* @param inetAddrPort String of the form "addr:port"
|
||||
*/
|
||||
public InetAddrPort(String inetAddrPort)
|
||||
throws java.net.UnknownHostException
|
||||
{
|
||||
int b = inetAddrPort.indexOf('[');
|
||||
if (b>0)
|
||||
throw new java.net.UnknownHostException("Bad [] syntax");
|
||||
if (b==0) // IPV6
|
||||
{
|
||||
int b2 = inetAddrPort.indexOf(']');
|
||||
if (b2<2)
|
||||
throw new java.net.UnknownHostException("Bad [] syntax");
|
||||
String addr=inetAddrPort.substring(1,b2);
|
||||
if (addr.indexOf('/')>0)
|
||||
addr=addr.substring(addr.indexOf('/')+1);
|
||||
inetAddrPort=inetAddrPort.substring(b2+1);
|
||||
int c = inetAddrPort.indexOf(':');
|
||||
if (c>0)
|
||||
throw new java.net.UnknownHostException("Bad [] syntax");
|
||||
if (c==0)
|
||||
inetAddrPort=inetAddrPort.substring(1);
|
||||
|
||||
if (addr.length()>0 && ! __0_0_0_0.equals(addr))
|
||||
{
|
||||
_addrIsHost=!Character.isDigit((addr.charAt(0)));
|
||||
this._addr=InetAddress.getByName(addr);
|
||||
}
|
||||
} else { // IPV4
|
||||
int c = inetAddrPort.indexOf(':');
|
||||
if (c>=0)
|
||||
{
|
||||
String addr=inetAddrPort.substring(0,c);
|
||||
if (addr.indexOf('/')>0)
|
||||
addr=addr.substring(addr.indexOf('/')+1);
|
||||
inetAddrPort=inetAddrPort.substring(c+1);
|
||||
|
||||
if (addr.length()>0 && ! __0_0_0_0.equals(addr))
|
||||
{
|
||||
_addrIsHost=!Character.isDigit((addr.charAt(0)));
|
||||
this._addr=InetAddress.getByName(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_port = Integer.parseInt(inetAddrPort);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Constructor.
|
||||
* @param address InetAddrPort top copy.
|
||||
*/
|
||||
public InetAddrPort(InetAddrPort address)
|
||||
{
|
||||
if (address!=null)
|
||||
{
|
||||
_addr=address._addr;
|
||||
_port=address._port;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the Host.
|
||||
* @return The IP address
|
||||
*/
|
||||
public String getHost()
|
||||
{
|
||||
if (_addr==null)
|
||||
return __0_0_0_0;
|
||||
|
||||
return _addrIsHost?_addr.getHostName():_addr.getHostAddress();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the Host.
|
||||
* @param host
|
||||
* @exception java.net.UnknownHostException
|
||||
*/
|
||||
public void setHost(String host)
|
||||
throws java.net.UnknownHostException
|
||||
{
|
||||
_addr=null;
|
||||
if (host!=null)
|
||||
{
|
||||
if (host.indexOf('/')>0)
|
||||
host=host.substring(0,host.indexOf('/'));
|
||||
_addrIsHost=!Character.isDigit((host.charAt(0)));
|
||||
_addr=InetAddress.getByName(host);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the IP address.
|
||||
* @return The IP address
|
||||
*/
|
||||
public InetAddress getInetAddress()
|
||||
{
|
||||
return _addr;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the IP address.
|
||||
* @param addr The IP address
|
||||
*/
|
||||
public void setInetAddress(InetAddress addr)
|
||||
{
|
||||
_addrIsHost=false;
|
||||
_addr=addr;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the port.
|
||||
* @return The port number
|
||||
*/
|
||||
public int getPort()
|
||||
{
|
||||
return _port;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the port.
|
||||
* @param port The port number
|
||||
*/
|
||||
public void setPort(int port)
|
||||
{
|
||||
_port=port;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
public String toString()
|
||||
{
|
||||
return getHost()+':'+_port;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Clone the InetAddrPort.
|
||||
* @return A new instance.
|
||||
*/
|
||||
public Object clone()
|
||||
{
|
||||
return new InetAddrPort(this);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Hash Code.
|
||||
* @return hash Code.
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
return _port+((_addr==null)?0:_addr.hashCode());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Equals.
|
||||
* @param o
|
||||
* @return True if is the same address and port.
|
||||
*/
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (o==null)
|
||||
return false;
|
||||
if (o==this)
|
||||
return true;
|
||||
if (o instanceof InetAddrPort)
|
||||
{
|
||||
InetAddrPort addr=(InetAddrPort)o;
|
||||
return addr._port==_port &&
|
||||
( addr._addr==_addr ||
|
||||
addr._addr!=null && addr._addr.equals(_addr));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,431 +0,0 @@
|
||||
// ========================================================================
|
||||
// $Id: Resource.java,v 1.32 2009/05/16 01:53:36 gregwilkins Exp $
|
||||
// Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ========================================================================
|
||||
package org.mortbay.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.mortbay.log.LogFactory;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Abstract resource class.
|
||||
*
|
||||
* @version $Id: Resource.java,v 1.32 2009/05/16 01:53:36 gregwilkins Exp $
|
||||
* @author Nuno Preguica
|
||||
* @author Greg Wilkins (gregw)
|
||||
*/
|
||||
public abstract class Resource implements Serializable
|
||||
{
|
||||
private static Log log = LogFactory.getLog(Resource.class);
|
||||
|
||||
Object _associate;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Construct a resource from a url.
|
||||
* @param url A URL.
|
||||
* @return A Resource object.
|
||||
*/
|
||||
public static Resource newResource(URL url)
|
||||
throws IOException
|
||||
{
|
||||
if (url==null)
|
||||
return null;
|
||||
|
||||
String urls=url.toExternalForm();
|
||||
if( urls.startsWith( "file:"))
|
||||
{
|
||||
try
|
||||
{
|
||||
FileResource fileResource= new FileResource(url);
|
||||
return fileResource;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
log.debug(LogSupport.EXCEPTION,e);
|
||||
return new BadResource(url,e.toString());
|
||||
}
|
||||
}
|
||||
else if( urls.startsWith( "jar:file:"))
|
||||
{
|
||||
return new JarFileResource(url);
|
||||
}
|
||||
else if( urls.startsWith( "jar:"))
|
||||
{
|
||||
return new JarResource(url);
|
||||
}
|
||||
|
||||
return new URLResource(url,null);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Construct a resource from a string.
|
||||
* @param resource A URL or filename.
|
||||
* @return A Resource object.
|
||||
*/
|
||||
public static Resource newResource(String resource)
|
||||
throws MalformedURLException, IOException
|
||||
{
|
||||
URL url=null;
|
||||
try
|
||||
{
|
||||
// Try to format as a URL?
|
||||
url = new URL(resource);
|
||||
}
|
||||
catch(MalformedURLException e)
|
||||
{
|
||||
if(!resource.startsWith("ftp:") &&
|
||||
!resource.startsWith("file:") &&
|
||||
!resource.startsWith("jar:"))
|
||||
{
|
||||
try
|
||||
{
|
||||
// It's a file.
|
||||
if (resource.startsWith("./"))
|
||||
resource=resource.substring(2);
|
||||
|
||||
File file=new File(resource).getCanonicalFile();
|
||||
url=file.toURI().toURL();
|
||||
|
||||
URLConnection connection=url.openConnection();
|
||||
FileResource fileResource= new FileResource(url,connection,file);
|
||||
return fileResource;
|
||||
}
|
||||
catch(Exception e2)
|
||||
{
|
||||
log.debug(LogSupport.EXCEPTION,e2);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log.warn("Bad Resource: "+resource);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
String nurl=url.toString();
|
||||
if (nurl.length()>0 &&
|
||||
nurl.charAt(nurl.length()-1)!=
|
||||
resource.charAt(resource.length()-1))
|
||||
{
|
||||
if ((nurl.charAt(nurl.length()-1)!='/' ||
|
||||
nurl.charAt(nurl.length()-2)!=resource.charAt(resource.length()-1))
|
||||
&&
|
||||
(resource.charAt(resource.length()-1)!='/' ||
|
||||
resource.charAt(resource.length()-2)!=nurl.charAt(nurl.length()-1)
|
||||
))
|
||||
{
|
||||
return new BadResource(url,"Trailing special characters stripped by URL in "+resource);
|
||||
}
|
||||
}
|
||||
return newResource(url);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Construct a system resource from a string.
|
||||
* The resource is tried as classloader resource before being
|
||||
* treated as a normal resource.
|
||||
*/
|
||||
public static Resource newSystemResource(String resource)
|
||||
throws IOException
|
||||
{
|
||||
URL url=null;
|
||||
// Try to format as a URL?
|
||||
ClassLoader
|
||||
loader=Thread.currentThread().getContextClassLoader();
|
||||
if (loader!=null)
|
||||
{
|
||||
url=loader.getResource(resource);
|
||||
if (url==null && resource.startsWith("/"))
|
||||
url=loader.getResource(resource.substring(1));
|
||||
}
|
||||
if (url==null)
|
||||
{
|
||||
loader=Resource.class.getClassLoader();
|
||||
if (loader!=null)
|
||||
{
|
||||
url=loader.getResource(resource);
|
||||
if (url==null && resource.startsWith("/"))
|
||||
url=loader.getResource(resource.substring(1));
|
||||
}
|
||||
}
|
||||
|
||||
if (url==null)
|
||||
{
|
||||
url=ClassLoader.getSystemResource(resource);
|
||||
if (url==null && resource.startsWith("/"))
|
||||
url=loader.getResource(resource.substring(1));
|
||||
}
|
||||
|
||||
if (url==null)
|
||||
return null;
|
||||
|
||||
return newResource(url);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected void finalize()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Release any resources held by the resource.
|
||||
*/
|
||||
public abstract void release();
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns true if the respresened resource exists.
|
||||
*/
|
||||
public abstract boolean exists();
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns true if the respresenetd resource is a container/directory.
|
||||
* If the resource is not a file, resources ending with "/" are
|
||||
* considered directories.
|
||||
*/
|
||||
public abstract boolean isDirectory();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns the last modified time
|
||||
*/
|
||||
public abstract long lastModified();
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Return the length of the resource
|
||||
*/
|
||||
public abstract long length();
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns an URL representing the given resource
|
||||
*/
|
||||
public abstract URL getURL();
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns an File representing the given resource or NULL if this
|
||||
* is not possible.
|
||||
*/
|
||||
public abstract File getFile()
|
||||
throws IOException;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns the name of the resource
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns an input stream to the resource
|
||||
*/
|
||||
public abstract InputStream getInputStream()
|
||||
throws java.io.IOException;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns an output stream to the resource
|
||||
*/
|
||||
public abstract OutputStream getOutputStream()
|
||||
throws java.io.IOException, SecurityException;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Deletes the given resource
|
||||
*/
|
||||
public abstract boolean delete()
|
||||
throws SecurityException;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Rename the given resource
|
||||
*/
|
||||
public abstract boolean renameTo( Resource dest)
|
||||
throws SecurityException;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns a list of resource names contained in the given resource
|
||||
* The resource names are not URL encoded.
|
||||
*/
|
||||
public abstract String[] list();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Returns the resource contained inside the current resource with the
|
||||
* given name.
|
||||
* @param path The path segment to add, which should be encoded by the
|
||||
* encode method.
|
||||
*/
|
||||
public abstract Resource addPath(String path)
|
||||
throws IOException,MalformedURLException;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Encode according to this resource type.
|
||||
* The default implementation calls URI.encodePath(uri)
|
||||
* @param uri
|
||||
* @return String encoded for this resource type.
|
||||
*/
|
||||
public String encode(String uri)
|
||||
{
|
||||
return URI.encodePath(uri);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Object getAssociate()
|
||||
{
|
||||
return _associate;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setAssociate(Object o)
|
||||
{
|
||||
_associate=o;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The canonical Alias of this resource or null if none.
|
||||
*/
|
||||
public URL getAlias()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public CachedResource cache()
|
||||
throws IOException
|
||||
{
|
||||
return new CachedResource(this);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the resource list as a HTML directory listing.
|
||||
* @param base The base URL
|
||||
* @param parent True if the parent directory should be included
|
||||
* @return String of HTML
|
||||
*/
|
||||
public String getListHTML(String base,
|
||||
boolean parent)
|
||||
throws IOException
|
||||
{
|
||||
if (!isDirectory())
|
||||
return null;
|
||||
|
||||
|
||||
String[] ls = list();
|
||||
if (ls==null)
|
||||
return null;
|
||||
Arrays.sort(ls);
|
||||
|
||||
String title = "Directory: "+URI.decodePath(base);
|
||||
title=StringUtil.replace(StringUtil.replace(title,"<","<"),">",">");
|
||||
StringBuffer buf=new StringBuffer(4096);
|
||||
buf.append("<HTML><HEAD><TITLE>");
|
||||
buf.append(title);
|
||||
buf.append("</TITLE></HEAD><BODY>\n<H1>");
|
||||
buf.append(title);
|
||||
buf.append("</H1><TABLE BORDER=0>");
|
||||
|
||||
if (parent)
|
||||
{
|
||||
buf.append("<TR><TD><A HREF=");
|
||||
buf.append(URI.encodePath(URI.addPaths(base,"../")));
|
||||
buf.append(">Parent Directory</A></TD><TD></TD><TD></TD></TR>\n");
|
||||
}
|
||||
|
||||
DateFormat dfmt=DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
|
||||
DateFormat.MEDIUM);
|
||||
for (int i=0 ; i< ls.length ; i++)
|
||||
{
|
||||
String encoded=URI.encodePath(ls[i]);
|
||||
// bugfix for I2P - Backport from Jetty 6 (zero file lengths and last-modified times)
|
||||
// http://jira.codehaus.org/browse/JETTY-361?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel#issue-tabs
|
||||
// See resource.diff attachment
|
||||
//Resource item = addPath(encoded);
|
||||
Resource item = addPath(ls[i]);
|
||||
|
||||
buf.append("<TR><TD><A HREF=\"");
|
||||
|
||||
String path=URI.addPaths(base,encoded);
|
||||
|
||||
if (item.isDirectory() && !path.endsWith("/"))
|
||||
path=URI.addPaths(path,"/");
|
||||
buf.append(path);
|
||||
buf.append("\">");
|
||||
buf.append(StringUtil.replace(StringUtil.replace(ls[i],"<","<"),">",">"));
|
||||
buf.append("</A> ");
|
||||
buf.append("</TD><TD ALIGN=right>");
|
||||
buf.append(item.length());
|
||||
buf.append(" bytes </TD><TD>");
|
||||
buf.append(dfmt.format(new Date(item.lastModified())));
|
||||
buf.append("</TD></TR>\n");
|
||||
}
|
||||
buf.append("</TABLE>\n");
|
||||
buf.append("</BODY></HTML>\n");
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param out
|
||||
* @param start First byte to write
|
||||
* @param count Bytes to write or -1 for all of them.
|
||||
*/
|
||||
public void writeTo(OutputStream out,long start,long count)
|
||||
throws IOException
|
||||
{
|
||||
InputStream in = getInputStream();
|
||||
try
|
||||
{
|
||||
in.skip(start);
|
||||
if (count<0)
|
||||
IO.copy(in,out);
|
||||
else
|
||||
IO.copy(in,out,(int)count);
|
||||
}
|
||||
finally
|
||||
{
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
3
apps/jetty/jetty-6.1.26/README-i2p.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
This is only what we need out of the 25 MB Jetty-6.1.26.zip.
|
||||
|
||||
NOTICE and LICENSE files moved to ../../../licenses
|
||||
BIN
apps/jetty/jetty-6.1.26/lib/ext/jetty-rewrite-handler-6.1.26.jar
Normal file
BIN
apps/jetty/jetty-6.1.26/lib/ext/jetty-sslengine-6.1.26.jar
Normal file
BIN
apps/jetty/jetty-6.1.26/lib/jetty-6.1.26.jar
Normal file
BIN
apps/jetty/jetty-6.1.26/lib/jetty-util-6.1.26.jar
Normal file
BIN
apps/jetty/jetty-6.1.26/start.jar
Normal file
9
apps/jetty/resources/log4j.properties
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
# This is not needed by Jetty - but it helps with many web apps.
|
||||
|
||||
log4j.rootLogger=INFO, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
<jar destfile="./build/mstreaming.jar" basedir="./build/obj" includes="**/*.class" >
|
||||
<manifest>
|
||||
<attribute name="Implementation-Version" value="${full.version}" />
|
||||
<attribute name="Built-By" value="${build.built-by}" />
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
|
||||
|
||||
@@ -21,7 +21,12 @@
|
||||
<pathelement location="../../../core/java/build/obj" />
|
||||
<pathelement location="../../../router/java/build/obj" />
|
||||
<pathelement location="../../jetty/jettylib/org.mortbay.jetty.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-util.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-sslengine.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-java5-threadpool.jar" />
|
||||
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-i2p.jar" />
|
||||
<pathelement location="../../systray/java/build/obj" />
|
||||
<pathelement location="../../systray/java/lib/systray4j.jar" />
|
||||
<pathelement location="../../desktopgui/build" />
|
||||
@@ -54,7 +59,12 @@
|
||||
<pathelement location="../../../core/java/build/i2p.jar" />
|
||||
<pathelement location="../../../router/java/build/router.jar" />
|
||||
<pathelement location="../../jetty/jettylib/org.mortbay.jetty.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-util.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-sslengine.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-java5-threadpool.jar" />
|
||||
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-i2p.jar" />
|
||||
<pathelement location="../../systray/java/build/systray.jar" />
|
||||
<pathelement location="../../systray/java/lib/systray4j.jar" />
|
||||
<pathelement location="../../desktopgui/dist/desktopgui.jar" />
|
||||
@@ -92,6 +102,7 @@
|
||||
<!-- DTG added in 0.8.4, not in the classpath for very old installs, before we changed wrapper.config to specify * -->
|
||||
<attribute name="Class-Path" value="i2p.jar router.jar jrobin.jar desktopgui.jar" />
|
||||
<attribute name="Implementation-Version" value="${full.version}" />
|
||||
<attribute name="Built-By" value="${build.built-by}" />
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.j.tr}" />
|
||||
@@ -172,6 +183,7 @@
|
||||
basedir="../jsp/" excludes="web.xml, *.css, **/*.java, *.jsp, *.jsi, web-fragment.xml, web-out.xml">
|
||||
<manifest>
|
||||
<attribute name="Implementation-Version" value="${full.version}" />
|
||||
<attribute name="Built-By" value="${build.built-by}" />
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.w.tr}" />
|
||||
@@ -236,7 +248,9 @@
|
||||
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
|
||||
<pathelement location="../../jetty/jettylib/commons-logging.jar" />
|
||||
<pathelement location="../../jetty/jettylib/commons-el.jar" />
|
||||
<pathelement location="../../jetty/jettylib/ant.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
|
||||
<pathelement location="${ant.home}/lib/ant.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-i2p.jar" />
|
||||
<pathelement location="../../systray/java/build/obj" />
|
||||
<pathelement location="../../systray/java/lib/systray4j.jar" />
|
||||
<pathelement location="../../desktopgui/dist/desktopgui.jar" />
|
||||
@@ -269,6 +283,11 @@
|
||||
<pathelement location="../../jetty/jettylib/commons-logging.jar" />
|
||||
<pathelement location="../../jetty/jettylib/commons-el.jar" />
|
||||
<pathelement location="../../jetty/jettylib/org.mortbay.jetty.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-util.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-sslengine.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-java5-threadpool.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-i2p.jar" />
|
||||
<pathelement location="../../systray/java/build/obj" />
|
||||
<pathelement location="../../systray/java/lib/systray4j.jar" />
|
||||
<pathelement location="../../desktopgui/dist/desktopgui.jar" />
|
||||
|
||||
@@ -14,7 +14,7 @@ import net.i2p.router.client.ClientManagerFacadeImpl;
|
||||
import net.i2p.router.startup.ClientAppConfig;
|
||||
import net.i2p.router.startup.LoadClientAppsJob;
|
||||
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.handler.ContextHandlerCollection;
|
||||
|
||||
/**
|
||||
* Saves changes to clients.config or webapps.config
|
||||
@@ -290,7 +290,7 @@ public class ConfigClientsHandler extends FormHandler {
|
||||
* requested and add the .war to that one
|
||||
*/
|
||||
private void startWebApp(String app) {
|
||||
Server s = WebAppStarter.getConsoleServer();
|
||||
ContextHandlerCollection s = WebAppStarter.getConsoleServer();
|
||||
if (s != null) {
|
||||
try {
|
||||
File path = new File(_context.getBaseDir(), "webapps");
|
||||
|
||||
@@ -52,7 +52,7 @@ public class ConfigClientsHelper extends HelperBase {
|
||||
if ((mode == 0 && disabled) ||
|
||||
(mode == 1 && (!disabled) && (!ssl)) ||
|
||||
(mode == 2 && (!disabled) && ssl))
|
||||
return "checked=\"true\"";
|
||||
return "checked=\"checked\"";
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ public class ConfigClientsHelper extends HelperBase {
|
||||
public String getAuth() {
|
||||
boolean enabled = _context.getBooleanProperty(PROP_AUTH);
|
||||
if (enabled)
|
||||
return "checked=\"true\"";
|
||||
return "checked=\"checked\"";
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -253,9 +253,9 @@ public class ConfigClientsHelper extends HelperBase {
|
||||
}
|
||||
buf.append("</td><td align=\"center\" width=\"10%\"><input type=\"checkbox\" class=\"optbox\" name=\"").append(index).append(".enabled\" value=\"true\" ");
|
||||
if (enabled) {
|
||||
buf.append("checked=\"true\" ");
|
||||
buf.append("checked=\"checked\" ");
|
||||
if (ro)
|
||||
buf.append("disabled=\"true\" ");
|
||||
buf.append("disabled=\"disabled\" ");
|
||||
}
|
||||
buf.append("></td><td align=\"center\" width=\"15%\">");
|
||||
// The icons were way too much, so there's an X in each button class,
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
|
||||
/**
|
||||
* Simple home page configuration.
|
||||
*
|
||||
* @since 0.9
|
||||
*/
|
||||
public class ConfigHomeHandler extends FormHandler {
|
||||
|
||||
private Map _settings;
|
||||
|
||||
@Override
|
||||
protected void processForm() {
|
||||
if (_action == null) return;
|
||||
String group = getJettyString("group");
|
||||
boolean deleting = _action.equals(_("Delete selected"));
|
||||
boolean adding = _action.equals(_("Add item"));
|
||||
boolean restoring = _action.equals(_("Restore defaults"));
|
||||
if (_action.equals(_("Save")) && "0".equals(group)) {
|
||||
boolean old = _context.getBooleanProperty(HomeHelper.PROP_OLDHOME);
|
||||
boolean nnew = getJettyString("oldHome") != null;
|
||||
if (old != nnew) {
|
||||
_context.router().saveConfig(HomeHelper.PROP_OLDHOME, "" + nnew);
|
||||
addFormNotice(_("Home page changed"));
|
||||
}
|
||||
} else if (adding || deleting || restoring) {
|
||||
String prop;
|
||||
String dflt;
|
||||
if ("1".equals(group)) {
|
||||
prop = HomeHelper.PROP_FAVORITES;
|
||||
dflt = HomeHelper.DEFAULT_FAVORITES;
|
||||
} else if ("2".equals(group)) {
|
||||
prop = HomeHelper.PROP_SERVICES;
|
||||
dflt = HomeHelper.DEFAULT_SERVICES;
|
||||
} else if ("3".equals(group)) {
|
||||
prop = SearchHelper.PROP_ENGINES;
|
||||
dflt = SearchHelper.ENGINES_DEFAULT;
|
||||
} else {
|
||||
addFormError("Bad group");
|
||||
return;
|
||||
}
|
||||
if (restoring) {
|
||||
_context.router().saveConfig(prop, dflt);
|
||||
addFormNotice(_("Restored default settings"));
|
||||
return;
|
||||
}
|
||||
String config = _context.getProperty(prop, dflt);
|
||||
Collection<HomeHelper.App> apps;
|
||||
if ("3".equals(group))
|
||||
apps = HomeHelper.buildSearchApps(config);
|
||||
else
|
||||
apps = HomeHelper.buildApps(_context, config);
|
||||
if (adding) {
|
||||
String name = getJettyString("name");
|
||||
if (name == null || name.length() <= 0) {
|
||||
addFormError(_("No name entered"));
|
||||
return;
|
||||
}
|
||||
String url = getJettyString("url");
|
||||
if (url == null || url.length() <= 0) {
|
||||
addFormError(_("No URL entered"));
|
||||
return;
|
||||
}
|
||||
name = DataHelper.escapeHTML(name).replace(",", ","); // HomeHelper.S
|
||||
url = DataHelper.escapeHTML(url).replace(",", ",");
|
||||
HomeHelper.App app = new HomeHelper.App(name, "", url, "/themes/console/images/itoopie_sm.png");
|
||||
apps.add(app);
|
||||
addFormNotice(_("Added") + ": " + app.name);
|
||||
} else {
|
||||
// deleting
|
||||
Set<String> toDelete = new HashSet();
|
||||
for (Object o : _settings.keySet()) {
|
||||
if (!(o instanceof String))
|
||||
continue;
|
||||
String k = (String) o;
|
||||
if (!k.startsWith("delete_"))
|
||||
continue;
|
||||
k = k.substring(7);
|
||||
toDelete.add(k);
|
||||
}
|
||||
for (Iterator<HomeHelper.App> iter = apps.iterator(); iter.hasNext(); ) {
|
||||
HomeHelper.App app = iter.next();
|
||||
if (toDelete.contains(app.name)) {
|
||||
iter.remove();
|
||||
addFormNotice(_("Removed") + ": " + app.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
HomeHelper.saveApps(_context, prop, apps, !("3".equals(group)));
|
||||
} else {
|
||||
addFormError(_("Unsupported"));
|
||||
}
|
||||
}
|
||||
|
||||
public void setSettings(Map settings) { _settings = new HashMap(settings); }
|
||||
|
||||
/** curses Jetty for returning arrays */
|
||||
private String getJettyString(String key) {
|
||||
String[] arr = (String[]) _settings.get(key);
|
||||
if (arr == null)
|
||||
return null;
|
||||
return arr[0].trim();
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ public class ConfigLoggingHandler extends FormHandler {
|
||||
private void saveChanges() {
|
||||
boolean shouldSave = false;
|
||||
|
||||
if (_levels != null || _newLogClass != null) {
|
||||
if ((_levels != null && _levels.length() > 0) || _newLogClass != null) {
|
||||
try {
|
||||
Properties props = new Properties();
|
||||
if (_levels != null)
|
||||
@@ -85,8 +85,9 @@ public class ConfigLoggingHandler extends FormHandler {
|
||||
_context.logManager().getLog(ConfigLoggingHandler.class).error("Error reading from the props?", ioe);
|
||||
addFormError("Error updating the log limits - levels not valid");
|
||||
}
|
||||
} else {
|
||||
} else if (!_context.logManager().getLimits().isEmpty()) {
|
||||
_context.logManager().setLimits(null);
|
||||
shouldSave = true;
|
||||
addFormNotice("Log limits cleared");
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ public class ConfigLoggingHelper extends HelperBase {
|
||||
String l = levels[i];
|
||||
buf.append("<option value=\"").append(l).append('\"');
|
||||
if (l.equals(cur))
|
||||
buf.append(" selected=\"true\"");
|
||||
buf.append(" selected=\"selected\"");
|
||||
buf.append('>').append(_(l)).append("</option>\n");
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ public class ConfigLoggingHelper extends HelperBase {
|
||||
|
||||
StringBuilder buf = new StringBuilder(65536);
|
||||
buf.append("<select name=\"newlogclass\">\n" +
|
||||
"<option value=\"\" selected=\"true\">")
|
||||
"<option value=\"\" selected=\"selected\">")
|
||||
.append(_("Select a class to add"))
|
||||
.append("</option>\n");
|
||||
|
||||
|
||||
@@ -11,12 +11,13 @@ public class ConfigNavHelper extends HelperBase {
|
||||
|
||||
/** configX.jsp */
|
||||
private static final String pages[] =
|
||||
{"", "net", "ui", "service", "update", "tunnels",
|
||||
{"", "net", "ui", "home", "service", "update", "tunnels",
|
||||
"clients", "peer", "keyring", "logging", "stats",
|
||||
"reseed", "advanced" };
|
||||
|
||||
private static final String titles[] =
|
||||
{_x("Bandwidth"), _x("Network"), _x("UI"), _x("Service"), _x("Update"), _x("Tunnels"),
|
||||
{_x("Bandwidth"), _x("Network"), _x("UI"), _x("Home Page"),
|
||||
_x("Service"), _x("Update"), _x("Tunnels"),
|
||||
_x("Clients"), _x("Peers"), _x("Keyring"), _x("Logging"), _x("Stats"),
|
||||
_x("Reseeding"), _x("Advanced") };
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ public class ConfigNetHelper extends HelperBase {
|
||||
public final static String PROP_I2NP_NTCP_PORT = "i2np.ntcp.port";
|
||||
public final static String PROP_I2NP_NTCP_AUTO_PORT = "i2np.ntcp.autoport";
|
||||
public final static String PROP_I2NP_NTCP_AUTO_IP = "i2np.ntcp.autoip";
|
||||
private final static String CHECKED = " checked=\"true\" ";
|
||||
private final static String DISABLED = " disabled=\"true\" ";
|
||||
private final static String CHECKED = " checked=\"checked\" ";
|
||||
private final static String DISABLED = " disabled=\"disabled\" ";
|
||||
|
||||
public String getUdphostname() {
|
||||
return _context.getProperty(UDPTransport.PROP_EXTERNAL_HOST, "");
|
||||
@@ -250,7 +250,7 @@ public class ConfigNetHelper extends HelperBase {
|
||||
}
|
||||
buf.append("<option style=\"text-align: right;\" value=\"").append(val).append("\" ");
|
||||
if (pct == val) {
|
||||
buf.append("selected=\"true\" ");
|
||||
buf.append("selected=\"selected\" ");
|
||||
found = true;
|
||||
}
|
||||
buf.append(">").append(val).append("%</option>\n");
|
||||
|
||||
@@ -56,7 +56,7 @@ public class ConfigReseedHelper extends HelperBase {
|
||||
if ((mode == 0 && (!disabled) && (!required)) ||
|
||||
(mode == 1 && (!disabled) && required) ||
|
||||
(mode == 2 && disabled))
|
||||
return "checked=\"true\"";
|
||||
return "checked=\"checked\"";
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public class ConfigReseedHelper extends HelperBase {
|
||||
private String checked(String prop) {
|
||||
boolean enabled = _context.getBooleanProperty(prop);
|
||||
if (enabled)
|
||||
return "checked=\"true\"";
|
||||
return "checked=\"checked\"";
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@@ -59,8 +59,16 @@ public class ConfigStatsHelper extends HelperBase {
|
||||
_filters.add(tok.nextToken().trim());
|
||||
}
|
||||
|
||||
public ConfigStatsHelper() {}
|
||||
|
||||
/**
|
||||
* Just hide for everybody unless already set.
|
||||
* To enable set advanced config stat.logFilters=foo before starting...
|
||||
* it has to be set at startup anyway for logging to be enabled at all
|
||||
* @since 0.9
|
||||
*/
|
||||
public boolean shouldShowLog() {
|
||||
return !_filters.isEmpty();
|
||||
}
|
||||
|
||||
public String getFilename() { return _context.statManager().getStatFile(); }
|
||||
|
||||
/**
|
||||
|
||||