Esempio n. 1
0
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([
                                ip[4][0] for ip in socket.getaddrinfo(
                                    fqdn, 0)])
                            if env.server_name:
                                local_hosts.add(env.server_name)
                                local_hosts.update([
                                    ip[4][0] for ip in socket.getaddrinfo(
                                        env.server_name, 0)])
                        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'] = 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)
Esempio n. 2
0
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()
    request.env.web2py_path = global_settings.applications_parent
    request.env.web2py_version = web2py_version
    request.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
                # ##################################################

                if not environ.get('PATH_INFO',None) and \
                        environ.get('REQUEST_URI',None):
                    # for fcgi, get path_info and query_string from request_uri
                    items = environ['REQUEST_URI'].split('?')
                    environ['PATH_INFO'] = items[0]
                    if len(items) > 1:
                        environ['QUERY_STRING'] = items[1]
                    else:
                        environ['QUERY_STRING'] = ''
                if not environ.get('HTTP_HOST',None):
                    environ['HTTP_HOST'] = '%s:%s' % (environ.get('SERVER_NAME'),
                                                      environ.get('SERVER_PORT'))

                (static_file, environ) = rewrite.url_in(request, environ)
                if static_file:
                    if environ.get('QUERY_STRING', '')[:10] == 'attachment':
                        response.headers['Content-Disposition'] = 'attachment'
                    response.stream(static_file, request=request)

                # ##################################################
                # fill in request items
                # ##################################################

                http_host = request.env.http_host.split(':',1)[0]

                local_hosts = [http_host,'::1','127.0.0.1','::ffff:127.0.0.1']
                if not global_settings.web2py_runtime_gae:
                    local_hosts.append(socket.gethostname())
                    try: local_hosts.append(socket.gethostbyname(http_host))
                    except socket.gaierror: pass
                request.client = get_client(request.env)
                if not is_valid_ip_address(request.client):
                    raise HTTP(400,"Bad Request (request.client=%s)" % \
                                   request.client)
                request.folder = abspath('applications',
                                         request.application) + os.sep
                x_req_with = str(request.env.http_x_requested_with).lower()
                request.ajax = x_req_with == 'xmlhttprequest'
                request.cid = request.env.http_web2py_component_element
                request.is_local = request.env.remote_addr in local_hosts
                request.is_https = request.env.wsgi_url_scheme \
                    in ['https', 'HTTPS'] or request.env.https == 'on'

                # ##################################################
                # compute a request.uuid to be used for tickets and toolbar
                # ##################################################

                response.uuid = request.compute_uuid()

                # ##################################################
                # access the requested application
                # ##################################################

                if not os.path.exists(request.folder):
                    if request.application == \
                            rewrite.thread.routes.default_application \
                            and request.application != 'welcome':
                        request.application = 'welcome'
                        redirect(Url(r=request))
                    elif rewrite.thread.routes.error_handler:
                        _handler = rewrite.thread.routes.error_handler
                        redirect(Url(_handler['application'],
                                     _handler['controller'],
                                     _handler['function'],
                                     args=request.application))
                    else:
                        raise HTTP(404, rewrite.thread.routes.error_message \
                                       % 'invalid request',
                                   web2py_error='invalid application')
                elif not request.is_local and \
                        os.path.exists(os.path.join(request.folder,'DISABLED')):
                    raise HTTP(503, "<html><body><h1>Temporarily down for maintenance</h1></body></html>")
                request.url = Url(r=request, args=request.args,
                                       extension=request.raw_extension)

                # ##################################################
                # 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 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
                # ##################################################

                if global_settings.debugging and request.application != "admin":
                    import gluon.debug
                    # activate the debugger and wait to reach application code
                    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)

                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_on_disk(request, response)

                # ##################################################
                # store cookies in headers
                # ##################################################

                if request.cid:
                    if response.flash and not 'web2py-component-flash' \
                            in http_response.headers:
                        http_response.headers['web2py-component-flash'] = \
                            urllib2.quote(xmlescape(response.flash)\
                                              .replace('\n',''))
                    if response.js and not 'web2py-component-command' \
                            in http_response.headers:
                        http_response.headers['web2py-component-command'] = \
                            response.js.replace('\n','')
                if session._forget and \
                        response.session_id_name in response.cookies:
                    del response.cookies[response.session_id_name]
                elif session._secure:
                    response.cookies[response.session_id_name]['secure'] = True

                http_response.cookies2headers(response.cookies)
                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, rewrite.thread.routes.error_message_ticket % \
                             dict(ticket=ticket),
                         web2py_error='ticket %s' % ticket)
Esempio n. 3
0
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 '/'
    """

    rewrite.select(environ)
    if rewrite.params.routes_in:
        environ = rewrite.filter_in(environ)

    request = Request()
    response = Response()
    session = Session()
    static_file = False
    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)

            # ##################################################
            # invoke the legacy URL parser and serve static file
            # ##################################################

            static_file = parse_url(request, environ)
            if static_file:
                if request.env.get('query_string', '')[:10] == 'attachment':
                    response.headers['Content-Disposition'] = 'attachment'
                response.stream(static_file, request=request)

            # ##################################################
            # 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 static_file:
                return http_response.to(responder)

            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 request.cid:
                if response.flash and not 'web2py-component-flash' in http_response.headers:
                    http_response.headers['web2py-component-flash'] = \
                        str(response.flash).replace('\n','')
                if response.js and not 'web2py-component-command' in http_response.headers:
                    http_response.headers['web2py-component-command'] = \
                        str(response.js).replace('\n','')
            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
Esempio n. 4
0
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)
Esempio n. 5
0
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 '/'
    """

    request = Request()
    response = Response()
    session = Session()
    request.env.web2py_path = global_settings.applications_parent
    request.env.web2py_version = web2py_version
    request.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
                # ##################################################

                if not environ.get('PATH_INFO',None) and environ.get('REQUEST_URI',None):
                    # for fcgi, get path_info and query_string from request_uri
                    items = environ['REQUEST_URI'].split('?')
                    environ['PATH_INFO'] = items[0]
                    if len(items) > 1:
                        environ['QUERY_STRING'] = items[1]
                    else:
                        environ['QUERY_STRING'] = ''
                (static_file, environ) = rewrite.url_in(request, environ)
                if static_file:
                    if request.env.get('query_string', '')[:10] == 'attachment':
                        response.headers['Content-Disposition'] = 'attachment'
                    response.stream(static_file, request=request)

                # ##################################################
                # fill in request items
                # ##################################################

                request.client = get_client(request.env)
                request.folder = os.path.join(request.env.applications_parent,
                        'applications', request.application) + '/'
                request.ajax = str(request.env.http_x_requested_with).lower() == 'xmlhttprequest'
                request.cid = request.env.http_web2py_component_element

                # ##################################################
                # access the requested application
                # ##################################################

                if not os.path.exists(request.folder):
                    if request.application == rewrite.thread.routes.default_application and request.application != 'welcome':
                        request.application = 'welcome'
                        redirect(Url(r=request))
                    elif rewrite.thread.routes.error_handler:
                        redirect(Url(rewrite.thread.routes.error_handler['application'],
                                     rewrite.thread.routes.error_handler['controller'],
                                     rewrite.thread.routes.error_handler['function'],
                                     args=request.application))
                    else:
                        raise HTTP(404,
                                   rewrite.thread.routes.error_message % 'invalid request',
                                   web2py_error='invalid application')
                request.url = Url(r=request, args=request.args,
                                       extension=request.raw_extension)

                # ##################################################
                # 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 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 static_file:
                    return http_response.to(responder)

                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('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 request.cid:
                    if response.flash and not 'web2py-component-flash' in http_response.headers:
                        http_response.headers['web2py-component-flash'] = \
                            str(response.flash).replace('\n','')
                    if response.js and not 'web2py-component-command' in http_response.headers:
                        http_response.headers['web2py-component-command'] = \
                            str(response.js).replace('\n','')
                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

            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,
                         rewrite.thread.routes.error_message_ticket % dict(ticket=ticket),
                         web2py_error='ticket %s' % ticket)
Esempio n. 6
0
File: main.py Progetto: w3fs/web2py
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()
    request.env.web2py_path = global_settings.applications_parent
    request.env.web2py_version = web2py_version
    request.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
                # ##################################################

                if not environ.get('PATH_INFO',None) and \
                        environ.get('REQUEST_URI',None):
                    # for fcgi, get path_info and query_string from request_uri
                    items = environ['REQUEST_URI'].split('?')
                    environ['PATH_INFO'] = items[0]
                    if len(items) > 1:
                        environ['QUERY_STRING'] = items[1]
                    else:
                        environ['QUERY_STRING'] = ''
                if not environ.get('HTTP_HOST',None):
                    environ['HTTP_HOST'] = '%s:%s' % (environ.get('SERVER_NAME'),
                                                      environ.get('SERVER_PORT'))

                (static_file, environ) = rewrite.url_in(request, environ)
                if static_file:
                    if request.env.get('query_string', '')[:10] == 'attachment':
                        response.headers['Content-Disposition'] = 'attachment'
                    response.stream(static_file, request=request)

                # ##################################################
                # fill in request items
                # ##################################################

                http_host = request.env.http_host.split(':',1)[0]

                local_hosts = [http_host,'::1','127.0.0.1','::ffff:127.0.0.1']
                if not global_settings.web2py_runtime_gae:
                    local_hosts += [socket.gethostname(),
                                    socket.gethostbyname(http_host)]
                request.client = get_client(request.env)
                request.folder = abspath('applications',
                                         request.application) + os.sep
                x_req_with = str(request.env.http_x_requested_with).lower()
                request.ajax = x_req_with == 'xmlhttprequest'
                request.cid = request.env.http_web2py_component_element
                request.is_local = request.env.remote_addr in local_hosts
                request.is_https = request.env.wsgi_url_scheme \
                    in ['https', 'HTTPS'] or request.env.https == 'on'

                # ##################################################
                # compute a request.uuid to be used for tickets and toolbar
                # ##################################################

                response.uuid = request.compute_uuid()

                # ##################################################
                # access the requested application
                # ##################################################

                if not os.path.exists(request.folder):
                    if request.application == \
                            rewrite.thread.routes.default_application \
                            and request.application != 'welcome':
                        request.application = 'welcome'
                        redirect(Url(r=request))
                    elif rewrite.thread.routes.error_handler:
                        _handler = rewrite.thread.routes.error_handler
                        redirect(Url(_handler['application'],
                                     _handler['controller'],
                                     _handler['function'],
                                     args=request.application))
                    else:
                        raise HTTP(404, rewrite.thread.routes.error_message \
                                       % 'invalid request',
                                   web2py_error='invalid application')
                elif not request.is_local and \
                        os.path.exists(os.path.join(request.folder,'DISABLED')):
                    raise HTTP(200, "<html><body><h1>Down for maintenance</h1></body></html>")
                request.url = Url(r=request, args=request.args,
                                       extension=request.raw_extension)

                # ##################################################
                # 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 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 static_file:
                    return http_response.to(responder)

                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()
                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_on_disk(request, response)

                # ##################################################
                # store cookies in headers
                # ##################################################

                if request.cid:

                    if response.flash and not 'web2py-component-flash' in http_response.headers:
                        http_response.headers['web2py-component-flash'] = \
                            str(response.flash).replace('\n','')
                    if response.js and not 'web2py-component-command' in http_response.headers:
                        http_response.headers['web2py-component-command'] = \
                            response.js.replace('\n','')
                if session._forget and \
                        response.session_id_name in response.cookies:
                    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

            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, rewrite.thread.routes.error_message_ticket % \
                             dict(ticket=ticket),
                         web2py_error='ticket %s' % ticket)
Esempio n. 7
0
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
Esempio n. 8
0
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('\\', '/')
            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)

            # ##################################################
            # build missing folder
            # ##################################################
            
            if not request.env.web2py_runtime_gae:
                for subfolder in ['models','views','controllers',
                                  '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._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
Esempio n. 9
0
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)
Esempio n. 10
0
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 '/'
    """

    rewrite.select(environ)
    if rewrite.thread.routes.routes_in:
        environ = rewrite.filter_in(environ)

    request = Request()
    response = Response()
    session = Session()
    static_file = False
    try:
        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)

                # ##################################################
                # invoke the legacy URL parser and serve static file
                # ##################################################

                static_file = parse_url(request, environ)
                if static_file:
                    if request.env.get('query_string',
                                       '')[:10] == 'attachment':
                        response.headers['Content-Disposition'] = 'attachment'
                    response.stream(static_file, request=request)

                # ##################################################
                # 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 static_file:
                    return http_response.to(responder)

                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 request.cid:
                    if response.flash and not 'web2py-component-flash' in http_response.headers:
                        http_response.headers['web2py-component-flash'] = \
                            str(response.flash).replace('\n','')
                    if response.js and not 'web2py-component-command' in http_response.headers:
                        http_response.headers['web2py-component-command'] = \
                            str(response.js).replace('\n','')
                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

            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(BaseAdapter.rollback)

                http_response = \
                    HTTP(500,
                         rewrite.thread.routes.error_message_ticket % dict(ticket=ticket),
                         web2py_error='ticket %s' % ticket)
Esempio n. 11
0
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, 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"
                    response.stream(static_file, request=request)

                # ##################################################
                # fill in request items
                # ##################################################
                app = request.application  ## must go after url_in!

                http_host = env.http_host.split(":", 1)[0]
                local_hosts = [http_host, "::1", "127.0.0.1", "::ffff:127.0.0.1"]
                if not global_settings.web2py_runtime_gae:
                    local_hosts.append(socket.gethostname())
                    try:
                        local_hosts.append(socket.gethostbyname(http_host))
                    except socket.gaierror:
                        pass
                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", "HTTPS"] or env.https == "on",
                )
                request.uuid = 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_on_disk(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"] = 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
                )
Esempio n. 12
0
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)
Esempio n. 13
0
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()
    request.env.web2py_path = global_settings.applications_parent
    request.env.web2py_version = web2py_version
    request.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
                # ##################################################

                if not environ.get("PATH_INFO", None) and environ.get("REQUEST_URI", None):
                    # for fcgi, get path_info and query_string from request_uri
                    items = environ["REQUEST_URI"].split("?")
                    environ["PATH_INFO"] = items[0]
                    if len(items) > 1:
                        environ["QUERY_STRING"] = items[1]
                    else:
                        environ["QUERY_STRING"] = ""
                if not environ.get("HTTP_HOST", None):
                    environ["HTTP_HOST"] = "%s:%s" % (environ.get("SERVER_NAME"), environ.get("SERVER_PORT"))

                (static_file, environ) = rewrite.url_in(request, environ)
                if static_file:
                    if request.env.get("query_string", "")[:10] == "attachment":
                        response.headers["Content-Disposition"] = "attachment"
                    response.stream(static_file, request=request)

                # ##################################################
                # fill in request items
                # ##################################################

                http_host = request.env.http_host.split(":", 1)[0]

                local_hosts = [http_host, "::1", "127.0.0.1", "::ffff:127.0.0.1"]
                if not global_settings.web2py_runtime_gae:
                    local_hosts += [socket.gethostname(), socket.gethostbyname(http_host)]
                request.client = get_client(request.env)
                request.folder = abspath("applications", request.application) + os.sep
                x_req_with = str(request.env.http_x_requested_with).lower()
                request.ajax = x_req_with == "xmlhttprequest"
                request.cid = request.env.http_web2py_component_element
                request.is_local = request.env.remote_addr in local_hosts
                request.is_https = request.env.wsgi_url_scheme in ["https", "HTTPS"] or request.env.https == "on"

                # ##################################################
                # compute a request.uuid to be used for tickets and toolbar
                # ##################################################

                response.uuid = request.compute_uuid()

                # ##################################################
                # access the requested application
                # ##################################################

                if not os.path.exists(request.folder):
                    if (
                        request.application == rewrite.thread.routes.default_application
                        and request.application != "welcome"
                    ):
                        request.application = "welcome"
                        redirect(Url(r=request))
                    elif rewrite.thread.routes.error_handler:
                        redirect(
                            Url(
                                rewrite.thread.routes.error_handler["application"],
                                rewrite.thread.routes.error_handler["controller"],
                                rewrite.thread.routes.error_handler["function"],
                                args=request.application,
                            )
                        )
                    else:
                        raise HTTP(
                            404,
                            rewrite.thread.routes.error_message % "invalid request",
                            web2py_error="invalid application",
                        )
                request.url = Url(r=request, args=request.args, extension=request.raw_extension)

                # ##################################################
                # 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 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 static_file:
                    return http_response.to(responder)

                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("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 request.cid:

                    if response.flash and not "web2py-component-flash" in http_response.headers:
                        http_response.headers["web2py-component-flash"] = dumps(str(response.flash).replace("\n", ""))
                    if response.js and not "web2py-component-command" in http_response.headers:
                        http_response.headers["web2py-component-command"] = response.js.replace("\n", "")
                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

            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,
                    rewrite.thread.routes.error_message_ticket % dict(ticket=ticket),
                    web2py_error="ticket %s" % ticket,
                )