Commits

Ian Bicking committed fc10555

Add per-host writable root, with a host subdirectory

Comments (0)

Files changed (6)

docs/services.txt

 
 Note ``index.html`` files will work.
 
+Also you may put files in ``$CONFIG_WRITABLE_ROOT/$HTTP_HOST/...`` for
+per-host files.  E.g., you can have an application serve up
+``alice.myblogservice.com`` and ``bob.myblogservice.com``, and put
+their files in ``$CONFIG_WRITABLE_ROOT/alice.myblogservice.com/`` or
+``$CONFIG_WRITABLE_ROOT/bob.myblogservice.com/`` to keep the files
+host-local.
+
 PostGIS
 ~~~~~~~
 
   <https://hudson.mozilla.org/job/addons.mozilla.org/>`_ that I would
   like here (checking coding conventions and other details).
 * writable-root should go before static files in precedence.
-* Static files should be per-domain optionally (first look in
-  ``PATH/domain/file`` then ``PATH/file``).

silverlining/mgr-scripts/master-runner.py

 # dull but used internally; we'll delete them for cleanliness:
 BORING_VARS = [
     'SILVER_APP_DATA', 'SILVER_PROCESS_GROUP', 'SILVER_PLATFORM',
-    'SILVER_PHP_ROOT', 'SILVER_REDIR_HOST', 'SILVER_FORWARDED']
+    'SILVER_PHP_ROOT', 'SILVER_REDIR_HOST', 'SILVER_FORWARDED',
+    'SILVER_HOST', 'SILVER_REMAINING_URI']
 
 
 def delete_boring_vars(environ):

silverlining/server-root/etc/apache2/sites-enabled/wsgi_runner

 RewriteCond %{ENV:SILVER_INSTANCE_NAME} ^([^.]*)\.
 RewriteRule . - [E=SILVER_APP_NAME:%1]
 
+RewriteCond %{HTTP_HOST} ^(.*)(?:\:\d+)?$
+RewriteRule . - [E=SILVER_HOST:%1]
+
 # Refuse /index.html files (redirect):
 RewriteCond /var/www/%{ENV:SILVER_INSTANCE_NAME}/static%{ENV:SILVER_REMAINING_URI} -f
 RewriteRule (.*/)index.html %{ENV:SILVER_REDIR_HOST}$1 [L,R=permanent]
 RewriteRule . /var/www/%{ENV:SILVER_INSTANCE_NAME}/static%{ENV:SILVER_REMAINING_URI}/index.html [L]
 
 ## FIXME: even when there is no writable root, these all get run:
-## Repeat static serving for writable-root files:
+## Repeat static serving for writable-root files; this entire stanza
+## is repeated twice, first using the host-specific location, then a
+## more general location:
+
+## Per-host:
+# Refuse /index.html files (redirect):
+RewriteCond %{ENV:CONFIG_WRITABLE_ROOT}/%{ENV:SILVER_HOST}%{ENV:SILVER_REMAINING_URI} -f
+RewriteRule (.*/)index.html %{ENV:SILVER_REDIR_HOST}$1 [L,R=permanent]
+# Serve up any static files:
+RewriteCond %{ENV:CONFIG_WRITABLE_ROOT}/%{ENV:SILVER_HOST}%{ENV:SILVER_REMAINING_URI} -f
+RewriteRule . %{ENV:CONFIG_WRITABLE_ROOT}/%{ENV:SILVER_HOST}%{ENV:SILVER_REMAINING_URI} [L]
+# Add a trailing slash when necessary:
+RewriteCond %{ENV:CONFIG_WRITABLE_ROOT}/%{ENV:SILVER_HOST}%{ENV:SILVER_REMAINING_URI} -d
+RewriteCond %{ENV:SILVER_REMAINING_URI} [^/]$
+RewriteCond %{ENV:CONFIG_WRITABLE_ROOT}/%{ENV:SILVER_HOST}%{ENV:SILVER_REMAINING_URI}/index.html -f
+RewriteRule (.*) %{ENV:SILVER_REDIR_HOST}$1/ [L,R=permanent]
+# Otherwise serve up index.html:
+RewriteCond %{ENV:CONFIG_WRITABLE_ROOT}/%{ENV:SILVER_HOST}%{ENV:SILVER_REMAINING_URI}/index.html -f
+RewriteRule . %{ENV:CONFIG_WRITABLE_ROOT}/%{ENV:SILVER_HOST}%{ENV:SILVER_REMAINING_URI}/index.html [L]
+
+## Not per-host:
 # Refuse /index.html files (redirect):
 RewriteCond %{ENV:CONFIG_WRITABLE_ROOT}%{ENV:SILVER_REMAINING_URI} -f
 RewriteRule (.*/)index.html %{ENV:SILVER_REDIR_HOST}$1 [L,R=permanent]

tests/functional/example-app/example_app.py

             body.append('path=%r %r' % (environ['SCRIPT_NAME'], environ['PATH_INFO']))
             body.append('Update run.')
             body = '\n'.join(body)
+        elif path_info == '/write-root':
+            write_root = os.environ['CONFIG_WRITABLE_ROOT']
+            host = environ['HTTP_HOST'].split(':')[0]
+            host_dir = os.path.join(write_root, host)
+            if not os.path.exists(host_dir):
+                os.mkdir(host_dir)
+            open(os.path.join(write_root, 'test-writable.txt'), 'w').write('test writable')
+            open(os.path.join(host_dir, 'test-hosted.txt'), 'w').write('test hosted')
+            body = 'WRITABLE_ROOT=%s' % write_root
         else:
             body = 'INSTANCE=%s' % os.environ['SILVER_INSTANCE_NAME']
         start_response('200 OK', [('Content-type', 'text/plain')])

tests/functional/runtest.py

             resp = urllib.urlopen('http://%s/static_file.txt' % name).read()
             print 'Got static HTTP response:\n%s' % resp
             assert resp.strip() == 'This is a test'
+            resp = urllib.urlopen('http://%s/write-root' % name).read()
+            assert resp.strip().startswith('WRITABLE_ROOT='), resp
+            resp = urllib.urlopen('http://%s/test-writable.txt' % name).read()
+            assert resp.strip() == 'test writable', resp
+            resp = urllib.urlopen('http://%s/test-hosted.txt' % name).read()
+            assert resp.strip() == 'test hosted', resp
 
         if run_stage(stage, 'update-path'):
             print 'Doing update to path'