Example #1
0
 def handle_unauthorized(self, errordata):
     @template(self.template, **self.template_opts)          
     def tmp():
         return errordata
     exc=get_http_exception(200)
     exc.body=tmp()
     raise exc
Example #2
0
 def __call__(self, environ, start_response):
     try:
         request = self.get_request(environ)
         path, realpath, statinfo = self.check_path(request.path)
         app = self.serve_file(path, realpath, statinfo, request)
         if app:
             return app(environ, start_response)
         exc = get_http_exception(httplib.NOT_FOUND)
         return exc(environ, start_response)
     except webob.exc.HTTPException, exc:
         return exc(environ, start_response)
Example #3
0
 def check_path(self, path):
     """
     takes a request path and looks for a real path related to it.
     returns the path (possibly corrected), the translated path, and
     stat() info. If is can be determined that the correct status code
     for this resource is not 200, it will raise a webob.exc.HTTPException
     here.
     """
     componentRoot = Configuration.componentRoot
     realpath = translate_path(componentRoot, path)
     try:
         s = os.stat(realpath)
     except (OSError, IOError), oy:
         if oy.errno == errno.ENOENT:
             raise get_http_exception(httplib.NOT_FOUND)
         elif oy.errno == errno.EACCES:
             raise get_http_exception(httplib.FORBIDDEN)
         # anything else?
         else:
             # let a more general 500 handler clean up.
             raise
Example #4
0
def serve_static(path, realpath, statinfo, request):
    if request.method not in ("GET", "HEAD"):
        return get_http_exception(httplib.METHOD_NOT_ALLOWED)
    type, contentenc = mimetypes.guess_type(realpath)

    if not type:
        type = "application/octet-stream"

    if Configuration.staticFileUseXSendFile:
        header = Configuration.staticFileXSendFileHeader
        if Configuration.staticFileXSendFilePathTranslated:
            xpath = realpath
        else:
            xpath = path

        # I don't think I need conditional_response here; if you
        # are using X-Sendfile your web server should be able to
        # deal (at least it can it later versions of lighttpd)
        res = webob.Response(content_type=type, content_length=statinfo.st_size, last_modified=statinfo.st_mtime)
        res.headers.add(header, xpath)
    else:
        res = webob.Response(
            content_type=type,
            conditional_response=True,
            app_iter=FileIterable(realpath),
            content_length=statinfo.st_size,
            last_modified=statinfo.st_mtime,
        )

        if Configuration.staticFileAddEtag:
            # this can be more efficient than generating an Etag
            # from the response body, so we're making it possible
            # to do here rather than in middleware
            etag = "%s|%d|%d" % (realpath, statinfo.st_size, statinfo.st_mtime)
            etag = md5.md5(etag).hexdigest()
            res.headers["etag"] = etag

    if contentenc:
        res.content_encoding = contentenc

    if type.startswith("text/"):
        if Configuration.defaultCharset:
            res.charset = Configuration.defaultCharset
        elif chardet and Configuration.staticFileUseChardet:
            res.charset = chardet.detect(open(realpath).read(1024))["encoding"]

    # Other custom header munging is left for middleware, or
    # something else
    return res
Example #5
0
def dispatch(environ, *args, **kwargs):
    log.debug("in dispatch")
    controller_name=kwargs.pop('controller', None)
    if not controller_name:
        log.debug("no controller found")
        return

    controller=Configuration.controllers.get(controller_name)
    if not controller:
        log.warn('no such controller found: %s', controller_name)
        return
    if isinstance(controller, basestring):
        try:
            controller=import_from_string(controller)
        except ImportError:
            return get_http_exception(httplib.INTERNAL_SERVER_ERROR,
                                      comment="couldn't import controller %s" % controller)
    else:
        log.debug("got a non-string for controller: %s", controller)
    action=kwargs.pop('action', 'index')
    reqmeth=environ['REQUEST_METHOD']
    if reqmeth=='HEAD':
        reqmeth='GET'
    method_qualified_action='%s_%s' % (action, reqmeth)
    meth=getattr(controller, method_qualified_action, None)
    if not meth:
        meth=getattr(controller, action, None)
    if not meth:
        log.debug(("no controller action found "
                   "(looked for action %s in controller %s)"),
                  action, controller)
        return 

    if not getattr(meth, 'exposed', False):
        log.info("request for method that isn't exposed, not honoring")
        return
    log.debug("method is %s", meth)
    try:
        res=meth(*args, **kwargs)
    except webob.exc.HTTPException, e:
        res=e
Example #6
0
def _redirect(url, status=httplib.MOVED_PERMANENTLY):
    raise get_http_exception(status, location=url)
Example #7
0
 def process_login(self):
     # I don't return anything here, but always
     # raise a 401
     exc=get_http_exception(401)
     exc.headers['WWW-Authenticate']='Basic: realm=' % self.realm
     raise exc
Example #8
0
def _interpret_response(res, meth):
    """
    coerces the response into a webob.Response object.

    Types accepted:

    - a webob.Response or callable
    - None, in which case Context.response is returned 
    - a string, which is set to the body of Context.response and the latter
      is returned
    - a unicode string (similar)
    - if content type is application/json and type is list, tuple, or dict,
      data will be json-ed and put in Context.response, which is returned
    - a list, tuple or generator -- becomes Context.response.app_iter
    - an integer is taken to be an HTTP status code and a default error
      response is generated.  An invalid code will cause an error.

    Anything else is turned in a string with str().

    This will also set attributes on response that have been set with the
    @expose decorator, but only if the context response is used; if another
    response is returned, those values will be ignored.
    
    """
    if isinstance(res, webob.Response):
        return res
    elif callable(res):
        # should be a WSGI application
        return res
    ctxt_res=Context.response
    if res is None:
        log.warn("returning None from controller action, returning context response")
        return ctxt_res
    # some response metadata may be set in the expose decorator
    # (perhaps too much -- for instance, "body".  If you do that,
    # it's your problem)
    response_attrs=getattr(meth, 'response_attrs', {})
    for k, v in response_attrs.iteritems():
        setattr(ctxt_res, k, v)
    
    if isinstance(res, str):
        ctxt_res.body=res
        return ctxt_res
    elif isinstance(res, unicode):
        ctxt_res.unicode_body=res
        return ctxt_res
    elif ctxt_res.content_type=='application/json' \
             and isinstance(res, (list,tuple,dict)):
        ctxt_res.body=simplejson.dumps(res)
        return ctxt_res
    elif isinstance(res, (list,tuple,types.GeneratorType)):
        ctxt_res.app_iter=res
        return ctxt_res
    elif isinstance(res, int):
        try:
            return get_http_exception(res)
        except KeyError:
            log.error("returning unrecognized http status code from controller: %d",
                     res)
            raise
    # last resort
    log.debug(("got unusual type, %s, as return value from action, "
               "stringifying as last resort"),
              type(res))
    ctxt_res.body=str(res)
    return ctxt_res
Example #9
0
        else:
            if stat.S_ISDIR(s.st_mode):
                # look for index files
                for ifile in Configuration.indexDocuments:
                    p = os.path.join(realpath, ifile)
                    if os.path.isfile(p):

                        # we have an index document.  Did the url
                        # start with a slash?  If so, redirect to
                        # slashed url.  (We don't do this before the
                        # index document check so that users aren't
                        # given information about the existence of
                        # directories without index documents.)

                        if not path.endswith("/"):
                            raise get_http_exception(httplib.MOVED_PERMANENTLY, add_slash=True)

                        return (untranslate_path(componentRoot, p), p, os.stat(p))
                raise get_http_exception(httplib.NOT_FOUND)
            elif stat.S_ISREG(s.st_mode):
                # is the file hidden?
                if self.is_hidden(path, realpath, s):
                    raise get_http_exception(httplib.NOT_FOUND)
                return path, realpath, s
            else:
                # don't know what the hell this is
                raise get_http_exception(httplib.FORBIDDEN)


class StaticFileServer(FileServerBase):
    """