Sketch of HTTP support, still untested WIP.

This commit is contained in:
Itamar Turner-Trauring
2022-06-22 14:19:29 -04:00
parent 7910867be6
commit 7577d1e24c
3 changed files with 30 additions and 4 deletions

View File

@ -64,6 +64,7 @@ from allmydata.interfaces import (
from allmydata.nodemaker import NodeMaker from allmydata.nodemaker import NodeMaker
from allmydata.blacklist import Blacklist from allmydata.blacklist import Blacklist
from allmydata import node from allmydata import node
from .protocol_switch import FoolscapOrHttp
KiB=1024 KiB=1024
@ -818,6 +819,13 @@ class _Client(node.Node, pollmixin.PollMixin):
if anonymous_storage_enabled(self.config): if anonymous_storage_enabled(self.config):
furl_file = self.config.get_private_path("storage.furl").encode(get_filesystem_encoding()) furl_file = self.config.get_private_path("storage.furl").encode(get_filesystem_encoding())
furl = self.tub.registerReference(FoolscapStorageServer(ss), furlFile=furl_file) furl = self.tub.registerReference(FoolscapStorageServer(ss), furlFile=furl_file)
(_, _, swissnum) = furl.rpartition("/")
class FoolscapOrHttpWithCert(FoolscapOrHttp):
certificate = self.tub.myCertificate
storage_server = ss
swissnum = swissnum
self.tub.negotiationClass = FoolscapOrHttpWithCert
announcement["anonymous-storage-FURL"] = furl announcement["anonymous-storage-FURL"] = furl
enabled_storage_servers = self._enable_storage_servers( enabled_storage_servers = self._enable_storage_servers(

View File

@ -51,7 +51,6 @@ from allmydata.util import configutil
from allmydata.util.yamlutil import ( from allmydata.util.yamlutil import (
safe_load, safe_load,
) )
from .protocol_switch import FoolscapOrHttp
from . import ( from . import (
__full_version__, __full_version__,
@ -708,7 +707,6 @@ def create_tub(tub_options, default_connection_handlers, foolscap_connection_han
the new Tub via `Tub.setOption` the new Tub via `Tub.setOption`
""" """
tub = Tub(**kwargs) tub = Tub(**kwargs)
tub.negotiationClass = FoolscapOrHttp
for (name, value) in list(tub_options.items()): for (name, value) in list(tub_options.items()):
tub.setOption(name, value) tub.setOption(name, value)
handlers = default_connection_handlers.copy() handlers = default_connection_handlers.copy()

View File

@ -7,9 +7,14 @@ from typing import Optional
from twisted.internet.protocol import Protocol from twisted.internet.protocol import Protocol
from twisted.python.failure import Failure from twisted.python.failure import Failure
from twisted.internet.ssl import CertificateOptions
from twisted.web.server import Site
from twisted.protocols.tls import TLSMemoryBIOFactory
from foolscap.negotiate import Negotiation from foolscap.negotiate import Negotiation
from .storage.http_server import HTTPServer
class ProtocolMode(Enum): class ProtocolMode(Enum):
"""Listening mode.""" """Listening mode."""
@ -47,6 +52,7 @@ class FoolscapOrHttp(Protocol, metaclass=PretendToBeNegotiation):
"_buffer", "_buffer",
"transport", "transport",
"__class__", "__class__",
"_http",
}: }:
object.__setattr__(self, name, value) object.__setattr__(self, name, value)
else: else:
@ -73,7 +79,7 @@ class FoolscapOrHttp(Protocol, metaclass=PretendToBeNegotiation):
if self._protocol_mode == ProtocolMode.FOOLSCAP: if self._protocol_mode == ProtocolMode.FOOLSCAP:
return self._foolscap.dataReceived(data) return self._foolscap.dataReceived(data)
if self._protocol_mode == ProtocolMode.HTTP: if self._protocol_mode == ProtocolMode.HTTP:
raise NotImplementedError() return self._http.dataReceived(data)
# UNDECIDED mode. # UNDECIDED mode.
self._buffer += data self._buffer += data
@ -83,12 +89,26 @@ class FoolscapOrHttp(Protocol, metaclass=PretendToBeNegotiation):
# Check if it looks like a Foolscap request. If so, it can handle this # Check if it looks like a Foolscap request. If so, it can handle this
# and later data: # and later data:
if self._buffer.startswith(b"GET /id/"): if self._buffer.startswith(b"GET /id/"):
# TODO or maybe just self.__class__ here too?
self._protocol_mode = ProtocolMode.FOOLSCAP self._protocol_mode = ProtocolMode.FOOLSCAP
buf, self._buffer = self._buffer, b"" buf, self._buffer = self._buffer, b""
return self._foolscap.dataReceived(buf) return self._foolscap.dataReceived(buf)
else: else:
self._protocol_mode = ProtocolMode.HTTP self._protocol_mode = ProtocolMode.HTTP
raise NotImplementedError("")
certificate_options = CertificateOptions(
privateKey=self.certificate.privateKey.original,
certificate=self.certificate.original,
)
http_server = HTTPServer(self.storage_server, self.swissnum)
factory = TLSMemoryBIOFactory(
certificate_options, False, Site(http_server.get_resource())
)
protocol = factory.buildProtocol(self.transport.getPeer())
protocol.makeConnection(self.transport)
protocol.dataReceived(self._buffer)
# TODO __getattr__ or maybe change the __class__
self._http = protocol
def connectionLost(self, reason: Failure) -> None: def connectionLost(self, reason: Failure) -> None:
if self._protocol_mode == ProtocolMode.FOOLSCAP: if self._protocol_mode == ProtocolMode.FOOLSCAP: