Exemplo n.º 1
0
    def test_add_directory_entry(self):
        """
        Adding a capability to a mutable directory
        """
        content = b"content " * 200
        http_client = create_tahoe_treq_client()
        tahoe_client = create_tahoe_client(
            DecodedURL.from_text(u"http://example.com/"),
            http_client,
        )

        # first create a mutable directory
        mut_cap = yield tahoe_client.create_mutable_directory()

        # create an immutable and link it into the directory
        file_cap = yield tahoe_client.create_immutable(content)
        yield tahoe_client.add_entry_to_mutable_directory(
            mut_cap, u"foo", file_cap)

        # prove we can access the expected file via a GET
        uri = DecodedURL.from_text(u"http://example.com/uri/")
        uri = uri.child(mut_cap.danger_real_capability_string(), u"foo")
        resp = http_client.get(uri.to_uri().to_text())

        self.assertThat(resp, succeeded(MatchesStructure(code=Equals(200), )))
        self.assertThat(
            resp.result.content(),
            succeeded(Equals(content)),
        )
Exemplo n.º 2
0
    def setUp(self):
        super(TestAdd, self).setUp()

        self.root = create_fake_tahoe_root()
        self.http_client = create_tahoe_treq_client(self.root)
        self.tahoe_client = create_tahoe_client(
            DecodedURL.from_text(u"http://example.com"),
            self.http_client,
        )
        self.magic_dir = FilePath(self.mktemp())
        self.magic_dir.makedirs()

        self.node = self.useFixture(NodeDirectory(FilePath(self.mktemp())))
        self.basedir = FilePath(self.mktemp())
        self.config = create_global_configuration(
            self.basedir,
            u"tcp:5555",
            self.node.path,
            u"tcp:localhost:5555",
        )
        clock = Clock()
        self.service = MagicFolderService(
            clock,
            self.config,
            WebSocketStatusService(clock, self.config),
            self.tahoe_client,
        )
Exemplo n.º 3
0
    def setUp(self):
        super(TestTahoeMonitor, self).setUp()

        self.root = create_fake_tahoe_root()
        self.http_client = create_tahoe_treq_client(self.root)
        self.tahoe_client = create_tahoe_client(
            DecodedURL.from_text(u"http://example.com"),
            self.http_client,
        )

        self.node = self.useFixture(NodeDirectory(FilePath(self.mktemp())))
        # when the "service" is run it wants to check shares-happy from Tahoe
        with self.node.tahoe_cfg.open("w") as f:
            f.write(b"[client]\nshares.happy = 1\n")
        self.basedir = FilePath(self.mktemp())
        self.config = create_global_configuration(
            self.basedir,
            u"tcp:0",
            self.node.path,
            u"tcp:localhost:0",
        )
        self.reactor = MemoryReactorClock()
        self.service = MagicFolderService(
            self.reactor,
            self.config,
            WebSocketStatusService(self.reactor, self.config),
            self.tahoe_client,
        )
Exemplo n.º 4
0
    def setUp(self):
        """
        Create a Tahoe-LAFS node which can contain some magic folder configuration
        and run it.
        """
        yield super(CreateMagicFolder, self).setUp()

        self.root = create_fake_tahoe_root()
        tahoe_client = create_tahoe_client(
            DecodedURL.from_text(u"http://invalid./"),
            create_tahoe_treq_client(self.root),
        )

        self.config_dir = FilePath(self.mktemp())
        self.config = create_testing_configuration(
            self.config_dir,
            FilePath(u"/non-tahoe-directory"),
        )
        status_service = WebSocketStatusService(reactor, self.config)
        folder_service = MagicFolderService(
            reactor,
            self.config,
            status_service,
            tahoe_client,
        )
        self.http_client = create_testing_http_client(
            reactor,
            self.config,
            folder_service,
            lambda: self.config.api_token,
            status_service,
        )
Exemplo n.º 5
0
def url_for_string(req, url_string):
    """
    Construct a universal URL using the given URL string.

    :param IRequest req: The request being served.  If ``redir_to`` is not
        absolute then this is used to determine the net location of this
        server and the resulting URL is made to point at it.

    :param bytes url_string: A byte string giving a universal or absolute URL.

    :return DecodedURL: An absolute URL based on this server's net location
        and the given URL string.
    """
    url = DecodedURL.from_text(url_string.decode("utf-8"))
    if not url.host:
        root = req.URLPath()
        netloc = root.netloc.split(b":", 1)
        if len(netloc) == 1:
            host = netloc
            port = None
        else:
            host = netloc[0]
            port = int(netloc[1])
        url = url.replace(
            scheme=root.scheme.decode("ascii"),
            host=host.decode("ascii"),
            port=port,
        )
    return url
Exemplo n.º 6
0
    def setUp(self):
        """
        Create a Tahoe-LAFS node which can contain some magic folder configuration
        and run it.
        """
        yield super(ListMagicFolder, self).setUp()

        # for these tests we never contact Tahoe so we can get
        # away with an "empty" Tahoe WebUI
        tahoe_client = create_tahoe_client(DecodedURL.from_text(u""),
                                           StubTreq(Resource())),
        self.config = create_testing_configuration(
            FilePath(self.mktemp()),
            FilePath(u"/no/tahoe/node-directory"),
        )
        status_service = WebSocketStatusService(reactor, self.config)
        global_service = MagicFolderService(
            reactor,
            self.config,
            status_service,
            tahoe_client,
        )
        self.http_client = create_testing_http_client(
            reactor,
            self.config,
            global_service,
            lambda: self.config.api_token,
            status_service,
        )
Exemplo n.º 7
0
    def test_add_snapshot_no_folder(self):
        """
        An error results using /v1/snapshot API on non-existent
        folder.
        """
        local_path = FilePath(self.mktemp())
        local_path.makedirs()
        root = create_fake_tahoe_root()
        tahoe_client = create_tahoe_client(
            DecodedURL.from_text(u"http://invalid./"),
            create_tahoe_treq_client(root),
        )
        treq = treq_for_folders(
            Clock(),
            FilePath(self.mktemp()),
            AUTH_TOKEN,
            {},
            start_folder_services=False,
            tahoe_client=tahoe_client,
        )

        self.assertThat(
            authorized_request(
                treq,
                AUTH_TOKEN,
                b"POST",
                self.url.child("a-folder-that-doesnt-exist").child('snapshot'),
            ), succeeded(matches_response(code_matcher=Equals(NOT_FOUND), ), ))
Exemplo n.º 8
0
    def __init__(self, temp, author, upload_dircap, root=None):
        """
        :param FilePath temp: A path where the fixture may write whatever it
            likes.

        :param LocalAuthor author: The author which will be used to sign
            snapshots the ``RemoteSnapshotCreator`` creates.

        :param bytes upload_dircap: The Tahoe-LAFS capability for a writeable
            directory into which new snapshots will be linked.

        :param IResource root: The root resource for the fake Tahoe-LAFS HTTP
            API hierarchy.  The default is one created by
            ``create_fake_tahoe_root``.
        """
        if root is None:
            root = create_fake_tahoe_root()
        self.temp = temp
        self.author = author
        self.upload_dircap = upload_dircap
        self.root = root
        self.http_client = create_tahoe_treq_client(self.root)
        self.tahoe_client = create_tahoe_client(
            DecodedURL.from_text(u"http://example.com"),
            self.http_client,
        )
Exemplo n.º 9
0
    def setup_example(self):
        self.author = create_local_author("alice")
        self.magic_path = FilePath(self.mktemp())
        self.magic_path.makedirs()
        self._global_config = create_testing_configuration(
            FilePath(self.mktemp()),
            FilePath("dummy"),
        )
        self.collective_cap = random_dircap()
        self.personal_cap = random_dircap()

        self.clock = Clock()
        self.status_service = WebSocketStatusService(self.clock,
                                                     self._global_config)
        self.folder_status = FolderStatus("default", self.status_service)

        self.config = self._global_config.create_magic_folder(
            "default",
            self.magic_path,
            self.author,
            self.collective_cap,
            self.personal_cap,
            1,
            None,
        )
        # Use a cooperator that does not cooperate.
        self.cooperator = Cooperator(
            terminationPredicateFactory=lambda: lambda: False,
            scheduler=lambda f: f(),
        )
        self.addCleanup(self.cooperator.stop)
        self.tahoe_client = create_tahoe_client(
            DecodedURL.from_text("http://invalid./"),
            create_tahoe_treq_client(create_fake_tahoe_root()),
        )
Exemplo n.º 10
0
 def test_decodedurl(self):
     """
     If the decorated method returns a ``DecodedURL`` then a redirect to that
     location is rendered into the response.
     """
     loc = u"http://example.invalid/foo?bar=baz"
     resource = StaticResource(DecodedURL.from_text(loc))
     self.assertThat(
         render(resource, {}),
         succeeded(
             MatchesPredicate(
                 lambda value: assert_soup_has_tag_with_attributes(
                     self,
                     BeautifulSoup(value, 'html5lib'),
                     "meta",
                     {"http-equiv": "refresh",
                      "content": "0;URL={}".format(loc),
                     },
                 )
                 # The assertion will raise if it has a problem, otherwise
                 # return None.  Turn the None into something
                 # MatchesPredicate recognizes as success.
                 or True,
                 "did not find meta refresh tag in %r",
             ),
         ),
     )
Exemplo n.º 11
0
class TestApiMonitor(AsyncTestCase):
    """
    Tests related to 'magic-folder-api monitor'
    """
    url = DecodedURL.from_text(u"http://invalid./v1/")

    def setUp(self):
        super(TestApiMonitor, self).setUp()
        self.magic_config = FilePath(self.mktemp())
        self.global_config = create_testing_configuration(
            self.magic_config,
            FilePath(u"/no/tahoe/node-directory"),
        )
        self.reactor = MemoryReactorClockResolver()
        self.pumper = create_pumper()
        self.service = WebSocketStatusService(
            self.reactor,
            self.global_config,
        )
        self.factory = StatusFactory(self.service)
        self.agent = create_memory_agent(
            self.reactor,
            self.pumper,
            lambda: self.factory.buildProtocol(None)
        )
        return self.pumper.start()

    def tearDown(self):
        super(TestApiMonitor, self).tearDown()
        return self.pumper.stop()

    @inline_callbacks
    def test_once(self):
        """
        Output a single status message with --once option
        """
        stdout = StringIO()
        stderr = StringIO()

        yield dispatch_magic_folder_api_command(
            ["--config", self.magic_config.path, "monitor",
             "--once",
            ],
            stdout=stdout,
            stderr=stderr,
            websocket_agent=self.agent,
            config=self.global_config,
        )
        self.pumper._flush()

        self.assertThat(
            json.loads(stdout.getvalue()),
            Equals({
                'state': {
                    'folders': {},
                    'synchronizing': False,
                }
            }),
        )
Exemplo n.º 12
0
    def test_add_participant_personal_dmd_non_dir(self, author, folder_name,
                                                  personal_dmd):
        """
        When a new Personal DMD is passed that is not a directory
        capability an error is produced.
        """
        local_path = FilePath(self.mktemp())
        local_path.makedirs()
        folder_config = magic_folder_config(
            create_local_author(author),
            FilePath(self.mktemp()),
            local_path,
        )

        root = create_fake_tahoe_root()
        # put our Collective DMD into the fake root
        root._uri.data[folder_config["collective-dircap"]] = dumps([
            u"dirnode",
            {
                u"children": {
                    author: format_filenode(folder_config["upload-dircap"]),
                },
            },
        ])
        tahoe_client = create_tahoe_client(
            DecodedURL.from_text(u"http://invalid./"),
            create_tahoe_treq_client(root),
        )
        treq = treq_for_folders(
            Clock(),
            FilePath(self.mktemp()),
            AUTH_TOKEN,
            {
                folder_name: folder_config,
            },
            start_folder_services=False,
            tahoe_client=tahoe_client,
        )

        # add a participant using the API
        self.assertThat(
            authorized_request(
                treq, AUTH_TOKEN, b"POST",
                self.url.child(folder_name, "participants"),
                dumps({
                    "author": {
                        "name": "kelly"
                    },
                    "personal_dmd": personal_dmd,
                }).encode("utf8")),
            succeeded(
                matches_response(
                    code_matcher=Equals(BAD_REQUEST),
                    body_matcher=AfterPreprocessing(
                        loads,
                        Equals({
                            "reason":
                            "personal_dmd must be a directory-capability"
                        })))))
Exemplo n.º 13
0
def main(reactor):
    url = (
        DecodedURL.from_text(u"https://httpbin.org").child(
            u"get")  # add path /get
        .add(u"foo", u"&")  # add query ?foo=%26
    )
    print(url.to_text())
    return treq.get(url).addCallback(print_response)
Exemplo n.º 14
0
    def test_authorized(self, auth_token, child_segments, content):
        """
        If the correct bearer token is not given in the **Authorization** header
        of the request then the response code is UNAUTHORIZED.

        :param bytes auth_token: A bearer token which, when presented, should
            authorize access to the resource.

        :param [unicode] child_segments: Additional path segments to add to the
            request path beneath **v1**.

        :param bytes content: The bytes we expect to see on a successful
            request.
        """
        def get_auth_token():
            return auth_token

        # Since we don't want to exercise any real magic-folder application
        # logic we'll just magic up the child resource being requested.
        branch = Data(
            content,
            b"application/binary",
        )
        segments_remaining = child_segments[:]
        while segments_remaining:
            name = segments_remaining.pop()
            resource = Resource()
            resource.putChild(name.encode("utf-8"), branch)
            branch = resource

        root = magic_folder_resource(
            get_auth_token,
            v1_resource=branch,
        )

        treq = StubTreq(root)
        url = DecodedURL.from_text(u"http://example.invalid./v1").child(
            *child_segments)
        encoded_url = url_to_bytes(url)

        # A request with no token at all or the wrong token should receive an
        # unauthorized response.
        headers = {
            b"Authorization": u"Bearer {}".format(auth_token).encode("ascii"),
        }

        self.assertThat(
            treq.get(
                encoded_url,
                headers=headers,
            ),
            succeeded(
                matches_response(
                    code_matcher=Equals(OK),
                    body_matcher=Equals(content),
                ), ),
        )
Exemplo n.º 15
0
 def setup_example(self):
     self.root = create_fake_tahoe_root()
     self.http_client = create_tahoe_treq_client(self.root)
     self.tahoe_client = create_tahoe_client(
         DecodedURL.from_text(u"http://example.com"),
         self.http_client,
     )
     self.alice = create_local_author(u"alice")
     self.stash_dir = FilePath(mktemp())
     self.stash_dir.makedirs()  # 'trial' will delete this when done
Exemplo n.º 16
0
 def setUp(self):
     super(CustomHTTPServerTests, self).setUp()
     # Could be a fixture, but will only be used in this test class so not
     # going to bother:
     self._http_server = TestApp()
     self.client = StorageClient(
         DecodedURL.from_text("http://127.0.0.1"),
         SWISSNUM_FOR_TEST,
         treq=StubTreq(self._http_server._app.resource()),
     )
Exemplo n.º 17
0
def magic_folder_invite(node_directory, alias, nickname, treq):
    """
    Invite a user identified by the nickname to a folder owned by the alias

    :param unicode node_directory: The root of the Tahoe-LAFS node.

    :param unicode alias: The alias of the folder to which the invitation is
        being generated.

    :param unicode nickname: The nickname of the invitee.

    :param HTTPClient treq: An ``HTTPClient`` or similar object to use to make
        the queries.

    :return Deferred[unicode]: A secret invitation code.
    """
    aliases = get_aliases(node_directory)[alias]
    nodeurl = get_node_url(node_directory)

    node_url = DecodedURL.from_text(unicode(nodeurl, 'utf-8'))

    # create an unlinked directory and get the dmd write-cap
    dmd_write_cap = yield tahoe_mkdir(node_url, treq)

    # derive a dmd read-only cap from it.
    dmd_readonly_cap = uri.from_string(
        dmd_write_cap).get_readonly().to_string()
    if dmd_readonly_cap is None:
        raise Exception("failed to diminish dmd write cap")

    # Now, we need to create a link to the nickname from inside the
    # collective to this read-cap. For that we will need to know
    # the write-cap of the collective (which is stored by the private/aliases
    # file in the node_directory) so that a link can be created inside it
    # to the .
    # To do that, we use tahoe ln dmd_read_cap <collective-write-cap>/<alias>

    magic_write_cap = get_aliases(node_directory)[alias]
    magic_readonly_cap = uri.from_string(
        magic_write_cap).get_readonly().to_string()

    # tahoe ln CLIENT_READCAP COLLECTIVE_WRITECAP/NICKNAME
    from_file = unicode(dmd_readonly_cap, 'utf-8')
    to_file = u"%s/%s" % (unicode(magic_write_cap, 'utf-8'), nickname)

    try:
        yield tahoe_mv(node_url, aliases, from_file, to_file, treq)
    except Exception:
        raise
        # return invite code, which is:
    #    magic_readonly_cap + INVITE_SEPARATOR + dmd_write_cap
    invite_code = "{}{}{}".format(magic_readonly_cap, INVITE_SEPARATOR,
                                  dmd_write_cap)

    returnValue(invite_code)
Exemplo n.º 18
0
 def tahoe_client_url(self):
     """
     The twisted client-string describing how we will connect to the
     Tahoe LAFS client we will use.
     """
     with self.database:
         cursor = self.database.cursor()
         cursor.execute("SELECT tahoe_node_directory FROM config")
         node_dir = FilePath(cursor.fetchone()[0])
     with node_dir.child("node.url").open("rt") as f:
         return DecodedURL.from_text(f.read().strip().decode("utf8"))
Exemplo n.º 19
0
    def test_download_no_arg(self):
        """
        Error if we GET from "/uri" with no ?uri= query-arg
        """

        http_client = create_tahoe_treq_client()

        uri = DecodedURL.from_text(u"http://example.com/uri/")
        resp = http_client.get(uri.to_uri().to_text())

        self.assertThat(resp, succeeded(MatchesStructure(code=Equals(400))))
Exemplo n.º 20
0
 def redirect_to(self, req):
     """
     :param allmydata.webish.MyRequest req:
     """
     ophandle = get_arg(req, "ophandle").decode("utf-8")
     assert ophandle
     here = DecodedURL.from_text(str(URLPath.fromRequest(req)))
     target = here.click(u"/").child(u"operations", ophandle)
     output = get_arg(req, "output")
     if output:
         target = target.add(u"output", output.decode("utf-8"))
     return target
Exemplo n.º 21
0
 def test_request_uri_decodedurl(self):
     """
     A URL may be passed as a `hyperlink.DecodedURL` object. It is converted
     to bytes when passed to the underlying agent.
     """
     url = DecodedURL.from_text(u"https://example.org/foo")
     self.client.request("GET", url)
     self.agent.request.assert_called_once_with(
         b"GET", b"https://example.org/foo",
         Headers({b"accept-encoding": [b"gzip"]}),
         None,
     )
Exemplo n.º 22
0
 def _setUp(self):
     self.clock = Clock()
     self.tempdir = self.useFixture(TempDir())
     self.storage_server = StorageServer(self.tempdir.path,
                                         b"\x00" * 20,
                                         clock=self.clock)
     self.http_server = HTTPServer(self.storage_server, SWISSNUM_FOR_TEST)
     self.client = StorageClient(
         DecodedURL.from_text("http://127.0.0.1"),
         SWISSNUM_FOR_TEST,
         treq=StubTreq(self.http_server.get_resource()),
     )
Exemplo n.º 23
0
 def test_bad_authentication(self):
     """
     If the wrong swissnum is used, an ``Unauthorized`` response code is
     returned.
     """
     client = StorageClientGeneral(
         StorageClient(
             DecodedURL.from_text("http://127.0.0.1"),
             b"something wrong",
             treq=StubTreq(self.http.http_server.get_resource()),
         ))
     with assert_fails_with_http_code(self, http.UNAUTHORIZED):
         result_of(client.get_version())
Exemplo n.º 24
0
    def test_download_missing(self):
        """
        Error if we download a capability that doesn't exist
        """

        http_client = create_tahoe_treq_client()
        cap_gen = capability_generator("URI:CHK:")

        uri = DecodedURL.from_text(u"http://example.com/uri?uri={}".format(
            next(cap_gen)))
        resp = http_client.get(uri.to_uri().to_text())

        self.assertThat(resp, succeeded(MatchesStructure(code=Equals(500))))
Exemplo n.º 25
0
    def test_download_missing(self):
        """
        If a capability is requested for which the stored cyphertext cannot be
        located, **GET /uri?uri=CAP** returns a GONE response code.
        """

        http_client = create_tahoe_treq_client()
        cap_gen = capability_generator("URI:CHK:")

        uri = DecodedURL.from_text(u"http://example.com/uri?uri={}".format(
            next(cap_gen)))
        resp = http_client.get(uri.to_uri().to_text())

        self.assertThat(resp, succeeded(MatchesStructure(code=Equals(GONE), )))
Exemplo n.º 26
0
def tahoe_create_alias(node_directory, alias, treq):
    # mkdir+add_alias

    nodeurl = get_node_url(node_directory)

    try:
        node_url = DecodedURL.from_text(unicode(nodeurl, 'utf-8'))
        new_uri = yield tahoe_mkdir(node_url, treq)
    except Exception:
        raise

    _add_alias(node_directory, alias, new_uri)

    returnValue(0)
Exemplo n.º 27
0
def status(folder_name, node_directory, treq):
    """
    Retrieve information about the current state of a named magic folder.

    :param unicode folder_name: The name of the magic folder about which to
        return information.

    :param FilePath node_directory: The path to the Tahoe-LAFS node directory
        which owns the magic folder in question.

    :return Deferred[Status]: A Deferred which fires with information about
        the magic folder.
    """
    magic_folders = load_magic_folders(node_directory.path)
    token = node_directory.descendant([u"private", u"api_auth_token"]).getContent()
    node_root_url = DecodedURL.from_text(
        node_directory.child(u"node.url").getContent().decode("ascii").strip(),
    )
    magic_root_url = DecodedURL.from_text(
        node_directory.child(u"magic-folder.url").getContent().decode("ascii").strip(),
    )

    try:
        folder_config = magic_folders[folder_name]
    except KeyError:
        raise BadFolderName(node_directory, folder_name)

    return status_from_folder_config(
        folder_name,
        folder_config[u"upload_dircap"].decode("ascii"),
        folder_config[u"collective_dircap"].decode("ascii"),
        node_root_url,
        magic_root_url,
        token,
        treq,
    )
Exemplo n.º 28
0
 def test_load_db(self):
     """
     ``load_global_configuration`` can read the global configuration written by
     ``create_global_configuration``.
     """
     create_global_configuration(self.temp, u"tcp:1234", self.node_dir,
                                 u"tcp:localhost:1234")
     config = load_global_configuration(self.temp)
     self.assertThat(
         config,
         MatchesStructure(
             api_endpoint=Equals(u"tcp:1234"),
             tahoe_client_url=Equals(
                 DecodedURL.from_text(u"http://127.0.0.1:9876/")),
         ))
Exemplo n.º 29
0
 def test_request_uri_hyperlink_params(self):
     """
     The *params* argument augments an instance of `hyperlink.DecodedURL`
     passed as the *url* parameter, just as if it were a string.
     """
     self.client.request(
         method="GET",
         url=DecodedURL.from_text(u"http://č.net"),
         params={"foo": "bar"},
     )
     self.agent.request.assert_called_once_with(
         b"GET", b"http://xn--bea.net/?foo=bar",
         Headers({b"accept-encoding": [b"gzip"]}),
         None,
     )
Exemplo n.º 30
0
    def render_GET(self, request):
        uri = DecodedURL.from_text(request.uri.decode('utf8'))
        capability = None
        for arg, value in uri.query:
            if arg == u"uri":
                capability = value
        # it's legal to use the form "/uri/<capability>"
        if capability is None and request.postpath and request.postpath[0]:
            capability = request.postpath[0]

        # Tahoe lets you get the children of directory-nodes by
        # appending names after the capability; we support up to 1
        # such path
        if len(request.postpath) > 1:
            if len(request.postpath) > 2:
                raise NotImplementedError
            child_name = request.postpath[1]
            return self._get_child_of_directory(request, capability,
                                                child_name)

        # if we don't yet have a capability, that's an error
        if capability is None:
            request.setResponseCode(http.BAD_REQUEST)
            return b"GET /uri requires uri="

        # the user gave us a capability; if our Grid doesn't have any
        # data for it, that's an error.
        if capability not in self.data:
            # Tahoe-LAFS actually has several different behaviors for the
            # ostensible "not found" case.
            #
            # * A request for a CHK cap will receive a GONE response with
            #   "NoSharesError" (and some other text) in a text/plain body.
            # * A request for a DIR2 cap will receive an OK response with
            #   a huge text/html body including "UnrecoverableFileError".
            # * A request for the child of a DIR2 cap will receive a GONE
            #   response with "UnrecoverableFileError" (and some other text)
            #   in a text/plain body.
            #
            # Also, all of these are *actually* behind a redirect to
            # /uri/<CAP>.
            #
            # GONE makes the most sense here and I don't want to deal with
            # redirects so here we go.
            request.setResponseCode(http.GONE)
            return u"No data for '{}'".format(capability).encode("ascii")

        return self.data[capability]