def test_router_prefix(self): ''' Test path_prefix ''' router_path_prefix = dict( BASE = dict( default_application = 'a1', applications = ['a1', 'a2'], path_prefix = '/path/to/apps', ), a1 = dict( controllers = ['c1a', 'c1b', 'default'], ), a2 = dict( default_controller = 'c2', controllers = [], ), ) load(rdict=router_path_prefix) self.assertEqual(str(URL(a='a1', c='c1a', f='f')), "/path/to/apps/c1a/f") self.assertEqual(str(URL(a='a2', c='c', f='f')), "/path/to/apps/a2/c/f") self.assertEqual(str(URL(a='a2', c='c2', f='f')), "/path/to/apps/a2/c2/f") self.assertEqual(filter_url('http://domain.com/a1/'), "/a1/default/index") self.assertEqual(filter_url('http://domain.com/path/to/apps/a1/'), "/a1/default/index") self.assertEqual(filter_url('http://domain.com/path/to/a1/'), "/a1/default/path ['to', 'a1']")
def toolbar(self): from html import DIV, SCRIPT, BEAUTIFY, TAG, URL BUTTON = TAG.button admin = URL("admin", "default", "design", args=current.request.application) from gluon.dal import thread dbstats = [TABLE(*[TR(PRE(row[0]),'%.2fms' % (row[1]*1000)) \ for row in i.db._timings]) \ for i in thread.instances] u = web2py_uuid() return DIV( BUTTON('design', _onclick="document.location='%s'" % admin), BUTTON('request', _onclick="jQuery('#request-%s').slideToggle()" % u), DIV(BEAUTIFY(current.request), _class="hidden", _id="request-%s" % u), BUTTON('session', _onclick="jQuery('#session-%s').slideToggle()" % u), DIV(BEAUTIFY(current.session), _class="hidden", _id="session-%s" % u), BUTTON('response', _onclick="jQuery('#response-%s').slideToggle()" % u), DIV(BEAUTIFY(current.response), _class="hidden", _id="response-%s" % u), BUTTON('db stats', _onclick="jQuery('#db-stats-%s').slideToggle()" % u), DIV(BEAUTIFY(dbstats), _class="hidden", _id="db-stats-%s" % u), SCRIPT("jQuery('.hidden').hide()"))
def toolbar(self): from html import DIV, SCRIPT, BEAUTIFY, TAG, URL BUTTON = TAG.button admin = URL("admin","default","design", args=current.request.application) from gluon.dal import thread if hasattr(thread,'instances'): dbstats = [TABLE(*[TR(PRE(row[0]),'%.2fms' % (row[1]*1000)) \ for row in i.db._timings]) \ for i in thread.instances] dbtables = dict([(i.uri, {'defined': sorted(list(set(i.db.tables) - set(i.db._LAZY_TABLES.keys()))) or '[no defined tables]', 'lazy': sorted(i.db._LAZY_TABLES.keys()) or '[no lazy tables]'}) for i in thread.instances]) else: dbstats = [] # if no db or on GAE dbtables = {} u = web2py_uuid() return DIV( BUTTON('design',_onclick="document.location='%s'" % admin), BUTTON('request',_onclick="jQuery('#request-%s').slideToggle()"%u), DIV(BEAUTIFY(current.request),_class="hidden",_id="request-%s"%u), BUTTON('session',_onclick="jQuery('#session-%s').slideToggle()"%u), DIV(BEAUTIFY(current.session),_class="hidden",_id="session-%s"%u), BUTTON('response',_onclick="jQuery('#response-%s').slideToggle()"%u), DIV(BEAUTIFY(current.response),_class="hidden",_id="response-%s"%u), BUTTON('db tables',_onclick="jQuery('#db-tables-%s').slideToggle()"%u), DIV(BEAUTIFY(dbtables),_class="hidden",_id="db-tables-%s"%u), BUTTON('db stats',_onclick="jQuery('#db-stats-%s').slideToggle()"%u), DIV(BEAUTIFY(dbstats),_class="hidden",_id="db-stats-%s"%u), SCRIPT("jQuery('.hidden').hide()") )
def test_router_args(self): ''' Test URL args parsing/generation ''' load(rdict=dict()) self.assertEqual(filter_url('http://domain.com/init/default/f/arg1'), "/init/default/f ['arg1']") self.assertEqual(filter_url('http://domain.com/init/default/f/arg1/'), "/init/default/f ['arg1']") self.assertEqual(filter_url('http://domain.com/init/default/f/arg1//'), "/init/default/f ['arg1', '']") self.assertEqual(filter_url('http://domain.com/init/default/f//arg1'), "/init/default/f ['', 'arg1']") self.assertEqual(filter_url('http://domain.com/init/default/f/arg1/arg2'), "/init/default/f ['arg1', 'arg2']") self.assertEqual(filter_url('http://domain.com/init/default/f', out=True), "/f") self.assertEqual(map_url_out(None, None, 'init', 'default', 'f', None, None, None, None, None), "/f") self.assertEqual(map_url_out(None, None, 'init', 'default', 'f', [], None, None, None, None), "/f") self.assertEqual(map_url_out(None, None, 'init', 'default', 'f', ['arg1'], None, None, None, None), "/f") self.assertEqual(map_url_out(None, None, 'init', 'default', 'f', ['arg1', ''], None, None, None, None), "/f") self.assertEqual(str(URL(a='init', c='default', f='f', args=None)), "/f") self.assertEqual(str(URL(a='init', c='default', f='f', args=['arg1'])), "/f/arg1") self.assertEqual(str(URL(a='init', c='default', f='f', args=['arg1', ''])), "/f/arg1//") self.assertEqual(str(URL(a='init', c='default', f='f', args=['arg1', '', 'arg3'])), "/f/arg1//arg3") self.assertEqual(str(URL(a='init', c='default', f='f', args=['ar g'])), "/f/ar%20g") self.assertEqual(str(URL(a='init', c='default', f='f', args=['årg'])), "/f/%C3%A5rg") self.assertEqual(str(URL(a='init', c='default', f='fünc')), "/f\xc3\xbcnc")
def toolbar(self): from html import DIV, SCRIPT, BEAUTIFY, TAG, URL, A BUTTON = TAG.button admin = URL("admin", "default", "design", args=current.request.application) from gluon.dal import DAL dbstats = [] dbtables = {} infos = DAL.get_instances() for k, v in infos.iteritems(): dbstats.append( TABLE(*[ TR(PRE(row[0]), '%.2fms' % (row[1] * 1000)) for row in v['dbstats'] ])) dbtables[k] = dict(defined=v['dbtables']['defined'] or '[no defined tables]', lazy=v['dbtables']['lazy'] or '[no lazy tables]') u = web2py_uuid() backtotop = A('Back to top', _href="#totop-%s" % u) return DIV(BUTTON('design', _onclick="document.location='%s'" % admin), BUTTON('request', _onclick="jQuery('#request-%s').slideToggle()" % u), BUTTON('response', _onclick="jQuery('#response-%s').slideToggle()" % u), BUTTON('session', _onclick="jQuery('#session-%s').slideToggle()" % u), BUTTON('db tables', _onclick="jQuery('#db-tables-%s').slideToggle()" % u), BUTTON('db stats', _onclick="jQuery('#db-stats-%s').slideToggle()" % u), DIV(BEAUTIFY(current.request), backtotop, _class="hidden", _id="request-%s" % u), DIV(BEAUTIFY(current.session), backtotop, _class="hidden", _id="session-%s" % u), DIV(BEAUTIFY(current.response), backtotop, _class="hidden", _id="response-%s" % u), DIV(BEAUTIFY(dbtables), backtotop, _class="hidden", _id="db-tables-%s" % u), DIV(BEAUTIFY(dbstats), backtotop, _class="hidden", _id="db-stats-%s" % u), SCRIPT("jQuery('.hidden').hide()"), _id="totop-%s" % u)
def requires_https(self): """ If request comes in over HTTP, redirect it to HTTPS and secure the session. """ if not global_settings.cronjob and not self.is_https: redirect(URL(scheme='https', args=self.args, vars=self.vars)) current.session.secure()
def requires_https(self): """ If request comes in over HTTP, redirect it to HTTPS and secure the session. """ cmd_opts = global_settings.cmd_options #checking if this is called within the scheduler or within the shell #in addition to checking if it's not a cronjob if ((cmd_opts and (cmd_opts.shell or cmd_opts.scheduler)) or global_settings.cronjob or self.is_https): current.session.secure() else: current.session.forget() redirect(URL(scheme='https', args=self.args, vars=self.vars))
def test_routes_anchor(self): ''' Test URL with anchor ''' self.assertEqual(str(URL(a='a', c='c', f='f', anchor='anchor')), "/a/c/f#anchor") load(rdict=dict()) self.assertEqual(str(URL(a='a', c='c', f='f', anchor='anchor')), "/a/c/f#anchor") args = ['a1', 'a2'] self.assertEqual(str(URL(a='a', c='c', f='f', args=args, anchor='anchor')), "/a/c/f/a1/a2#anchor") vars = dict(v1=1, v2=2) self.assertEqual(str(URL(a='a', c='c', f='f', vars=vars, anchor='anchor')), "/a/c/f?v1=1&v2=2#anchor") self.assertEqual(str(URL(a='a', c='c', f='f', args=args, vars=vars, anchor='anchor')), "/a/c/f/a1/a2?v1=1&v2=2#anchor") self.assertEqual(str(URL(a='init', c='default', f='index')), "/") self.assertEqual(str(URL(a='init', c='default', f='f')), "/f") self.assertEqual(str(URL(a='init', c='default', f='index', anchor='anchor')), "/#anchor") self.assertEqual(str(URL(a='init', c='default', f='f', anchor='anchor')), "/f#anchor")
def test_router_hyphen(self): ''' Test hyphen conversion ''' router_hyphen = dict( BASE = dict( applications = ['init', 'app1', 'app2'], ), init = dict( controllers = ['default'], ), app1 = dict( controllers = ['default'], map_hyphen = True, ), app2 = dict( controllers = ['default'], map_hyphen = False, ), ) load(rdict=router_hyphen) self.assertEqual(filter_url('http://domain.com/init/default/fcn_1', out=True), "/fcn_1") self.assertEqual(filter_url('http://domain.com/static/filename-with_underscore'), "%s/applications/init/static/filename-with_underscore" % root) self.assertEqual(filter_url('http://domain.com/init/static/filename-with_underscore', out=True), "/init/static/filename-with_underscore") self.assertEqual(filter_url('http://domain.com/app2/fcn_1'), "/app2/default/fcn_1") self.assertEqual(filter_url('http://domain.com/app2/ctr/fcn_1', domain=('app2',None), out=True), "/ctr/fcn_1") self.assertEqual(filter_url('http://domain.com/app2/static/filename-with_underscore', domain=('app2',None), out=True), "/app2/static/filename-with_underscore") self.assertEqual(filter_url('http://domain.com/app2/static/filename-with_underscore'), "%s/applications/app2/static/filename-with_underscore" % root) self.assertEqual(str(URL(a='init', c='default', f='a_b')), "/a_b") self.assertEqual(str(URL(a='app1', c='default', f='a_b')), "/app1/a-b") self.assertEqual(str(URL(a='app2', c='default', f='a_b')), "/app2/a_b") self.assertEqual(str(URL(a='app1', c='static', f='a/b_c')), "/app1/static/a/b_c") self.assertEqual(str(URL(a='app1', c='static/a', f='b_c')), "/app1/static/a/b_c") self.assertEqual(str(URL(a='app2', c='static', f='a/b_c')), "/app2/static/a/b_c") self.assertEqual(str(URL(a='app2', c='static/a', f='b_c')), "/app2/static/a/b_c")
def test_routes_absolute(self): ''' Test absolute URL ''' load(data='') r = Storage() r.env = Storage() r.env.http_host = 'domain.com' r.env.wsgi_url_scheme = 'httpx' # distinguish incoming scheme self.assertEqual(str(URL(r=r, a='a', c='c', f='f')), "/a/c/f") self.assertEqual(str(URL(r=r, a='a', c='c', f='f', host=True)), "httpx://domain.com/a/c/f") self.assertEqual(str(URL(r=r, a='a', c='c', f='f', host='host.com')), "httpx://host.com/a/c/f") self.assertEqual(str(URL(r=r, a='a', c='c', f='f', scheme=True)), "httpx://domain.com/a/c/f") self.assertEqual(str(URL(r=r, a='a', c='c', f='f', scheme=False)), "/a/c/f") self.assertEqual(str(URL(r=r, a='a', c='c', f='f', scheme='https')), "https://domain.com/a/c/f") self.assertEqual(str(URL(r=r, a='a', c='c', f='f', scheme='wss')), "wss://domain.com/a/c/f") self.assertEqual( str(URL(r=r, a='a', c='c', f='f', scheme=True, host=True)), "httpx://domain.com/a/c/f") self.assertEqual( str(URL(r=r, a='a', c='c', f='f', scheme='https', host=True)), "https://domain.com/a/c/f") self.assertEqual( str(URL(r=r, a='a', c='c', f='f', scheme=False, host=True)), "httpx://domain.com/a/c/f") self.assertEqual( str(URL(r=r, a='a', c='c', f='f', scheme=True, host='host.com')), "httpx://host.com/a/c/f") self.assertEqual( str(URL(r=r, a='a', c='c', f='f', scheme=False, host='host.com')), "httpx://host.com/a/c/f") self.assertEqual(str(URL(r=r, a='a', c='c', f='f', port=1234)), "httpx://domain.com:1234/a/c/f") self.assertEqual( str(URL(r=r, a='a', c='c', f='f', scheme=True, port=1234)), "httpx://domain.com:1234/a/c/f") self.assertEqual( str(URL(r=r, a='a', c='c', f='f', host='host.com', port=1234)), "httpx://host.com:1234/a/c/f") self.assertEqual( str( URL(r=r, a='a', c='c', f='f', scheme='wss', host='host.com', port=1234)), "wss://host.com:1234/a/c/f")
def test_routes_anchor(self): ''' Test URL with anchor ''' self.assertEqual(str(URL(a='a', c='c', f='f', anchor='anchor')), "/a/c/f#anchor") load(data='') self.assertEqual(str(URL(a='a', c='c', f='f', anchor='anchor')), "/a/c/f#anchor") args = ['a1', 'a2'] self.assertEqual( str(URL(a='a', c='c', f='f', args=args, anchor='anchor')), "/a/c/f/a1/a2#anchor") vars = dict(v1=1, v2=2) self.assertEqual( str(URL(a='a', c='c', f='f', vars=vars, anchor='anchor')), "/a/c/f?v1=1&v2=2#anchor") self.assertEqual( str(URL(a='a', c='c', f='f', args=args, vars=vars, anchor='anchor')), "/a/c/f/a1/a2?v1=1&v2=2#anchor") data = r'''routes_out = [ ('/init/default/index', '/'), ]''' load(data=data) self.assertEqual(str(URL(a='init', c='default', f='index')), "/") self.assertEqual( str(URL(a='init', c='default', f='index', anchor='anchor')), "/init/default/index#anchor") data = r'''routes_out = [ (r'/init/default/index(?P<anchor>(#.*)?)', r'/\g<anchor>'), ]''' load(data=data) self.assertEqual(str(URL(a='init', c='default', f='index')), "/") self.assertEqual( str(URL(a='init', c='default', f='index', anchor='anchor')), "/#anchor") data = r'''routes_out = [ (r'/init/default/index(?P<qa>([?#].*)?)', r'/\g<qa>'), ]''' load(data=data) self.assertEqual(str(URL(a='init', c='default', f='index')), "/") self.assertEqual( str(URL(a='init', c='default', f='index', anchor='anchor')), "/#anchor") query = dict(var='abc') self.assertEqual( str(URL(a='init', c='default', f='index', vars=query)), "/?var=abc") self.assertEqual( str( URL(a='init', c='default', f='index', vars=query, anchor='anchor')), "/?var=abc#anchor")
def test_routes_args(self): ''' Test URL args parsing/generation ''' data = r'''routes_in = [ ('/robots.txt', '/welcome/static/robots.txt'), ('/favicon.ico', '/welcome/static/favicon.ico'), ('/admin$anything', '/admin$anything'), ('.*:https?://(.*\\.)?domain1.com:$method /', '/app1/default'), ('.*:https?://(.*\\.)?domain1.com:$method /static/$anything', '/app1/static/$anything'), ('.*:https?://(.*\\.)?domain1.com:$method /appadmin/$anything', '/app1/appadmin/$anything'), ('.*:https?://(.*\\.)?domain1.com:$method /$anything', '/app1/default/$anything'), ('.*:https?://(.*\\.)?domain2.com:$method /', '/app2/default'), ('.*:https?://(.*\\.)?domain2.com:$method /static/$anything', '/app2/static/$anything'), ('.*:https?://(.*\\.)?domain2.com:$method /appadmin/$anything', '/app2/appadmin/$anything'), ('.*:https?://(.*\\.)?domain2.com:$method /$anything', '/app2/default/$anything'), ('.*:https?://(.*\\.)?domain3.com:$method /', '/app3/defcon3'), ('.*:https?://(.*\\.)?domain3.com:$method /static/$anything', '/app3/static/$anything'), ('.*:https?://(.*\\.)?domain3.com:$method /appadmin/$anything', '/app3/appadmin/$anything'), ('.*:https?://(.*\\.)?domain3.com:$method /$anything', '/app3/defcon3/$anything'), ('/', '/welcome/default'), ('/welcome/default/$anything', '/welcome/default/$anything'), ('/welcome/$anything', '/welcome/default/$anything'), ('/static/$anything', '/welcome/static/$anything'), ('/appadmin/$anything', '/welcome/appadmin/$anything'), ('/$anything', '/welcome/default/$anything'), ] routes_out = [ ('/welcome/static/$anything', '/static/$anything'), ('/welcome/appadmin/$anything', '/appadmin/$anything'), ('/welcome/default/$anything', '/$anything'), ('/app1/static/$anything', '/static/$anything'), ('/app1/appadmin/$anything', '/appadmin/$anything'), ('/app1/default/$anything', '/$anything'), ('/app2/static/$anything', '/static/$anything'), ('/app2/appadmin/$anything', '/appadmin/$anything'), ('/app2/default/$anything', '/$anything'), ('/app3/static/$anything', '/static/$anything'), ('/app3/appadmin/$anything', '/appadmin/$anything'), ('/app3/defcon3/$anything', '/$anything') ] ''' load(data=data) self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1'), "/welcome/default/f ['arg1']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1/'), "/welcome/default/f ['arg1']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1//'), "/welcome/default/f ['arg1', '']") self.assertEqual( filter_url('http://domain.com/welcome/default/f//arg1'), "/welcome/default/f ['', 'arg1']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1/arg2'), "/welcome/default/f ['arg1', 'arg2']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1//arg2'), "/welcome/default/f ['arg1', '', 'arg2']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1//arg3/'), "/welcome/default/f ['arg1', '', 'arg3']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1//arg3//'), "/welcome/default/f ['arg1', '', 'arg3', '']") self.assertEqual( filter_url('http://domain.com/welcome/default/f', out=True), "/f") self.assertEqual(regex_filter_out('/welcome/default/f'), "/f") self.assertEqual(str(URL(a='welcome', c='default', f='f', args=None)), "/f") self.assertEqual( str(URL(a='welcome', c='default', f='f', args=['arg1'])), "/f/arg1") self.assertEqual( str(URL(a='welcome', c='default', f='f', args=['arg1', ''])), "/f/arg1//") self.assertEqual( str(URL(a='welcome', c='default', f='f', args=['arg1', '', 'arg3'])), "/f/arg1//arg3") self.assertEqual( str(URL(a='welcome', c='default', f='f', args=['ar g'])), "/f/ar%20g") self.assertEqual( str(URL(a='welcome', c='default', f='f', args=['årg'])), "/f/%C3%A5rg") self.assertEqual(str(URL(a='welcome', c='default', f='fünc')), "/f\xc3\xbcnc")
def call_minify(files=files): return minify.minify(files, URL('static', 'temp'), current.request.folder, self.optimize_css, self.optimize_js)
def LOAD(c=None, f='index', args=None, vars=None, extension=None, target=None,ajax=False,ajax_trap=False, url=None,user_signature=False, timeout=None, times=1, content='loading...',**attr): """ LOAD a component into the action's document Timing options: -times: An integer or string ("infinity"/"continuous") specifies how many times the component is requested -timeout (milliseconds): specifies the time to wait before starting the request or the frequency if times is greater than 1 or "infinity". Timing options default to the normal behavior. The component is added on page loading without delay. """ from html import TAG, DIV, URL, SCRIPT, XML if args is None: args = [] vars = Storage(vars or {}) target = target or 'c'+str(random.random())[2:] attr['_id']=target request = current.request if '.' in f: f, extension = f.rsplit('.',1) if url or ajax: url = url or URL(request.application, c, f, r=request, args=args, vars=vars, extension=extension, user_signature=user_signature) # timing options if isinstance(times, basestring): if times.upper() in ("INFINITY", "CONTINUOUS"): times = "Infinity" else: raise TypeError("Unsupported times argument %s" % times) elif isinstance(times, int): if times <= 0: raise ValueError("Times argument must be greater than zero, 'Infinity' or None") else: raise TypeError("Unsupported times argument type %s" % type(times)) if timeout is not None: if not isinstance(timeout, (int, long)): raise ValueError("Timeout argument must be an integer or None") elif timeout <= 0: raise ValueError("Timeout argument must be greater than zero or None") statement = "web2py_component('%s','%s', %s, %s);" \ % (url, target, timeout, times) else: statement = "web2py_component('%s','%s');" % (url, target) script = SCRIPT(statement, _type="text/javascript") if not content is None: return TAG[''](script, DIV(content,**attr)) else: return TAG[''](script) else: if not isinstance(args,(list,tuple)): args = [args] c = c or request.controller other_request = Storage(request) other_request['env'] = Storage(request.env) other_request.controller = c other_request.function = f other_request.extension = extension or request.extension other_request.args = List(args) other_request.vars = vars other_request.get_vars = vars other_request.post_vars = Storage() other_response = Response() other_request.env.path_info = '/' + \ '/'.join([request.application,c,f] + \ map(str, other_request.args)) other_request.env.query_string = \ vars and URL(vars=vars).split('?')[1] or '' other_request.env.http_web2py_component_location = \ request.env.path_info other_request.cid = target other_request.env.http_web2py_component_element = target other_response.view = '%s/%s.%s' % (c,f, other_request.extension) other_environment = copy.copy(current.globalenv) ### NASTY other_response._view_environment = other_environment other_response.generic_patterns = \ copy.copy(current.response.generic_patterns) other_environment['request'] = other_request other_environment['response'] = other_response ## some magic here because current are thread-locals original_request, current.request = current.request, other_request original_response, current.response = current.response, other_response page = run_controller_in(c, f, other_environment) if isinstance(page, dict): other_response._vars = page other_response._view_environment.update(page) run_view_in(other_response._view_environment) page = other_response.body.getvalue() current.request, current.response = original_request, original_response js = None if ajax_trap: link = URL(request.application, c, f, r=request, args=args, vars=vars, extension=extension, user_signature=user_signature) js = "web2py_trap_form('%s','%s');" % (link, target) script = js and SCRIPT(js,_type="text/javascript") or '' return TAG[''](DIV(XML(page),**attr),script)
def LOAD(c=None, f='index', args=None, vars=None, extension=None, target=None, ajax=False, ajax_trap=False, url=None, user_signature=False, timeout=None, times=1, content='loading...', post_vars=Storage(), **attr): """ LOADs a component into the action's document Args: c(str): controller f(str): function args(tuple or list): arguments vars(dict): vars extension(str): extension target(str): id of the target ajax(bool): True to enable AJAX bahaviour ajax_trap(bool): True if `ajax` is set to `True`, traps both links and forms "inside" the target url(str): overrides `c`,`f`,`args` and `vars` user_signature(bool): adds hmac signature to all links with a key that is different for every user timeout(int): in milliseconds, specifies the time to wait before starting the request or the frequency if times is greater than 1 or "infinity" times(integer or str): how many times the component will be requested "infinity" or "continuous" are accepted to reload indefinitely the component """ from html import TAG, DIV, URL, SCRIPT, XML if args is None: args = [] vars = Storage(vars or {}) target = target or 'c' + str(random.random())[2:] attr['_id'] = target request = current.request if '.' in f: f, extension = f.rsplit('.', 1) if url or ajax: url = url or URL(request.application, c, f, r=request, args=args, vars=vars, extension=extension, user_signature=user_signature) # timing options if isinstance(times, basestring): if times.upper() in ("INFINITY", "CONTINUOUS"): times = "Infinity" else: raise TypeError("Unsupported times argument %s" % times) elif isinstance(times, int): if times <= 0: raise ValueError( "Times argument must be greater than zero, 'Infinity' or None" ) else: raise TypeError("Unsupported times argument type %s" % type(times)) if timeout is not None: if not isinstance(timeout, (int, long)): raise ValueError("Timeout argument must be an integer or None") elif timeout <= 0: raise ValueError( "Timeout argument must be greater than zero or None") statement = "$.web2py.component('%s','%s', %s, %s);" \ % (url, target, timeout, times) attr['_data-w2p_timeout'] = timeout attr['_data-w2p_times'] = times else: statement = "$.web2py.component('%s','%s');" % (url, target) attr['_data-w2p_remote'] = url if not target is None: return DIV(content, **attr) else: if not isinstance(args, (list, tuple)): args = [args] c = c or request.controller other_request = Storage(request) other_request['env'] = Storage(request.env) other_request.controller = c other_request.function = f other_request.extension = extension or request.extension other_request.args = List(args) other_request.vars = vars other_request.get_vars = vars other_request.post_vars = post_vars other_response = Response() other_request.env.path_info = '/' + \ '/'.join([request.application, c, f] + map(str, other_request.args)) other_request.env.query_string = \ vars and URL(vars=vars).split('?')[1] or '' other_request.env.http_web2py_component_location = \ request.env.path_info other_request.cid = target other_request.env.http_web2py_component_element = target other_request.restful = types.MethodType( request.restful.im_func, other_request ) # A bit nasty but needed to use LOAD on action decorates with @request.restful() other_response.view = '%s/%s.%s' % (c, f, other_request.extension) other_environment = copy.copy(current.globalenv) # NASTY other_response._view_environment = other_environment other_response.generic_patterns = \ copy.copy(current.response.generic_patterns) other_environment['request'] = other_request other_environment['response'] = other_response ## some magic here because current are thread-locals original_request, current.request = current.request, other_request original_response, current.response = current.response, other_response page = run_controller_in(c, f, other_environment) if isinstance(page, dict): other_response._vars = page other_response._view_environment.update(page) run_view_in(other_response._view_environment) page = other_response.body.getvalue() current.request, current.response = original_request, original_response js = None if ajax_trap: link = URL(request.application, c, f, r=request, args=args, vars=vars, extension=extension, user_signature=user_signature) js = "$.web2py.trap_form('%s','%s');" % (link, target) script = js and SCRIPT(js, _type="text/javascript") or '' return TAG[''](DIV(XML(page), **attr), script)
def wsgibase(environ, responder): """ this is the gluon wsgi application. the first function called when a page is requested (static or dynamic). it can be called by paste.httpserver or by apache mod_wsgi. - fills request with info - the environment variables, replacing '.' with '_' - adds web2py path and version info - compensates for fcgi missing path_info and query_string - validates the path in url The url path must be either: 1. for static pages: - /<application>/static/<file> 2. for dynamic pages: - /<application>[/<controller>[/<function>[/<sub>]]][.<extension>] - (sub may go several levels deep, currently 3 levels are supported: sub1/sub2/sub3) The naming conventions are: - application, controller, function and extension may only contain [a-zA-Z0-9_] - file and sub may also contain '-', '=', '.' and '/' """ current.__dict__.clear() request = Request() response = Response() session = Session() env = request.env env.web2py_path = global_settings.applications_parent env.web2py_version = web2py_version env.update(global_settings) static_file = False try: try: try: # ################################################## # handle fcgi missing path_info and query_string # select rewrite parameters # rewrite incoming URL # parse rewritten header variables # parse rewritten URL # serve file if static # ################################################## fixup_missing_path_info(environ) (static_file, version, environ) = url_in(request, environ) response.status = env.web2py_status_code or response.status if static_file: if environ.get('QUERY_STRING', '').startswith('attachment'): response.headers['Content-Disposition'] \ = 'attachment' if version: response.headers['Cache-Control'] = 'max-age=315360000' response.headers[ 'Expires'] = 'Thu, 31 Dec 2037 23:59:59 GMT' response.stream(static_file, request=request) # ################################################## # fill in request items # ################################################## app = request.application # must go after url_in! if not global_settings.local_hosts: local_hosts = set(['127.0.0.1', '::ffff:127.0.0.1', '::1']) if not global_settings.web2py_runtime_gae: try: fqdn = socket.getfqdn() local_hosts.add(socket.gethostname()) local_hosts.add(fqdn) local_hosts.update([ addrinfo[4][0] for addrinfo in getipaddrinfo(fqdn) ]) if env.server_name: local_hosts.add(env.server_name) local_hosts.update([ addrinfo[4][0] for addrinfo in getipaddrinfo(env.server_name) ]) except (socket.gaierror, TypeError): pass global_settings.local_hosts = list(local_hosts) else: local_hosts = global_settings.local_hosts client = get_client(env) x_req_with = str(env.http_x_requested_with).lower() request.update( client = client, folder = abspath('applications', app) + os.sep, ajax = x_req_with == 'xmlhttprequest', cid = env.http_web2py_component_element, is_local = env.remote_addr in local_hosts, is_https = env.wsgi_url_scheme in HTTPS_SCHEMES or \ request.env.http_x_forwarded_proto in HTTPS_SCHEMES \ or env.https == 'on') request.compute_uuid() # requires client request.url = environ['PATH_INFO'] # ################################################## # access the requested application # ################################################## if not exists(request.folder): if app == rwthread.routes.default_application \ and app != 'welcome': redirect(URL('welcome', 'default', 'index')) elif rwthread.routes.error_handler: _handler = rwthread.routes.error_handler redirect( URL(_handler['application'], _handler['controller'], _handler['function'], args=app)) else: raise HTTP(404, rwthread.routes.error_message % 'invalid request', web2py_error='invalid application') elif not request.is_local and \ exists(pjoin(request.folder, 'DISABLED')): raise HTTP( 503, "<html><body><h1>Temporarily down for maintenance</h1></body></html>" ) # ################################################## # build missing folders # ################################################## create_missing_app_folders(request) # ################################################## # get the GET and POST data # ################################################## parse_get_post_vars(request, environ) # ################################################## # expose wsgi hooks for convenience # ################################################## request.wsgi.environ = environ_aux(environ, request) request.wsgi.start_response = \ lambda status='200', headers=[], \ exec_info=None, response=response: \ start_response_aux(status, headers, exec_info, response) request.wsgi.middleware = \ lambda *a: middleware_aux(request, response, *a) # ################################################## # load cookies # ################################################## if env.http_cookie: try: request.cookies.load(env.http_cookie) except Cookie.CookieError, e: pass # invalid cookies # ################################################## # try load session or create new session file # ################################################## if not env.web2py_disable_session: session.connect(request, response) # ################################################## # run controller # ################################################## if global_settings.debugging and app != "admin": import gluon.debug # activate the debugger gluon.debug.dbg.do_debug(mainpyfile=request.folder) serve_controller(request, response, session) except HTTP, http_response: if static_file: return http_response.to(responder, env=env) if request.body: request.body.close() # ################################################## # on success, try store session in database # ################################################## session._try_store_in_db(request, response) # ################################################## # on success, commit database # ################################################## if response.do_not_commit is True: BaseAdapter.close_all_instances(None) # elif response._custom_commit: # response._custom_commit() elif response.custom_commit: BaseAdapter.close_all_instances(response.custom_commit) else: BaseAdapter.close_all_instances('commit') # ################################################## # if session not in db try store session on filesystem # this must be done after trying to commit database! # ################################################## session._try_store_in_cookie_or_file(request, response) if request.cid: if response.flash: http_response.headers['web2py-component-flash'] = \ urllib2.quote(xmlescape(response.flash)\ .replace('\n','')) if response.js: http_response.headers['web2py-component-command'] = \ urllib2.quote(response.js.replace('\n','')) # ################################################## # store cookies in headers # ################################################## rcookies = response.cookies if session._forget and response.session_id_name in rcookies: del rcookies[response.session_id_name] elif session._secure: rcookies[response.session_id_name]['secure'] = True http_response.cookies2headers(rcookies) ticket = None except RestrictedError, e: if request.body: request.body.close() # ################################################## # on application error, rollback database # ################################################## ticket = e.log(request) or 'unknown' if response._custom_rollback: response._custom_rollback() else: BaseAdapter.close_all_instances('rollback') http_response = \ HTTP(500, rwthread.routes.error_message_ticket % dict(ticket=ticket), web2py_error='ticket %s' % ticket)
def test_router_functions(self): ''' Test function-omission with functions=[something] ''' router_functions = dict( BASE = dict( applications = ['init', 'app', 'app2'], default_application = 'app', ), init = dict( controllers = ['default'], ), app = dict( controllers = ['default', 'ctr'], functions = dict( default=['index', 'user', 'help'], ctr=['ctrf1', 'ctrf2', 'ctrf3'], ), default_function = dict( default='index', ctr='ctrf1', ), ), app2 = dict( controllers = ['default', 'ctr'], functions = ['index', 'user', 'help'], ), ) load(rdict=router_functions) # outbound self.assertEqual(str(URL(a='init', c='default', f='f', args=['arg1'])), "/init/f/arg1") self.assertEqual(str(URL(a='init', c='default', f='index', args=['arg1'])), "/init/index/arg1") self.assertEqual(str(URL(a='app', c='default', f='index', args=['arg1'])), "/arg1") self.assertEqual(str(URL(a='app', c='default', f='user', args=['arg1'])), "/user/arg1") self.assertEqual(str(URL(a='app', c='default', f='user', args=['index'])), "/user/index") self.assertEqual(str(URL(a='app', c='default', f='index', args=['index'])), "/index/index") self.assertEqual(str(URL(a='app', c='default', f='index', args=['init'])), "/index/init") self.assertEqual(str(URL(a='app', c='default', f='index', args=['ctr'])), "/index/ctr") self.assertEqual(str(URL(a='app', c='ctr', f='index', args=['arg'])), "/ctr/index/arg") self.assertEqual(str(URL(a='app', c='ctr', f='ctrf1', args=['arg'])), "/ctr/arg") self.assertEqual(str(URL(a='app', c='ctr', f='ctrf1', args=['ctrf2'])), "/ctr/ctrf1/ctrf2") self.assertEqual(str(URL(a='app2', c='default', f='index', args=['arg1'])), "/app2/arg1") self.assertEqual(str(URL(a='app2', c='default', f='user', args=['arg1'])), "/app2/user/arg1") self.assertEqual(str(URL(a='app2', c='default', f='user', args=['index'])), "/app2/user/index") self.assertEqual(str(URL(a='app2', c='default', f='index', args=['index'])), "/app2/index/index") self.assertEqual(str(URL(a='app2', c='default', f='index', args=['init'])), "/app2/index/init") self.assertEqual(str(URL(a='app2', c='default', f='index', args=['ctr'])), "/app2/index/ctr") # inbound self.assertEqual(filter_url('http://d.com/arg'), "/app/default/index ['arg']") self.assertEqual(filter_url('http://d.com/user'), "/app/default/user") self.assertEqual(filter_url('http://d.com/user/arg'), "/app/default/user ['arg']") self.assertEqual(filter_url('http://d.com/ctr'), "/app/ctr/ctrf1") self.assertEqual(filter_url('http://d.com/ctr/arg'), "/app/ctr/ctrf1 ['arg']") self.assertEqual(filter_url('http://d.com/app2/arg'), "/app2/default/index ['arg']") self.assertEqual(filter_url('http://d.com/app2/user'), "/app2/default/user") self.assertEqual(filter_url('http://d.com/app2/user/arg'), "/app2/default/user ['arg']") self.assertEqual(filter_url('http://d.com/app2/ctr'), "/app2/ctr/index") self.assertEqual(filter_url('http://d.com/app2/ctr/index/arg'), "/app2/ctr/index ['arg']") self.assertEqual(filter_url('http://d.com/app2/ctr/arg'), "/app2/ctr/arg")
def fakeWSGIOutApp(envir, responder): args = envir.get('PATH_INFO').split('/') response = HTTP(envir.get('ERROR_CODE', 200), URL(a=args[1], c=args[2], f=args[3], args=args[4:])) retval = response.to(responder) return retval
def wsgibase(environ, responder): """ this is the gluon wsgi application. the first function called when a page is requested (static or dynamic). it can be called by paste.httpserver or by apache mod_wsgi. - fills request with info - the environment variables, replacing '.' with '_' - adds web2py path and version info - compensates for fcgi missing path_info and query_string - validates the path in url The url path must be either: 1. for static pages: - /<application>/static/<file> 2. for dynamic pages: - /<application>[/<controller>[/<function>[/<sub>]]][.<extension>] - (sub may go several levels deep, currently 3 levels are supported: sub1/sub2/sub3) The naming conventions are: - application, controller, function and extension may only contain [a-zA-Z0-9_] - file and sub may also contain '-', '=', '.' and '/' """ if rewrite.params.routes_in: environ = rewrite.filter_in(environ) request = Request() response = Response() session = Session() try: try: # ################################################## # parse the environment variables # ################################################## for (key, value) in environ.items(): request.env[key.lower().replace('.', '_')] = value request.env.web2py_path = web2py_path request.env.web2py_version = web2py_version request.env.update(settings) # ################################################## # validate the path in url # ################################################## if not request.env.path_info and request.env.request_uri: # for fcgi, decode path_info and query_string items = request.env.request_uri.split('?') request.env.path_info = items[0] if len(items) > 1: request.env.query_string = items[1] else: request.env.query_string = '' path = request.env.path_info.replace('\\', '/') # ################################################## # serve if a static file # ################################################## match = regex_static.match(regex_space.sub('_', path)) if match and match.group('x'): static_file = os.path.join(request.env.web2py_path, 'applications', match.group('b'), 'static', match.group('x')) if request.env.get('query_string', '')[:10] == 'attachment': response.headers['Content-Disposition'] = 'attachment' response.stream(static_file, request=request) # ################################################## # parse application, controller and function # ################################################## path = re.sub('%20', ' ', path) match = regex_url.match(path) if not match or match.group('c') == 'static': raise HTTP(400, rewrite.params.error_message, web2py_error='invalid path') request.application = \ regex_space.sub('_', match.group('a') or 'init') request.controller = \ regex_space.sub('_', match.group('c') or 'default') request.function = \ regex_space.sub('_', match.group('f') or 'index') group_e = match.group('e') raw_extension = group_e and regex_space.sub('_', group_e) or None request.extension = raw_extension or 'html' request.raw_args = match.group('r') request.args = List([]) if request.application in rewrite.params.routes_apps_raw: # application is responsible for parsing args request.args = None elif request.raw_args: match = regex_args.match(request.raw_args) if match: group_s = match.group('s') request.args = \ List((group_s and group_s.split('/')) or []) else: raise HTTP(400, rewrite.params.error_message, web2py_error='invalid path') request.client = get_client(request.env) request.folder = os.path.join(request.env.web2py_path, 'applications', request.application) + '/' # ################################################## # access the requested application # ################################################## if not os.path.exists(request.folder): if request.application == 'init': request.application = 'welcome' redirect(URL(r=request)) elif rewrite.params.error_handler: redirect( URL(rewrite.params.error_handler['application'], rewrite.params.error_handler['controller'], rewrite.params.error_handler['function'], args=request.application)) else: raise HTTP(400, rewrite.params.error_message, web2py_error='invalid application') request.url = URL(r=request, args=request.args, extension=raw_extension) # ################################################## # build missing folder # ################################################## if not request.env.web2py_runtime_gae: for subfolder in [ 'models', 'views', 'controllers', 'databases', 'modules', 'cron', 'errors', 'sessions', 'languages', 'static', 'private', 'uploads' ]: path = os.path.join(request.folder, subfolder) if not os.path.exists(path): os.mkdir(path) # ################################################## # get the GET and POST data # ################################################## parse_get_post_vars(request, environ) # ################################################## # expose wsgi hooks for convenience # ################################################## request.wsgi.environ = environ_aux(environ, request) request.wsgi.start_response = lambda status='200', headers=[], \ exec_info=None, response=response: \ start_response_aux(status, headers, exec_info, response) request.wsgi.middleware = lambda *a: middleware_aux( request, response, *a) # ################################################## # load cookies # ################################################## if request.env.http_cookie: try: request.cookies.load(request.env.http_cookie) except Cookie.CookieError, e: pass # invalid cookies # ################################################## # try load session or create new session file # ################################################## session.connect(request, response) # ################################################## # set no-cache headers # ################################################## response.headers['Content-Type'] = contenttype('.' + request.extension) response.headers['Cache-Control'] = \ 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0' response.headers['Expires'] = \ time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime()) response.headers['Pragma'] = 'no-cache' # ################################################## # run controller # ################################################## serve_controller(request, response, session) except HTTP, http_response: if request.body: request.body.close() # ################################################## # on success, try store session in database # ################################################## session._try_store_in_db(request, response) # ################################################## # on success, commit database # ################################################## if response._custom_commit: response._custom_commit() else: BaseAdapter.close_all_instances(BaseAdapter.commit) # ################################################## # if session not in db try store session on filesystem # this must be done after trying to commit database! # ################################################## session._try_store_on_disk(request, response) # ################################################## # store cookies in headers # ################################################## if session._forget: del response.cookies[response.session_id_name] elif session._secure: response.cookies[response.session_id_name]['secure'] = True if len(response.cookies) > 0: http_response.headers['Set-Cookie'] = \ [str(cookie)[11:] for cookie in response.cookies.values()] ticket = None
def LOAD(c=None, f='index', args=None, vars=None, extension=None, target=None,ajax=False,ajax_trap=False, url=None,user_signature=False, content='loading...',**attr): from html import TAG, DIV, URL, SCRIPT, XML if args is None: args = [] vars = Storage(vars or {}) target = target or 'c'+str(random.random())[2:] attr['_id']=target request = current.request if '.' in f: f, extension = f.split('.',1) if url or ajax: url = url or URL(request.application, c, f, r=request, args=args, vars=vars, extension=extension, user_signature=user_signature) script = SCRIPT('web2py_component("%s","%s")' % (url, target), _type="text/javascript") return TAG[''](script, DIV(content,**attr)) else: if not isinstance(args,(list,tuple)): args = [args] c = c or request.controller other_request = Storage() for key, value in request.items(): other_request[key] = value other_request['env'] = Storage() for key, value in request.env.items(): other_request.env['key'] = value other_request.controller = c other_request.function = f other_request.extension = extension or request.extension other_request.args = List(args) other_request.vars = vars other_request.get_vars = vars other_request.post_vars = Storage() other_response = Response() other_request.env.path_info = '/' + \ '/'.join([request.application,c,f] + \ map(str, other_request.args)) other_request.env.query_string = \ vars and URL(vars=vars).split('?')[1] or '' other_request.env.http_web2py_component_location = \ request.env.path_info other_request.cid = target other_request.env.http_web2py_component_element = target other_response.view = '%s/%s.%s' % (c,f, other_request.extension) other_environment = copy.copy(current.globalenv) ### NASTY other_response._view_environment = other_environment other_response.generic_patterns = \ copy.copy(current.response.generic_patterns) other_environment['request'] = other_request other_environment['response'] = other_response ## some magic here because current are thread-locals original_request, current.request = current.request, other_request original_response, current.response = current.response, other_response page = run_controller_in(c, f, other_environment) if isinstance(page, dict): other_response._vars = page for key in page: other_response._view_environment[key] = page[key] run_view_in(other_response._view_environment) page = other_response.body.getvalue() current.request, current.response = original_request, original_response js = None if ajax_trap: link = URL(request.application, c, f, r=request, args=args, vars=vars, extension=extension, user_signature=user_signature) js = "web2py_trap_form('%s','%s');" % (link, target) script = js and SCRIPT(js,_type="text/javascript") or '' return TAG[''](DIV(XML(page),**attr),script)