fenfire-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ff-cvs] storm ./Makefile doc/dartboard/pointer_identiti...


From: Benja Fallenstein
Subject: [ff-cvs] storm ./Makefile doc/dartboard/pointer_identiti...
Date: Wed, 10 Sep 2003 09:20:28 -0400

CVSROOT:        /cvsroot/storm
Module name:    storm
Branch:         
Changes by:     Benja Fallenstein <address@hidden>      03/09/10 09:20:28

Modified files:
        .              : Makefile 
        doc/dartboard/pointer_identities--benja: idea.rst 
        org/nongnu/storm/pointers: PointerBlock.java PointerId.java 
                                   PointerIndex.java 
        org/nongnu/storm/util: CopyUtil.java HTTPProxy.java 
                               HtmlLinkIndex.java 

Log message:
        Implement backlinks and history and automatic compilation of RST

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/storm/storm/Makefile.diff?tr1=1.23&tr2=1.24&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/storm/storm/doc/dartboard/pointer_identities--benja/idea.rst.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/storm/storm/org/nongnu/storm/pointers/PointerBlock.java.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/storm/storm/org/nongnu/storm/pointers/PointerId.java.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/storm/storm/org/nongnu/storm/pointers/PointerIndex.java.diff?tr1=1.7&tr2=1.8&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/storm/storm/org/nongnu/storm/util/CopyUtil.java.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/storm/storm/org/nongnu/storm/util/HTTPProxy.java.diff?tr1=1.47&tr2=1.48&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/storm/storm/org/nongnu/storm/util/HtmlLinkIndex.java.diff?tr1=1.1&tr2=1.2&r1=text&r2=text

Patches:
Index: storm/Makefile
diff -u storm/Makefile:1.23 storm/Makefile:1.24
--- storm/Makefile:1.23 Mon Jun 23 17:18:31 2003
+++ storm/Makefile      Wed Sep 10 09:20:27 2003
@@ -2,14 +2,15 @@
 
 TEST=org/
 
+NAVIDOC_DEPENDS = ../navidoc-depends
 RAWSRC = `find org/ -name "*.java"` `find com/ -name "*.java"`
 CLASSDIR=CLASSES/
 STORM_DEPENDS=../storm-depends
 
CLASSPATH=$(CLASSDIR):$(STORM_DEPENDS)/cryptix-jce-provider.jar:$(STORM_DEPENDS)/jython.jar:$(STORM_DEPENDS)/gisp.jar:$(STORM_DEPENDS)/dom4j.jar:$(STORM_DEPENDS)/log4j.jar:$(shell
 echo $$CLASSPATH)
-PYTHONPATH=-Dpython.path=.:$(STORM_DEPENDS)/jythonlib.jar:$(STORM_DEPENDS)/pythonlib.jar
+PYTHONPATH=-Dpython.path=.:$(STORM_DEPENDS)/jythonlib.jar:$(STORM_DEPENDS)/pythonlib.jar:../navidoc/:$(NAVIDOC_DEPENDS)/docutils.jar
 export CLASSPATH
 JAVAC=javac
-JAVA=java
+JAVA=java -Dpython.cachedir=. -Dpython.path=$(PYTHONPATH) 
-Dpython.verbose=message
 KEYFILE=my.keys
 
 clean:
Index: storm/doc/dartboard/pointer_identities--benja/idea.rst
diff -u storm/doc/dartboard/pointer_identities--benja/idea.rst:1.4 
storm/doc/dartboard/pointer_identities--benja/idea.rst:1.5
--- storm/doc/dartboard/pointer_identities--benja/idea.rst:1.4  Wed Jul  9 
21:51:14 2003
+++ storm/doc/dartboard/pointer_identities--benja/idea.rst      Wed Sep 10 
09:20:27 2003
@@ -4,7 +4,7 @@
 
 :Author:  Benja Fallenstein <address@hidden>
 :Created: 2003-07-10
-:Changed: $Date: 2003/07/10 01:51:14 $
+:Changed: $Date: 2003/09/10 13:20:27 $
 
 .. contents::
 
@@ -36,64 +36,6 @@
 any (cryptographic) thing that you can do.
 
 
-What timestamping does
-----------------------
-
-One important technique here is timestamping. When
-signatures aren't timestamped, once the key is
-compromised, no signatures signed by this key
-can be trusted any more: There's no way to verify
-they were created before the key was revoked.
-
-If signatures are timestamped, you can verify
-that a signature was created before the key
-was revoked. So, you cannot create new signatures
-(the problem above isn't completely solved),
-but the old signatures don't become invalid.
-
-Unfortunately, the good methods for timestamping
-have been heavily patented (by `Surety, Inc.`__).
-
-__ http://www.surety.com/
-
-Here's a simple, patentless timestamping 
-technology (there was a patent, but it's been
-overturned):
-
-    There is a Trusted Third Party (TTP) which is
-    trusted by everybody. To obtain a timestamp,
-    submit a hash of your document to the TTP.
-    The TTP will sign a statement like, "Hash H
-    was submitted on 2003-07-10." Showing the
-    TTP's signature proves that the document
-    really existed on that date.
-
-Of course, the TTP could be fraudulent.
-
-Here's a much better system:
-
-    There is a central timestamping service (TS).
-    To obtain a timestamp, submit its hash to the TS.
-    The TS operates in a sequence of "rounds," say,
-    one minute long. It builds a hash tree of all
-    documents submitted in one round. Showing the chain
-    of hashes required to authenticate your document
-    as part of the hash proves that your document
-    existed during that timestamping round.
-
-    Each round includes the hash of the previous round,
-    so each round certifies the previous round. Once
-    a week or so, the TS publishes the current round's
-    hash in a widely-witnessed manner (e.g., in an
-    important newspaper). Thus, even if one doesn't trust
-    the TS or anybody on the network at all, the age
-    of a document can be proven (well enough that it
-    should stand up in court) with a resolution of
-    one week (in the example).
-
-Unfortunately, this one's patented.
-
-
 Using a public key infrastructure (PKI)?
 ----------------------------------------
 
@@ -231,4 +173,98 @@
 guarantee that your private key will not be exposed,
 you need to give somebody else the right to assign
 you a new key; which means you need to trust them
-not to assign your key to someone else.
\ No newline at end of file
+not to assign your key to someone else.
+
+
+Non-repudiability
+=================
+
+Now, an important consideration here is 
+*non-repudiability*: the inability to sign a message
+today and say tomorrow, "No, it wasn't me!"
+
+Repudiability is a problem in public-key cryptography
+when keys expire oor are revoked. If anybody could
+have a copy of the corresponding private key,
+a signature given with it isn't worth anything-- even
+if it was given *before* the key expired, because
+we cannot prove that.
+
+In our context, repudiability results in two problems:
+
+- Web page authors can claim they never published
+  a version of their page which they really *did*
+  publish.
+- Parent authorities deny the history of their
+  child authorities. I.e., a parent authority changes
+  the child authority's key to one that the parent
+  authority controls; it doesn't sign the blocks
+  that the child authority had signed, so all the
+  blocks signed by the child authority are invalidated
+  and all history of the data is lost.
+
+Normally, timestamping is used to proof the validity
+of signatures after the key was revoked.
+
+
+How timestamping works
+----------------------
+
+The trick with timestamping is,
+if signatures are timestamped, you can verify
+that a signature was created *before* the key
+was revoked.
+
+Unfortunately, the good methods for timestamping
+have been heavily patented (by `Surety, Inc.`__).
+
+__ http://www.surety.com/
+
+Here's a simple, patentless timestamping 
+technology (there was a patent, but it's been
+overturned):
+
+    There is a Trusted Third Party (TTP) which is
+    trusted by everybody. To obtain a timestamp,
+    submit a hash of your document to the TTP.
+    The TTP will sign a statement like, "Hash H
+    was submitted on 2003-07-10." Showing the
+    TTP's signature proves that the document
+    really existed on that date.
+
+Of course, the TTP could be fraudulent.
+
+Here's a much better system:
+
+    There is a central timestamping service (TS).
+    To obtain a timestamp, submit its hash to the TS.
+    The TS operates in a sequence of "rounds," say,
+    one minute long. It builds a hash tree of all
+    documents submitted in one round. Showing the chain
+    of hashes required to authenticate your document
+    as part of the hash proves that your document
+    existed during that timestamping round.
+
+    Each round includes the hash of the previous round,
+    so each round certifies the previous round. Once
+    a week or so, the TS publishes the current round's
+    hash in a widely-witnessed manner (e.g., in an
+    important newspaper). Thus, even if one doesn't trust
+    the TS or anybody on the network at all, the age
+    of a document can be proven (well enough that it
+    should stand up in court) with a resolution of
+    one week (in the example).
+
+Unfortunately, this one's patented.
+
+
+So what can we do?
+------------------
+
+Well, first of all, we need some way to keep signatures
+valid even after the key that originally signed them
+has expired (or been revoked) and been replaced by
+a new key, without having to take every signature given
+with the old key and giving it again with the new key.
+
+The key, here, is to 
\ No newline at end of file
Index: storm/org/nongnu/storm/pointers/PointerBlock.java
diff -u storm/org/nongnu/storm/pointers/PointerBlock.java:1.4 
storm/org/nongnu/storm/pointers/PointerBlock.java:1.5
--- storm/org/nongnu/storm/pointers/PointerBlock.java:1.4       Thu May 22 
18:03:52 2003
+++ storm/org/nongnu/storm/pointers/PointerBlock.java   Wed Sep 10 09:20:27 2003
@@ -110,4 +110,9 @@
        if(!s.verify(signature))
            throw new IOException("Wrong signature in block: "+block.getId());
     }
+
+    public boolean equals(Object o) {
+       if(!(o instanceof PointerBlock)) return false;
+       return ((PointerBlock)o).blockId.equals(blockId);
+    }
 }
Index: storm/org/nongnu/storm/pointers/PointerId.java
diff -u storm/org/nongnu/storm/pointers/PointerId.java:1.5 
storm/org/nongnu/storm/pointers/PointerId.java:1.6
--- storm/org/nongnu/storm/pointers/PointerId.java:1.5  Tue May 13 10:40:28 2003
+++ storm/org/nongnu/storm/pointers/PointerId.java      Wed Sep 10 09:20:27 2003
@@ -50,6 +50,8 @@
     }
     private static SecureRandom random = new SecureRandom();
 
+
+
     private String uri;
     private byte[] bytes;
     private String randomPart;
@@ -58,7 +60,7 @@
        uri = uri.toLowerCase().intern();
        this.uri = uri;
        
-       int colon = uri.lastIndexOf(':');
+       int colon = uri.indexOf(':', PREFIX_LEN+1);
 
        if(!uri.startsWith(PREFIX))
            throw new IllegalArgumentException("Storm URN must start "+PREFIX+" 
[[ was "+uri+" ]]");
Index: storm/org/nongnu/storm/pointers/PointerIndex.java
diff -u storm/org/nongnu/storm/pointers/PointerIndex.java:1.7 
storm/org/nongnu/storm/pointers/PointerIndex.java:1.8
--- storm/org/nongnu/storm/pointers/PointerIndex.java:1.7       Thu May 22 
18:03:52 2003
+++ storm/org/nongnu/storm/pointers/PointerIndex.java   Wed Sep 10 09:20:27 2003
@@ -75,6 +75,57 @@
        return b.getName();
     }
 
+    /** Get a list of past pointer blocks of a pointer (newest first) */
+    public SortedSet getHistory(PointerId id) throws IOException {
+       SortedSet s = new TreeSet(new Comparator() {
+               public int compare(Object o1, Object o2) {
+                   PointerBlock p1 = (PointerBlock)o1;
+                   PointerBlock p2 = (PointerBlock)o2;
+                   if(p1.getTimestamp() == p2.getTimestamp())
+                       return 0;
+                   else if(p1.getTimestamp() < p2.getTimestamp())
+                       return +1;
+                   else
+                       return -1;
+               }
+           });
+       
+       Collector c = db.get(id.toString()).block();
+       for(Iterator i=c.iterator(); i.hasNext();) {    
+           IndexedPool.Mapping m = (IndexedPool.Mapping)i.next();
+           if(dbg) p("Process: "+m.block+" "+m.value);
+
+           long timestamp;
+           try {
+               timestamp = Long.parseLong(m.value);
+           } catch(NumberFormatException _) {
+               // malformed entry
+               continue;
+           }
+           PointerBlock p;
+           try {
+               p = new PointerBlock(pool.get(m.block));
+           } catch(Throwable _) {
+               System.out.println("Couldn't use '"+m.block+"' because: "+_);
+               continue;
+           }
+
+           if(p.getPointer().equals(id) &&
+              p.getTimestamp() == timestamp) {
+               s.add(p);
+           }
+       }
+
+       return s;
+    }
+
+    /** Return whether a particular pointer block is the
+     *  newest one for its pointer.
+     */
+    public boolean isCurrent(PointerBlock pb) throws IOException, 
GeneralSecurityException {
+       return pb.equals(getPointerBlock(pb.getPointer()));
+    }
+
     public PointerBlock getPointerBlock(PointerId id) 
        throws IOException, GeneralSecurityException {
        if(dbg) p("Get: "+id);
Index: storm/org/nongnu/storm/util/CopyUtil.java
diff -u storm/org/nongnu/storm/util/CopyUtil.java:1.3 
storm/org/nongnu/storm/util/CopyUtil.java:1.4
--- storm/org/nongnu/storm/util/CopyUtil.java:1.3       Sat Apr 19 08:20:32 2003
+++ storm/org/nongnu/storm/util/CopyUtil.java   Wed Sep 10 09:20:27 2003
@@ -90,9 +90,13 @@
     }
 
     /** Read data from an input stream into a String.
-     *  Most useful for debug output. Encoding is US-ASCII.
+     *  Most useful for debug output. Default encoding is US-ASCII.
      */
+    static public String readString(InputStream in, String encoding) throws 
IOException {
+       return new String(readBytes(in), encoding);
+    }
+
     static public String readString(InputStream in) throws IOException {
-       return new String(readBytes(in), "US-ASCII");
+       return readString(in, "US-ASCII");
     }
 }
Index: storm/org/nongnu/storm/util/HTTPProxy.java
diff -u storm/org/nongnu/storm/util/HTTPProxy.java:1.47 
storm/org/nongnu/storm/util/HTTPProxy.java:1.48
--- storm/org/nongnu/storm/util/HTTPProxy.java:1.47     Mon Jun 23 17:18:31 2003
+++ storm/org/nongnu/storm/util/HTTPProxy.java  Wed Sep 10 09:20:27 2003
@@ -36,6 +36,7 @@
 import java.net.*;
 import java.util.*;
 import java.security.*;
+import org.python.util.PythonInterpreter;
 
 /** An HTTP server serving blocks from a Storm pool. When started from command 
  *  line, it servers the directory given as first argument.
@@ -52,9 +53,11 @@
     protected String URNPAC;
     protected String BACKLINKS;
     protected String QUERY = "search?q=";
+    protected String HISTORY = "history?doc=";
     protected HTTPServer server;
 
     protected boolean acceptPut = false;
+    protected boolean showBlocks = false;
     protected KeyPair keyPair;
     
     public HTTPProxy(IndexedPool pool, int port) throws IOException {
@@ -103,9 +106,12 @@
                boolean rewrite = false, backlinks = false;
                String uri = req.getRequestURI();
                if(HTTPProxy.dbg) p("<"+port+"> GET: "+uri + " (" + 
this.getRemoteIPAddress() + ")");
-
-               /* URN proxy requests don't start with slash */
-               if(!uri.startsWith("/"))
+               
+               if(uri.startsWith("x-storm:"))
+                   /* Work around Amaya bug */
+                   uri = REWRITE + "/urn:" + uri;
+               else if(!uri.startsWith("/"))
+                  /* URN proxy requests don't start with slash */
                    return serveBlock(uri, resf);
                else
                    uri = uri.substring(1);
@@ -113,10 +119,14 @@
                if(uri.equals(URNPAC))
                    return makePAC(req, resf);
                if(uri.startsWith(QUERY))
-                   return query(req, resf, uri);
+                   return query(req, resf, uri, false);
+               if(uri.startsWith("rewrite/" + QUERY))
+                   return query(req, resf, uri.substring("rewrite/".length()), 
true);
+               if(uri.startsWith(HISTORY))
+                   return history(req, resf, uri);
 
                String element;
-               while(!uri.startsWith("urn:")) {
+               while(!uri.startsWith("urn")) {
                    int slash = uri.indexOf('/');
                    if(slash != -1) {
                        element = uri.substring(0, slash);
@@ -131,6 +141,8 @@
                        backlinks = true;
                    else if(element.equals(""))
                        return serveHomePage(rewrite, backlinks, resf);
+                   else if(element.equals("pointers"))
+                       return servePointerList(resf);
                    else
                        throw new FileNotFoundException("Unknown: "+uri);
                }
@@ -141,7 +153,7 @@
                BlockId id = getBlockId(uri);
 
                if((!rewrite && !backlinks) || 
-                  !id.getContentType().equals("text/html"))
+                  !id.getContentType().startsWith("text/html"))
                    return serveBlock(uri, resf);
 
 
@@ -152,7 +164,7 @@
                HTTPResponse resp = resf.makeResponse(200, "Ok");
                resp.setField("Content-Type", id.getContentType());
 
-               String s = CopyUtil.readString(block.getInputStream());
+               String s = CopyUtil.readString(block.getInputStream(), "UTF-8");
 
                String prefix = "";
                if(rewrite) {
@@ -164,9 +176,9 @@
                    s = rewriteURIs(s, prefix);
 
                if(backlinks)
-                   s = insertBacklinks(s, prefix, id);
+                   s = insertBacklinks(s, prefix, uri);
                        
-               byte[] bytes = s.getBytes("US-ASCII");
+               byte[] bytes = s.getBytes("UTF-8");
                resp.getOutputStream().write(bytes);
                resp.close();
                return resp;
@@ -227,14 +239,19 @@
            
            writeRewriteLinks(w, rewrite);
 
+           w.write("<form action=\""+(rewrite ? "/rewrite" : "")+"/search\" 
method=\"get\">Find pointer: <input type=\"text\" name=\"q\"><input 
type=\"submit\" value=\"Find\"></form>");
+
            if(acceptPut) {
                w.write("<h2>New pointer</h2>\n\n");
 
-               w.write("<FORM action=\"/new-pointer\" method=\"post\">\n");
+               w.write("<FORM action=\""+(rewrite ? "/rewrite" : 
"")+"/new-pointer\" method=\"post\">\n");
                w.write("<P>\n");
                w.write("Title: <INPUT type=\"text\" name=\"title\">");
                w.write("<SELECT name=\"target\">\n");
-               w.write("<OPTION selected 
value=\"urn:x-storm:1.0:text/plain,3i42h3s6nnfq2msvx7xzkyayscx5qbyj.lwpnacqdbzryxw3vhjvcj64qbznghohhhzwclnq\">Text
 file</OPTION>\n");
+               w.write("<OPTION selected 
value=\"urn:x-storm:1.0:text/prs.fallenstein.rst,3i42h3s6nnfq2msvx7xzkyayscx5qbyj.lwpnacqdbzryxw3vhjvcj64qbznghohhhzwclnq\">ReStructuredText
 file</OPTION>\n");
+               w.write("<OPTION 
value=\"urn:x-storm:1.0:text/plain,3i42h3s6nnfq2msvx7xzkyayscx5qbyj.lwpnacqdbzryxw3vhjvcj64qbznghohhhzwclnq\">Text
 file</OPTION>\n");
+               w.write("<OPTION 
value=\"urn:x-storm:1.0:text/html,3i42h3s6nnfq2msvx7xzkyayscx5qbyj.lwpnacqdbzryxw3vhjvcj64qbznghohhhzwclnq\">HTML
 page</OPTION>\n");
+               w.write("<OPTION 
value=\"urn:x-storm:1.0:application/vnd.sun.xml.writer,b3xaowxhn3gg2hmz4e7rofjgfuesytja.jjdrwdheghbhr5qzc5we2giul22s6ljipavhj3q\">OpenOffice.org
 Writer document</OPTION>\n");
                w.write("<OPTION 
value=\"urn:x-storm:1.0:application/vnd.kde.kword,ly3m5evqznmuxnuxyduv43ikvor2dkze.gxeygfionykrrizvwkoyevkdysdnrksw4t5i2yi\">KWord
 file</OPTION>\n");
                w.write("</SELECT>\n");
                w.write("<INPUT type=\"submit\" value=\"Create\">\n");
@@ -275,17 +292,20 @@
                 }
            }
 
-           w.write("<h2>Blocks</h2>\n\n");
+           if(showBlocks) {
+               w.write("<h2>Blocks</h2>\n\n");
 
-           synchronized(ids) {
-               for(Iterator i=ids.iterator(); i.hasNext();) {
-                   BlockId id = (BlockId)i.next();
-                   String s = id.getURI();
-                    if(rewrite) 
-                       s = base + s;
-                   w.write("<a href=\""+s+"\">"+id+"</a><br>\n");
+               synchronized(ids) {
+                   for(Iterator i=ids.iterator(); i.hasNext();) {
+                       BlockId id = (BlockId)i.next();
+                       String s = id.getURI();
+                       if(rewrite) 
+                           s = base + s;
+                       w.write("<a href=\""+s+"\">"+id+"</a><br>\n");
+                   }
                }
            }
+
            w.write("</body></html>\n");
            w.close();
            return resp;
@@ -305,6 +325,43 @@
                return resp;
        }
 
+       protected HTTPResponse servePointerList(HTTPResponse.Factory resf) 
+           throws IOException {
+           
+           HTTPResponse resp = resf.makeResponse(200, "Ok");
+           resp.setField("Content-Type", "text/plain");
+           Writer w = new OutputStreamWriter(resp.getOutputStream(), 
"US-ASCII");
+           PointerIndex pIndex = 
+               (PointerIndex)pool.getIndex(PointerIndex.uri);
+                
+           Collector pIds = pIndex.getIds();
+
+           /*
+           try {
+               // wait for DHT to receive information from network
+               Thread.sleep(2000);
+           } catch(InterruptedException _) {}
+           */
+
+           synchronized(pIds) {
+                for(Iterator i=pIds.iterator(); i.hasNext();) {
+                   PointerId id = (PointerId)i.next();
+                    try {
+                        PointerBlock pb = pIndex.getPointerBlock(id); 
+                        String n = pb.getName();
+                        String s = id.getURI();
+                       w.write(id.getURI()); w.write('\n');
+                       w.write(pb.getName()); w.write('\n');
+                       w.write('\n');
+                    } 
+                    catch(GeneralSecurityException _) { _.printStackTrace(); }
+                }
+           }
+
+           w.close();
+           return resp;
+       }
+
        protected String rewriteURIs(String s, String prefix) {
            // Block urns can be in upper or lower or mixed case; 
            // matching on the lower-case version makes
@@ -335,8 +392,8 @@
            return s;
        }
 
-       protected String insertBacklinks(String s, String prefix, BlockId id) 
-           throws IOException {
+       protected String insertBacklinks(String s, String prefix, String uri) 
+           throws IOException, GeneralSecurityException {
            if(HTTPProxy.dbg) p("Getting HtmlLinkIndex.");
                    
            HtmlLinkIndex idx = null;
@@ -344,15 +401,18 @@
                idx = (HtmlLinkIndex)pool.getIndex(HtmlLinkIndex.uri);
            } catch(NoSuchElementException _) {}
                    
+           PointerIndex pIndex = 
+               (PointerIndex)pool.getIndex(PointerIndex.uri);
+
            if(HTTPProxy.dbg) p("HtmlLinkIndex = "+idx);
                    
            if(idx != null) {
                if(HTTPProxy.dbg) p("Looking for links");
-               Collector links = idx.getLinksTo(id);
+               Collector links = idx.getLinksTo(uri);
                
                try {
                    // XXX Are we trying to wait for indexing?
-                   Thread.sleep(2000);
+                   Thread.sleep(500);
                } catch(InterruptedException _) {}
                
                if(HTTPProxy.dbg) p("Iter thru links");
@@ -360,31 +420,42 @@
                synchronized(links) {
                    for(Iterator iter=links.iterator(); 
                        iter.hasNext();) {
-                       HtmlLinkIndex.Link link = 
-                           (HtmlLinkIndex.Link)iter.next();
-                       if(HTTPProxy.dbg) p("Link: "+link.linkText);
-                       t += "[<a href=\""+prefix+link.linkFrom.getURI()+
-                           "\">"+link.linkText+"</a>]<br>";
+                       PointerBlock pb = (PointerBlock)iter.next();
+                       if(HTTPProxy.dbg) p("Linking pointer block: "+pb);
+                       if(pIndex.isCurrent(pb)) {
+                           String name = pb.getName();
+                           if(name.endsWith(" (HTML)"))
+                               name = name.substring(0, name.length()-7);
+                           t += "[<a href=\""+prefix+pb.getPointer()+
+                               "\">"+name+"</a>]<br>";
+                       }
                    }
                }
-               if(!t.equals("")) {
-                   int i = s.indexOf("<body");
-                   i = s.indexOf(">", i);
-                   if(i < 0) i = 0;
-                   else i++;
-                   s = s.substring(0, i) 
-                       + "\n<p><small>This page is referred to as:<br>"
+               if(!t.equals(""))
+                   t = "\n<p align=\"right\"><small>This page is linked 
from:<br>"
                        + t
-                       + "</small></p>\n" 
-                       + s.substring(i);
-               }
+                       + "</small></p>\n";
+
+               String history = "";
+               p("Backlinks URI: "+uri);
+               if(uri.toLowerCase().startsWith("urn:x-storm:pointer-0.1:"))
+                   history = "\n<p align=\"right\"><small><a 
href=\""+ROOTURL+HISTORY+uri+"\">History</a></p></center>";
+
+               int i = s.indexOf("<body");
+               i = s.indexOf(">", i);
+               if(i < 0) i = 0;
+               else i++;
+               s = s.substring(0, i) 
+                   + history
+                   + t
+                   + s.substring(i);
            }
            return s;
        }
 
        protected HTTPResponse query(HTTPRequest req, 
                                     HTTPResponse.Factory resf,
-                                    String uri) throws IOException {
+                                    String uri, boolean rewrite) throws 
IOException {
            String query = 
                java.net.URLDecoder.decode(uri.substring(QUERY.length()));
 
@@ -405,7 +476,7 @@
 
            for(Iterator i=pBlocks.iterator(); i.hasNext();) {
                PointerBlock p = (PointerBlock)i.next();
-               w.write("<p><b><a href=\""+p.getPointer().getURI()+"\">");
+               w.write("<p><b><a href=\""+(rewrite ? ROOTURL+REWRITE+"/" : 
"")+p.getPointer().getURI()+"\">");
                w.write(p.getName()+"</a></b><br />\n");
                w.write("<small>"+p.getPointer().getURI()+"</small></p>\n\n");
            }
@@ -415,6 +486,41 @@
            return resp;
        }
 
+
+       protected HTTPResponse history(HTTPRequest req, 
+                                      HTTPResponse.Factory resf,
+                                      String uri) throws IOException, 
GeneralSecurityException {
+           PointerId ptr = new PointerId(uri.substring(HISTORY.length()));
+           PointerIndex pIndex = 
+               (PointerIndex)pool.getIndex(PointerIndex.uri);
+           SortedSet history = pIndex.getHistory(ptr);
+           
+           HTTPResponse resp = resf.makeResponse(200, "Ok");
+           resp.setField("Content-Type", "text/html;charset=UTF-8");
+
+           Writer w = new OutputStreamWriter(resp.getOutputStream(), 
+                                             "UTF-8");
+           String title = "History of \""+pIndex.getTitle(ptr)+"\"";
+           w.write("<html><head><title>"+title+"</title></head><body>\n");
+           w.write("<h1>"+title+"</h1>\n");
+           w.write("<p><a href=\""+ptr+"\">"+ptr+"</a></p>\n\n");
+
+           if(history.isEmpty()) w.write("<p>No versions available.</p>\n\n");
+
+           for(Iterator i=history.iterator(); i.hasNext();) {
+               PointerBlock p = (PointerBlock)i.next();
+               w.write("<p><b><a href=\""+p.getTarget()+"\">");
+               w.write(new Date(p.getTimestamp()).toLocaleString());
+               w.write("</a></b><br />\n");
+               w.write("<small>"+p.getTarget()+"</small></p>\n\n");
+           }
+
+           w.write("</body></html>\n");
+           w.close();
+           return resp;
+       }
+
+
        protected HTTPResponse makePAC(HTTPRequest req, 
                                       HTTPResponse.Factory resf) 
            throws IOException {
@@ -439,7 +545,7 @@
        protected HTTPResponse doPut(HTTPRequest req, HTTPResponse.Factory 
resf) 
            throws IOException {
 
-           String uri = req.getRequestURI();
+           String uri = URLDecoder.decode(req.getRequestURI());
            System.out.println("PUT: "+uri);
 
            if(!acceptPut)
@@ -447,46 +553,82 @@
 
            if(uri.startsWith("/"))
                uri = uri.substring(1);
+           else if(uri.startsWith("x-storm:"))
+               /* Work around Amaya bug */
+               uri = REWRITE + "/urn:" + uri;
 
            boolean rewrite = false;
            if(uri.startsWith(REWRITE+"/")) {
                uri = uri.substring(REWRITE.length()+1);
                rewrite = true;
            }
+           if(uri.startsWith(BACKLINKS+"/")) {
+               uri = uri.substring(BACKLINKS.length()+1);
+           }
 
            if(dbg) p("PUT accepted");
            PointerId id = new PointerId(uri);
            PointerIndex idx = 
                (PointerIndex)pool.getIndex(PointerIndex.uri);
-           BlockId current;
+           String contentType, title;
 
            try {
-               current = idx.get(id);
+               // because we don't get a content-type
+               // assume it's the same as before
+               contentType = idx.get(id).getContentType();
+               title = idx.getPointerBlock(id).getName();
            } catch(Exception _) {
                _.printStackTrace();
-               throw new Error("Exception while getting key XXX");
+               if(uri.endsWith(":stylesheet")) {
+                   // guess
+                   contentType = "text/css";
+                   title = "CSS stylesheet";
+               } else
+                   throw new Error("Exception while getting key XXX");
            }
 
            if(dbg) p("Got old pointer value");
            
-           // because we don't get a content-type
-           // assume it's the same as before
            BlockOutputStream bos = 
-               pool.getBlockOutputStream(current.getContentType());
+               pool.getBlockOutputStream(contentType);
 
-           if(!rewrite || !current.getContentType().equals("text/html")) {
+           if(!rewrite || !contentType.equals("text/html")) {
                CopyUtil.copy(req.getInputStream(), bos);
            } else {
                String s = CopyUtil.readString(req.getInputStream());
                String prefix = ROOTURL+REWRITE+"/";
                s = unrewriteURIs(s, prefix);
                bos.write(s.getBytes("US-ASCII"));
+               bos.close();
            }
 
            if(dbg) p("Created new block: "+bos.getBlockId());
+           
+           // If it may be an RST file, try to compile it.
+           p("showct");
+           p("CT: <"+contentType+">");
+           if(contentType.startsWith("text/plain")) {
+               // Try to extract title
+               String charset = "iso-8859-1";
+               String prefix = "text/plain;charset=";
+               if(contentType.startsWith(prefix))
+                   charset = contentType.substring(prefix.length());
+               BufferedReader r = new BufferedReader(new 
InputStreamReader(bos.getBlock().getInputStream(), charset));
+               String l = r.readLine();
+               // XXX recognizes only titles of the style I use myself ;-)
+               if(l != null && l.startsWith("===")) {
+                   String l2 = r.readLine();
+                   if(l2 != null && !l2.equals(""))
+                       title = l2.trim();
+               }
+                   
+               new Thread(new CompileRST(id, bos.getBlock(), title)).start();
+               p("Other thread continues");
+           }
 
+           // Now set RST pointer.
            try {
-               idx.set(id, bos.getBlockId(), keyPair);
+               idx.set(id, bos.getBlockId(), keyPair, title);
            } catch(Exception _) {
                _.printStackTrace();
                throw new Error("Exception while getting key XXX");
@@ -522,7 +664,8 @@
                return doUnknown(req, resf);
 
            if(!uri.equals("/new-pointer") &&
-              !uri.equals("/new-pointer-plain"))
+              !uri.equals("/new-pointer-plain") &&
+              !uri.equals("/rewrite/new-pointer"))
                return resf.makeError(404, "Not found");
 
            String formdata =
@@ -568,12 +711,13 @@
                w.write(id.getURI());
                w.close();
            } else {
+               boolean rewrite = uri.equals("/rewrite/new-pointer");
                resp.setField("Content-Type", "text/html");
                Writer w = new OutputStreamWriter(resp.getOutputStream(), 
                                                  "US-ASCII");
                w.write("<html><head><title>Created</title></head><body>");
                w.write("New pointer created at: \n");
-               w.write("<a href=\""+id.getURI()+"\">"+id.getURI()+"</a>\n");
+               w.write("<a href=\""+(rewrite ? REWRITE : 
"")+id.getURI()+"\">"+id.getURI()+"</a>\n");
                w.write("<p><a href=\"/\">Back to the home page.</a>\n");
                w.write("</body></html>");
                w.close();
@@ -644,7 +788,7 @@
                return idx.get(new PointerId(uri));
            } catch(Exception _) {
                _.printStackTrace();
-               throw new Error("Exception while getting key XXX");
+               throw new Error("Exception while getting key XXX: "+_);
            }
        } else {
            throw new Error("Malformed Storm URN: "+uri);
@@ -655,6 +799,62 @@
         public HTTPConnection newConnection(Socket s) throws IOException {
             return new StormConnection(s);
         }
+    }
+
+    static PythonInterpreter interp;
+    protected class CompileRST implements Runnable {
+       PointerId rst, html;
+       Block src;
+       String title, stylesheet;
+
+       protected CompileRST(PointerId rst, Block src, String title) {
+           this.rst = rst;
+           this.html = new PointerId(rst.getURI() + ":html");
+           this.src = src;
+           this.title = title;
+
+           String s = rst.getURI();
+           stylesheet = s.substring(0, s.lastIndexOf(':')) + ":stylesheet";
+           p("Stylesheet URI: "+stylesheet);
+       }
+
+       public void run() {
+           p("Start compiling RST...");
+           if(interp == null) {
+               interp = new PythonInterpreter();
+               interp.exec("import docutils");
+           }
+
+           try {
+               String file = "/tmp/"+rst;
+               CopyUtil.copy(src.getInputStream(),
+                             new FileOutputStream(file));
+
+               p("Start docutils.");
+               interp.exec("docutils.core.publish_cmdline(writer_name='html', 
argv=['"+file+"', '"+file+".gen.html', '--input-encoding=iso-8859-1', 
'--output-encoding=utf-8', '--generator', '--source-link', 
'--stylesheet="+stylesheet+"'])");
+               p("Docutils finished.");
+
+               BlockOutputStream bos = 
+                   pool.getBlockOutputStream("text/html;charset=utf-8");
+               CopyUtil.copy(new FileInputStream(file + ".gen.html"), bos);
+
+               p("HTML block created: "+bos.getBlockId());
+           
+               try {
+                   PointerIndex idx = 
+                       (PointerIndex)pool.getIndex(PointerIndex.uri);
+                   idx.set(html, bos.getBlockId(), keyPair, title + " (HTML)");
+               } catch(Exception _) {
+                   _.printStackTrace();
+                   throw new Error("Exception while putting key XXX");
+               }
+
+               p("Pointer set: "+html.getURI());
+           } catch(IOException _) {
+               throw new Error("Error while compiling RST: "+_);
+           }
+           p("RST compiled.");
+       }
     }
 
     public static void main(String[] args) throws Exception {
Index: storm/org/nongnu/storm/util/HtmlLinkIndex.java
diff -u storm/org/nongnu/storm/util/HtmlLinkIndex.java:1.1 
storm/org/nongnu/storm/util/HtmlLinkIndex.java:1.2
--- storm/org/nongnu/storm/util/HtmlLinkIndex.java:1.1  Sat May  3 15:45:26 2003
+++ storm/org/nongnu/storm/util/HtmlLinkIndex.java      Wed Sep 10 09:20:28 2003
@@ -27,6 +27,7 @@
  */
 package org.nongnu.storm.util;
 import org.nongnu.storm.*;
+import org.nongnu.storm.pointers.*;
 import org.nongnu.storm.impl.AsyncSetCollector;
 import java.io.*;
 import java.util.*;
@@ -37,29 +38,32 @@
  */
 public class HtmlLinkIndex {
     public static final String uri =
-       "urn:urn-5:T7uu149pw0Z0ANuQPwkw1oRVfZVn";
+       "urn:urn-5:tYgOeOBalVf5iRPrIuSZl81OJGS3";
 
     public static final IndexType type = new IndexType();
 
-    public static class Link {
-       public final BlockId linkFrom;
-       public final String linkText;
-       protected Link(BlockId f, String t) { linkFrom=f; linkText=t; }
-    }
-
     protected IndexedPool pool;
     protected IndexedPool.DB db;
 
     protected static class IndexType implements IndexedPool.IndexType {
        public Set getMappings(Block block) throws IOException {
-           if(!block.getId().getContentType().equals("text/html"))
+           PointerBlock pb;
+           try {
+               pb = new PointerBlock(block);
+           } catch(Throwable _) {
+               return Collections.EMPTY_SET;
+           }
+
+           if(!pb.getTarget().getContentType().startsWith("text/html"))
                return Collections.EMPTY_SET;
 
+           Block target = block.getPool().get(pb.getTarget());
+
            Set mappings = new HashSet();
-           String s = CopyUtil.readString(block.getInputStream());
+           String s = CopyUtil.readString(target.getInputStream());
            int i = 0;
            while(true) {
-               i = s.indexOf("href=\"urn:x-storm:1.0:", i);
+               i = s.indexOf("href=\"urn:x-storm:", i);
                if(i < 0) break;
                i += "href=\"".length();
                int j = s.indexOf('"', i);
@@ -69,15 +73,8 @@
                int k = urn.indexOf('#');
                if(k > 0) urn = urn.substring(0, k);
 
-               j = s.indexOf('>', j);
-               if(j < 0) break;
-               k = s.indexOf("</a>", j);
-               if(k < 0) break;
-
-               String link = s.substring(j+1, k);
-
                mappings.add(new IndexedPool.Mapping(block.getId(),
-                                                    urn, link));
+                                                    urn, ""));
            }
 
            return mappings;
@@ -102,13 +99,20 @@
        this.db = db;
     }
 
-    public SetCollector getLinksTo(BlockId id) throws IOException {
-       Collector c = db.get(id.getURI());
+    /** Return a set of PointerBlocks linking to this target.
+     */
+    public SetCollector getLinksTo(String uri) throws IOException {
+       Collector c = db.get(uri);
        final AsyncSetCollector result = new AsyncSetCollector();
        c.addCollectionListener(new CollectionListener() {
                public boolean item(Object item) {
-                   IndexedPool.Mapping m = (IndexedPool.Mapping)item;
-                   result.receive(new Link(m.block, m.value));
+                   try {
+                       IndexedPool.Mapping m = (IndexedPool.Mapping)item;
+                       result.receive(new PointerBlock(pool.get(m.block)));
+                   } catch(Exception _) {
+                       _.printStackTrace();
+                       throw new Error(""+_); // XXX
+                   }
                    return true;
                }
                public void finish(boolean timeout) {




reply via email to

[Prev in Thread] Current Thread [Next in Thread]