Hi folks,
The attached code is a very rough sketch of a possible solution to
the URN->UR*->URL scenario which relies on the DNS, HTTP and HTML.
I'm not suggesting this is The Answer as far as URNs are concerned.
An Answer, perhaps? :-)
There is a demo running with the NCSA httpd on
http://www.mrrl.lut.ac.uk/pickup.html
The theory is that the first script is run under the nph- "rule"
by the Web server, which enables it to send re-directs to the
client (your client must support re-directs :-).
In attempting to resolve a URN of the form
urn://urn.mrrl.lut.ac.uk/martin/top
it does a DNS TXT lookup on the domain component, e.g.
urn.mrrl.lut.ac.uk. 86400 TXT http://www.mrrl.lut.ac.uk/urn
Because I'm lazy, the first http URL returned is taken as the URL
of the server which is willing to perform the URN resolution. Then
the rest of the URN is appended - in the example this gives us
http://www.mrrl.lut.ac.uk/urn/martin/top
In the demo /urn is remapped to the second script via a ScriptAlias
ScriptAlias /urn/ /usr/local/etc/httpd/cgi-bin/stuff/
which does an on-the-fly HTML rendering of an URC template-style
thing, e.g.
Title: Top level "URN"
Description: This is my first attempt to play around with the URN+URC
approach to organizing (meta? ;-)information. It would probably be
better if the URC were interpreted by the client!
URL-v0: http://www.mrrl.lut.ac.uk/
Title-v0: MRRL Web server
URL-v1: http://hill.lut.ac.uk/
Title-v1: Hill's Web server
URL-v2: gopher://info.lut.ac.uk/
Title-v2: Computing Services gopher server
becomes what you see in
http://www.mrrl.lut.ac.uk/urn/martin/top
Should this idea catch on, I presume most of this code would end up in
the WWW client. Thus, deciding which TXT RR to use, and how the URC
is processed (i.e. more likely as a template/urc than a text/html)
would probably be left up to the client (with hints from the user!).
Adding the client side code (in say Mosaic or Lynx) doesn't look like
it should be a big deal, but I'm sure the client authors will
immediately tell me why it is...
Cheerio,
Martin
--%#%record%#%
Content-Type: text/plain
Content-Name: nph-urn2urc
Content-Length: 783
#!/usr/local/bin/perl -- #-*-Perl-*-
$dig = "/usr/local/bin/dig";
$default = "http://mrrl.lut.ac.uk/quackquackoops.html";
$urn = $ENV{"QUERY_STRING"};
$urn =~ tr/;\`//;
$urn =~ tr/+/ /;
$urn =~ s/%(..)/pack("c",hex($1))/ge;
$urn =~ s/^urn=//;
($host,$resource) = $urn =~ m!^urn://([^/]+)/(.*)$!;
chop(@DIG = `$dig txt $host +pfset=0x2020`);
foreach(@DIG){
next if /^\s+$/;
if (/^$host\.\s+TXT\s+(.*)$/) {
$url = $1;
$url =~ s/;//g;
$url =~ s/\`//g;
if ($url =~ /^http/) { # simple-minded - pick first http !!
print "HTTP/1.0 302 Found\n";
print "Location: $url/$resource\n";
print "Server: $ENV{\"SERVER_SOFTWARE\"}\n";
exit;
}
}
}
print "HTTP/1.0 302 Found\n";
print "Location: $default\n";
print "Server: $ENV{\"SERVER_SOFTWARE\"}\n";
--%#%record%#%
Content-Type: text/plain
Content-Name: stuff
Content-Length: 741
#!/usr/local/bin/perl
($user,$path) = $ENV{"PATH_INFO"} =~ m!^/([^/]+)/(.*)$!;
$top = (getpwnam($user))[7];
print "Content-Type: text/html\n\n<html><head>\n";
open(TOP,"$top/.world/$path")||die "Couldn't open $top/.world/$path: $!";
while(<TOP>) {
if (/^Title:\s*(.*)$/) {
print "<title>$1</title></head><body><h2>Title</h2>$1<p>\n";
}
if (/^Description:\s*(.*)$/) {
print "<h2>Description</h2>$1\n";
while(<TOP>) {
last unless /^\s/;
print;
}
print "<p><h2>Links</h2><ul>\n";
}
if (/^URL-v([^:]+):\s*(.*)$/) {
$urlv = $2;
next;
}
if (/^Title-v([^:]+):\s*(.*)$/) {
print "<li><a href=\"$urlv\">$2</a>\n";
next;
}
}
close(TOP);
print "</ul><p></body></html>\n";
--%#%record%#%
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Content-Length: 18
--%#%record%#%--