diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index 7c9d101214838a4549684b83d95ef78bcd0e9652..a570de2d06a28cc6e3a67fcbf8e29de0f747b90a 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -329,14 +329,18 @@ public class I2PSnarkServlet extends Default { // Opera and text-mode browsers: no   and no input type=image values submitted String ua = req.getHeader("User-Agent"); - boolean isDegraded = ua != null && (ua.startsWith("Opera") || ua.startsWith("Lynx") || + boolean isDegraded = ua != null && (ua.startsWith("Lynx") || ua.startsWith("ELinks") || ua.startsWith("Dillo")); + boolean noThinsp = isDegraded || ua.startsWith("Opera"); if (_manager.util().connected()) { if (isDegraded) out.write("<a href=\"/i2psnark/?action=StopAll&nonce=" + _nonce + "\"><img title=\""); - else - out.write("<input type=\"image\" name=\"action\" value=\"StopAll\" title=\""); + else { + // http://www.onenaught.com/posts/382/firefox-4-change-input-type-image-only-submits-x-and-y-not-name + //out.write("<input type=\"image\" name=\"action\" value=\"StopAll\" title=\""); + out.write("<input type=\"image\" name=\"action_StopAll\" value=\"foo\" title=\""); + } out.write(_("Stop all torrents and the I2P tunnel")); out.write("\" src=\"" + _imgPath + "stop_all.png\" alt=\""); out.write(_("Stop All")); @@ -347,7 +351,7 @@ public class I2PSnarkServlet extends Default { if (isDegraded) out.write("<a href=\"/i2psnark/?action=StartAll&nonce=" + _nonce + "\"><img title=\""); else - out.write("<input type=\"image\" name=\"action\" value=\"StartAll\" title=\""); + out.write("<input type=\"image\" name=\"action_StartAll\" value=\"foo\" title=\""); out.write(_("Start all torrents and the I2P tunnel")); out.write("\" src=\"" + _imgPath + "start_all.png\" alt=\""); out.write(_("Start All")); @@ -362,7 +366,7 @@ public class I2PSnarkServlet extends Default { Snark snark = (Snark)snarks.get(i); boolean showDebug = "2".equals(peerParam); boolean showPeers = showDebug || "1".equals(peerParam) || Base64.encode(snark.meta.getInfoHash()).equals(peerParam); - displaySnark(out, snark, uri, i, stats, showPeers, isDegraded, showDebug); + displaySnark(out, snark, uri, i, stats, showPeers, isDegraded, noThinsp, showDebug); } if (snarks.isEmpty()) { @@ -404,8 +408,19 @@ public class I2PSnarkServlet extends Default { private void processRequest(HttpServletRequest req) { String action = req.getParameter("action"); if (action == null) { - _manager.addMessage("No action specified"); - return; + // http://www.onenaught.com/posts/382/firefox-4-change-input-type-image-only-submits-x-and-y-not-name + Map params = req.getParameterMap(); + for (Object o : params.keySet()) { + String key = (String) o; + if (key.startsWith("action_") && key.endsWith(".x")) { + action = key.substring(0, key.length() - 2).substring(7); + break; + } + } + if (action == null) { + _manager.addMessage("No action specified"); + return; + } } // sadly, Opera doesn't send value with input type=image, so we have to use GET there //if (!"POST".equals(req.getMethod())) { @@ -698,7 +713,7 @@ public class I2PSnarkServlet extends Default { private static final int MAX_DISPLAYED_FILENAME_LENGTH = 50; private static final int MAX_DISPLAYED_ERROR_LENGTH = 43; private void displaySnark(PrintWriter out, Snark snark, String uri, int row, long stats[], boolean showPeers, - boolean isDegraded, boolean showDebug) throws IOException { + boolean isDegraded, boolean noThinsp, boolean showDebug) throws IOException { String filename = snark.torrent; File f = new File(filename); filename = f.getName(); // the torrent may be the canonical name, so lets just grab the local name @@ -758,11 +773,11 @@ public class I2PSnarkServlet extends Default { if (isRunning && curPeers > 0 && !showPeers) statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "trackererror.png\" title=\"" + err + "\"></td><td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Tracker Error") + ": <a href=\"" + uri + "?p=" + Base64.encode(snark.meta.getInfoHash()) + "\">" + - curPeers + thinsp(isDegraded) + + curPeers + thinsp(noThinsp) + ngettext("1 peer", "{0} peers", knownPeers) + "</a>"; else if (isRunning) statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "trackererror.png\" title=\"" + err + "\"></td><td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Tracker Error") + - ": " + curPeers + thinsp(isDegraded) + + ": " + curPeers + thinsp(noThinsp) + ngettext("1 peer", "{0} peers", knownPeers); else { if (err.length() > MAX_DISPLAYED_ERROR_LENGTH) @@ -774,11 +789,11 @@ public class I2PSnarkServlet extends Default { if (isRunning && curPeers > 0 && !showPeers) statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "seeding.png\" ></td><td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Seeding") + ": <a href=\"" + uri + "?p=" + Base64.encode(snark.meta.getInfoHash()) + "\">" + - curPeers + thinsp(isDegraded) + + curPeers + thinsp(noThinsp) + ngettext("1 peer", "{0} peers", knownPeers) + "</a>"; else if (isRunning) statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "seeding.png\" ></td><td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Seeding") + - ": " + curPeers + thinsp(isDegraded) + + ": " + curPeers + thinsp(noThinsp) + ngettext("1 peer", "{0} peers", knownPeers); else statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "complete.png\" ></td><td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Complete"); @@ -786,24 +801,24 @@ public class I2PSnarkServlet extends Default { if (isRunning && curPeers > 0 && downBps > 0 && !showPeers) statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "downloading.png\" ></td><td class=\"snarkTorrentStatus " + rowClass + "\">" + _("OK") + ": <a href=\"" + uri + "?p=" + Base64.encode(snark.meta.getInfoHash()) + "\">" + - curPeers + thinsp(isDegraded) + + curPeers + thinsp(noThinsp) + ngettext("1 peer", "{0} peers", knownPeers) + "</a>"; else if (isRunning && curPeers > 0 && downBps > 0) statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "downloading.png\" ></td><td class=\"snarkTorrentStatus " + rowClass + "\">" + _("OK") + - ": " + curPeers + thinsp(isDegraded) + + ": " + curPeers + thinsp(noThinsp) + ngettext("1 peer", "{0} peers", knownPeers); else if (isRunning && curPeers > 0 && !showPeers) statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "stalled.png\" ></td><td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Stalled") + ": <a href=\"" + uri + "?p=" + Base64.encode(snark.meta.getInfoHash()) + "\">" + - curPeers + thinsp(isDegraded) + + curPeers + thinsp(noThinsp) + ngettext("1 peer", "{0} peers", knownPeers) + "</a>"; else if (isRunning && curPeers > 0) statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "stalled.png\" ></td><td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Stalled") + - ": " + curPeers + thinsp(isDegraded) + + ": " + curPeers + thinsp(noThinsp) + ngettext("1 peer", "{0} peers", knownPeers); else if (isRunning && knownPeers > 0) statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "nopeers.png\" ></td><td class=\"snarkTorrentStatus " + rowClass + "\">" + _("No Peers") + - ": 0" + thinsp(isDegraded) + knownPeers ; + ": 0" + thinsp(noThinsp) + knownPeers ; else if (isRunning) statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "nopeers.png\" ></td><td class=\"snarkTorrentStatus " + rowClass + "\">" + _("No Peers"); else @@ -880,7 +895,7 @@ public class I2PSnarkServlet extends Default { out.write("</td>\n\t"); out.write("<td align=\"right\" class=\"snarkTorrentDownloaded " + rowClass + "\">"); if (remaining > 0) - out.write(formatSize(total-remaining) + thinsp(isDegraded) + formatSize(total)); + out.write(formatSize(total-remaining) + thinsp(noThinsp) + formatSize(total)); else out.write(formatSize(total)); // 3GB out.write("</td>\n\t"); @@ -905,7 +920,7 @@ public class I2PSnarkServlet extends Default { if (isDegraded) out.write("<a href=\"/i2psnark/?action=Stop_" + b64 + "&nonce=" + _nonce + "\"><img title=\""); else - out.write("<input type=\"image\" name=\"action\" value=\"Stop_" + b64 + "\" title=\""); + out.write("<input type=\"image\" name=\"action_Stop_" + b64 + "\" value=\"foo\" title=\""); out.write(_("Stop the torrent")); out.write("\" src=\"" + _imgPath + "stop.png\" alt=\""); out.write(_("Stop")); @@ -917,7 +932,7 @@ public class I2PSnarkServlet extends Default { if (isDegraded) out.write("<a href=\"/i2psnark/?action=Start_" + b64 + "&nonce=" + _nonce + "\"><img title=\""); else - out.write("<input type=\"image\" name=\"action\" value=\"Start_" + b64 + "\" title=\""); + out.write("<input type=\"image\" name=\"action_Start_" + b64 + "\" value=\"foo\" title=\""); out.write(_("Start the torrent")); out.write("\" src=\"" + _imgPath + "start.png\" alt=\""); out.write(_("Start")); @@ -929,7 +944,7 @@ public class I2PSnarkServlet extends Default { if (isDegraded) out.write("<a href=\"/i2psnark/?action=Remove_" + b64 + "&nonce=" + _nonce + "\"><img title=\""); else - out.write("<input type=\"image\" name=\"action\" value=\"Remove_" + b64 + "\" title=\""); + out.write("<input type=\"image\" name=\"action_Remove_" + b64 + "\" value=\"foo\" 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. @@ -946,7 +961,7 @@ public class I2PSnarkServlet extends Default { if (isDegraded) out.write("<a href=\"/i2psnark/?action=Delete_" + b64 + "&nonce=" + _nonce + "\"><img title=\""); else - out.write("<input type=\"image\" name=\"action\" value=\"Delete_" + b64 + "\" title=\""); + out.write("<input type=\"image\" name=\"action_Delete_" + b64 + "\" value=\"foo\" 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. @@ -1384,7 +1399,7 @@ public class I2PSnarkServlet extends Default { private static String urlify(String s) { StringBuilder buf = new StringBuilder(256); // browsers seem to work without doing this but let's be strict - String link = s.replace("&", "&"); + String link = s.replace("&", "&").replace(" ", "%20"); buf.append("<a href=\"").append(link).append("\">").append(link).append("</a>"); return buf.toString(); }