import os
localDir = os.path.dirname(__file__)
logfile = os.path.join(localDir, "test_misc_tools.log")
import cherrypy
from cherrypy import tools
def setup_server():
class Root:
def index(self):
yield "Hello, world"
index.exposed = True
h = [("Content-Language", "en-GB"), ('Content-Type', 'text/plain')]
tools.response_headers(headers=h)(index)
def other(self):
return "salut"
other.exposed = True
other._cp_config = {
'tools.response_headers.on': True,
'tools.response_headers.headers': [("Content-Language", "fr"),
('Content-Type', 'text/plain')],
'tools.log_hooks.on': True,
}
class Accept:
_cp_config = {'tools.accept.on': True}
def index(self):
return 'Atom feed'
index.exposed = True
# In Python 2.4+, we could use a decorator instead:
# @tools.accept('application/atom+xml')
def feed(self):
return """
Unknown Blog
"""
feed.exposed = True
feed._cp_config = {'tools.accept.media': 'application/atom+xml'}
def select(self):
# We could also write this: mtype = cherrypy.lib.accept.accept(...)
mtype = tools.accept.callable(['text/html', 'text/plain'])
if mtype == 'text/html':
return "
Page Title
"
else:
return "PAGE TITLE"
select.exposed = True
class Referer:
def accept(self):
return "Accepted!"
accept.exposed = True
reject = accept
class AutoVary:
def index(self):
# Read a header directly with 'get'
ae = cherrypy.request.headers.get('Accept-Encoding')
# Read a header directly with '__getitem__'
cl = cherrypy.request.headers['Host']
# Read a header directly with '__contains__'
hasif = 'If-Modified-Since' in cherrypy.request.headers
# Read a header directly with 'has_key'
if hasattr(dict, 'has_key'):
# Python 2
has = cherrypy.request.headers.has_key('Range')
else:
# Python 3
has = 'Range' in cherrypy.request.headers
# Call a lib function
mtype = tools.accept.callable(['text/html', 'text/plain'])
return "Hello, world!"
index.exposed = True
conf = {'/referer': {'tools.referer.on': True,
'tools.referer.pattern': r'http://[^/]*example\.com',
},
'/referer/reject': {'tools.referer.accept': False,
'tools.referer.accept_missing': True,
},
'/autovary': {'tools.autovary.on': True},
}
root = Root()
root.referer = Referer()
root.accept = Accept()
root.autovary = AutoVary()
cherrypy.tree.mount(root, config=conf)
cherrypy.config.update({'log.error_file': logfile})
from cherrypy.test import helper
class ResponseHeadersTest(helper.CPWebCase):
setup_server = staticmethod(setup_server)
def testResponseHeadersDecorator(self):
self.getPage('/')
self.assertHeader("Content-Language", "en-GB")
self.assertHeader('Content-Type', 'text/plain;charset=utf-8')
def testResponseHeaders(self):
self.getPage('/other')
self.assertHeader("Content-Language", "fr")
self.assertHeader('Content-Type', 'text/plain;charset=utf-8')
class RefererTest(helper.CPWebCase):
setup_server = staticmethod(setup_server)
def testReferer(self):
self.getPage('/referer/accept')
self.assertErrorPage(403, 'Forbidden Referer header.')
self.getPage('/referer/accept',
headers=[('Referer', 'http://www.example.com/')])
self.assertStatus(200)
self.assertBody('Accepted!')
# Reject
self.getPage('/referer/reject')
self.assertStatus(200)
self.assertBody('Accepted!')
self.getPage('/referer/reject',
headers=[('Referer', 'http://www.example.com/')])
self.assertErrorPage(403, 'Forbidden Referer header.')
class AcceptTest(helper.CPWebCase):
setup_server = staticmethod(setup_server)
def test_Accept_Tool(self):
# Test with no header provided
self.getPage('/accept/feed')
self.assertStatus(200)
self.assertInBody('Unknown Blog')
# Specify exact media type
self.getPage('/accept/feed',
headers=[('Accept', 'application/atom+xml')])
self.assertStatus(200)
self.assertInBody('Unknown Blog')
# Specify matching media range
self.getPage('/accept/feed', headers=[('Accept', 'application/*')])
self.assertStatus(200)
self.assertInBody('Unknown Blog')
# Specify all media ranges
self.getPage('/accept/feed', headers=[('Accept', '*/*')])
self.assertStatus(200)
self.assertInBody('Unknown Blog')
# Specify unacceptable media types
self.getPage('/accept/feed', headers=[('Accept', 'text/html')])
self.assertErrorPage(406,
"Your client sent this Accept header: text/html. "
"But this resource only emits these media types: "
"application/atom+xml.")
# Test resource where tool is 'on' but media is None (not set).
self.getPage('/accept/')
self.assertStatus(200)
self.assertBody('Atom feed')
def test_accept_selection(self):
# Try both our expected media types
self.getPage('/accept/select', [('Accept', 'text/html')])
self.assertStatus(200)
self.assertBody('Page Title
')
self.getPage('/accept/select', [('Accept', 'text/plain')])
self.assertStatus(200)
self.assertBody('PAGE TITLE')
self.getPage('/accept/select',
[('Accept', 'text/plain, text/*;q=0.5')])
self.assertStatus(200)
self.assertBody('PAGE TITLE')
# text/* and */* should prefer text/html since it comes first
# in our 'media' argument to tools.accept
self.getPage('/accept/select', [('Accept', 'text/*')])
self.assertStatus(200)
self.assertBody('Page Title
')
self.getPage('/accept/select', [('Accept', '*/*')])
self.assertStatus(200)
self.assertBody('Page Title
')
# Try unacceptable media types
self.getPage('/accept/select', [('Accept', 'application/xml')])
self.assertErrorPage(
406,
"Your client sent this Accept header: application/xml. "
"But this resource only emits these media types: "
"text/html, text/plain.")
class AutoVaryTest(helper.CPWebCase):
setup_server = staticmethod(setup_server)
def testAutoVary(self):
self.getPage('/autovary/')
self.assertHeader(
"Vary",
'Accept, Accept-Charset, Accept-Encoding, '
'Host, If-Modified-Since, Range'
)