forked from I2P_Developers/i2p.i2p
- Add details page in susidns
- Add source in Daemon - Honor list property in BFNS.lookup()
This commit is contained in:
@@ -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 +
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
30
apps/susidns/src/java/src/i2p/susi/dns/FormatDate.java
Normal file
30
apps/susidns/src/java/src/i2p/susi/dns/FormatDate.java
Normal 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));
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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>
|
||||
|
135
apps/susidns/src/jsp/details.jsp
Normal file
135
apps/susidns/src/jsp/details.jsp
Normal 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&filter=none&begin=0&end=99"><%=intl._("private")%></a> |
|
||||
<a href="addressbook.jsp?book=master&filter=none&begin=0&end=99"><%=intl._("master")%></a> |
|
||||
<a href="addressbook.jsp?book=router&filter=none&begin=0&end=99"><%=intl._("router")%></a> |
|
||||
<a href="addressbook.jsp?book=published&filter=none&begin=0&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} © <a href="${version.url}">susi</a> 2005</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user