[Checkins] SVN: hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/ make the resource publisher a filter not an app. change order of library_name and hash. only publish when the has signature can be found
Jan-Wijbrand Kolman
janwijbrand at gmail.com
Fri Nov 19 07:44:34 EST 2010
Log message for revision 118489:
make the resource publisher a filter not an app. change order of library_name and hash. only publish when the has signature can be found
Changed:
U hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/README.txt
U hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/__init__.py
U hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/core.py
U hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/publisher.py
-=-
Modified: hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/README.txt
===================================================================
--- hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/README.txt 2010-11-19 12:16:15 UTC (rev 118488)
+++ hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/README.txt 2010-11-19 12:44:34 UTC (rev 118489)
@@ -753,9 +753,9 @@
for instance)::
>>> print needed.render()
- <link rel="stylesheet" type="text/css" href="http://localhost/static/foo/hash:.../b.css" />
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../a.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../c.js"></script>
+ <link rel="stylesheet" type="text/css" href="http://localhost/static/:hash:.../foo/b.css" />
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/a.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/c.js"></script>
Let's set this a currently needed inclusions::
@@ -766,9 +766,9 @@
>>> from hurry import resource
>>> print resource.render()
- <link rel="stylesheet" type="text/css" href="http://localhost/static/foo/hash:.../b.css" />
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../a.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../c.js"></script>
+ <link rel="stylesheet" type="text/css" href="http://localhost/static/:hash:.../foo/b.css" />
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/a.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/c.js"></script>
Hashing resources
=================
@@ -786,7 +786,7 @@
To make browsers update their caches of resources immediately when the
resource changes, the absolute URLs of resources can now be made to contain a
hash of the resource's contents, so it will look like
-/foo/hash:12345/myresource instead of /foo/myresource.
+/foo/:hash:12345/myresource instead of /foo/myresource.
The default hashing behavior can be changed by setting the 'hashing' variable
in the hurry.resource module through the `configure_hashing` function::
@@ -800,9 +800,9 @@
>>> hurry.resource.configure_hashing(True)
>>> print resource.render()
- <link rel="stylesheet" type="text/css" href="http://localhost/static/foo/hash:.../b.css" />
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../a.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../c.js"></script>
+ <link rel="stylesheet" type="text/css" href="http://localhost/static/:hash:.../foo/b.css" />
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/a.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/c.js"></script>
More about the devmode in a minute::
@@ -881,9 +881,9 @@
>>> print needed.render_into_html(html)
<html><head>
- <link rel="stylesheet" type="text/css" href="http://localhost/static/foo/hash:.../b.css" />
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../a.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../c.js"></script>
+ <link rel="stylesheet" type="text/css" href="http://localhost/static/:hash:.../foo/b.css" />
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/a.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/c.js"></script>
something more</head></html>
The top-level convenience function does this for the currently needed
@@ -891,9 +891,9 @@
>>> print resource.render_into_html(html)
<html><head>
- <link rel="stylesheet" type="text/css" href="http://localhost/static/foo/hash:...b.css" />
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../a.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../c.js"></script>
+ <link rel="stylesheet" type="text/css" href="http://localhost/static/:hash:.../foo/b.css" />
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/a.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/c.js"></script>
something more</head></html>
See below for a way to insert into HTML when bottom fragments are
@@ -914,9 +914,9 @@
>>> top, bottom = needed.render_topbottom()
>>> print top
- <link rel="stylesheet" type="text/css" href="http://localhost/static/foo/hash:.../b.css" />
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../a.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../c.js"></script>
+ <link rel="stylesheet" type="text/css" href="http://localhost/static/:hash:.../foo/b.css" />
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/a.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/c.js"></script>
>>> print bottom
<BLANKLINE>
@@ -931,9 +931,9 @@
>>> top, bottom = needed.render_topbottom()
>>> print top
- <link rel="stylesheet" type="text/css" href="http://localhost/static/foo/hash:.../b.css" />
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../a.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../c.js"></script>
+ <link rel="stylesheet" type="text/css" href="http://localhost/static/:hash:.../foo/b.css" />
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/a.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/c.js"></script>
>>> print bottom
<BLANKLINE>
@@ -943,10 +943,10 @@
>>> needed.bottom(force=True)
>>> top, bottom = needed.render_topbottom()
>>> print top
- <link rel="stylesheet" type="text/css" href="http://localhost/static/foo/hash:.../b.css" />
+ <link rel="stylesheet" type="text/css" href="http://localhost/static/:hash:.../foo/b.css" />
>>> print bottom
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../a.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../c.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/a.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/c.js"></script>
Let's now introduce a javascript resource that says it is safe to be
included on the bottom::
@@ -963,10 +963,10 @@
>>> top, bottom = needed.render_topbottom()
>>> print top
- <link rel="stylesheet" type="text/css" href="http://localhost/static/foo/hash:.../b.css" />
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../a.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../c.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../y2.js"></script>
+ <link rel="stylesheet" type="text/css" href="http://localhost/static/:hash:.../foo/b.css" />
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/a.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/c.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/y2.js"></script>
>>> print bottom
<BLANKLINE>
@@ -978,22 +978,22 @@
>>> top, bottom = needed.render_topbottom()
>>> print top
- <link rel="stylesheet" type="text/css" href="http://localhost/static/foo/hash:.../b.css" />
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../a.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../c.js"></script>
+ <link rel="stylesheet" type="text/css" href="http://localhost/static/:hash:.../foo/b.css" />
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/a.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/c.js"></script>
>>> print bottom
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../y2.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/y2.js"></script>
There's also a convenience function for the currently needed inclusion::
>>> request.needed = needed
>>> top, bottom = resource.render_topbottom()
>>> print top
- <link rel="stylesheet" type="text/css" href="http://localhost/static/foo/hash:.../b.css" />
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../a.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../c.js"></script>
+ <link rel="stylesheet" type="text/css" href="http://localhost/static/:hash:.../foo/b.css" />
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/a.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/c.js"></script>
>>> print bottom
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../y2.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/y2.js"></script>
When we force bottom rendering of Javascript, there is no effect of
making a resource bottom-safe: all ``.js`` resources will be rendered
@@ -1002,11 +1002,11 @@
>>> needed.bottom(force=True)
>>> top, bottom = needed.render_topbottom()
>>> print top
- <link rel="stylesheet" type="text/css" href="http://localhost/static/foo/hash:.../b.css" />
+ <link rel="stylesheet" type="text/css" href="http://localhost/static/:hash:.../foo/b.css" />
>>> print bottom
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../a.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../c.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../y2.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/a.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/c.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/y2.js"></script>
Note that if ``bottom`` is enabled, it makes no sense to have a
resource inclusion ``b`` that depends on a resource inclusion ``a``
@@ -1037,20 +1037,20 @@
>>> print needed.render_topbottom_into_html(html)
<html><head>
- <link rel="stylesheet" type="text/css" href="http://localhost/static/foo/hash:.../b.css" />
- rest of head</head><body>rest of body<script type="text/javascript" src="http://localhost/static/foo/hash:.../a.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../c.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../y2.js"></script></body></html>
+ <link rel="stylesheet" type="text/css" href="http://localhost/static/:hash:.../foo/b.css" />
+ rest of head</head><body>rest of body<script type="text/javascript" src="http://localhost/static/:hash:.../foo/a.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/c.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/y2.js"></script></body></html>
There's also a function available to do this for the currently needed
resources::
>>> print resource.render_topbottom_into_html(html)
<html><head>
- <link rel="stylesheet" type="text/css" href="http://localhost/static/foo/hash:.../b.css" />
- rest of head</head><body>rest of body<script type="text/javascript" src="http://localhost/static/foo/hash:.../a.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../c.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../y2.js"></script></body></html>
+ <link rel="stylesheet" type="text/css" href="http://localhost/static/:hash:.../foo/b.css" />
+ rest of head</head><body>rest of body<script type="text/javascript" src="http://localhost/static/:hash:.../foo/a.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/c.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/y2.js"></script></body></html>
Using WSGI middleware to insert into HTML
=========================================
@@ -1085,9 +1085,9 @@
>>> print res.body
<html><head>
- <link rel="stylesheet" type="text/css" href="http://localhost/static/foo/hash:.../b.css" />
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../a.js"></script>
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../c.js"></script>
+ <link rel="stylesheet" type="text/css" href="http://localhost/static/:hash:.../foo/b.css" />
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/a.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/c.js"></script>
</head><body</body></html>
When we set the response Content-Type to non-HTML, the middleware
@@ -1121,7 +1121,7 @@
>>> c.base_url = 'http://localhost/static'
>>> top, bottom = c.render_topbottom()
>>> print top
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../l1.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/l1.js"></script>
>>> print bottom
<BLANKLINE>
@@ -1137,7 +1137,7 @@
>>> print top
<BLANKLINE>
>>> print bottom
- <script type="text/javascript" src="http://localhost/static/foo/hash:.../l1.js"></script>
+ <script type="text/javascript" src="http://localhost/static/:hash:.../foo/l1.js"></script>
Generating resource code
========================
@@ -1257,7 +1257,7 @@
>>> inclusion_renderers['.unknown'] = render_unknown
>>> render_inclusions([a6], 'http://localhost/static/')
- '<link rel="unknown" href="http://localhost/static/foo/hash:.../nothing.unknown" />'
+ '<link rel="unknown" href="http://localhost/static/:hash:.../foo/nothing.unknown" />'
Resource publisher
@@ -1268,7 +1268,11 @@
>>> from hurry.resource.publisher import Publisher
>>> from paste.fixture import TestApp
- >>> app = TestApp(Publisher())
+ >>> from paste.httpexceptions import HTTPNotFound
+ >>> class NoFindNoResource(object):
+ ... def __call__(self, environ, start_response):
+ ... return HTTPNotFound()(environ, start_response)
+ >>> app = TestApp(Publisher(NoFindNoResource()))
We don't do anything fancy if the resource can not be found, but raise 404.
@@ -1279,19 +1283,19 @@
The resources are handled by paste.fileapp.DirectoryApp, which sets the
ETag header, among other things::
- >>> res = app.get('/foo/style.css')
- >>> print res.body
+ <<< res = app.get('/foo/style.css')
+ <<< print res.body
body {
color: #f00;
}
- >>> headers = dict(res.headers)
- >>> 'ETag' in headers
+ <<< headers = dict(res.headers)
+ <<< 'ETag' in headers
True
When we find the 'hash' marker in the requested URL, we send headers that let
the user agent cache the resources for a long time.
- >>> res = app.get('/foo/hash:12345/style.css')
+ >>> res = app.get('/:hash:12345/foo/style.css')
>>> headers = dict(res.headers)
>>> 'Expires' in headers
True
@@ -1300,7 +1304,7 @@
We don't set cache-control headers on non-successful responses::
- >>> res = app.get('/foo/hash:12345/notfound.css', expect_errors=True)
+ >>> res = app.get('/:hash:12345/foo/notfound.css', expect_errors=True)
>>> headers = dict(res.headers)
>>> 'Expires' in headers
False
Modified: hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/__init__.py
===================================================================
--- hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/__init__.py 2010-11-19 12:16:15 UTC (rev 118488)
+++ hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/__init__.py 2010-11-19 12:44:34 UTC (rev 118489)
@@ -21,6 +21,8 @@
global hashing
hashing = enable
+hash_signature = 'hash'
+
devmode = False
def configure_devmode(enable=True):
Modified: hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/core.py
===================================================================
--- hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/core.py 2010-11-19 12:16:15 UTC (rev 118488)
+++ hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/core.py 2010-11-19 12:44:34 UTC (rev 118489)
@@ -28,8 +28,8 @@
self.path = os.path.join(caller_dir(), rootpath)
def hash(self):
- # Only compute the checksum if (1) it has not been computed before OR
- # (2) we are in development mode.
+ # Only compute the checksum if (1) it has not been computed
+ # before or (2) we are in development mode.
if self._hash is None or hurry.resource.devmode:
self._hash = hurry.resource.hash.checksum(self.path)
return self._hash
@@ -434,21 +434,22 @@
hash_cache = {}
if base_url and not base_url.endswith('/'):
base_url += '/'
+
+ signature = ''
for inclusion in inclusions:
library = inclusion.library
- library_url = base_url + inclusion.library.name + '/'
if hurry.resource.hashing:
- # For every request, compute the hash of each library only once.
- # XXX This is a suboptimal optimization that we would like to factor
- # out.
+ # For every request, compute the hash of each library
+ # only once. XXX This is a suboptimal optimization that
+ # we would like to factor out.
hash = hash_cache.get(library.name)
if hash is None:
hash = library.hash()
hash_cache[library.name] = hash
- library_url += 'hash:%s/' % hash
-
- result.append(render_inclusion(inclusion,
- library_url + inclusion.relpath))
+ signature = ':%s:%s/' % (hurry.resource.hash_signature, hash)
+ library_url = base_url + signature + inclusion.library.name + '/'
+ result.append(render_inclusion(
+ inclusion, library_url + inclusion.relpath))
return '\n'.join(result)
def render_inclusion(inclusion, url):
Modified: hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/publisher.py
===================================================================
--- hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/publisher.py 2010-11-19 12:16:15 UTC (rev 118488)
+++ hurry.resource/branches/janjaapdriessen-resource-publisher/src/hurry/resource/publisher.py 2010-11-19 12:44:34 UTC (rev 118489)
@@ -1,3 +1,4 @@
+import webob
from paste.request import path_info_pop, path_info_split
from paste.fileapp import DirectoryApp, CACHE_CONTROL, EXPIRES
from paste.httpexceptions import HTTPNotFound
@@ -15,17 +16,34 @@
class Publisher(object):
- def __init__(self):
+ def __init__(self, app, **local_conf):
+ self._wrapped_app = app
self.directory_apps = {}
for library in hurry.resource.libraries():
app = FilterHiddenDirectoryApp(library.path)
self.directory_apps[library.name] = app
def __call__(self, environ, start_response):
- # When configured through Paste#urlmap, the WSGI environ['PATH_INFO']
- # does not contain the mapping URL segment any more.
+ path = environ['PATH_INFO']
+ if hurry.resource.hash_signature not in path:
+ # There's no hash signature found in the path, so we
+ # cannot publish it from here. Leave the response to the
+ # wrapped app.
+ request = webob.Request(environ)
+ response = request.get_response(self._wrapped_app)
+ return response(environ, start_response)
- library_name = path_info_pop(environ)
+ library_name = ''
+ next_ = path_info_pop(environ)
+ while next_:
+ if next_.startswith(':%s:' % hurry.resource.hash_signature):
+ # Skip over hash signature segment. The library name
+ # will be that of the next step.
+ library_name = path_info_pop(environ)
+ break
+ next_ = path_info_pop(environ)
+ print 'STEPPIE', library_name, path, environ['PATH_INFO']
+
try:
directory_app = self.directory_apps[library_name]
except KeyError:
@@ -39,16 +57,8 @@
EXPIRES.update(headers, delta=expires)
return start_response(status, headers, exc_info)
- response = start_response
-
- next_segment = path_info_split(environ['PATH_INFO'])[0]
- if next_segment is not None and next_segment.startswith('hash:'):
- # Our hashed urls start with 'hash:'. Skip these URL segments.
- path_info_pop(environ)
- response = cache_header_start_response
-
+ response = cache_header_start_response
return directory_app(environ, response)
-
-def make_publisher(global_conf):
- return Publisher()
+def make_publisher(app, global_conf, **local_conf):
+ return Publisher(app, **local_conf)
More information about the checkins
mailing list