Пример #1
0
def serve_controller(request, response, session):
    """
    This function is used to generate a dynamic page.
    It first runs all models, then runs the function in the controller,
    and then tries to render the output using a view/template.
    this function must run from the [application] folder.
    A typical example would be the call to the url
    /[application]/[controller]/[function] that would result in a call
    to [function]() in applications/[application]/[controller].py
    rendered by applications/[application]/views/[controller]/[function].html
    """

    # ##################################################
    # build environment for controller and view
    # ##################################################

    environment = build_environment(request, response, session)

    # set default view, controller can override it

    response.view = '%s/%s.%s' % (request.controller, request.function,
                                  request.extension)

    # also, make sure the flash is passed through
    # ##################################################
    # process models, controller and view (if required)
    # ##################################################

    run_models_in(environment)
    response._view_environment = copy.copy(environment)
    page = run_controller_in(request.controller, request.function, environment)
    if isinstance(page, dict):
        response._vars = page
        response._view_environment.update(page)
        page = run_view_in(response._view_environment)

    if not request.env.web2py_disable_garbage_collect:
        # logic to garbage collect after exec, not always, once every 100 requests
        global requests
        requests = ('requests' in globals()) and (requests + 1) % 100 or 0
        if not requests:
            gc.collect()
        # end garbage collection logic

    # ##################################################
    # set default headers it not set
    # ##################################################

    default_headers = [
        ('Content-Type', contenttype('.' + request.extension)),
        ('Cache-Control',
         'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'),
        ('Expires', unlocalised_http_header_date(time.gmtime())),
        ('Pragma', 'no-cache')
    ]
    for key, value in default_headers:
        response.headers.setdefault(key, value)

    raise HTTP(response.status, page, **response.headers)
Пример #2
0
def serve_controller(request, response, session):
    """
    This function is used to generate a dynamic page.
    It first runs all models, then runs the function in the controller,
    and then tries to render the output using a view/template.
    this function must run from the [application] folder.
    A typical example would be the call to the url
    /[application]/[controller]/[function] that would result in a call
    to [function]() in applications/[application]/[controller].py
    rendered by applications/[application]/views/[controller]/[function].html
    """

    # ##################################################
    # build environment for controller and view
    # ##################################################

    environment = build_environment(request, response, session)

    # set default view, controller can override it

    response.view = '%s/%s.%s' % (request.controller,
                                  request.function,
                                  request.extension)

    # also, make sure the flash is passed through
    # ##################################################
    # process models, controller and view (if required)
    # ##################################################

    run_models_in(environment)
    response._view_environment = copy.copy(environment)
    page = run_controller_in(request.controller, request.function, environment)
    if isinstance(page, dict):
        response._vars = page
        response._view_environment.update(page)
        page = run_view_in(response._view_environment)

    if not request.env.web2py_disable_garbage_collect:
        # logic to garbage collect after exec, not always, once every 100 requests
        global requests
        requests = ('requests' in globals()) and (requests + 1) % 100 or 0
        if not requests:
            gc.collect()
        # end garbage collection logic

    # ##################################################
    # set default headers it not set
    # ##################################################

    default_headers = [
        ('Content-Type', contenttype('.' + request.extension)),
        ('Cache-Control',
         'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'),
        ('Expires', unlocalised_http_header_date(time.gmtime())),
        ('Pragma', 'no-cache')]
    for key, value in default_headers:
        response.headers.setdefault(key, value)

    raise HTTP(response.status, page, **response.headers)
Пример #3
0
def stream_file_or_304_or_206(
    static_file,
    chunk_size=DEFAULT_CHUNK_SIZE,
    request=None,
    headers={},
    status=200,
    error_message=None
    ):
    # FIX THIS
    # if error_message is None:
    #     error_message = rewrite.THREAD_LOCAL.routes.error_message % 'invalid request'
    try:
        if PY2:
            open_f = file # this makes no sense but without it GAE cannot open files
        else:
            open_f = open
        fp = open_f(static_file,'rb')
    except IOError as e:
        if e.errno == errno.EISDIR:
            raise HTTP(403, error_message, web2py_error='file is a directory')
        elif e.errno == errno.EACCES:
            raise HTTP(403, error_message, web2py_error='inaccessible file')
        else:
            raise HTTP(404, error_message, web2py_error='invalid file')
    else:
        fp.close()
    stat_file = os.stat(static_file)
    fsize = stat_file[stat.ST_SIZE]
    modified = stat_file[stat.ST_MTIME]
    mtime = unlocalised_http_header_date(time.gmtime(modified))
    headers.setdefault('Content-Type', contenttype(static_file))
    headers.setdefault('Last-Modified', mtime)
    headers.setdefault('Pragma', 'cache')
    headers.setdefault('Cache-Control', 'private')

    # if this is a normal response and not a respnse to an error page
    if status == 200:
        if request and request.env.http_if_modified_since == mtime:
            raise HTTP(304, **{'Content-Type': headers['Content-Type']})

        elif request and request.env.http_range:
            start_items = regex_start_range.findall(request.env.http_range)
            if not start_items:
                start_items = [0]
            stop_items = regex_stop_range.findall(request.env.http_range)
            if not stop_items or int(stop_items[0]) > fsize - 1:
                stop_items = [fsize - 1]
            part = (int(start_items[0]), int(stop_items[0]), fsize)
            bytes = part[1] - part[0] + 1
            try:
                stream = open(static_file, 'rb')
            except IOError as e:
                if e.errno in (errno.EISDIR, errno.EACCES):
                    raise HTTP(403)
                else:
                    raise HTTP(404)
            stream.seek(part[0])
            headers['Content-Range'] = 'bytes %i-%i/%i' % part
            headers['Content-Length'] = '%i' % bytes
            status = 206
    # in all the other cases (not 304, not 206, but 200 or error page)
    if status != 206:
        enc = request.env.http_accept_encoding
        if enc and 'gzip' in enc and not 'Content-Encoding' in headers:
            gzipped = static_file + '.gz'
            if os.path.isfile(gzipped) and os.path.getmtime(gzipped) >= modified:
                static_file = gzipped
                fsize = os.path.getsize(gzipped)
                headers['Content-Encoding'] = 'gzip'
                headers['Vary'] = 'Accept-Encoding'
        try:
            stream = open(static_file, 'rb')
        except IOError as e:
            # this better not happen when returning an error page ;-)
            if e.errno in (errno.EISDIR, errno.EACCES):
                raise HTTP(403)
            else:
                raise HTTP(404)
        headers['Content-Length'] = fsize
        bytes = None
    if request and request.env.web2py_use_wsgi_file_wrapper:
        wrapped = request.env.wsgi_file_wrapper(stream, chunk_size)
    else:
        wrapped = streamer(stream, chunk_size=chunk_size, bytes=bytes)
    raise HTTP(status, wrapped, **headers)
Пример #4
0
def stream_file_or_304_or_206(
    static_file,
    chunk_size=DEFAULT_CHUNK_SIZE,
    request=None,
    headers={},
    status=200,
    error_message=None
    ):
    # FIX THIS
    # if error_message is None:
    #     error_message = rewrite.THREAD_LOCAL.routes.error_message % 'invalid request'
    try:
        if PY2:
            open_f = file # this makes no sense but without it GAE cannot open files
        else:
            open_f = open
        fp = open_f(static_file,'rb')
    except IOError as e:
        if e.errno == errno.EISDIR:
            raise HTTP(403, error_message, web2py_error='file is a directory')
        elif e.errno == errno.EACCES:
            raise HTTP(403, error_message, web2py_error='inaccessible file')
        else:
            raise HTTP(404, error_message, web2py_error='invalid file')
    else:
        fp.close()
    stat_file = os.stat(static_file)
    fsize = stat_file[stat.ST_SIZE]
    modified = stat_file[stat.ST_MTIME]
    mtime = unlocalised_http_header_date(time.gmtime(modified))
    headers.setdefault('Content-Type', contenttype(static_file))
    headers.setdefault('Last-Modified', mtime)
    headers.setdefault('Pragma', 'cache')
    headers.setdefault('Cache-Control', 'private')

    # if this is a normal response and not a respnse to an error page
    if status == 200:
        if request and request.env.http_if_modified_since == mtime:
            raise HTTP(304, **{'Content-Type': headers['Content-Type']})

        elif request and request.env.http_range:
            start_items = regex_start_range.findall(request.env.http_range)
            if not start_items:
                start_items = [0]
            stop_items = regex_stop_range.findall(request.env.http_range)
            if not stop_items or int(stop_items[0]) > fsize - 1:
                stop_items = [fsize - 1]
            part = (int(start_items[0]), int(stop_items[0]), fsize)
            bytes = part[1] - part[0] + 1
            try:
                stream = open(static_file, 'rb')
            except IOError as e:
                if e.errno in (errno.EISDIR, errno.EACCES):
                    raise HTTP(403)
                else:
                    raise HTTP(404)
            stream.seek(part[0])
            headers['Content-Range'] = 'bytes %i-%i/%i' % part
            headers['Content-Length'] = '%i' % bytes
            status = 206
    # in all the other cases (not 304, not 206, but 200 or error page)
    if status != 206:
        enc = request.env.http_accept_encoding
        if enc and 'gzip' in enc and not 'Content-Encoding' in headers:
            gzipped = static_file + '.gz'
            if os.path.isfile(gzipped) and os.path.getmtime(gzipped) >= modified:
                static_file = gzipped
                fsize = os.path.getsize(gzipped)
                headers['Content-Encoding'] = 'gzip'
                headers['Vary'] = 'Accept-Encoding'
        try:
            stream = open(static_file, 'rb')
        except IOError as e:
            # this better not happen when returning an error page ;-)
            if e.errno in (errno.EISDIR, errno.EACCES):
                raise HTTP(403)
            else:
                raise HTTP(404)
        headers['Content-Length'] = fsize
        bytes = None
    if request and request.env.web2py_use_wsgi_file_wrapper:
        wrapped = request.env.wsgi_file_wrapper(stream, chunk_size)
    else:
        wrapped = streamer(stream, chunk_size=chunk_size, bytes=bytes)
    raise HTTP(status, wrapped, **headers)