Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Changeset 823

Show
Ignore:
Timestamp:
11/14/05 02:29:11
Author:
fumanchu
Message:

Modified _cpGlobalInformation to _cpGlobalHandler, and moved its call from _cphttptools to _cputil.get_object_trail. Also made it handle all methods, and fixed the NameError? it was generating, and wrote a test.

Also, fixed test_core and test_config, which weren't honoring the value of "server.protocolVersion" set by test.py.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/cherrypy/_cphttptools.py

    r819 r823  
    6363            # right away. 
    6464            self.processRequestLine(requestLine) 
    65  
    66             # handles "OPTIONS * HTTP/1.1" requests 
    67             # we could avoid testing for the method value here but 
    68             # we still do it to avoid an useless call to getSpecialAttribute 
    69             # OPTIONS request should be very rare compare to regular requests 
    70             # let's not add too much overhead 
    71             if cherrypy.request.method == 'OPTIONS': 
    72                 if _cputil.getSpecialAttribute("_cpGlobalInformation")() == True: 
    73                     # if we had such a request we don't have to keep processing 
    74                     return 
    7565             
    7666            try: 
  • trunk/cherrypy/_cputil.py

    r816 r823  
    3131    else: 
    3232        nameList = objectpath.split('/') 
     33     
    3334    if nameList == ['global']: 
    34         nameList = ['global_'] 
     35        # Special-case a Request-URI of * to allow for our default handler. 
     36        root = getattr(cherrypy, 'root', None) 
     37        if root is None: 
     38            return [('root', None), ('global_', None), ('index', None)] 
     39        gh = getattr(root, 'global_', _cpGlobalHandler) 
     40        return [('root', cherrypy.root), ('global_', gh), ('index', None)] 
     41     
    3542    nameList = ['root'] + nameList + ['index'] 
    3643     
     
    7178        raise cherrypy.HTTPError(500, msg) 
    7279 
    73 def _cpGlobalInformation(): 
    74     """Handles OPTIONS * HTTP/1.1 requests""" 
     80def _cpGlobalHandler(): 
     81    """Default handler for a Request-URI of '*'.""" 
     82    response = cherrypy.response 
     83    response.headerMap['Content-Type'] = 'text/plain' 
     84     
     85    # OPTIONS is defined in HTTP 1.1 and greater 
    7586    request = cherrypy.request 
    76     if request.method == 'OPTIONS': 
    77         # this normally should be * but processRequestLine 
    78         # switched it to 'global' for the configuration handling 
    79         if request.path == 'global': 
    80             # OPTIONS is defined in HTTP 1.1 
    81             if request.version >= '1.1': 
    82                 response = cherrypy.response 
    83                 response.body = [] 
    84                 response.status = '200 OK' 
    85                 response.headerMap['Allow'] = 'HEAD, GET, POST, PUT, OPTIONS' 
    86                 response.headerMap['Content-Length'] = 0 
    87                 response.headerMap['Content-Type'] = 'text/plain' 
    88                 response.finalize() 
    89                 getSpecialAttribute("_cpLogAccess")() 
    90                 return True 
    91     return False 
     87    if request.method == 'OPTIONS' and request.version >= 1.1: 
     88        response.headerMap['Allow'] = 'HEAD, GET, POST, PUT, OPTIONS' 
     89    else: 
     90        response.headerMap['Allow'] = 'HEAD, GET, POST' 
     91    return "" 
     92_cpGlobalHandler.exposed = True 
    9293 
    9394def logtime(): 
  • trunk/cherrypy/test/test_config.py

    r778 r823  
    3232               'server.environment': 'production', 
    3333               'server.showTracebacks': True, 
    34                'server.protocolVersion': "HTTP/1.1", 
    3534               }, 
    3635    '/': { 
  • trunk/cherrypy/test/test_core.py

    r819 r823  
    326326               'server.environment': 'production', 
    327327               'server.showTracebacks': True, 
    328                'server.protocolVersion': "HTTP/1.1", 
    329328               }, 
    330329    '/flatten': { 
     
    547546        # HTTPRedirect on error 
    548547        self.getPage("/redirect/error/") 
    549         self.assertStatus('303 See Other'
     548        self.assertStatus(('302 Found', '303 See Other')
    550549        self.assertInBody('/errpage') 
    551550         
     
    553552        self.getPage("/redirect/stringify") 
    554553        self.assertStatus('200 OK') 
    555         self.assertBody("(['http://127.0.0.1:8000/'], 303)") 
     554        protocol = cherrypy.config.get('server.protocolVersion') 
     555        if protocol == "HTTP/1.1": 
     556            self.assertBody("(['http://127.0.0.1:8000/'], 303)") 
     557        else: 
     558            self.assertBody("(['http://127.0.0.1:8000/'], 302)") 
    556559     
    557560    def testCPFilterList(self): 
     
    616619     
    617620    def testRanges(self): 
    618         self.getPage("/ranges/get_ranges", [('Range', 'bytes=3-6')]) 
    619         self.assertBody("[(3, 7)]") 
    620          
    621         # Test multiple ranges and a suffix-byte-range-spec, for good measure. 
    622         self.getPage("/ranges/get_ranges", [('Range', 'bytes=2-4,-1')]) 
    623         self.assertBody("[(2, 5), (7, 8)]") 
    624          
    625         # Get a partial file. 
    626         self.getPage("/ranges/slice_file", [('Range', 'bytes=2-5')]) 
    627         self.assertStatus("206 Partial Content") 
    628         self.assertHeader("Content-Type", "text/html") 
    629         self.assertHeader("Content-Range", "bytes 2-5/14") 
    630         self.assertBody("llo,") 
    631          
    632         # What happens with overlapping ranges (and out of order, too)? 
    633         self.getPage("/ranges/slice_file", [('Range', 'bytes=4-6,2-5')]) 
    634         self.assertStatus("206 Partial Content") 
    635         ct = "" 
    636         for k, v in self.headers: 
    637             if k.lower() == "content-type": 
    638                 ct = v 
    639                 break 
    640         expected_type = "multipart/byteranges; boundary=" 
    641         self.assert_(ct.startswith(expected_type)) 
    642         boundary = ct[len(expected_type):] 
    643         expected_body = """--%s 
     621        protocol = cherrypy.config.get('server.protocolVersion') 
     622        if protocol == "HTTP/1.1": 
     623            self.getPage("/ranges/get_ranges", [('Range', 'bytes=3-6')]) 
     624            self.assertBody("[(3, 7)]") 
     625             
     626            # Test multiple ranges and a suffix-byte-range-spec, for good measure. 
     627            self.getPage("/ranges/get_ranges", [('Range', 'bytes=2-4,-1')]) 
     628            self.assertBody("[(2, 5), (7, 8)]") 
     629             
     630            # Get a partial file. 
     631            self.getPage("/ranges/slice_file", [('Range', 'bytes=2-5')]) 
     632            self.assertStatus("206 Partial Content") 
     633            self.assertHeader("Content-Type", "text/html") 
     634            self.assertHeader("Content-Range", "bytes 2-5/14") 
     635            self.assertBody("llo,") 
     636             
     637            # What happens with overlapping ranges (and out of order, too)? 
     638            self.getPage("/ranges/slice_file", [('Range', 'bytes=4-6,2-5')]) 
     639            self.assertStatus("206 Partial Content") 
     640            ct = "" 
     641            for k, v in self.headers: 
     642                if k.lower() == "content-type": 
     643                    ct = v 
     644                    break 
     645            expected_type = "multipart/byteranges; boundary=" 
     646            self.assert_(ct.startswith(expected_type)) 
     647            boundary = ct[len(expected_type):] 
     648            expected_body = """--%s 
    644649Content-type: text/html 
    645650Content-range: bytes 4-6/14 
     
    652657llo,  
    653658--%s""" % (boundary, boundary, boundary) 
    654         self.assertBody(expected_body) 
    655         self.assertHeader("Content-Length") 
    656          
    657         # Test "416 Requested Range Not Satisfiable" 
    658         self.getPage("/ranges/slice_file", [('Range', 'bytes=2300-2900')]) 
    659         self.assertStatus("416 Requested Range Not Satisfiable") 
    660         self.assertHeader("Content-Range", "bytes */14") 
     659            self.assertBody(expected_body) 
     660            self.assertHeader("Content-Length") 
     661             
     662            # Test "416 Requested Range Not Satisfiable" 
     663            self.getPage("/ranges/slice_file", [('Range', 'bytes=2300-2900')]) 
     664            self.assertStatus("416 Requested Range Not Satisfiable") 
     665            self.assertHeader("Content-Range", "bytes */14") 
     666        else: 
     667            self.getPage("/ranges/slice_file", [('Range', 'bytes=2-5')]) 
     668            self.assertStatus("200 OK") 
     669            self.assertBody("Hello, world\r\n") 
    661670     
    662671    def testExpect(self): 
     
    764773        self.assertHeader("Content-Length", "0") 
    765774         
     775        # Now be really dastardly and delete our custom global_ handler, 
     776        # to see if the default one works. 
     777        del Root.global_ 
     778        self.getPage("*", method="OPTIONS") 
     779        self.assertStatus("200 OK") 
     780        self.assertHeader("Allow", 'HEAD, GET, POST, PUT, OPTIONS') 
     781         
    766782        # For method dispatchers: make sure that an HTTP method doesn't 
    767783        # collide with a virtual path atom. If you build HTTP-method 

Hosted by WebFaction

Log in as guest/cpguest to create tickets