merge of '3b6c4d6af6fae83cc9b7d42e8515804ae48ec675'

and '799a00a4929a59478c534a56cce350cdb9a042e0'
This commit is contained in:
z3d
2010-11-23 13:54:18 +00:00
51 changed files with 998 additions and 303 deletions

View File

@@ -49,6 +49,8 @@ import net.i2p.util.SecureFileOutputStream;
*/
class ConfigParser {
private static final boolean isWindows = System.getProperty("os.name").startsWith("Win");
/**
* Strip the comments from a String. Lines that begin with '#' and ';' are
* considered comments, as well as any part of a line after a '#'.
@@ -276,7 +278,8 @@ class ConfigParser {
* Write contents of Map map to the File file. Output is written
* with one key, value pair on each line, in the format: key=value.
* Write to a temp file in the same directory and then rename, to not corrupt
* simultaneous accesses by the router.
* simultaneous accesses by the router. Except on Windows where renameTo()
* will fail if the target exists.
*
* @param map
* A Map to write to file.
@@ -286,14 +289,19 @@ class ConfigParser {
* if file cannot be written to.
*/
public static void write(Map map, File file) throws IOException {
File tmp = SecureFile.createTempFile("hoststxt-", ".tmp", file.getAbsoluteFile().getParentFile());
ConfigParser
boolean success = false;
if (!isWindows) {
File tmp = SecureFile.createTempFile("temp-", ".tmp", file.getAbsoluteFile().getParentFile());
ConfigParser
.write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(tmp), "UTF-8")));
boolean success = tmp.renameTo(file);
success = tmp.renameTo(file);
if (!success) {
tmp.delete();
//System.out.println("Warning: addressbook rename fail from " + tmp + " to " + file);
}
}
if (!success) {
// hmm, that didn't work, try it the old way
System.out.println("Warning: addressbook rename fail from " + tmp + " to " + file);
tmp.delete();
ConfigParser
.write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8")));
}

View File

@@ -0,0 +1,14 @@
package org.klomp.snark;
/**
* Callback used to fetch data
* @since 0.8.2
*/
interface DataLoader
{
/**
* This is the callback that PeerConnectionOut calls to get the data from disk
* @return bytes or null for errors
*/
public byte[] loadData(int piece, int begin, int length);
}

View File

@@ -39,23 +39,28 @@ class Message
final static byte REQUEST = 6;
final static byte PIECE = 7;
final static byte CANCEL = 8;
final static byte EXTENSION = 20;
// Not all fields are used for every message.
// KEEP_ALIVE doesn't have a real wire representation
byte type;
// Used for HAVE, REQUEST, PIECE and CANCEL messages.
// low byte used for EXTENSION message
int piece;
// Used for REQUEST, PIECE and CANCEL messages.
int begin;
int length;
// Used for PIECE and BITFIELD messages
// Used for PIECE and BITFIELD and EXTENSION messages
byte[] data;
int off;
int len;
// Used to do deferred fetch of data
DataLoader dataLoader;
SimpleTimer.TimedEvent expireEvent;
/** Utility method for sending a message through a DataStream. */
@@ -68,6 +73,13 @@ class Message
return;
}
// Get deferred data
if (data == null && dataLoader != null) {
data = dataLoader.loadData(piece, begin, length);
if (data == null)
return; // hmm will get retried, but shouldn't happen
}
// Calculate the total length in bytes
// Type is one byte.
@@ -85,8 +97,12 @@ class Message
if (type == REQUEST || type == CANCEL)
datalen += 4;
// length is 1 byte
if (type == EXTENSION)
datalen += 1;
// add length of data for piece or bitfield array.
if (type == BITFIELD || type == PIECE)
if (type == BITFIELD || type == PIECE || type == EXTENSION)
datalen += len;
// Send length
@@ -105,8 +121,11 @@ class Message
if (type == REQUEST || type == CANCEL)
dos.writeInt(length);
if (type == EXTENSION)
dos.writeByte((byte) piece & 0xff);
// Send actual data
if (type == BITFIELD || type == PIECE)
if (type == BITFIELD || type == PIECE || type == EXTENSION)
dos.write(data, off, len);
}
@@ -135,6 +154,8 @@ class Message
return "PIECE(" + piece + "," + begin + "," + length + ")";
case CANCEL:
return "CANCEL(" + piece + "," + begin + "," + length + ")";
case EXTENSION:
return "EXTENSION(" + piece + ',' + data.length + ')';
default:
return "<UNKNOWN>";
}

View File

@@ -59,6 +59,11 @@ public class Peer implements Comparable
private long uploaded_old[] = {-1,-1,-1};
private long downloaded_old[] = {-1,-1,-1};
// bytes per bt spec: 0011223344556677
static final long OPTION_EXTENSION = 0x0000000000100000l;
static final long OPTION_FAST = 0x0000000000000004l;
private long options;
/**
* Creates a disconnected peer given a PeerID, your own id and the
* relevant MetaInfo.
@@ -285,9 +290,8 @@ public class Peer implements Comparable
// Handshake write - header
dout.write(19);
dout.write("BitTorrent protocol".getBytes("UTF-8"));
// Handshake write - zeros
byte[] zeros = new byte[8];
dout.write(zeros);
// Handshake write - options
dout.writeLong(OPTION_EXTENSION);
// Handshake write - metainfo hash
byte[] shared_hash = metainfo.getInfoHash();
dout.write(shared_hash);
@@ -312,8 +316,8 @@ public class Peer implements Comparable
+ "'Bittorrent protocol', got '"
+ bittorrentProtocol + "'");
// Handshake read - zeros
din.readFully(zeros);
// Handshake read - options
options = din.readLong();
// Handshake read - metainfo hash
bs = new byte[20];
@@ -325,6 +329,15 @@ public class Peer implements Comparable
din.readFully(bs);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Read the remote side's hash and peerID fully from " + toString());
// if ((options & OPTION_EXTENSION) != 0) {
if (options != 0) {
// send them something
if (_log.shouldLog(Log.DEBUG))
//_log.debug("Peer supports extension message, what should we say? " + toString());
_log.debug("Peer supports options 0x" + Long.toString(options, 16) + ", what should we say? " + toString());
}
return bs;
}

View File

@@ -171,6 +171,13 @@ class PeerConnectionIn implements Runnable
if (_log.shouldLog(Log.DEBUG))
_log.debug("Received cancel(" + piece + "," + begin + ") from " + peer + " on " + peer.metainfo.getName());
break;
case 20: // Extension message
int id = din.readUnsignedByte();
byte[] payload = new byte[i-2];
din.readFully(payload);
ps.extensionMessage(id, payload);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Received extension message from " + peer + " on " + peer.metainfo.getName());
default:
byte[] bs = new byte[i-1];
din.readFully(bs);

View File

@@ -430,6 +430,33 @@ class PeerConnectionOut implements Runnable
return total;
}
/** @since 0.8.2 */
void sendPiece(int piece, int begin, int length, DataLoader loader)
{
boolean sendNow = false;
// are there any cases where we should?
if (sendNow) {
// queue the real thing
byte[] bytes = loader.loadData(piece, begin, length);
if (bytes != null)
sendPiece(piece, begin, length, bytes);
return;
}
// queue a fake message... set everything up,
// except save the PeerState instead of the bytes.
Message m = new Message();
m.type = Message.PIECE;
m.piece = piece;
m.begin = begin;
m.length = length;
m.dataLoader = loader;
m.off = 0;
m.len = length;
addMessage(m);
}
void sendPiece(int piece, int begin, int length, byte[] bytes)
{
Message m = new Message();
@@ -488,4 +515,16 @@ class PeerConnectionOut implements Runnable
}
}
}
/** @since 0.8.2 */
void sendExtension(int id, byte[] bytes) {
Message m = new Message();
m.type = Message.EXTENSION;
m.piece = id;
m.data = bytes;
m.begin = 0;
m.length = bytes.length;
addMessage(m);
}
}

View File

@@ -20,14 +20,20 @@
package org.klomp.snark;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.i2p.I2PAppContext;
import net.i2p.util.Log;
class PeerState
import org.klomp.snark.bencode.BDecoder;
import org.klomp.snark.bencode.BEValue;
class PeerState implements DataLoader
{
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(PeerState.class);
final Peer peer;
@@ -201,13 +207,28 @@ class PeerState
return;
}
if (_log.shouldLog(Log.INFO))
_log.info("Queueing (" + piece + ", " + begin + ", "
+ length + ")" + " to " + peer);
// don't load the data into mem now, let PeerConnectionOut do it
out.sendPiece(piece, begin, length, this);
}
/**
* This is the callback that PeerConnectionOut calls
*
* @return bytes or null for errors
* @since 0.8.2
*/
public byte[] loadData(int piece, int begin, int length) {
byte[] pieceBytes = listener.gotRequest(peer, piece, begin, length);
if (pieceBytes == null)
{
// XXX - Protocol error-> diconnect?
if (_log.shouldLog(Log.WARN))
_log.warn("Got request for unknown piece: " + piece);
return;
return null;
}
// More sanity checks
@@ -219,13 +240,13 @@ class PeerState
+ ", " + begin
+ ", " + length
+ "' message from " + peer);
return;
return null;
}
if (_log.shouldLog(Log.INFO))
_log.info("Sending (" + piece + ", " + begin + ", "
+ length + ")" + " to " + peer);
out.sendPiece(piece, begin, length, pieceBytes);
return pieceBytes;
}
/**
@@ -413,6 +434,24 @@ class PeerState
out.cancelRequest(piece, begin, length);
}
/** @since 0.8.2 */
void extensionMessage(int id, byte[] bs)
{
if (id == 0) {
InputStream is = new ByteArrayInputStream(bs);
try {
BDecoder dec = new BDecoder(is);
BEValue bev = dec.bdecodeMap();
Map map = bev.getMap();
if (_log.shouldLog(Log.DEBUG))
_log.debug("Got extension handshake message " + bev.toString());
} catch (Exception e) {}
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Got extended message type: " + id + " length: " + bs.length);
}
}
void unknownMessage(int type, byte[] bs)
{
if (_log.shouldLog(Log.WARN))

View File

@@ -242,6 +242,13 @@ public class I2PSnarkServlet extends Default {
List snarks = getSortedSnarks(req);
String uri = req.getRequestURI();
boolean isForm = _manager.util().connected() || !snarks.isEmpty();
if (isForm) {
out.write("<form action=\"");
out.write(uri);
out.write("\" method=\"POST\">\n");
out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n");
}
out.write(TABLE_HEADER);
out.write("<img border=\"0\" src=\"/themes/snark/ubergine/images/status.png\"");
out.write(" title=\"");
@@ -301,25 +308,17 @@ public class I2PSnarkServlet extends Default {
out.write("</th>\n");
out.write("<th align=\"center\">");
if (_manager.util().connected()) {
out.write("<a href=\"" + uri + "?action=StopAll&nonce=" + _nonce +
"\" title=\"");
out.write("<input type=\"image\" name=\"action\" value=\"StopAll\" title=\"");
out.write(_("Stop all torrents and the I2P tunnel"));
out.write("\">");
out.write("<img src=\"/themes/snark/ubergine/images/stop_all.png\" title=\"");
out.write(_("Stop all torrents and the I2P tunnel"));
out.write("\" alt=\"");
out.write("\" src=\"/themes/snark/ubergine/images/stop_all.png\" alt=\"");
out.write(_("Stop All"));
out.write("\">");
out.write("</a>");
} else if (!snarks.isEmpty()) {
out.write("<a href=\"" + uri + "?action=StartAll&nonce=" + _nonce +
"\" title=\"");
out.write("<input type=\"image\" name=\"action\" value=\"StartAll\" title=\"");
out.write(_("Start all torrents and the I2P tunnel"));
out.write("\" src=\"/themes/snark/ubergine/images/start_all.png\" alt=\"");
out.write(_("Start All"));
out.write("\">");
out.write("<img src=\"/themes/snark/ubergine/images/start_all.png\" title=\"");
out.write(_("Start all torrents and the I2P tunnel"));
out.write("\" alt=\"Start All\">");
out.write("</a>");
} else {
out.write("&nbsp;");
}
@@ -357,6 +356,8 @@ public class I2PSnarkServlet extends Default {
}
out.write("</table>");
if (isForm)
out.write("</form>\n");
}
/**
@@ -366,7 +367,11 @@ public class I2PSnarkServlet extends Default {
String action = req.getParameter("action");
if (action == null) {
// noop
} else if ("Add".equals(action)) {
return;
}
if (!"POST".equals(req.getMethod()))
return;
if ("Add".equals(action)) {
String newFile = req.getParameter("newFile");
String newURL = req.getParameter("newURL");
// NOTE - newFile currently disabled in HTML form - see below
@@ -410,8 +415,8 @@ public class I2PSnarkServlet extends Default {
} else {
// no file or URL specified
}
} else if ("Stop".equals(action)) {
String torrent = req.getParameter("torrent");
} else if (action.startsWith("Stop_")) {
String torrent = action.substring(5);
if (torrent != null) {
byte infoHash[] = Base64.decode(torrent);
if ( (infoHash != null) && (infoHash.length == 20) ) { // valid sha1
@@ -425,8 +430,8 @@ public class I2PSnarkServlet extends Default {
}
}
}
} else if ("Start".equals(action)) {
String torrent = req.getParameter("torrent");
} else if (action.startsWith("Start_")) {
String torrent = action.substring(6);
if (torrent != null) {
byte infoHash[] = Base64.decode(torrent);
if ( (infoHash != null) && (infoHash.length == 20) ) { // valid sha1
@@ -441,8 +446,8 @@ public class I2PSnarkServlet extends Default {
}
}
}
} else if ("Remove".equals(action)) {
String torrent = req.getParameter("torrent");
} else if (action.startsWith("Remove_")) {
String torrent = action.substring(7);
if (torrent != null) {
byte infoHash[] = Base64.decode(torrent);
if ( (infoHash != null) && (infoHash.length == 20) ) { // valid sha1
@@ -461,8 +466,8 @@ public class I2PSnarkServlet extends Default {
}
}
}
} else if ("Delete".equals(action)) {
String torrent = req.getParameter("torrent");
} else if (action.startsWith("Delete_")) {
String torrent = action.substring(7);
if (torrent != null) {
byte infoHash[] = Base64.decode(torrent);
if ( (infoHash != null) && (infoHash.length == 20) ) { // valid sha1
@@ -618,10 +623,10 @@ public class I2PSnarkServlet extends Default {
if (r.startsWith(skip))
r = r.substring(skip.length());
String llc = l.toLowerCase();
if (llc.startsWith("the ") || llc.startsWith("the."))
if (llc.startsWith("the ") || llc.startsWith("the.") || llc.startsWith("the_"))
l = l.substring(4);
String rlc = r.toLowerCase();
if (rlc.startsWith("the ") || rlc.startsWith("the."))
if (rlc.startsWith("the ") || rlc.startsWith("the.") || rlc.startsWith("the_"))
r = r.substring(4);
return collator.compare(l, r);
}
@@ -828,62 +833,55 @@ public class I2PSnarkServlet extends Default {
out.write("</td>\n\t");
out.write("<td align=\"center\" class=\"snarkTorrentAction " + rowClass + "\">");
String parameters = "&nonce=" + _nonce + "&torrent=" + Base64.encode(snark.meta.getInfoHash());
String b64 = Base64.encode(snark.meta.getInfoHash());
if (showPeers)
parameters = parameters + "&p=1";
if (isRunning) {
out.write("<a href=\"" + uri + "?action=Stop" + parameters
+ "\" title=\"");
out.write("<input type=\"image\" name=\"action\" value=\"Stop_");
out.write(b64);
out.write("\" title=\"");
out.write(_("Stop the torrent"));
out.write("\">");
out.write("<img src=\"/themes/snark/ubergine/images/stop.png\" title=\"");
out.write(_("Stop the torrent"));
out.write("\" alt=\"");
out.write("\" src=\"/themes/snark/ubergine/images/stop.png\" alt=\"");
out.write(_("Stop"));
out.write("\">");
out.write("</a>");
} else {
if (isValid) {
out.write("<a href=\"" + uri + "?action=Start" + parameters
+ "\" title=\"");
out.write("<input type=\"image\" name=\"action\" value=\"Start_");
out.write(b64);
out.write("\" title=\"");
out.write(_("Start the torrent"));
out.write("\">");
out.write("<img src=\"/themes/snark/ubergine/images/start.png\" title=\"");
out.write(_("Start the torrent"));
out.write("\" alt=\"");
out.write("\" src=\"/themes/snark/ubergine/images/start.png\" alt=\"");
out.write(_("Start"));
out.write("\">");
out.write("</a>");
}
out.write("<a href=\"" + uri + "?action=Remove" + parameters
+ "\" title=\"");
out.write("<input type=\"image\" name=\"action\" value=\"Remove_");
out.write(b64);
out.write("\" title=\"");
out.write(_("Remove the torrent from the active list, deleting the .torrent file"));
out.write("\" onclick=\"if (!confirm('");
// 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
out.write(_("Are you sure you want to delete the file \\''{0}.torrent\\'' (downloaded data will not be deleted) ?", fullFilename));
out.write("')) { return false; }\">");
out.write("<img src=\"/themes/snark/ubergine/images/remove.png\" title=\"");
out.write(_("Remove the torrent from the active list, deleting the .torrent file"));
out.write("\" alt=\"");
out.write("')) { return false; }\"");
out.write(" src=\"/themes/snark/ubergine/images/remove.png\" alt=\"");
out.write(_("Remove"));
out.write("\">");
out.write("</a>");
out.write("<a href=\"" + uri + "?action=Delete" + parameters
+ "\" title=\"");
out.write("<input type=\"image\" name=\"action\" value=\"Delete_");
out.write(b64);
out.write("\" title=\"");
out.write(_("Delete the .torrent file and the associated data file(s)"));
out.write("\" onclick=\"if (!confirm('");
// 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
out.write(_("Are you sure you want to delete the torrent \\''{0}\\'' and all downloaded data?", fullFilename));
out.write("')) { return false; }\">");
out.write("<img src=\"/themes/snark/ubergine/images/delete.png\" title=\"");
out.write(_("Delete the .torrent file and the associated data file(s)"));
out.write("\" alt=\"");
out.write("')) { return false; }\"");
out.write(" src=\"/themes/snark/ubergine/images/delete.png\" alt=\"");
out.write(_("Delete"));
out.write("\">");
out.write("</a>");
}
out.write("</td>\n</tr>\n");

View File

@@ -36,7 +36,7 @@ public class ConfigPeerHandler extends FormHandler {
return;
}
addFormError(_("Invalid peer"));
} else if (_action.equals(_("Adjust Profile Bonuses"))) {
} else if (_action.equals(_("Adjust peer bonuses"))) {
Hash h = getHash();
if (h != null) {
PeerProfile prof = _context.profileOrganizer().getProfile(h);
@@ -59,6 +59,8 @@ public class ConfigPeerHandler extends FormHandler {
addFormError(_("Invalid peer"));
} else if (_action.startsWith("Check")) {
addFormError(_("Unsupported"));
} else {
addFormError("Unknown action \"" + _action + '"');
}
}

View File

@@ -20,26 +20,23 @@ public class FormHandler {
protected Log _log;
private String _nonce;
protected String _action;
protected String _method;
protected String _passphrase;
private List<String> _errors;
private List<String> _notices;
private final List<String> _errors;
private final List<String> _notices;
private boolean _processed;
private boolean _valid;
public FormHandler() {
_errors = new ArrayList();
_notices = new ArrayList();
_action = null;
_processed = false;
_valid = true;
_nonce = null;
_passphrase = null;
}
/**
* Configure this bean to query a particular router context
*
* @param contextId begging few characters of the routerHash, or null to pick
* @param contextId beginning few characters of the routerHash, or null to pick
* the first one we come across.
*/
public void setContextId(String contextId) {
@@ -54,6 +51,14 @@ public class FormHandler {
public void setNonce(String val) { _nonce = val; }
public void setAction(String val) { _action = val; }
public void setPassphrase(String val) { _passphrase = val; }
/**
* Call this to prevent changes using GET
*
* @param the request method
* @since 0.8.2
*/
public void storeMethod(String val) { _method = val; }
/**
* Override this to perform the final processing (in turn, adding formNotice
@@ -145,6 +150,12 @@ public class FormHandler {
_valid = false;
return;
}
// To prevent actions with GET, jsps must call storeMethod()
if (_method != null && !"POST".equals(_method)) {
addFormError("Invalid form submission, requires POST not " + _method);
_valid = false;
return;
}
String sharedNonce = System.getProperty("router.consoleNonce");
if ( (sharedNonce != null) && (sharedNonce.equals(_nonce) ) ) {
@@ -211,4 +222,8 @@ public class FormHandler {
return Messages.getString(s, o, _context);
}
/** two params @since 0.8.2 */
public String _(String s, Object o, Object o2) {
return Messages.getString(s, o, o2, _context);
}
}

View File

@@ -1,6 +1,7 @@
package net.i2p.router.web;
import java.io.IOException;
import java.io.Writer;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
@@ -9,7 +10,8 @@ import java.util.TreeSet;
import net.i2p.data.DataHelper;
import net.i2p.stat.Rate;
public class GraphHelper extends HelperBase {
public class GraphHelper extends FormHandler {
protected Writer _out;
private int _periodCount;
private boolean _showEvents;
private int _width;
@@ -29,9 +31,6 @@ public class GraphHelper extends HelperBase {
static final int MAX_Y = 1024;
private static final int MIN_REFRESH = 15;
public GraphHelper() {
}
/** set the defaults after we have a context */
@Override
public void setContextId(String contextId) {
@@ -43,6 +42,12 @@ public class GraphHelper extends HelperBase {
_showEvents = Boolean.valueOf(_context.getProperty(PROP_EVENTS)).booleanValue();
}
/**
* This was a HelperBase but now it's a FormHandler
* @since 0.8.2
*/
public void storeWriter(Writer out) { _out = out; }
public void setPeriodCount(String str) {
try { _periodCount = Integer.parseInt(str); } catch (NumberFormatException nfe) {}
}
@@ -125,10 +130,15 @@ public class GraphHelper extends HelperBase {
}
public String getForm() {
saveSettings();
String prev = System.getProperty("net.i2p.router.web.GraphHelper.nonce");
if (prev != null) System.setProperty("net.i2p.router.web.GraphHelper.noncePrev", prev);
String nonce = "" + _context.random().nextLong();
System.setProperty("net.i2p.router.web.GraphHelper.nonce", nonce);
try {
_out.write("<br><h3>" + _("Configure Graph Display") + " [<a href=\"configstats\">" + _("Select Stats") + "</a>]</h3>");
_out.write("<form action=\"graphs\" method=\"POST\">");
_out.write("<form action=\"graphs\" method=\"POST\">\n" +
"<input type=\"hidden\" name=\"action\" value=\"foo\">\n" +
"<input type=\"hidden\" name=\"nonce\" value=\"" + nonce + "\" >\n");
_out.write(_("Periods") + ": <input size=\"3\" type=\"text\" name=\"periodCount\" value=\"" + _periodCount + "\"><br>\n");
_out.write(_("Plot averages") + ": <input type=\"radio\" class=\"optbox\" name=\"showEvents\" value=\"false\" " + (_showEvents ? "" : "checked=\"true\" ") + "> ");
_out.write(_("or")+ " " +_("plot events") + ": <input type=\"radio\" class=\"optbox\" name=\"showEvents\" value=\"true\" "+ (_showEvents ? "checked=\"true\" " : "") + "><br>\n");
@@ -143,6 +153,15 @@ public class GraphHelper extends HelperBase {
return "";
}
/**
* This was a HelperBase but now it's a FormHandler
* @since 0.8.2
*/
@Override
protected void processForm() {
saveSettings();
}
/**
* Silently save settings if changed, no indication of success or failure
* @since 0.7.10
@@ -159,6 +178,7 @@ public class GraphHelper extends HelperBase {
_context.router().setConfigSetting(PROP_REFRESH, "" + _refreshDelaySeconds);
_context.router().setConfigSetting(PROP_EVENTS, "" + _showEvents);
_context.router().saveConfig();
addFormNotice(_("Graph settings saved"));
}
}

View File

@@ -28,7 +28,13 @@ public abstract class HelperBase {
/** might be useful in the jsp's */
//public RouterContext getContext() { return _context; }
public void setWriter(Writer out) { _out = out; }
/**
* Renamed from setWriter, we realy don't want setFoo(non-String)
* Prevent jsp.error.beans.property.conversion 500 error for ?writer=foo
* @since 0.8.2
*/
public void storeWriter(Writer out) { _out = out; }
/** translate a string */
public String _(String s) {

View File

@@ -16,6 +16,7 @@
<%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigNetHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />

View File

@@ -18,6 +18,7 @@
<%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigAdvancedHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />

View File

@@ -21,6 +21,7 @@ button span.hide{
<%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigClientsHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %>
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:setProperty name="formhandler" property="action" value="<%=request.getParameter("action")%>" />
<jsp:setProperty name="formhandler" property="nonce" value="<%=request.getParameter("nonce")%>" />

View File

@@ -13,6 +13,7 @@
<%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigKeyringHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />

View File

@@ -15,6 +15,7 @@
<%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigLoggingHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />

View File

@@ -5,7 +5,7 @@
%>
<jsp:useBean class="net.i2p.router.web.ConfigNavHelper" id="navHelper" scope="request" />
<jsp:setProperty name="navHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:setProperty name="navHelper" property="writer" value="<%=out%>" />
<% navHelper.storeWriter(out); %>
<div class="confignav" id="confignav">
<center>
<%

View File

@@ -13,6 +13,7 @@
<%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigPeerHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />
@@ -27,7 +28,7 @@
peer = net.i2p.data.DataHelper.stripHTML(request.getParameter("peer")); // XSS
%>
<div class="configure">
<form action="" method="POST">
<form action="configpeer" method="POST">
<% String prev = System.getProperty("net.i2p.router.web.ConfigPeerHandler.nonce");
if (prev != null) System.setProperty("net.i2p.router.web.ConfigPeerHandler.noncePrev", prev);
System.setProperty("net.i2p.router.web.ConfigPeerHandler.nonce", new java.util.Random().nextLong()+""); %>
@@ -64,7 +65,7 @@
<a name="shitlist"> </a><h2><%=intl._("Banned Peers")%></h2>
<jsp:useBean class="net.i2p.router.web.ProfilesHelper" id="profilesHelper" scope="request" />
<jsp:setProperty name="profilesHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:setProperty name="profilesHelper" property="writer" value="<%=out%>" />
<% profilesHelper.storeWriter(out); %>
<jsp:getProperty name="profilesHelper" property="shitlistSummary" />
<div class="wideload"><h2><%=intl._("Banned IPs")%></h2>
<jsp:getProperty name="peerhelper" property="blocklistSummary" />

View File

@@ -13,6 +13,7 @@
<%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigServiceHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />

View File

@@ -58,8 +58,9 @@ function toggleAll(category)
<%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigStatsHandler" id="formhandler" scope="request" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<% formhandler.storeMethod(request.getMethod()); %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />
<jsp:useBean class="net.i2p.router.web.ConfigStatsHelper" id="statshelper" scope="request" />

View File

@@ -15,6 +15,7 @@
<div class="main" id="main">
<%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigTunnelsHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %>
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:setProperty name="formhandler" property="shouldsave" value="<%=request.getParameter("shouldsave")%>" />
<jsp:setProperty name="formhandler" property="action" value="<%=request.getParameter("action")%>" />

View File

@@ -18,6 +18,7 @@
<%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigUIHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />

View File

@@ -13,6 +13,7 @@
<%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigUpdateHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />

View File

@@ -1,5 +1,5 @@
<%@page contentType="text/plain"
%><jsp:useBean id="helper" class="net.i2p.router.web.StatHelper"
/><jsp:setProperty name="helper" property="peer" value="<%=request.getParameter("peer")%>"
/><jsp:setProperty name="helper" property="writer" value="<%=out%>"
/><jsp:getProperty name="helper" property="profile" />
/><% helper.storeWriter(out);
%><jsp:getProperty name="helper" property="profile" />

View File

@@ -13,9 +13,12 @@
<div class="graphspanel">
<div class="widepanel">
<jsp:useBean class="net.i2p.router.web.GraphHelper" id="graphHelper" scope="request" />
<% graphHelper.storeMethod(request.getMethod()); %>
<jsp:setProperty name="graphHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<% /* GraphHelper sets the defaults in setContextId, so setting the properties must be after the context */ %>
<jsp:setProperty name="graphHelper" property="*" />
<jsp:setProperty name="graphHelper" property="writer" value="<%=out%>" />
<% graphHelper.storeWriter(out); %>
<jsp:getProperty name="graphHelper" property="allMessages" />
<jsp:getProperty name="graphHelper" property="images" />
<jsp:getProperty name="graphHelper" property="form" />
</div></div></div></body></html>

View File

@@ -3,6 +3,6 @@
<meta http-equiv="pragma" content="no-cache" />
</head>
<body>
The I2PSnark Anonymous BitTorrent Client is not running. Please visit the <a href="/configclients.jsp">config clients page</a>
The I2PSnark Anonymous BitTorrent Client is not running. Please visit the <a href="/configclients#webapp">config clients page</a>
to start it.
</body></html>

View File

@@ -3,5 +3,5 @@
<meta http-equiv="pragma" content="no-cache" />
</head>
<body>
The I2P Tunnel Manager is not currently running. Please visit the <a href="/configclients.jsp">Client Configuration</a> page to start it.
The I2P Tunnel Manager is not currently running. Please visit the <a href="/configclients#webapp">Client Configuration</a> page to start it.
</body></html>

View File

@@ -10,6 +10,6 @@
<div class="main" id="main">
<jsp:useBean class="net.i2p.router.web.JobQueueHelper" id="jobQueueHelper" scope="request" />
<jsp:setProperty name="jobQueueHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:setProperty name="jobQueueHelper" property="writer" value="<%=out%>" />
<% jobQueueHelper.storeWriter(out); %>
<jsp:getProperty name="jobQueueHelper" property="jobQueueSummary" />
<hr></div></body></html>

View File

@@ -10,7 +10,8 @@
<h1><%=intl._("I2P Router Logs")%></h1>
<div class="main" id="main">
<div class="joblog"><h3><%=intl._("I2P Version & Running Environment")%></h3><a name="version"> </a>
<p><%=intl._("Please report bugs on <a href=\"http://trac.i2p2.i2p/newticket\">trac.i2p2.i2p</a>.")%>
<p><%=intl._("Please report bugs on <a href=\"http://trac.i2p2.i2p/newticket\">trac.i2p2.i2p</a> or <a href=\"http://trac.i2p2.de/newticket\">trac.i2p2.de</a>.")%>
<%=intl._("You may use the username \"guest\" and password \"guest\" if you do not wish to register.")%>
<p><i><%=intl._("Please include this information in bug reports")%>:</i>
<p>
<b>I2P version:</b> <jsp:getProperty name="helper" property="version" /><br>

View File

@@ -12,7 +12,7 @@
<div class="wideload">
<jsp:useBean class="net.i2p.router.web.NetDbHelper" id="netdbHelper" scope="request" />
<jsp:setProperty name="netdbHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:setProperty name="netdbHelper" property="writer" value="<%=out%>" />
<% netdbHelper.storeWriter(out); %>
<jsp:setProperty name="netdbHelper" property="full" value="<%=request.getParameter("f")%>" />
<jsp:setProperty name="netdbHelper" property="router" value="<%=request.getParameter("r")%>" />
<jsp:setProperty name="netdbHelper" property="lease" value="<%=request.getParameter("l")%>" />

View File

@@ -12,7 +12,7 @@
<%@include file="summary.jsi" %>
<jsp:useBean class="net.i2p.router.web.OldConsoleHelper" id="conhelper" scope="request" />
<jsp:setProperty name="conhelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:setProperty name="conhelper" property="writer" value="<%=out%>" />
<% conhelper.storeWriter(out); %>
<h1>I2P Router &raquo; Old Console</h1>
<div class="main" id="main">
<jsp:getProperty name="conhelper" property="console" />

View File

@@ -11,7 +11,7 @@
<div class="main" id="main"><div class="wideload">
<jsp:useBean class="net.i2p.router.web.PeerHelper" id="peerHelper" scope="request" />
<jsp:setProperty name="peerHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:setProperty name="peerHelper" property="writer" value="<%=out%>" />
<% peerHelper.storeWriter(out); %>
<jsp:setProperty name="peerHelper" property="urlBase" value="peers.jsp" />
<jsp:setProperty name="peerHelper" property="sort" value="<%=request.getParameter("sort") != null ? request.getParameter("sort") : ""%>" />
<jsp:getProperty name="peerHelper" property="peerSummary" />

View File

@@ -10,7 +10,7 @@
<div class="main" id="main"><div class="wideload">
<jsp:useBean class="net.i2p.router.web.ProfilesHelper" id="profilesHelper" scope="request" />
<jsp:setProperty name="profilesHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:setProperty name="profilesHelper" property="writer" value="<%=out%>" />
<% profilesHelper.storeWriter(out); %>
<jsp:setProperty name="profilesHelper" property="full" value="<%=request.getParameter("f")%>" />
<jsp:getProperty name="profilesHelper" property="profileSummary" />
<a name="shitlist"> </a><h2><%=intl._("Banned Peers")%></h2>

View File

@@ -9,7 +9,7 @@
<%@include file="summary.jsi" %>
<jsp:useBean class="net.i2p.router.web.OldConsoleHelper" id="oldhelper" scope="request" />
<jsp:setProperty name="oldhelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:setProperty name="oldhelper" property="writer" value="<%=out%>" />
<% oldhelper.storeWriter(out); %>
<jsp:setProperty name="oldhelper" property="full" value="<%=request.getParameter("f")%>" />
<h1><%=intl._("I2P Router Statistics")%></h1>
<div class="main" id="main">

View File

@@ -11,7 +11,7 @@
<jsp:setProperty name="helper" property="updateNonce" value="<%=request.getParameter("updateNonce")%>" />
<jsp:setProperty name="helper" property="consoleNonce" value="<%=request.getParameter("consoleNonce")%>" />
<jsp:setProperty name="helper" property="requestURI" value="<%=request.getRequestURI()%>" />
<jsp:setProperty name="helper" property="writer" value="<%=out%>" />
<% helper.storeWriter(out); %>
<%
/*
* The following is required for the reseed button to work, although we probably

View File

@@ -3,6 +3,6 @@
<meta http-equiv="pragma" content="no-cache" />
</head>
<body>
SusiDNS is not running. Go to <a href="/configclients.jsp">the config clients page</a>
SusiDNS is not running. Go to <a href="/configclients#webapp">the config clients page</a>
to start it.
</body></html>

View File

@@ -3,6 +3,6 @@
<meta http-equiv="pragma" content="no-cache" />
</head>
<body>
SusiMail is not running. Go to <a href="/configclients.jsp">the config clients page</a>
SusiMail is not running. Go to <a href="/configclients#webapp">the config clients page</a>
to start it.
</body></html>

View File

@@ -10,6 +10,6 @@
<div class="main" id="main">
<jsp:useBean class="net.i2p.router.web.TunnelHelper" id="tunnelHelper" scope="request" />
<jsp:setProperty name="tunnelHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:setProperty name="tunnelHelper" property="writer" value="<%=out%>" />
<% tunnelHelper.storeWriter(out); %>
<jsp:getProperty name="tunnelHelper" property="tunnelSummary" />
</div></body></html>

View File

@@ -98,6 +98,7 @@ public class Connection {
_log = _context.logManager().getLog(Connection.class);
_receiver = new ConnectionDataReceiver(_context, this);
_inputStream = new MessageInputStream(_context);
// FIXME pass through a passive flush delay setting as the 4th arg
_outputStream = new MessageOutputStream(_context, _receiver, (opts == null ? Packet.MAX_PAYLOAD_SIZE : opts.getMaxMessageSize()));
_outboundPackets = new TreeMap();
_options = (opts != null ? opts : new ConnectionOptions());