def main(argv=None): """http://aspen.io/cli/ """ try: # Do imports. # =========== # These are in here so that if you Ctrl-C during an import, the # KeyboardInterrupt is caught and ignored. Yes, that's how much I care. # No, I don't care enough to put aspen/__init__.py in here too. import os import logging import socket import sys import time import traceback from os.path import exists, join from aspen.server import restarter from aspen.website import Website log = logging.getLogger("aspen.cli") # Actual stuff. # ============= if argv is None: argv = sys.argv[1:] website = Website(argv) try: if hasattr(socket, "AF_UNIX"): if website.sockfam == socket.AF_UNIX: if exists(website.address): log.info("Removing stale socket.") os.remove(website.address) if website.port is not None: welcome = "port %d" % website.port else: welcome = website.address log.info("Starting %s engine." % website.engine.name) website.engine.bind() log.warn("Greetings, program! Welcome to %s." % welcome) if website.changes_kill: log.info("Aspen will die when files change.") restarter.install(website) website.start() except KeyboardInterrupt, SystemExit: pass except: traceback.print_exc() finally: if hasattr(socket, "AF_UNIX"): if website.sockfam == socket.AF_UNIX: if exists(website.address): os.remove(website.address) website.stop()
def test_github_oauth_url_not_susceptible_to_injection_attack(self): expected = 'https://github.com/login/oauth/authorize?client_id=cheese&redirect_uri=nuts?data=b3B0LWluLC9vbi90d2l0dGVyLyI+PGltZyBzcmM9eCBvbmVycm9yPXByb21wdCgxKTs+Lw==' website = Website([]) website.github_client_id = 'cheese' website.github_callback = 'nuts' actual = github.oauth_url(website=website, action='opt-in', then=self.xss) assert actual == expected
def test_github_oauth_url_not_susceptible_to_injection_attack(self): expected = 'https://github.com/login/oauth/authorize?client_id=cheese&redirect_uri=nuts?data=b3B0LWluLC9vbi90d2l0dGVyLyI+PGltZyBzcmM9eCBvbmVycm9yPXByb21wdCgxKTs+Lw==' website = Website([]) website.github_client_id = 'cheese' website.github_callback= 'nuts' actual = github.oauth_url( website=website , action='opt-in' , then=self.xss ) assert actual == expected, actual
def __call__(self, path='/', *a): """Given an URL path, return This only allows you to simulate GET requests with no querystring, so it's limited. But it's a something. Kind of. Almost. """ website = Website(self.argv + list(a)) request = StubRequest(path) request.website = website response = website.handle_safely(request) return response
def __call__(self, path='/', *a): """Given an URL path, return This only allows you to simulate GET requests with no querystring, so it's limited. But it's a something. Kind of. Almost. """ website = Website(self.argv + list(a)) request = StubRequest(path) request.website = website response = website.handle(request) return response
def __call__(self, path='/', *a): """Given an URL path, return This only allows you to simulate GET requests with no querystring, so it's limited. But it's a something. Kind of. Almost. """ path = path.encode('ascii') # StubRequest/Request takes bytestings only. website = Website(self.argv + list(a)) request = StubRequest(path) request.website = website response = website.handle_safely(request) return response
def test_call_wraps_wsgi_middleware(): website = Website([]) website.wsgi_app = TestMiddleware(website.wsgi_app) respond = [False, False] def start_response_should_404(status, headers): assert status.lower().strip() == '404 not found' respond[0] = True website(build_environ('/'), start_response_should_404) assert respond[0] def start_response_should_200(status, headers): assert status.lower().strip() == '200 ok' respond[1] = True website(build_environ('/middleware'), start_response_should_200) assert respond[1]
def test_call_wraps_wsgi_middleware(): website = Website([]) website.wsgi_app = TestMiddleware(website.wsgi_app) respond = [False, False] def start_response_should_404(status, headers): assert status.lower().strip() == '404 not found', status respond[0] = True website(build_environ('/'), start_response_should_404) assert respond[0] def start_response_should_200(status, headers): assert status.lower().strip() == '200 ok', status respond[1] = True website(build_environ('/middleware'), start_response_should_200) assert respond[1]
def setUp(self): website = Website([ '--www_root', WWW_ROOT, '--project_root', PROJECT_ROOT, '--show_tracebacks', b'yes' ]) redis.flushdb() self.client = TestClient(website)
def main(argv=None): try: configuration = Configuration(argv) configuration.app = app = Application() website = Website(configuration) configuration.website = website # to support re-handling, especially website = configuration.hooks.run('startup', website) # change current working directory os.chdir(configuration.root) if configuration.conf.aspen.no('changes_kill'): # restart for template files too; # TODO can't we just invalidate the simplate cache for these? dot_aspen = join(configuration.root, '.aspen') for root, dirs, files in os.walk(dot_aspen): for filename in files: restarter.add(join(root, filename)) app.add_loop(Loop(restarter.loop)) port = configuration.address[1] app.add_service(Service(http.HttpServer(website), port)) log.warn("Greetings, program! Welcome to port %d." % port) app.run() except KeyboardInterrupt, SystemExit: configuration.hooks.run('shutdown', website)
def get(**_kw): kw = dict(website=Website([]), fs='', raw='[---]\n[---] text/plain via stdlib_template\n', media_type='', mtime=0) kw.update(_kw) return NegotiatedResource(**kw)
def test_negotiated_resource_is_instantiable(): website = Website([]) fs = '' raw = '[---]\n[---] text/plain via stdlib_template\n' media_type = '' mtime = 0 actual = NegotiatedResource(website, fs, raw, media_type, mtime).__class__ assert actual is NegotiatedResource
def test_negotiated_resource_is_instantiable(): website = Website([]) fs = '' raw = '^L^L #!tornado text/plain\n' media_type = '' mtime = 0 actual = NegotiatedResource(website, fs, raw, media_type, mtime).__class__ assert actual is NegotiatedResource, actual
def get(**_kw): kw = dict( website = Website([]) , fs = '' , raw = '^L^L #!tornado text/plain\n' , media_type = '' , mtime = 0 ) kw.update(_kw) return NegotiatedResource(**kw)
def test_configuration_script_can_set_renderer_default(mk): CONFIG = """ website.renderer_default="stdlib_format" """ SIMPLATE = """ name="program" [----] Greetings, {name}! """ mk( ('.aspen/configure-aspen.py', CONFIG), ('index.html.spt', SIMPLATE) ) w = Website(['--www_root', FSFIX, '-p', fix('.aspen'), '--show_tracebacks=yes']) request = StubRequest(b'/') request.website = w response = w.handle_safely(request) actual = response.body.strip() expected = 'Greetings, program!' assert actual == expected
def test_configuration_script_can_set_renderer_default(): CONFIG = """ website.renderer_default="stdlib_format" """ SIMPLATE = """ name="program" [----] Greetings, {name}! """ mk( ('.aspen/configure-aspen.py', CONFIG), ('index.html.spt', SIMPLATE) ) w = Website(['--www_root', FSFIX, '-p', fix('.aspen'), '--show_tracebacks=yes']) request = StubRequest(b'/') request.website = w response = w.handle_safely(request) actual = response.body.strip() expected = 'Greetings, program!' assert actual == expected, actual
def test_website_doesnt_clobber_outbound(mk): mk( ( '.aspen/configure-aspen.py' , 'import random\nwebsite.hooks.outbound.append(random.choice)' ) ) project_root = os.path.join(FSFIX, '.aspen') website = Website(['--www_root='+FSFIX, '--project_root='+project_root]) expected = 2 actual = len(website.hooks.outbound) assert actual == expected
def test_double_failure_still_sets_response_dot_request(mk): mk( '.aspen' , ('.aspen/foo.py', """ def bar(response): response.request """) , ( '.aspen/configure-aspen.py' , 'import foo\nwebsite.hooks.outbound.append(foo.bar)' ) , ('index.html.spt', "raise heck\n[---]\n") ) # Intentionally break the website object so as to trigger a double failure. project_root = os.path.join(FSFIX, '.aspen') website = Website(['--www_root='+FSFIX, '--project_root='+project_root]) del website.renderer_factories response = website.handle_safely(StubRequest()) expected = 500 actual = response.code assert actual == expected
def test_double_failure_still_sets_response_dot_request(): mk( '.aspen' , ('.aspen/foo.py', """ def bar(response): response.request """) , ( '.aspen/configure-aspen.py' , 'import foo\nwebsite.hooks.outbound.append(foo.bar)' ) , ('index.html.spt', "raise heck\n[---]\n") ) # Intentionally break the website object so as to trigger a double failure. project_root = os.path.join(FSFIX, '.aspen') website = Website(['--www_root='+FSFIX, '--project_root='+project_root]) del website.renderer_factories response = website.handle_safely(StubRequest()) expected = 500 actual = response.code assert actual == expected, actual
def from_fs(cls, fs, *a): """Takes a path under FSFIX using / as the path separator. """ fs = os.sep.join(fs.split(os.sep)) request = Request.from_wsgi(StubWSGIRequest(fs)) website = Website([ '--www_root', FSFIX , '--project_root', '.aspen' ] + list(a)) request.www_root = os.path.join(os.path.dirname(__file__), FSFIX) request.fs = fs request.context = {} request.website = website request._media_type = None return request
def handle(path): website = Website(Configuration(['fsfix'])) return website.handle(Request.from_diesel(DieselReq(path)))
"""Provide a WSGI callable. It would be a little nicer if this was at aspen:wsgi instead of aspen.wsgi:website, but then Website would be instantiated even if we don't want it to be. Here, it's only instantiated when someone passes this to gunicorn, spawning, etc. """ from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals from aspen.website import Website website = Website([])
def test_basic(): website = Website([]) expected = os.getcwd() actual = website.www_root assert actual == expected
"""Configuration script for the http://aspen.io/ website. """ import os import os.path from aspen.configuration import parse from aspen.website import Website distribution_root = os.path.dirname(__file__) website = Website( www_root=os.path.join(distribution_root, 'doc') , project_root=os.path.join(distribution_root, 'doc', '.aspen') ) opts = {} def add_stuff_to_request_context(website, dispatch_result): # Define some closures for generating image markup. # ================================================= def translate(src): if src[0] != '/': rel = os.path.dirname(dispatch_result.match)[len(website.www_root):] src = '/'.join([rel, src]) src = opts['base'] + src return src def img(src): src = translate(src) html = '<img src="%s" />' % src return html def screenshot(short, imgtype='png', href=''):
def __init__(self, app): BaseWebsite.__init__(self) self.app = app self.version = version.get_version() self.configure_typecasters() self.configure_renderers()
actual = handle('/', '--unavailable=10').headers['Retry-After'] expected = datetime.datetime.utcnow().strftime('%a, %d %b %Y') assert actual.startswith(expected), actual assert actual.endswith(' +0000'), actual def test_double_failure_still_sets_response_dot_request(): mk( '.aspen' , ('.aspen/foo.py', """ def bar(response): response.request """) , ( '.aspen/configure-aspen.py' , 'import foo\nwebsite.hooks.outbound_late.register(foo.bar)' ) , ('index.html', "raise heck") ) # Intentionally break the website object so as to trigger a double failure. website = Website(['--www_root='+FSFIX, '--project_root=.aspen']) del website.renderer_factories response = website.handle_safely(StubRequest()) expected = 500 actual = response.code assert actual == expected, actual attach_teardown(globals())
from __future__ import absolute_import, division, print_function, unicode_literals import os from aspen.website import Website project_root = os.path.dirname(__file__) www_root = os.path.join(project_root, 'www') website = Website(project_root=project_root, www_root=www_root)
import __builtin__ import base64 from urllib import quote as urlquote from liberapay import canonize, fill_accept_header, insert_constants, utils, wireup from liberapay.cron import Cron from liberapay.models.community import Community from liberapay.models.participant import Participant from liberapay.security import authentication, csrf, x_frame_options from liberapay.utils import erase_cookie, http_caching, i18n, set_cookie, timer from liberapay.renderers import csv_dump, jinja2_htmlescaped, jinja2_html_jswrapped, jinja2_xml_min import aspen from aspen.website import Website website = Website() # Configure renderers # =================== website.renderer_default = 'unspecified' # require explicit renderer, to avoid escaping bugs website.renderer_factories['csv_dump'] = csv_dump.Factory(website) website.renderer_factories['jinja2_htmlescaped'] = jinja2_htmlescaped.Factory( website) website.renderer_factories[ 'jinja2_html_jswrapped'] = jinja2_html_jswrapped.Factory(website) website.renderer_factories['jinja2_xml_min'] = jinja2_xml_min.Factory(website) website.default_renderers_by_media_type['text/html'] = 'jinja2_htmlescaped' website.default_renderers_by_media_type[ 'text/plain'] = 'jinja2' # unescaped is fine here
import os from aspen.website import Website project_root = os.path.dirname(__file__) www_root = os.path.join(project_root, 'www') website = Website(project_root=project_root, www_root=www_root) # Install the eval renderer. # ========================== from aspen import renderers class Renderer(renderers.Renderer): def render_content(self, context): return eval(self.compiled, globals(), context) class Factory(renderers.Factory): Renderer = Renderer website.renderer_factories['eval'] = Factory(website)
import base64 import gratipay import gratipay.wireup from gratipay import utils, security from gratipay.cron import Cron from gratipay.models.participant import Participant from gratipay.security import authentication, csrf from gratipay.utils import erase_cookie, http_caching, i18n, set_cookie, timer from gratipay.version import get_version from gratipay.renderers import csv_dump, jinja2_htmlescaped, eval_, scss import aspen from aspen.website import Website website = Website() # Configure renderers # =================== website.renderer_default = 'unspecified' # require explicit renderer, to avoid escaping bugs website.renderer_factories['csv_dump'] = csv_dump.Factory(website) website.renderer_factories['eval'] = eval_.Factory(website) website.renderer_factories['jinja2_htmlescaped'] = jinja2_htmlescaped.Factory( website) website.renderer_factories['scss'] = scss.Factory(website) website.default_renderers_by_media_type['text/html'] = 'jinja2_htmlescaped' website.default_renderers_by_media_type[ 'text/plain'] = 'jinja2' # unescaped is fine here website.default_renderers_by_media_type['text/css'] = 'scss'
def test_basic(): website = Website(Configuration([])) expected = os.getcwd() actual = website.root assert actual == expected, actual
def handle(path='/'): website = Website(['fsfix']) request = StubRequest(path) request.website = website response = website.handle(request) return response
import os import string import random from os.path import basename, dirname from aspen import Response from aspen.website import Website from . import gfm from .nav import NavItem website = Website(www_root='www', project_root='.') # Manually register markdown renderer to work around Heroku deployment woes. website.renderer_factories['markdown'] = gfm.Factory(website) website.renderer_factories['jinja2'].Renderer.global_context = { 'range': range, 'unicode': unicode, 'enumerate': enumerate, 'len': len, 'float': float, 'type': type, 'str': str, } website.renderer_default = "markdown" def add_nav_to_website(website):
import aspen from aspen.website import Website aspen.logging.LOGGING_THRESHOLD = 2 # Hide Aspen's startup messages website = Website() aspen.logging.LOGGING_THRESHOLD = 0
def main(argv=None): """http://aspen.io/cli/ """ try: # Do imports. # =========== # These are in here so that if you Ctrl-C during an import, the # KeyboardInterrupt is caught and ignored. Yes, that's how much I care. # No, I don't care enough to put aspen/__init__.py in here too. import os import logging import socket import sys import time import traceback from os.path import exists, join import aspen from aspen import restarter from aspen.website import Website log = logging.getLogger('aspen.cli') # Website # ======= # User-developers get this website object inside of their simplates and # hooks. It provides access to configuration information in addition to # being a WSGI callable and holding the request/response handling # logic. See aspen/website.py if argv is None: argv = sys.argv[1:] website = Website(argv) # Start serving the website. # ========================== # This amounts to binding the requested socket, with logging and # restarting as needed. Wrap the whole thing in a try/except to # do some cleanup on shutdown. try: if hasattr(socket, 'AF_UNIX'): if website.sockfam == socket.AF_UNIX: if exists(website.address): log.info("Removing stale socket.") os.remove(website.address) if website.port is not None: welcome = "port %d" % website.port else: welcome = website.address log.info("Starting %s engine." % website.engine.name) website.engine.bind() log.warn("Greetings, program! Welcome to %s." % welcome) if website.changes_kill: log.info("Aspen will die when files change.") restarter.install(website) website.start() except socket.error: # Be friendly about port conflicts. # ================================= # The traceback one gets from a port conflict is not that friendly. # Here's a helper to let the user know (in color?!) that a port # conflict is the probably the problem. But in case it isn't # (website.start fires the start hook, and maybe the user tries to # connect to a network service in there?), don't fully swallow the # exception. Also, be explicit about the port number. What if they # have logging turned off? Then they won't see the port number in # the "Greetings, program!" line. They definitely won't see it if # using an engine like eventlet that binds to the port early. if website.port is not None: msg = "Is something already running on port %s? Because ..." msg %= website.port if not aspen.WINDOWS: # Assume we can use ANSI color escapes if not on Windows. # XXX Maybe a bad assumption if this is going into a log # file? msg = '\033[01;33m%s\033[00m' % msg print >> sys.stderr, msg raise except KeyboardInterrupt, SystemExit: pass except: traceback.print_exc() finally: if hasattr(socket, 'AF_UNIX'): if website.sockfam == socket.AF_UNIX: if exists(website.address): os.remove(website.address) website.stop()
import base64 from urllib import quote as urlquote from liberapay import canonize, fill_accept_header, insert_constants, utils, wireup from liberapay.cron import Cron from liberapay.models.community import Community from liberapay.models.participant import Participant from liberapay.security import authentication, csrf, x_frame_options from liberapay.utils import erase_cookie, http_caching, i18n, set_cookie, timer from liberapay.renderers import csv_dump, jinja2_htmlescaped, jinja2_html_jswrapped, jinja2_xml_min import aspen from aspen.website import Website website = Website() # Configure renderers # =================== website.renderer_default = 'unspecified' # require explicit renderer, to avoid escaping bugs website.renderer_factories['csv_dump'] = csv_dump.Factory(website) website.renderer_factories['jinja2_htmlescaped'] = jinja2_htmlescaped.Factory(website) website.renderer_factories['jinja2_html_jswrapped'] = jinja2_html_jswrapped.Factory(website) website.renderer_factories['jinja2_xml_min'] = jinja2_xml_min.Factory(website) website.default_renderers_by_media_type['text/html'] = 'jinja2_htmlescaped' website.default_renderers_by_media_type['text/plain'] = 'jinja2' # unescaped is fine here def _assert(x):
) expected = "Greetings, baz!" actual = handle('/', '--project_root=.aspen').body assert actual == expected, actual def test_double_failure_still_sets_response_dot_request(): mk( '.aspen' , ('.aspen/foo.py', """ def bar(response): response.request """) , ( '.aspen/configure-aspen.py' , 'import foo\nwebsite.hooks.outbound_late.register(foo.bar)' ) , ('index.html', "raise heck") ) # Intentionally break the website object so as to trigger a double failure. website = Website(['--www_root='+FSFIX, '--project_root=.aspen']) del website.renderer_factories response = website.handle(StubRequest()) expected = 500 actual = response.code assert actual == expected, actual attach_teardown(globals())
def _main(argv): # Do imports. # =========== # These are in here so that if you Ctrl-C during an import, the # KeyboardInterrupt is caught and ignored. Yes, that's how much I care. # No, I don't care enough to put aspen/__init__.py in here too. import os import signal import socket import sys import traceback import aspen from aspen import execution from aspen.website import Website # Set up signal handling. # ======================= def SIGHUP(signum, frame): aspen.log_dammit("Received HUP, re-executing.") execution.execute() if not aspen.WINDOWS: signal.signal(signal.SIGHUP, SIGHUP) def SIGINT(signum, frame): aspen.log_dammit("Received INT, exiting.") raise SystemExit signal.signal(signal.SIGINT, SIGINT) def SIGQUIT(signum, frame): aspen.log_dammit("Received QUIT, exiting.") raise SystemExit if not aspen.WINDOWS: signal.signal(signal.SIGQUIT, SIGQUIT) # Website # ======= # User-developers get this website object inside of their resources and # hooks. It provides access to configuration information in addition to # being a WSGI callable and holding the request/response handling # logic. See aspen/website.py if argv is None: argv = sys.argv[1:] website = Website(argv) # Start serving the website. # ========================== # This amounts to binding the requested socket, with logging and # restarting as needed. Wrap the whole thing in a try/except to # do some cleanup on shutdown. try: if hasattr(socket, 'AF_UNIX'): if website.network_sockfam == socket.AF_UNIX: if os.path.exists(website.network_address): aspen.log("Removing stale socket.") os.remove(website.network_address) if website.network_port is not None: welcome = "port %d" % website.network_port else: welcome = website.network_address aspen.log("Starting %s engine." % website.network_engine.name) website.network_engine.bind() aspen.log_dammit("Greetings, program! Welcome to %s." % welcome) if website.changes_reload: aspen.log("Aspen will restart when configuration scripts or " "Python modules change.") execution.install(website) website.start() except socket.error: # Be friendly about port conflicts. # ================================= # The traceback one gets from a port conflict or permission error # is not that friendly. Here's a helper to let the user know (in # color?!) that a port conflict or a permission error is probably # the problem. But in case it isn't (website.start fires the start # hook, and maybe the user tries to connect to a network service in # there?), don't fully swallow the exception. Also, be explicit # about the port number. What if they have logging turned off? Then # they won't see the port number in the "Greetings, program!" line. # They definitely won't see it if using an engine like eventlet # that binds to the port early. if website.network_port is not None: msg = "Is something already running on port %s? Because ..." if not aspen.WINDOWS: if website.network_port < 1024: if os.geteuid() > 0: msg = ("Do you have permission to bind to port %s?" " Because ...") msg %= website.network_port if not aspen.WINDOWS: # Assume we can use ANSI color escapes if not on Windows. # XXX Maybe a bad assumption if this is going into a log # file? See also: colorama msg = '\033[01;33m%s\033[00m' % msg aspen.log_dammit(msg) raise except (KeyboardInterrupt, SystemExit): raise # Don't bother logging these. except: aspen.log_dammit(traceback.format_exc()) finally: if hasattr(socket, 'AF_UNIX'): if website.network_sockfam == socket.AF_UNIX: if os.path.exists(website.network_address): os.remove(website.network_address) website.stop()
import gratipay import gratipay.wireup from gratipay import utils from gratipay.cron import Cron from gratipay.models.participant import Participant from gratipay.security import authentication, csrf, security_headers from gratipay.utils import erase_cookie, http_caching, i18n, set_cookie, timer from gratipay.version import get_version from gratipay.renderers import csv_dump, jinja2_htmlescaped, eval_, scss import aspen from aspen.website import Website website = Website() # Configure renderers # =================== website.renderer_default = 'unspecified' # require explicit renderer, to avoid escaping bugs website.renderer_factories['csv_dump'] = csv_dump.Factory(website) website.renderer_factories['eval'] = eval_.Factory(website) website.renderer_factories['jinja2_htmlescaped'] = jinja2_htmlescaped.Factory(website) website.renderer_factories['scss'] = scss.Factory(website) website.default_renderers_by_media_type['text/html'] = 'jinja2_htmlescaped' website.default_renderers_by_media_type['text/plain'] = 'jinja2' # unescaped is fine here website.default_renderers_by_media_type['text/css'] = 'scss' website.default_renderers_by_media_type['image/*'] = 'eval'
def test_double_failure_still_sets_response_dot_request(): mk( '.aspen' , ('.aspen/foo.py', """ def bar(response): response.request """) , ( '.aspen/configure-aspen.py' , 'import foo\nwebsite.hooks.outbound.append(foo.bar)' ) , ('index.html', "raise heck") ) # Intentionally break the website object so as to trigger a double failure. project_root = os.path.join(FSFIX, '.aspen') website = Website(['--www_root='+FSFIX, '--project_root='+project_root]) del website.renderer_factories response = website.handle_safely(StubRequest()) expected = 500 actual = response.code assert actual == expected, actual def test_website_doesnt_clobber_outbound(): mk( ( '.aspen/configure-aspen.py' , 'import random\nwebsite.hooks.outbound.append(random.choice)' ) )
def test_configuration_script_ignores_blank_indexfilenames(): w = Website(['--indices', 'index.html,, ,default.html']) assert w.indices[0] == 'index.html' assert w.indices[1] == 'default.html' assert len(w.indices) == 2, "Too many indexfile entries"
def make_request(filename='echo.sock'): request = Request(uri='/echo.sock') request.website = Website([]) request.fs = fix(filename) return request
def check(): website = Website(Configuration(['fsfix'])) response = website.handle(Request.from_diesel(DieselReq())) return response