Ticket #253: render-deferred.patch

File render-deferred.patch, 5.0 KB (added by jknight, 11 years ago)
  • server.py

    old new  
    160160        except: 
    161161            self.processingFailed(failure.Failure()) 
    162162 
    163  
    164     def render(self, resrc): 
    165         try: 
    166             body = resrc.render(self) 
    167         except UnsupportedMethod, e: 
    168             allowedMethods = e.allowedMethods 
    169             if (self.method == "HEAD") and ("GET" in allowedMethods): 
    170                 # We must support HEAD (RFC 2616, 5.1.1).  If the 
    171                 # resource doesn't, fake it by giving the resource 
    172                 # a 'GET' request and then return only the headers, 
    173                 # not the body. 
    174                 log.msg("Using GET to fake a HEAD request for %s" % 
    175                         (resrc,)) 
    176                 self.method = "GET" 
    177                 body = resrc.render(self) 
    178  
    179                 if body is NOT_DONE_YET: 
    180                     log.msg("Tried to fake a HEAD request for %s, but " 
    181                             "it got away from me." % resrc) 
    182                     # Oh well, I guess we won't include the content length. 
    183                 else: 
    184                     self.setHeader('content-length', str(len(body))) 
    185  
    186                 self.write('') 
    187                 self.finish() 
    188                 return 
    189  
    190             if self.method in (supportedMethods): 
    191                 # We MUST include an Allow header 
    192                 # (RFC 2616, 10.4.6 and 14.7) 
    193                 self.setHeader('Allow', allowedMethods) 
    194                 s = ('''Your browser approached me (at %(URI)s) with''' 
    195                      ''' the method "%(method)s".  I only allow''' 
    196                      ''' the method%(plural)s %(allowed) here.''' % { 
    197                     'URI': self.uri, 
    198                     'method': self.method, 
    199                     'plural': ((len(allowedMethods) > 1) and 's') or '', 
    200                     'allowed': string.join(allowedMethods, ', ') 
    201                     }) 
    202                 epage = error.ErrorPage(http.NOT_ALLOWED, 
    203                                         "Method Not Allowed", s) 
    204                 body = epage.render(self) 
    205             else: 
    206                 epage = error.ErrorPage(http.NOT_IMPLEMENTED, "Huh?", 
    207                                         """I don't know how to treat a""" 
    208                                         """ %s request.""" 
    209                                         % (self.method)) 
    210                 body = epage.render(self) 
    211         # end except UnsupportedMethod 
    212  
     163    def _cbRender(self, body, resrc): 
     164 
    213165        if body == NOT_DONE_YET: 
    214166            return 
    215167        if type(body) is not types.StringType: 
     
    232184            self.setHeader('content-length', str(len(body))) 
    233185            self.write(body) 
    234186        self.finish() 
     187 
     188    def _ebRender(self, failure, resrc): 
     189        failure.trap(UnsupportedMethod) 
     190        e = failure.value 
     191        allowedMethods = e.allowedMethods 
     192        if (self.method == "HEAD") and ("GET" in allowedMethods): 
     193            # We must support HEAD (RFC 2616, 5.1.1).  If the 
     194            # resource doesn't, fake it by giving the resource 
     195            # a 'GET' request and then return only the headers, 
     196            # not the body. 
     197            log.msg("Using GET to fake a HEAD request for %s" % 
     198                    (resrc,)) 
     199            self.method = "GET" 
     200            body = resrc.render(self) 
     201 
     202            if body is NOT_DONE_YET: 
     203                log.msg("Tried to fake a HEAD request for %s, but " 
     204                        "it got away from me." % resrc) 
     205                # Oh well, I guess we won't include the content length. 
     206            else: 
     207                self.setHeader('content-length', str(len(body))) 
     208 
     209            self.write('') 
     210            self.finish() 
     211            return 
     212 
     213        if self.method in (supportedMethods): 
     214            # We MUST include an Allow header 
     215            # (RFC 2616, 10.4.6 and 14.7) 
     216            self.setHeader('Allow', allowedMethods) 
     217            s = ('''Your browser approached me (at %(URI)s) with''' 
     218                 ''' the method "%(method)s".  I only allow''' 
     219                 ''' the method%(plural)s %(allowed) here.''' % { 
     220                'URI': self.uri, 
     221                'method': self.method, 
     222                'plural': ((len(allowedMethods) > 1) and 's') or '', 
     223                'allowed': string.join(allowedMethods, ', ') 
     224                }) 
     225            epage = error.ErrorPage(http.NOT_ALLOWED, 
     226                                    "Method Not Allowed", s) 
     227            body = epage.render(self) 
     228        else: 
     229            epage = error.ErrorPage(http.NOT_IMPLEMENTED, "Huh?", 
     230                                    """I don't know how to treat a""" 
     231                                    """ %s request.""" 
     232                                    % (self.method)) 
     233            body = epage.render(self) 
     234 
     235    def render(self, resrc): 
     236        defer.maybeDeferred(resrc.render, self).addErrback(self._ebRender, resrc).addCallback(self._cbRender, resrc).addErrback(self.processingFailed) 
     237 
     238 
    235239 
    236240    def processingFailed(self, reason): 
    237241        log.err(reason)