Skip to content

Commit

Permalink
only uppercase HTTP methods are allowed. (fix for bug@#176415)
Browse files Browse the repository at this point in the history
  • Loading branch information
anandology committed Jan 4, 2008
1 parent 77a888e commit ca35d12
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 6 deletions.
2 changes: 1 addition & 1 deletion test/alltests.py
@@ -1,7 +1,7 @@
import webtest

def suite():
modules = ["doctests", "db"]
modules = ["doctests", "db", "application"]
return webtest.suite(modules)

if __name__ == "__main__":
Expand Down
53 changes: 53 additions & 0 deletions test/application.py
@@ -0,0 +1,53 @@
import webtest
import time

import web

data = """
import web
urls = ("/", "%(classname)s")
app = web.application(urls, globals(), autoreload=True)
class %(classname)s:
def GET(self):
return "%(output)s"
"""

def write(filename, data):
f = open(filename, 'w')
f.write(data)
f.close()

class ApplicationTest(webtest.TestCase):
def test_reloader(self):
write('foo.py', data % dict(classname='a', output='a'))
import foo
app = foo.app

self.assertEquals(app.request('/').data, 'a')

# test class change
time.sleep(1)
write('foo.py', data % dict(classname='a', output='b'))
self.assertEquals(app.request('/').data, 'b')

# test urls change
time.sleep(1)
write('foo.py', data % dict(classname='c', output='c'))
self.assertEquals(app.request('/').data, 'c')

def testUppercaseMethods(self):
urls = ("/", "hello")
app = web.application(urls, locals())
class hello:
def GET(self): return "hello"
def internal(self): return "secret"

response = app.request('/', method='internal')
self.assertEquals(response.status, '405 Method Not Allowed')

if __name__ == '__main__':
webtest.main()

8 changes: 7 additions & 1 deletion web/application.py
Expand Up @@ -165,7 +165,12 @@ def is_generator(x): return x and hasattr(x, 'next')

def wsgi(env, start_resp):
self.load(env)

try:
# allow uppercase methods only
if web.ctx.method.upper() != web.ctx.method:
raise web.nomethod()

result = self.handle_with_processors()
except NotFound:
web.ctx.status = "404 Not Found"
Expand Down Expand Up @@ -451,10 +456,11 @@ def __call__(self):
def check(self, mod):
try:
mtime = os.stat(mod.__file__).st_mtime
except (AttributeError, OSError, IOError):
except (AttributeError, OSError, IOError):
return
if mod.__file__.endswith('.pyc') and os.path.exists(mod.__file__[:-1]):
mtime = max(os.stat(mod.__file__[:-1]).st_mtime, mtime)

if mod not in self.mtimes:
self.mtimes[mod] = mtime
elif self.mtimes[mod] < mtime:
Expand Down
11 changes: 7 additions & 4 deletions web/webapi.py
Expand Up @@ -124,13 +124,16 @@ def __init__(self, url):

class NoMethod(HTTPError):
"""A `405 Method Not Allowed` error."""
def __init__(self, cls):
def __init__(self, cls=None):
status = '405 Method Not Allowed'
headers = {}
headers['Content-Type'] = 'text/html'
headers['Allow'] = ', '.join([method for method in \
['GET', 'HEAD', 'POST', 'PUT', 'DELETE'] \
if hasattr(cls, method)])

methods = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE']
if cls:
methods = [method for method in methods if hasattr(cls, method)]

headers['Allow'] = ', '.join(methods)
data = None
HTTPError.__init__(self, status, headers, data)

Expand Down

0 comments on commit ca35d12

Please sign in to comment.