From d3f2df00be40e521aa3f3bfe76779f16e4713808 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Wed, 29 Oct 2008 15:34:31 -0700 Subject: [PATCH] webapi: serve the /static URL tree from /public_html (configurable) --- docs/configuration.txt | 12 ++++++++++++ docs/webapi.txt | 18 ++++++++++++++++-- src/allmydata/client.py | 4 +++- src/allmydata/test/test_web.py | 18 ++++++++++++++++-- src/allmydata/webish.py | 6 ++++-- 5 files changed, 51 insertions(+), 7 deletions(-) diff --git a/docs/configuration.txt b/docs/configuration.txt index d25bddd9..2bfdc481 100644 --- a/docs/configuration.txt +++ b/docs/configuration.txt @@ -58,6 +58,18 @@ web.port = (strports string, optional) If this is not provided, the node will not run a web server. +web.static = (string, optional) + + This controls where the /static portion of the URL space is served. The + value is a directory name (~username is allowed, and non-absolute names are + interpreted relative to the node's basedir) which can contain HTML and other + files. This can be used to serve a javascript-based frontend to the Tahoe + node, or other services. + + The default value is "public_html", which will serve $BASEDIR/public_html . + With the default settings, http://127.0.0.1:8123/static/foo.html will serve + the contents of $BASEDIR/public_html/foo.html . + tub.port = (integer, optional) This controls which port the node uses to accept Foolscap connections from diff --git a/docs/webapi.txt b/docs/webapi.txt index b93babfa..59ac9ed1 100644 --- a/docs/webapi.txt +++ b/docs/webapi.txt @@ -6,8 +6,9 @@ 3. URLs, Machine-Oriented Interfaces 4. Browser Operations: Human-Oriented Interfaces 5. Welcome / Debug / Status pages -6. Safety and security issues -- names vs. URIs -7. Concurrency Issues +6. Static Files in /public_html +7. Safety and security issues -- names vs. URIs +8. Concurrency Issues == Enabling the web-API port == @@ -1164,6 +1165,19 @@ GET / (introducer status) clients over time. +== Static Files in /public_html == + +The webapi server will take any request for a URL that starts with /static +and serve it from a configurable directory which defaults to +$BASEDIR/public_html . This is configured by setting the "[node]web.static" +value in $BASEDIR/tahoe.cfg . If this is left at the default value of +"public_html", then http://localhost:8123/static/subdir/foo.html will be +served with the contents of the file $BASEDIR/public_html/subdir/foo.html . + +This can be useful to serve a javascript application which provides a +prettier front-end to the rest of the Tahoe webapi. + + == safety and security issues -- names vs. URIs == Summary: use explicit file- and dir- caps whenever possible, to reduce the diff --git a/src/allmydata/client.py b/src/allmydata/client.py index 463a5cbd..22930ab6 100644 --- a/src/allmydata/client.py +++ b/src/allmydata/client.py @@ -254,7 +254,9 @@ class Client(node.Node, pollmixin.PollMixin): from allmydata.webish import WebishServer nodeurl_path = os.path.join(self.basedir, "node.url") - ws = WebishServer(webport, nodeurl_path) + staticdir = self.get_config("node", "web.static", "public_html") + staticdir = os.path.expanduser(staticdir) + ws = WebishServer(webport, nodeurl_path, staticdir) self.add_service(ws) def init_ftp_server(self): diff --git a/src/allmydata/test/test_web.py b/src/allmydata/test/test_web.py index 0d80b52e..684ac844 100644 --- a/src/allmydata/test/test_web.py +++ b/src/allmydata/test/test_web.py @@ -1,4 +1,4 @@ -import re, urllib +import os.path, re, urllib import simplejson from twisted.application import service from twisted.trial import unittest @@ -123,7 +123,8 @@ class WebMixin(object): def setUp(self): self.s = FakeClient() self.s.startService() - self.ws = s = webish.WebishServer("0") + self.staticdir = self.mktemp() + self.ws = s = webish.WebishServer("0", staticdir=self.staticdir) s.setServiceParent(self.s) self.webish_port = port = s.listener._port.getHost().port self.webish_url = "http://localhost:%d" % port @@ -2396,6 +2397,19 @@ class Web(WebMixin, testutil.StallMixin, unittest.TestCase): d.addCallback(_done) return d + def test_static(self): + webdir = os.path.join(self.staticdir, "subdir") + fileutil.make_dirs(webdir) + f = open(os.path.join(webdir, "hello.txt"), "wb") + f.write("hello") + f.close() + + d = self.GET("/static/subdir/hello.txt") + def _check(res): + self.failUnlessEqual(res, "hello") + d.addCallback(_check) + return d + class Util(unittest.TestCase): def test_abbreviate_time(self): diff --git a/src/allmydata/webish.py b/src/allmydata/webish.py index 0b3add8c..14c62313 100644 --- a/src/allmydata/webish.py +++ b/src/allmydata/webish.py @@ -3,7 +3,7 @@ import time from twisted.application import service, strports, internet from twisted.web import http from twisted.internet import defer -from nevow import appserver, inevow +from nevow import appserver, inevow, static from allmydata.util import log from allmydata.web import introweb, root @@ -123,7 +123,7 @@ class WebishServer(service.MultiService): name = "webish" root_class = root.Root - def __init__(self, webport, nodeurl_path=None): + def __init__(self, webport, nodeurl_path=None, staticdir=None): service.MultiService.__init__(self) self.webport = webport self.root = self.root_class() @@ -132,6 +132,8 @@ class WebishServer(service.MultiService): if self.root.child_operations: self.site.remember(self.root.child_operations, IOpHandleTable) self.root.child_operations.setServiceParent(self) + if staticdir: + self.root.putChild("static", static.File(staticdir)) s = strports.service(webport, site) s.setServiceParent(self) self.listener = s # stash it so the tests can query for the portnum -- 2.45.2