Stop talking about furl, it's a NURL.

This commit is contained in:
Itamar Turner-Trauring 2022-03-28 11:35:45 -04:00
parent 119ba9468e
commit da6838d6f9
5 changed files with 29 additions and 29 deletions

View File

@ -35,10 +35,10 @@ Glossary
(the storage service is an example of such an object) (the storage service is an example of such an object)
NURL NURL
a self-authenticating URL-like string almost exactly like a fURL but without being tied to Foolscap a self-authenticating URL-like string almost exactly like a NURL but without being tied to Foolscap
swissnum swissnum
a short random string which is part of a fURL and which acts as a shared secret to authorize clients to use a storage service a short random string which is part of a fURL/NURL and which acts as a shared secret to authorize clients to use a storage service
lease lease
state associated with a share informing a storage server of the duration of storage desired by a client state associated with a share informing a storage server of the duration of storage desired by a client
@ -211,15 +211,15 @@ To further clarify, consider this example.
Alice operates a storage node. Alice operates a storage node.
Alice generates a key pair and secures it properly. Alice generates a key pair and secures it properly.
Alice generates a self-signed storage node certificate with the key pair. Alice generates a self-signed storage node certificate with the key pair.
Alice's storage node announces (to an introducer) a fURL containing (among other information) the SPKI hash. Alice's storage node announces (to an introducer) a NURL containing (among other information) the SPKI hash.
Imagine the SPKI hash is ``i5xb...``. Imagine the SPKI hash is ``i5xb...``.
This results in a fURL of ``pb://i5xb...@example.com:443/g3m5...#v=1``. This results in a NURL of ``pb://i5xb...@example.com:443/g3m5...#v=1``.
Bob creates a client node pointed at the same introducer. Bob creates a client node pointed at the same introducer.
Bob's client node receives the announcement from Alice's storage node Bob's client node receives the announcement from Alice's storage node
(indirected through the introducer). (indirected through the introducer).
Bob's client node recognizes the fURL as referring to an HTTP-dialect server due to the ``v=1`` fragment. Bob's client node recognizes the NURL as referring to an HTTP-dialect server due to the ``v=1`` fragment.
Bob's client node can now perform a TLS handshake with a server at the address in the fURL location hints Bob's client node can now perform a TLS handshake with a server at the address in the NURL location hints
(``example.com:443`` in this example). (``example.com:443`` in this example).
Following the above described validation procedures, Following the above described validation procedures,
Bob's client node can determine whether it has reached Alice's storage node or not. Bob's client node can determine whether it has reached Alice's storage node or not.
@ -230,7 +230,7 @@ Additionally,
by continuing to interact using TLS, by continuing to interact using TLS,
Bob's client and Alice's storage node are assured of both **message authentication** and **message confidentiality**. Bob's client and Alice's storage node are assured of both **message authentication** and **message confidentiality**.
Bob's client further inspects the fURL for the *swissnum*. Bob's client further inspects the NURL for the *swissnum*.
When Bob's client issues HTTP requests to Alice's storage node it includes the *swissnum* in its requests. When Bob's client issues HTTP requests to Alice's storage node it includes the *swissnum* in its requests.
**Storage authorization** has been achieved. **Storage authorization** has been achieved.
@ -266,8 +266,8 @@ Generation of a new certificate allows for certain non-optimal conditions to be
* The ``commonName`` of ``newpb_thingy`` may be changed to a more descriptive value. * The ``commonName`` of ``newpb_thingy`` may be changed to a more descriptive value.
* A ``notValidAfter`` field with a timestamp in the past may be updated. * A ``notValidAfter`` field with a timestamp in the past may be updated.
Storage nodes will announce a new fURL for this new HTTP-based server. Storage nodes will announce a new NURL for this new HTTP-based server.
This fURL will be announced alongside their existing Foolscap-based server's fURL. This NURL will be announced alongside their existing Foolscap-based server's fURL.
Such an announcement will resemble this:: Such an announcement will resemble this::
{ {
@ -312,7 +312,7 @@ The follow sequence of events is likely:
#. The client uses the information in its cache to open a Foolscap connection to the storage server. #. The client uses the information in its cache to open a Foolscap connection to the storage server.
Ideally, Ideally,
the client would not rely on an update from the introducer to give it the GBS fURL for the updated storage server. the client would not rely on an update from the introducer to give it the GBS NURL for the updated storage server.
Therefore, Therefore,
when an updated client connects to a storage server using Foolscap, when an updated client connects to a storage server using Foolscap,
it should request the server's version information. it should request the server's version information.

View File

@ -155,24 +155,24 @@ class StorageClient(object):
self, url, swissnum, treq=treq self, url, swissnum, treq=treq
): # type: (DecodedURL, bytes, Union[treq,StubTreq,HTTPClient]) -> None ): # type: (DecodedURL, bytes, Union[treq,StubTreq,HTTPClient]) -> None
""" """
The URL is a HTTPS URL ("https://..."). To construct from a furl, use The URL is a HTTPS URL ("https://..."). To construct from a NURL, use
``StorageClient.from_furl()``. ``StorageClient.from_nurl()``.
""" """
self._base_url = url self._base_url = url
self._swissnum = swissnum self._swissnum = swissnum
self._treq = treq self._treq = treq
@classmethod @classmethod
def from_furl(cls, furl: DecodedURL, persistent: bool = True) -> "StorageClient": def from_nurl(cls, nurl: DecodedURL, persistent: bool = True) -> "StorageClient":
""" """
Create a ``StorageClient`` for the given furl. Create a ``StorageClient`` for the given NURL.
``persistent`` indicates whether to use persistent HTTP connections. ``persistent`` indicates whether to use persistent HTTP connections.
""" """
assert furl.fragment == "v=1" assert nurl.fragment == "v=1"
assert furl.scheme == "pb" assert nurl.scheme == "pb"
swissnum = furl.path[0].encode("ascii") swissnum = nurl.path[0].encode("ascii")
certificate_hash = furl.user.encode("ascii") certificate_hash = nurl.user.encode("ascii")
treq_client = HTTPClient( treq_client = HTTPClient(
Agent( Agent(
@ -182,7 +182,7 @@ class StorageClient(object):
) )
) )
https_url = DecodedURL().replace(scheme="https", host=furl.host, port=furl.port) https_url = DecodedURL().replace(scheme="https", host=nurl.host, port=nurl.port)
return cls(https_url, swissnum, treq_client) return cls(https_url, swissnum, treq_client)
def relative_url(self, path): def relative_url(self, path):

View File

@ -528,7 +528,7 @@ def listen_tls(
interface: Optional[str], interface: Optional[str],
) -> Deferred[Tuple[DecodedURL, IListeningPort]]: ) -> Deferred[Tuple[DecodedURL, IListeningPort]]:
""" """
Start a HTTPS storage server on the given port, return the fURL and the Start a HTTPS storage server on the given port, return the NURL and the
listening port. listening port.
The hostname is the external IP or hostname clients will connect to; it The hostname is the external IP or hostname clients will connect to; it
@ -546,9 +546,9 @@ def listen_tls(
endpoint_string += ":interface={}".format(quoteStringArgument(interface)) endpoint_string += ":interface={}".format(quoteStringArgument(interface))
endpoint = serverFromString(reactor, endpoint_string) endpoint = serverFromString(reactor, endpoint_string)
def build_furl(listening_port: IListeningPort) -> DecodedURL: def build_nurl(listening_port: IListeningPort) -> DecodedURL:
furl = DecodedURL().replace( nurl = DecodedURL().replace(
fragment="v=1", # how we know this furl is HTTP-based fragment="v=1", # how we know this NURL is HTTP-based (i.e. not Foolscap)
host=hostname, host=hostname,
port=listening_port.getHost().port, port=listening_port.getHost().port,
path=(str(server._swissnum, "ascii"),), path=(str(server._swissnum, "ascii"),),
@ -560,8 +560,8 @@ def listen_tls(
), ),
scheme="pb", scheme="pb",
) )
return furl return nurl
return endpoint.listen(Site(server.get_resource())).addCallback( return endpoint.listen(Site(server.get_resource())).addCallback(
lambda listening_port: (build_furl(listening_port), listening_port) lambda listening_port: (build_nurl(listening_port), listening_port)
) )

View File

@ -1073,7 +1073,7 @@ class _HTTPMixin(_SharedMixin):
# Listen on randomly assigned port, using self-signed cert we generated # Listen on randomly assigned port, using self-signed cert we generated
# manually: # manually:
certs_dir = Path(__file__).parent / "certs" certs_dir = Path(__file__).parent / "certs"
furl, listening_port = yield listen_tls( nurl, listening_port = yield listen_tls(
reactor, reactor,
http_storage_server, http_storage_server,
"127.0.0.1", "127.0.0.1",
@ -1088,7 +1088,7 @@ class _HTTPMixin(_SharedMixin):
# state across tests: # state across tests:
returnValue( returnValue(
_HTTPStorageServer.from_http_client( _HTTPStorageServer.from_http_client(
StorageClient.from_furl(furl, persistent=False) StorageClient.from_nurl(nurl, persistent=False)
) )
) )

View File

@ -29,8 +29,8 @@ from ..storage.http_common import get_spki_hash
from ..storage.http_client import _StorageClientHTTPSPolicy from ..storage.http_client import _StorageClientHTTPSPolicy
class HTTPSFurlTests(SyncTestCase): class HTTPSNurlTests(SyncTestCase):
"""Tests for HTTPS furls.""" """Tests for HTTPS NURLs."""
def test_spki_hash(self): def test_spki_hash(self):
"""The output of ``get_spki_hash()`` matches the semantics of RFC 7469. """The output of ``get_spki_hash()`` matches the semantics of RFC 7469.