# 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)) + "
" + + "Resource: " + html.PRE(reflect.safe_repr(resrc)) + "
" + + "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)) + "
" + - "Resource: " + html.PRE(reflect.safe_repr(resrc)) + "
" + - "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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