Exemple #1
0
    def _resource_located(self, result, request, response, old_res, credentials, old_loc, old_rem):
        if (result is None) or (isinstance(result, tuple) and (result[0] is None)):
            self.log("No resource found for sub-path '%s'", http.tuple2path(old_rem))
            raise http.NotFoundError()

        if isinstance(result, tuple):

            if (len(result) < 1) or (len(result) > 3):
                raise http.InternalServerError("Invalid Resource Result")

            resource = result[0]
            if isinstance(server, defer.Deferred):
                resource.addCallback(lambda r: (r,) + result[1:])
                resource.addCallback(self._resource_located, request, response, old_res, credentials, old_loc, old_rem)
                return resource

            resource = IWebResource(resource)

            if len(result) == 1:
                new_rem = ()
                new_loc = old_loc + old_rem
            elif len(result) < 3:
                new_rem = ((len(result) > 1) and result[1]) or ()
                delta = len(old_rem) - len(new_rem)
                if delta > 0:
                    new_loc = old_loc + old_rem[:delta]
                else:
                    new_loc = old_loc
            else:
                new_loc = result[2]
                new_rem = result[3]

        else:

            resource = IWebResource(result)
            new_rem = ()
            new_loc = old_loc + old_rem

        if len(new_rem) > 0:
            # Still not a leaf, continue
            self.log(
                "Intermediary resource %s found for sub-path '%s' " "with remaining path '%s'",
                resource,
                http.tuple2path(new_loc),
                http.tuple2path(new_rem),
            )
            return self._process_resource(request, response, resource, credentials, new_loc, new_rem)
        else:
            # We found the leaf
            self.log("resource %s found for sub-path '%s'", resource, http.tuple2path(new_loc))
            return self._start_rendering(request, response, resource, credentials, new_loc)
Exemple #2
0
    def _locate_resource(self, request, response, resource, credentials, location, remaining):
        self.log("Locating resource for sub-path '%s'", http.tuple2path(remaining))
        d = resource.locate_resource(request, location, tuple(remaining))
        if isinstance(d, defer.Deferred):
            return d.addCallback(self._resource_located, request, response, resource, credentials, location, remaining)

        return self._resource_located(d, request, response, resource, credentials, location, remaining)
Exemple #3
0
    def _authenticate_resource(self, request, response, resource, credentials, location, continuation, *args):
        authenticator = resource.authenticator or self._authenticator
        if authenticator:
            self.log("Authenticating request %s for path '%s' with %s", request, http.tuple2path(location), resource)

            try:
                d = authenticator.authenticate(request, credentials, location)
                if isinstance(d, defer.Deferred):
                    args = (request, response, resource, credentials, location, continuation, args)
                    d.addCallbacks(
                        self._got_authentication_result,
                        self._authentication_failed,
                        callbackArgs=args,
                        errbackArgs=args,
                    )
                    return d
            except:
                self._authentication_failed(
                    Failure(), request, response, resource, credentials, location, continuation, args
                )
            else:
                return self._got_authentication_result(
                    d, request, response, resource, credentials, location, continuation, args
                )

        return continuation(request, response, resource, credentials, location, *args)
Exemple #4
0
    def _got_authorization(self, authorized, request, response, resource, location):
        if not authorized:
            self.log(
                "Request %s not authorized for resource %s " "with path '%s'",
                request,
                resource,
                http.tuple2path(location),
            )
            raise http.ForbiddenError("Resource Access Forbidden")

        self.log("Request %s authorized for resource %s with path '%s'", request, resource, http.tuple2path(location))
        return self._render_resource(request, response, resource, location)
Exemple #5
0
    def action_GET(self, request, response, location):
        rel_loc = request.context.get("rel_loc")
        if rel_loc is None:
            raise http.NotFoundError()

        rel_path = http.tuple2path(rel_loc)
        full_path = os.path.join(self._root_path, rel_path)
        res_path = os.path.realpath(full_path)
        if not res_path.startswith(self._root_path):
            raise http.ForbiddenError()
        if os.path.isdir(res_path):
            raise http.ForbiddenError()
        if not os.path.isfile(res_path):
            raise http.NotFoundError()

        rst = os.stat(res_path)

        # FIXME: Caching Policy, should be extracted to a ICachingPolicy
        cache_control_header = request.get_header("cache-control") or ""
        pragma_header = request.get_header("pragma") or ""
        cache_control = http.parse_header_values(cache_control_header)
        pragma = http.parse_header_values(pragma_header)
        if not (u"no-cache" in cache_control or u"no-cache" in pragma):
            if u"max-age" in cache_control:
                max_age = int(cache_control[u"max-age"])
                if max_age == 0 or (time.time() - rst.st_mtime) < max_age:
                    response.set_status(http.Status.NOT_MODIFIED)
                    return

        length = rst.st_size
        mime_type, content_encoding = self._mime_types.guess_type(res_path)
        mime_type = mime_type or "application/octet-stream"

        response.set_length(length)
        response.set_mime_type(mime_type)
        response.set_header("connection", "close")
        if content_encoding is not None:
            response.set_header("content-encoding", content_encoding)

        try:
            res = open(res_path, "rb")
        except IOError:
            raise http.ForbiddenError()

        response.do_not_cache()

        return threads.deferToThread(self._write_resource, #@UndefinedVariable
                                     response, res)
Exemple #6
0
    def _authorize_rendering(self, request, response, resource, credentials, location):
        response._set_location(location)
        authorizer = resource.authorizer or self._authorizer

        if authorizer:
            self.log("Authorizing request %s for path '%s'", request, http.tuple2path(location))
            d = authorizer.authorize(request, credentials, location)

            if isinstance(d, defer.Deferred):
                args = (request, response, resource, location)
                d.addCallbacks(self._got_authorization, self._authorization_failed, callbackArgs=args, errbackArgs=args)
                return d

            return self._got_authorization(d, request, response, resource, location)

        return self._render_resource(request, response, resource, location)
Exemple #7
0
    def locate_resource(self, request, location, remaining):
        request_host = request.get_header('host')
        if request_host is not None:
            if ':' in request_host:
                request_host = request_host.split(":", 1)[0]
            if request_host != self.hostname:
                new_uri = "%s://%s:%s%s" % (
                    request.scheme.name.lower(),
                    self.hostname,
                    self.port,
                    http.tuple2path(location + remaining))
                return Redirect(new_uri)

        if self._static and remaining[0] == u"static":
            return self._static, remaining[1:]

        return self._build_root(request), remaining
Exemple #8
0
 def check(tup, encoding="utf8"):
     inter = http.tuple2path(tup, encoding=encoding)
     result = http.path2tuple(inter, encoding=encoding)
     self.assertEqual(result, tup)
Exemple #9
0
 def t2p(tup, expected, encoding="utf8"):
     result = http.tuple2path(tup, encoding=encoding)
     self.assertEqual(result, expected)
Exemple #10
0
 def check(tup, expected):
     result = http.tuple2path(tup)
     self.assertEqual(result, expected)
Exemple #11
0
 def make_model_address(self, location):
     host, port = location[0]
     path = "/" + http.tuple2path(location[1:])
     return http.compose(host=host, port=port, path=path)
Exemple #12
0
 def make_model_address(self, location):
     host, port = location[0]
     path = "/" + http.tuple2path(location[1:])
     return http.compose(host=host, port=port, path=path,
                         query=http.compose_qs(self.arguments),
                         scheme=self.scheme)
Exemple #13
0
 def _render_resource(self, request, response, resource, location):
     self.log("Rendering path '%s' for request %s", http.tuple2path(location), request)
     d = resource.render_resource(request, response, location)
     if isinstance(d, defer.Deferred):
         return d.addCallback(self._resource_rendered, request, response)
     return self._resource_rendered(d, request, response)
Exemple #14
0
 def make_model_address(self, location):
     return '/' + http.tuple2path(location)