'''Using deliverance as middleware with proxying.

This turned out to be none too trivial to do -- all the examples on the
internet seemd to focus on using deliverance-proxy or using it in an ini file.
The following were of help: 

  * http://codespeak.net/svn/z3/deliverance/sandbox/ianb/ploneconf2008/index.txt
  * http://www.gawel.org/weblog/en/2008/12/skinning-with-pyquery-and-deliverance
  * http://macadames.wordpress.com/2009/05/23/some-deliverance-tips/
  * http://www.coactivate.org/projects/deliverance/lists/deliverance-discussion/archive/2009/05/1241444934295/forum_view
  * http://www.sixfeetup.com/blog/2009/4/27/deploying-plone-and-zine-together-with-deliverance-using-repoze

Deliverance Problems with gzipped Content
=========================================

It seems that Deliverance has problems with gzipped content (at least when
proxying). When deliverating gzip-deflated content you get errors like:

Content Encoding Error

The page you are trying to view cannot be shown because it uses an invalid or
unsupported form of compression.

Turns out (it seems) that deliverance automatically gunzips the content but
fails to remove the relevant header leading to the browser getting confused
(content is not compressed but headers say it is ...). Fix is as follows:

--- deliverance/middleware.py   (revision 67469)
+++ deliverance/middleware.py   (working copy)
@@ -89,6 +89,13 @@
             self.known_titles[req.url] = self._get_title(resp.body)
             self.known_html.add(req.url)
         resp = rule_set.apply_rules(req, resp, resource_fetcher, log)
+        if resp.headers.get('Content-Encoding', '') == 'gzip':
+            # this middleware appears to unzip gzipped stuff
+            # if we do not delete content encoding browser will receive
+            # unencoded content but a Content-Encoding header telling it that
+            # it gzipped and get confused with the result being
+            # a mysterious content encoding error
+            del resp.headers['Content-Encoding']
         if clientside:
             resp.decode_content()
             resp.body = self._substitute_jsenable(resp.body)
'''
import os
import paste.urlmap
import deliverance.middleware
import paste.proxy
from webob import Request, Response

HERE = os.path.dirname(__file__)

def make_app():
    app = paste.urlmap.URLMap()

    # set up theme consistent with our rules file
    theme_path = os.path.join(HERE, 'demo-template.html')
    app['/theme.html'] = Response(open(theme_path).read())

    rules_path = os.path.join('demo-rules.xml')
    rules = open(rules_path).read()
    app['/rules.xml'] = Response(rules, content_type="application/xml")

    # Wow, this took *hours* to get right since it involved a lot of debugging
    #
    # 0. Using simple Proxy no transformation was happening (because no
    # matching tag were found). Did work in deliverance-proxy though ...
    # (Not really clear how good Proxy is but not clear what's better -
    # http://pythonpaste.org/archives/message/20090707.162854.e2f6ecd9.en.html)
    #
    # 1. Checked it work with a simple Response (as below)
    #
    # 2. Checked direct proxying working with no deliverance
    #
    # 3. Tried using wsgiproxy instead but that barfed on some weird lxml.etree
    # error (XMLSyntaxError: None)
    #
    # 4. Wrapped proxy ourselves as above - doing this revealed that everything
    # was gzip encoded. Not clear why this should be a problem (after all
    # deliverance-proxy was working though I note that seems hand-crafted) but
    # it was a possibility so decided to try and de-code content
    #
    # 5. After various searching came across
    # http://blog.ianbicking.org/2008/07/30/making-a-proxy-with-wsgi-and-lxml/
    # and modified. This did the trick
    #
    # 6. NB: doing the decoding obviates the need for the gzip-deflated hack
    # to deliverance mentioned above

    dest = 'http://blog.openshakespeare.org/'
    # dest = 'http://knowledgeforge.net/ckan/'

    # import wsgiproxy.app
    # app['/'] = wsgiproxy.app.WSGIProxyApp(dest)
    # app['/'] = paste.proxy.Proxy(dest)

    class MyProxy(object):
        def __init__(self, dest):
           self.proxy = paste.proxy.Proxy(dest) 
        
        def __call__(self, environ, start_response):
            req = Request(environ)
            res = req.get_response(self.proxy)
            # result = ''
            # for out in self.proxy(environ, start_response):
            #    result += out
            # res = Response(result)
            res.decode_content()
            return res(environ, start_response)

    app['/'] = MyProxy(dest)
    app['/test-nonproxy'] = Response('''\
    <html><title>About this site</title></html>
    <body>
    <div id="content">
    This is all about this site.
    </div>
    <div id="footer">a footer that will be ignored</div>
    </body></html>
    ''')

    from deliverance.middleware import DeliveranceMiddleware, SubrequestRuleGetter
    from deliverance.log import PrintingLogger
    import logging
    deliv = DeliveranceMiddleware(app, SubrequestRuleGetter('/rules.xml'),
        PrintingLogger,
        log_factory_kw=dict(print_level=logging.WARNING))
    return deliv
    # return app

if __name__ == '__main__':
    import paste.httpserver
    app = make_app()
    paste.httpserver.serve(app, port=5000)

