# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: esteve@fluidinfo.com-20090330154531-smvmdg947gmchi7a
# target_branch: ../trunk/
# testament_sha1: f801b703f4d6c20a800529a0cec961ea6b079e4d
# timestamp: 2009-03-30 19:05:48 +0200
# base_revision_id: svn-v4:bbbe8e31-12d6-0310-92fd-\
#   ac37d47ddeeb:trunk:26540
# 
# Begin patch
=== modified file 'twisted/web/server.py'
--- twisted/web/server.py	2009-01-28 21:46:48 +0000
+++ twisted/web/server.py	2009-03-30 15:45:31 +0000
@@ -127,76 +127,86 @@
 
 
     def render(self, resrc):
-        try:
-            body = resrc.render(self)
-        except UnsupportedMethod, e:
-            allowedMethods = e.allowedMethods
-            if (self.method == "HEAD") and ("GET" in allowedMethods):
-                # We must support HEAD (RFC 2616, 5.1.1).  If the
-                # resource doesn't, fake it by giving the resource
-                # a 'GET' request and then return only the headers,
-                # not the body.
-                log.msg("Using GET to fake a HEAD request for %s" %
-                        (resrc,))
-                self.method = "GET"
-                body = resrc.render(self)
+        def _cbRender(body):
+            if body == NOT_DONE_YET:
+                warnings.warn(
+                    "Returning NOT_DONE_YET is deprecated, return a Deferred instead.",
+                    DeprecationWarning, stacklevel=2)
+                return
+            if type(body) is not types.StringType:
+                body = resource.ErrorPage(
+                    http.INTERNAL_SERVER_ERROR,
+                    "Request did not return a string",
+                    "Request: " + html.PRE(reflect.safe_repr(self)) + "<br />" +
+                    "Resource: " + html.PRE(reflect.safe_repr(resrc)) + "<br />" +
+                    "Value: " + html.PRE(reflect.safe_repr(body))).render(self)
 
-                if body is NOT_DONE_YET:
-                    log.msg("Tried to fake a HEAD request for %s, but "
-                            "it got away from me." % resrc)
-                    # Oh well, I guess we won't include the content length.
-                else:
+            if self.method == "HEAD":
+                if len(body) > 0:
+                    # This is a Bad Thing (RFC 2616, 9.4)
+                    log.msg("Warning: HEAD request %s for resource %s is"
+                            " returning a message body."
+                            "  I think I'll eat it."
+                            % (self, resrc))
                     self.setHeader('content-length', str(len(body)))
-
                 self.write('')
-                self.finish()
-                return
-
-            if self.method in (supportedMethods):
-                # We MUST include an Allow header
-                # (RFC 2616, 10.4.6 and 14.7)
-                self.setHeader('Allow', allowedMethods)
-                s = ('''Your browser approached me (at %(URI)s) with'''
-                     ''' the method "%(method)s".  I only allow'''
-                     ''' the method%(plural)s %(allowed)s here.''' % {
-                    'URI': self.uri,
-                    'method': self.method,
-                    'plural': ((len(allowedMethods) > 1) and 's') or '',
-                    'allowed': string.join(allowedMethods, ', ')
-                    })
-                epage = resource.ErrorPage(http.NOT_ALLOWED,
-                                           "Method Not Allowed", s)
-                body = epage.render(self)
             else:
-                epage = resource.ErrorPage(http.NOT_IMPLEMENTED, "Huh?",
-                                           "I don't know how to treat a"
-                                           " %s request." % (self.method,))
-                body = epage.render(self)
-        # end except UnsupportedMethod
-
-        if body == NOT_DONE_YET:
-            return
-        if type(body) is not types.StringType:
-            body = resource.ErrorPage(
-                http.INTERNAL_SERVER_ERROR,
-                "Request did not return a string",
-                "Request: " + html.PRE(reflect.safe_repr(self)) + "<br />" +
-                "Resource: " + html.PRE(reflect.safe_repr(resrc)) + "<br />" +
-                "Value: " + html.PRE(reflect.safe_repr(body))).render(self)
-
-        if self.method == "HEAD":
-            if len(body) > 0:
-                # This is a Bad Thing (RFC 2616, 9.4)
-                log.msg("Warning: HEAD request %s for resource %s is"
-                        " returning a message body."
-                        "  I think I'll eat it."
-                        % (self, resrc))
                 self.setHeader('content-length', str(len(body)))
-            self.write('')
-        else:
-            self.setHeader('content-length', str(len(body)))
-            self.write(body)
-        self.finish()
+                self.write(body)
+            self.finish()
+
+        def _ebRender(fail):
+            r = fail.trap(UnsupportedMethod)
+            if r == UnsupportedMethod:
+                allowedMethods = fail.value.allowedMethods
+
+                if (self.method == "HEAD") and ("GET" in allowedMethods):
+                    # We must support HEAD (RFC 2616, 5.1.1).  If the
+                    # resource doesn't, fake it by giving the resource
+                    # a 'GET' request and then return only the headers,
+                    # not the body.
+                    log.msg("Using GET to fake a HEAD request for %s" %
+                            (resrc,))
+                    self.method = "GET"
+                    body = resrc.render(self)
+
+                    if body is NOT_DONE_YET:
+                        log.msg("Tried to fake a HEAD request for %s, but "
+                                "it got away from me." % resrc)
+                        # Oh well, I guess we won't include the content length.
+                    else:
+                        self.setHeader('content-length', str(len(body)))
+
+                    self.write('')
+                    self.finish()
+                    return
+
+                if self.method in (supportedMethods):
+                    # We MUST include an Allow header
+                    # (RFC 2616, 10.4.6 and 14.7)
+                    self.setHeader('Allow', allowedMethods)
+                    s = ('''Your browser approached me (at %(URI)s) with'''
+                         ''' the method "%(method)s".  I only allow'''
+                         ''' the method%(plural)s %(allowed)s here.''' % {
+                        'URI': self.uri,
+                        'method': self.method,
+                        'plural': ((len(allowedMethods) > 1) and 's') or '',
+                        'allowed': string.join(allowedMethods, ', ')
+                        })
+                    epage = resource.ErrorPage(http.NOT_ALLOWED,
+                                               "Method Not Allowed", s)
+                    body = epage.render(self)
+                else:
+                    epage = resource.ErrorPage(http.NOT_IMPLEMENTED, "Huh?",
+                                               "I don't know how to treat a"
+                                               " %s request." % (self.method,))
+                    body = epage.render(self)
+                # end except UnsupportedMethod
+                return _cbRender(body)
+
+        d = defer.maybeDeferred(resrc.render, self)
+        d.addCallbacks(_cbRender, _ebRender)
+        return d
 
     def processingFailed(self, reason):
         log.err(reason)

# Begin bundle
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
