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
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)
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
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
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
def _redirect(url, status=httplib.MOVED_PERMANENTLY): raise get_http_exception(status, location=url)
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
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
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): """