def __init__(self,
              request,
              field,
              id_field=None,
              db=None,
              orderby=None,
              limitby=(0, 10),
              keyword='_autocomplete_%(fieldname)s',
              min_length=2):
     self.request = request
     self.keyword = keyword % dict(fieldname=field.name)
     self.db = db or field._db
     self.orderby = orderby
     self.limitby = limitby
     self.min_length = min_length
     self.fields = [field]
     if id_field:
         self.is_reference = True
         self.fields.append(id_field)
     else:
         self.is_reference = False
     if hasattr(request, 'application'):
         self.url = Url(r=request, args=request.args)
         self.callback()
     else:
         self.url = request
Exemple #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 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)
Exemple #3
0
def parse_url(request, environ):
    "parse and rewrite the incoming URL"

    # ##################################################
    # 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'))
        return static_file

    # ##################################################
    # 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.thread.routes.error_message % 'invalid request',
                   web2py_error='invalid path')

    request.application = \
        regex_space.sub('_', match.group('a') or rewrite.thread.routes.default_application)
    request.controller = \
        regex_space.sub('_', match.group('c') or rewrite.thread.routes.default_controller)
    request.function = \
        regex_space.sub('_', match.group('f') or rewrite.thread.routes.default_function)
    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.thread.routes.routes_apps_raw:
        # application is responsible for parsing args
        request.args = None
    elif request.raw_args:
        match = regex_args.match(request.raw_args.replace(' ', '_'))
        if match:
            group_s = match.group('s')
            request.args = \
                List((group_s and group_s.split('/')) or [])
        else:
            raise HTTP(400,
                       rewrite.thread.routes.error_message % 'invalid request',
                       web2py_error='invalid path')
    request.client = get_client(request.env)
    request.folder = os.path.join(request.env.web2py_path, '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:
            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(400,
                       rewrite.thread.routes.error_message % 'invalid request',
                       web2py_error='invalid application')
    request.url = Url(r=request, args=request.args, extension=raw_extension)
    return None