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: session_file = None session_new = False # ################################################## # 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('\\', '/') path = regex_space.sub('_', path) match = regex_url.match(path) if not match: raise HTTP(400, rewrite.params.error_message, web2py_error='invalid path') # ################################################## # serve if a static file # ################################################## if match.group('c') == 'static': raise HTTP(400, rewrite.params.error_message) if 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 # ################################################## request.application = match.group('a') or 'init' request.controller = match.group('c') or 'default' request.function = match.group('f') or 'index' raw_extension = match.group('e') request.extension = raw_extension or 'html' request.args = \ List((match.group('s') and match.group('s').split('/')) or []) 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) # ################################################## # get the GET and POST data -DONE # ################################################## # ## parse GET vars, even if POST dget = cgi.parse_qsl(request.env.query_string, keep_blank_values=1) for (key, value) in dget: if key in request.vars: if isinstance(request.vars[key], list): request.vars[key].append(value) else: request.vars[key] = [request.vars[key], value] else: request.vars[key] = value request.get_vars[key] = request.vars[key] # ## parse POST vars if any request.body = copystream_progress(request) ### stores request body if request.body and request.env.request_method in ('POST', 'PUT', 'BOTH'): dpost = cgi.FieldStorage(fp=request.body, environ=environ, keep_blank_values=1) request.body.seek(0) try: keys = sorted(dpost) except TypeError: keys = [] for key in keys: dpk = dpost[key] if isinstance(dpk, list): if not dpk[0].filename: value = [x.value for x in dpk] else: value = [x for x in dpk] elif not dpk.filename: value = dpk.value else: value = dpk request.post_vars[key] = request.vars[key] = value # ################################################## # 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: SQLDB.close_all_instances(SQLDB.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._secure: response.cookies[response.session_id_name]['secure'] = \ True http_response.headers['Set-Cookie'] = [str(cookie)[11:] for cookie in response.cookies.values()] ticket=None
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: SQLDB.close_all_instances(SQLDB.rollback) http_response = \ HTTP(500, rewrite.params.error_message_ticket % dict(ticket=ticket), web2py_error='ticket %s' % ticket) except: if request.body: request.body.close() # ################################################## # on application error, rollback database # ##################################################
session._unlock(response) http_error_status = check_error_route(500, items[0]) return HTTP(http_error_status, error_message_ticket % dict(ticket=ticket), web2py_error='ticket %s' % ticket).to(responder) except: # ################################################## # on application error, rollback database # ################################################## try: if response._custom_rollback: response._custom_rollback() else: SQLDB.close_all_instances(SQLDB.rollback) except: pass e = RestrictedError('Framework', '', '', locals()) try: ticket = e.log(request) except: ticket = 'unrecoverable' logging.error(e.traceback) session._unlock(response) http_error_status = check_error_route(500, items[0]) return HTTP(http_error_status, error_message_ticket % dict(ticket=ticket), web2py_error='ticket %s' % ticket).to(responder)
def wsgibase(environ, responder): """ this is the gluon wsgi application. the furst function called when a page is requested (static or dynamical). it can be called by paste.httpserver or by apache mod_wsgi. """ request = Request() response = Response() session = Session() try: try: session_file = None session_new = False # ################################################## # parse the environment variables - DONE # ################################################## for (key, value) in environ.items(): request.env[key.lower().replace('.', '_')] = value request.env.web2py_path = web2py_path request.env.web2py_version = web2py_version # ################################################## # valudate 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[1:].replace('\\', '/') path = regex_space.sub('_', path) if not regex_url.match(path): raise HTTP(400, error_message, web2py_error='invalid path') items = path.split('/') # ################################################## # serve if a static file # ################################################## if len(items) > 1 and items[1] == 'static': if len(items) < 3 or not items[2]: raise HTTP(400, error_message) static_file = os.path.join(request.env.web2py_path, 'applications', items[0], 'static', '/'.join(items[2:])) response.stream(static_file, request=request) # ################################################## # parse application, controller and function # ################################################## if len(items) and items[-1] == '': del items[-1] if len(items) == 0: items = ['init'] if len(items) == 1: items.append('default') if len(items) == 2: items.append('index') if len(items) > 3: (items, request.args) = (items[:3], items[3:]) if request.args == None: request.args = [] request.application = items[0] request.controller = items[1] request.function = items[2] 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 items == ['init', 'default', 'index']: items[0] = 'welcome' redirect(html.URL(*items)) raise HTTP(400, error_message, web2py_error='invalid application') # ################################################## # get the GET and POST data -DONE # ################################################## request.body = tempfile.TemporaryFile() if request.env.content_length: copystream(request.env.wsgi_input, request.body, int(request.env.content_length)) # ## parse GET vars, even if POST dget = cgi.parse_qsl(request.env.query_string, keep_blank_values=1) for (key, value) in dget: if request.vars.has_key(key): if isinstance(request.vars[key], list): request.vars[key].append(value) else: request.vars[key] = [request.vars[key], value] else: request.vars[key] = value request.get_vars[key] = request.vars[key] # ## parse POST vars if any if request.env.request_method in ['POST', 'BOTH']: dpost = cgi.FieldStorage(fp=request.body, environ=environ, keep_blank_values=1) request.body.seek(0) try: keys = dpost.keys() except TypeError: keys = [] for key in keys: dpk = dpost[key] if isinstance(dpk, list): value = [x.value for x in dpk] elif not dpk.filename: value = dpk.value else: value = dpk request.post_vars[key] = request.vars[key] = value # ################################################## # load cookies # ################################################## request.cookies = Cookie.SimpleCookie() response.cookies = Cookie.SimpleCookie() if request.env.http_cookie: request.cookies.load(request.env.http_cookie) # ################################################## # try load session or create new session file # ################################################## session.connect(request, response) # ################################################## # set no-cache headers # ################################################## 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 # ################################################## if not items[1] == 'static': serve_controller(request, response, session) except HTTP, http_response: # ################################################## # on sucess, try store session in database # ################################################## session._try_store_in_db(request, response) # ################################################## # on sucess, committ database # ################################################## if response._custom_commit: response._custom_commit() else: SQLDB.close_all_instances(SQLDB.commit) # ################################################## # if session not in db try store session on filesystem # ################################################## session._try_store_on_disk(request, response) # ################################################## # store cookies in headers # ################################################## if session._secure: response.cookies[response.session_id_name]['secure'] = \ True http_response.headers['Set-Cookie'] = [ str(cookie)[11:] for cookie in response.cookies.values() ] # ################################################## # whatever happens return the intended HTTP response # ################################################## session._unlock(response) return http_response.to(responder) except RestrictedError, e: # ################################################## # on application error, rollback database # ################################################## if response._custom_rollback: response._custom_rollback() else: SQLDB.close_all_instances(SQLDB.rollback) try: ticket = e.log(request) except: ticket = 'unknown' logging.error(e.traceback) session._unlock(response) http_error_status = check_error_route(500, items[0]) return HTTP(http_error_status, error_message_ticket % dict(ticket=ticket), web2py_error='ticket %s' % ticket).to(responder)
def wsgibase(environ, responder): """ this is the gluon wsgi application. the furst function called when a page is requested (static or dynamical). it can be called by paste.httpserver or by apache mod_wsgi. """ request = Request() response = Response() session = Session() try: try: session_file = None session_new = False # ################################################## # parse the environment variables - DONE # ################################################## for (key, value) in environ.items(): request.env[key.lower().replace('.', '_')] = value request.env.web2py_path = web2py_path request.env.web2py_version = web2py_version # ################################################## # valudate 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[1:].replace('\\', '/') path = regex_space.sub('_', path) if not regex_url.match(path): raise HTTP(400, error_message, web2py_error='invalid path') items = path.split('/') # ################################################## # serve if a static file # ################################################## if len(items) > 1 and items[1] == 'static': if len(items) < 3 or not items[2]: raise HTTP(400, error_message) static_file = os.path.join(request.env.web2py_path, 'applications', items[0], 'static', '/'.join(items[2:])) response.stream(static_file, request=request) # ################################################## # parse application, controller and function # ################################################## if len(items) and items[-1] == '': del items[-1] if len(items) == 0: items = ['init'] if len(items) == 1: items.append('default') if len(items) == 2: items.append('index') if len(items) > 3: (items, request.args) = (items[:3], items[3:]) if request.args == None: request.args = [] request.application = items[0] request.controller = items[1] request.function = items[2] 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 items == ['init', 'default', 'index']: items[0] = 'welcome' redirect(html.URL(*items)) raise HTTP(400, error_message, web2py_error='invalid application') # ################################################## # get the GET and POST data -DONE # ################################################## request.body = tempfile.TemporaryFile() if request.env.content_length: copystream(request.env.wsgi_input, request.body, int(request.env.content_length)) # ## parse GET vars, even if POST dget = cgi.parse_qsl(request.env.query_string, keep_blank_values=1) for (key, value) in dget: if request.vars.has_key(key): if isinstance(request.vars[key], list): request.vars[key].append(value) else: request.vars[key] = [request.vars[key], value] else: request.vars[key] = value request.get_vars[key] = request.vars[key] # ## parse POST vars if any if request.env.request_method in ['POST', 'BOTH']: dpost = cgi.FieldStorage(fp=request.body, environ=environ, keep_blank_values=1) request.body.seek(0) try: keys = dpost.keys() except TypeError: keys = [] for key in keys: dpk = dpost[key] if isinstance(dpk, list): value = [x.value for x in dpk] elif not dpk.filename: value = dpk.value else: value = dpk request.post_vars[key] = request.vars[key] = value # ################################################## # load cookies # ################################################## request.cookies = Cookie.SimpleCookie() response.cookies = Cookie.SimpleCookie() if request.env.http_cookie: request.cookies.load(request.env.http_cookie) # ################################################## # try load session or create new session file # ################################################## session.connect(request, response) # ################################################## # set no-cache headers # ################################################## 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 # ################################################## if not items[1] == 'static': serve_controller(request, response, session) except HTTP, http_response: # ################################################## # on sucess, try store session in database # ################################################## session._try_store_in_db(request, response) # ################################################## # on sucess, committ database # ################################################## if response._custom_commit: response._custom_commit() else: SQLDB.close_all_instances(SQLDB.commit) # ################################################## # if session not in db try store session on filesystem # ################################################## session._try_store_on_disk(request, response) # ################################################## # store cookies in headers # ################################################## if session._secure: response.cookies[response.session_id_name]['secure'] = \ True http_response.headers['Set-Cookie'] = [str(cookie)[11:] for cookie in response.cookies.values()] # ################################################## # whatever happens return the intended HTTP response # ################################################## session._unlock(response) return http_response.to(responder) except RestrictedError, e: # ################################################## # on application error, rollback database # ################################################## if response._custom_rollback: response._custom_rollback() else: SQLDB.close_all_instances(SQLDB.rollback) try: ticket = e.log(request) except: ticket = 'unknown' logging.error(e.traceback) session._unlock(response) http_error_status = check_error_route(500, items[0]) return HTTP(http_error_status, error_message_ticket % dict(ticket=ticket), web2py_error='ticket %s' % ticket).to(responder)