""" An abstraction layer over OS-dependent file-like objects, that provides a consistent view of a *duplex byte stream*. """ import sys import os import socket import time import errno from plainbox.vendor.rpyc.lib import safe_import from plainbox.vendor.rpyc.lib.compat import poll, select_error, BYTES_LITERAL, get_exc_errno, maxint win32file = safe_import("win32file") win32pipe = safe_import("win32pipe") msvcrt = safe_import("msvcrt") ssl = safe_import("ssl") retry_errnos = (errno.EAGAIN, errno.EWOULDBLOCK) class Stream(object): """Base Stream""" __slots__ = () def close(self): """closes the stream, releasing any system resources associated with it""" raise NotImplementedError() @property def closed(self): """tests whether the stream is closed or not"""
""" *Channel* is an abstraction layer over streams that works with *packets of data*, rather than an endless stream of bytes, and adds support for compression. """ from plainbox.vendor.rpyc.lib import safe_import from plainbox.vendor.rpyc.lib.compat import Struct, BYTES_LITERAL zlib = safe_import("zlib") # * 64 bit length field? # * separate \n into a FlushingChannel subclass? # * add thread safety as a subclass? class Channel(object): """Channel implementation. Note: In order to avoid problems with all sorts of line-buffered transports, we deliberately add ``\\n`` at the end of each frame. """ COMPRESSION_THRESHOLD = 3000 COMPRESSION_LEVEL = 1 FRAME_HEADER = Struct("!LB") FLUSHER = BYTES_LITERAL( "\n") # cause any line-buffered layers below us to flush __slots__ = ["stream", "compress"] def __init__(self, stream, compress=True): self.stream = stream if not zlib: compress = False
raise AuthenticationError("wrong magic word") return sock, None RPyC comes bundled with an authenticator for ``SSL`` (using certificates). This authenticator, for instance, both verifies the peer's identity and wraps the socket with an encrypted transport (which replaces the original socket). Authenticators are used by :class:`~rpyc.utils.server.Server` to validate an incoming connection. Using them is pretty trivial :: s = ThreadedServer(...., authenticator = magic_word_authenticator) s.start() """ import sys from plainbox.vendor.rpyc.lib import safe_import ssl = safe_import("ssl") class AuthenticationError(Exception): """raised to signal a failed authentication attempt""" pass class SSLAuthenticator(object): """An implementation of the authenticator protocol for ``SSL``. The given socket is wrapped by ``ssl.wrap_socket`` and is validated based on certificates :param keyfile: the server's key file :param certfile: the server's certificate file :param ca_certs: the server's certificate authority file :param cert_reqs: the certificate requirements. By default, if ``ca_cert`` is
import socket import time import threading # noqa: F401 import errno import logging from contextlib import closing try: import Queue except ImportError: import queue as Queue from plainbox.vendor.rpyc.core import SocketStream, Channel from plainbox.vendor.rpyc.utils.registry import UDPRegistryClient from plainbox.vendor.rpyc.utils.authenticators import AuthenticationError from plainbox.vendor.rpyc.lib import safe_import, spawn, spawn_waitready from plainbox.vendor.rpyc.lib.compat import poll, get_exc_errno signal = safe_import("signal") gevent = safe_import("gevent") class Server(object): """Base server implementation :param service: the :class:`~rpyc.core.service.Service` to expose :param hostname: the host to bind to. Default is IPADDR_ANY, but you may want to restrict it only to ``localhost`` in some setups :param ipv6: whether to create an IPv6 or IPv4 socket. The default is IPv4 :param port: the TCP port to bind to :param backlog: the socket's backlog (passed to ``listen()``) :param reuse_addr: whether or not to create the socket with the ``SO_REUSEADDR`` option set. :param authenticator: the :ref:`api-authenticators` to use. If ``None``, no authentication is performed.
import os import socket import time import threading import errno import logging try: import Queue except ImportError: import queue as Queue from plainbox.vendor.rpyc.core import SocketStream, Channel, Connection from plainbox.vendor.rpyc.utils.registry import UDPRegistryClient from plainbox.vendor.rpyc.utils.authenticators import AuthenticationError from plainbox.vendor.rpyc.lib import safe_import from plainbox.vendor.rpyc.lib.compat import poll, get_exc_errno signal = safe_import("signal") class Server(object): """Base server implementation :param service: the :class:`service <service.Service>` to expose :param hostname: the host to bind to. Default is IPADDR_ANY, but you may want to restrict it only to ``localhost`` in some setups :param ipv6: whether to create an IPv6 or IPv4 socket. The default is IPv4 :param port: the TCP port to bind to :param backlog: the socket's backlog (passed to ``listen()``) :param reuse_addr: whether or not to create the socket with the ``SO_REUSEADDR`` option set. :param authenticator: the :ref:`api-authenticators` to use. If ``None``, no authentication is performed. :param registrar: the :class:`registrar <rpyc.utils.registry.RegistryClient>` to use.
""" An abstraction layer over OS-dependent file-like objects, that provides a consistent view of a *duplex byte stream*. """ import sys import os import socket import errno from plainbox.vendor.rpyc.lib import safe_import, Timeout, socket_backoff_connect from plainbox.vendor.rpyc.lib.compat import poll, select_error, BYTES_LITERAL, get_exc_errno, maxint # noqa: F401 win32file = safe_import("win32file") win32pipe = safe_import("win32pipe") win32event = safe_import("win32event") retry_errnos = (errno.EAGAIN, errno.EWOULDBLOCK) class Stream(object): """Base Stream""" __slots__ = () def close(self): """closes the stream, releasing any system resources associated with it""" raise NotImplementedError() @property def closed(self): """tests whether the stream is closed or not""" raise NotImplementedError()