- Add details page in susidns

- Add source in Daemon
- Honor list property in BFNS.lookup()
This commit is contained in:
zzz
2011-03-24 03:00:47 +00:00
parent d6999a3327
commit ca5484a984
7 changed files with 297 additions and 22 deletions

View File

@@ -115,6 +115,7 @@ public class Daemon {
// If it is a text file, we do things differently, to avoid O(n**2) behavior
// when scanning large subscription results (i.e. those that return the whole file, not just the new entries) -
// we load all the known hostnames into a Set one time.
// This also has the advantage of not flushing the NamingService's LRU cache.
String nsClass = router.getClass().getSimpleName();
boolean isTextFile = nsClass.equals("HostsTxtNamingService") || nsClass.equals("SingleFileNamingService");
Set<String> knownNames = null;
@@ -152,7 +153,9 @@ public class Daemon {
if (!isKnown) {
if (AddressBook.isValidKey(key)) {
Destination dest = new Destination(entry.getValue());
boolean success = router.put(key, dest);
Properties props = new Properties();
props.setProperty("s", sub.getLocation());
boolean success = router.put(key, dest, props);
if (log != null) {
if (success)
log.append("New address " + key +

View File

@@ -24,18 +24,18 @@
package i2p.susi.dns;
import java.util.Date;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.data.Base32;
import net.i2p.data.Base64;
import net.i2p.data.Certificate;
public class AddressBean
{
private String name, destination;
public AddressBean()
{
}
private final String name, destination;
private Properties props;
public AddressBean(String name, String destination)
{
@@ -48,21 +48,11 @@ public class AddressBean
return destination;
}
public void setDestination(String destination)
{
this.destination = destination;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
/** @since 0.8.6 */
public String getB32()
{
@@ -72,4 +62,88 @@ public class AddressBean
byte[] hash = I2PAppContext.getGlobalContext().sha().calculateHash(dest).getData();
return Base32.encode(hash) + ".b32.i2p";
}
/** @since 0.8.6 */
public void setProperties(Properties p) {
props = p;
}
/** @since 0.8.6 */
public String getSource() {
String rv = getProp("s");
if (rv.startsWith("http://"))
rv = "<a href=\"" + rv + "\">" + rv + "</a>";
return rv;
}
/** @since 0.8.6 */
public String getAdded() {
return getDate("a");
}
/** @since 0.8.6 */
public String getModded() {
return getDate("m");
}
/** @since 0.8.6 */
public String getNotes() {
return getProp("notes");
}
/**
* Do this the easy way
* @since 0.8.6
*/
public String getCert() {
// (4 / 3) * (pubkey length + signing key length)
String cert = destination.substring(512);
if (cert.equals("AAAA"))
return _("None");
byte[] enc = Base64.decode(cert);
if (enc == null)
// shouldn't happen
return "invalid";
int type = enc[0] & 0xff;
switch (type) {
case Certificate.CERTIFICATE_TYPE_HASHCASH:
return _("Hashcash");
case Certificate.CERTIFICATE_TYPE_HIDDEN:
return _("Hidden");
case Certificate.CERTIFICATE_TYPE_SIGNED:
return _("Signed");
default:
return _("Type {0}", type);
}
}
/** @since 0.8.6 */
private String getProp(String p) {
if (props == null)
return "";
String rv = props.getProperty(p);
return rv != null ? rv : "";
}
/** @since 0.8.6 */
private String getDate(String key) {
String d = getProp(key);
if (d.length() > 0) {
try {
d = FormatDate.format(Long.parseLong(d));
} catch (NumberFormatException nfe) {}
}
return d;
}
/** translate */
private static String _(String s) {
return Messages.getString(s);
}
/** translate */
private static String _(String s, Object o) {
return Messages.getString(s, o);
}
}

View File

@@ -0,0 +1,30 @@
package i2p.susi.dns;
import java.util.Date;
import java.text.DateFormat;
import java.util.TimeZone;
import net.i2p.I2PAppContext;
/**
* Format a date in local time zone
* @since 0.8.6
*/
public abstract class FormatDate
{
private static final DateFormat _dateFormat;
static {
DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
// the router sets the JVM time zone to UTC but saves the original here so we can get it
String systemTimeZone = I2PAppContext.getGlobalContext().getProperty("i2p.systemTimeZone");
if (systemTimeZone != null)
fmt.setTimeZone(TimeZone.getTimeZone(systemTimeZone));
_dateFormat = fmt;
}
public static String format(long date)
{
return _dateFormat.format(new Date(date));
}
}

View File

@@ -45,6 +45,7 @@ import net.i2p.data.Destination;
public class NamingServiceBean extends AddressbookBean
{
private static final String DEFAULT_NS = "BlockfileNamingService";
private String detail;
private boolean isDirect() {
return getBook().equals("published");
@@ -280,4 +281,22 @@ public class NamingServiceBean extends AddressbookBean
message = "<p class=\"messages\">" + message + "</p>";
return message;
}
public void setH(String h) {
this.detail = h;
}
public AddressBean getLookup() {
if (this.detail == null)
return null;
Properties nsOptions = new Properties();
Properties outProps = new Properties();
nsOptions.setProperty("list", getFileName());
Destination dest = getNamingService().lookup(this.detail, nsOptions, outProps);
if (dest == null)
return null;
AddressBean rv = new AddressBean(this.detail, dest.toBase64());
rv.setProperties(outProps);
return rv;
}
}

View File

@@ -153,7 +153,7 @@ ${book.loadBookMessages}
<td class="names"><a href="http://${addr.name}/">${addr.name}</a>
</td><td class="names">
<span class="addrhlpr">(<a href="http://${addr.b32}/">b32</a>)</span>
<span class="addrhlpr">(<a href="http://${addr.name}/?i2paddresshelper=${addr.destination}"><%=intl._("helper")%></a>)</span>
<span class="addrhlpr">(<a href="details.jsp?h=${addr.name}"><%=intl._("details")%></a>)</span>
</td>
<td class="destinations"><textarea rows="1" style="height: 3em;" cols="40" wrap="off" readonly="readonly" name="dest_${addr.name}" >${addr.destination}</textarea></td>
</tr>

View File

@@ -0,0 +1,135 @@
<%
/*
* Created on Sep 02, 2005
*
* This file is part of susidns project, see http://susi.i2p/
*
* Copyright (C) 2005 <susi23@mail.i2p>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Revision: 1.3 $
*/
// 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"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<jsp:useBean id="version" class="i2p.susi.dns.VersionBean" scope="application" />
<jsp:useBean id="book" class="i2p.susi.dns.NamingServiceBean" scope="session" />
<jsp:useBean id="intl" class="i2p.susi.dns.Messages" scope="application" />
<jsp:setProperty name="book" property="*" />
<jsp:setProperty name="book" property="resetDeletionMarks" value="1"/>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>${book.book} <%=intl._("addressbook")%> - susidns</title>
<link rel="stylesheet" type="text/css" href="css.css">
</head>
<body>
<div class="page">
<div id="logo">
<img src="images/logo.png" alt="susidns logo" border="0"/>
</div>
<hr>
<div id="navi">
<p>
<%=intl._("addressbooks")%>
<a href="addressbook.jsp?book=private&amp;filter=none&amp;begin=0&amp;end=99"><%=intl._("private")%></a> |
<a href="addressbook.jsp?book=master&amp;filter=none&amp;begin=0&amp;end=99"><%=intl._("master")%></a> |
<a href="addressbook.jsp?book=router&amp;filter=none&amp;begin=0&amp;end=99"><%=intl._("router")%></a> |
<a href="addressbook.jsp?book=published&amp;filter=none&amp;begin=0&amp;end=99"><%=intl._("published")%></a> *
<a href="subscriptions.jsp"><%=intl._("subscriptions")%></a> *
<a href="config.jsp"><%=intl._("configuration")%></a> *
<a href="index.jsp"><%=intl._("overview")%></a>
</p>
</div>
<hr>
<div id="headline">
<h3><%=intl._(book.getBook())%> <%=intl._("addressbook")%>: ${book.fileName}</h3>
</div>
<div id="book">
<%
String detail = request.getParameter("h");
if (detail == null) {
%><p>No host specified</p><%
} else {
i2p.susi.dns.AddressBean addr = book.getLookup();
if (addr == null) {
%><p>Not found: <%=detail%></p><%
} else {
String b32 = addr.getB32();
%>
<jsp:setProperty name="book" property="trClass" value="0" />
<table class="book" cellspacing="0" cellpadding="5">
<tr class="list${book.trClass}">
<td><%=intl._("Host Name")%></td>
<td><a href="http://<%=addr.getName()%>/"><%=addr.getName()%></a></td>
</tr><tr class="list${book.trClass}">
<td><%=intl._("Base 32 Address")%></td>
<td><a href="http://<%=b32%>/"><%=b32%></a></td>
</tr><tr class="list${book.trClass}">
<td><%=intl._("Address Helper")%></td>
<td><a href="http://<%=addr.getName()%>/?i2paddresshelper=<%=addr.getDestination()%>"><%=intl._("link")%></a></td>
</tr><tr class="list${book.trClass}">
<td><%=intl._("Public Key")%></td>
<td><%=intl._("ElGamal 2048 bit")%></td>
</tr><tr class="list${book.trClass}">
<td><%=intl._("Signing Key")%></td>
<td><%=intl._("DSA 1024 bit")%></td>
</tr><tr class="list${book.trClass}">
<td><%=intl._("Certificate")%></td>
<td><%=addr.getCert()%></td>
</tr><tr class="list${book.trClass}">
<td><%=intl._("Added Date")%></td>
<td><%=addr.getAdded()%></td>
</tr><tr class="list${book.trClass}">
<td><%=intl._("Source")%></td>
<td><%=addr.getSource()%></td>
</tr><tr class="list${book.trClass}">
<td><%=intl._("Last Modified")%></td>
<td><%=addr.getModded()%></td>
</tr><tr class="list${book.trClass}">
<td><%=intl._("Notes")%></td>
<td><%=addr.getNotes()%></td>
</tr><tr class="list${book.trClass}">
<td><%=intl._("Destination")%></td>
<td class="destinations"><textarea rows="1" style="height: 3em;" cols="70" wrap="off" readonly="readonly" ><%=addr.getDestination()%></textarea></td>
</tr></table>
</div>
<div id="buttons">
<form method="POST" action="details.jsp">
<input type="hidden" name="serial" value="${book.serial}">
<input type="hidden" name="h" value="<%=detail%>">
<input type="submit" name="action" value="<%=intl._("Delete")%>" >
</form>
</div>
<%
}
}
%>
<hr>
<div id="footer">
<p class="footer">susidns v${version.version} &copy; <a href="${version.url}">susi</a> 2005</p>
</div>
</div>
</body>
</html>

View File

@@ -347,17 +347,31 @@ public class BlockfileNamingService extends DummyNamingService {
////////// Start NamingService API
/*
* @param options If non-null and contains the key "list", lookup in
* that list only, otherwise all lists
*/
@Override
public Destination lookup(String hostname, Properties lookupOptions, Properties storedOptions) {
Destination d = super.lookup(hostname, null, null);
String listname = null;
if (lookupOptions != null)
listname = lookupOptions.getProperty("list");
Destination d = null;
// only use cache if we aren't retreiving options or specifying the list
if (listname == null && storedOptions == null) {
d = super.lookup(hostname, null, null);
if (d != null)
return d;
}
String key = hostname.toLowerCase();
synchronized(_bf) {
if (_isClosed)
return null;
for (String list : _lists) {
if (listname != null && !list.equals(listname))
continue;
try {
DestEntry de = getEntry(list, key);
if (de != null) {