connection.py 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. from __future__ import absolute_import
  2. import socket
  3. import importlib
  4. identity = lambda x: x
  5. class Factory(object):
  6. """
  7. A class for creating custom socket connections.
  8. To create a simple connection:
  9. server_address = ('localhost', 80)
  10. Factory()(server_address)
  11. To create an SSL connection:
  12. Factory(wrapper=ssl.wrap_socket)(server_address)
  13. To create an SSL connection with parameters to wrap_socket:
  14. wrapper = functools.partial(ssl.wrap_socket, ssl_cert=get_cert())
  15. Factory(wrapper=wrapper)(server_address)
  16. To create an IPv6 connection:
  17. Factory(ipv6=True)(server_address)
  18. Note that Factory doesn't save the state of the socket itself. The
  19. caller must do that, as necessary. As a result, the Factory may be
  20. re-used to create new connections with the same settings.
  21. """
  22. family = socket.AF_INET
  23. def __init__(self, bind_address=('', 0), wrapper=identity, ipv6=False):
  24. self.bind_address = bind_address
  25. self.wrapper = wrapper
  26. if ipv6:
  27. self.family = socket.AF_INET6
  28. def from_legacy_params(self, localaddress='', localport=0, ssl=False,
  29. ipv6=False):
  30. if localaddress or localport:
  31. self.bind_address = (localaddress, localport)
  32. if ssl:
  33. self.wrapper = importlib.import_module('ssl').wrap_socket
  34. if ipv6:
  35. self.family = socket.AF_INET6
  36. def connect(self, server_address):
  37. sock = self.wrapper(socket.socket(self.family, socket.SOCK_STREAM))
  38. sock.bind(self.bind_address)
  39. sock.connect(server_address)
  40. return sock
  41. __call__ = connect