3 from eventlet import greenio
4 from eventlet import greenpool
5 from eventlet import greenthread
6 from eventlet.green import socket
7 from eventlet.support import greenlets as greenlet
10 def connect(addr, family=socket.AF_INET, bind=None):
11 """Convenience function for opening client sockets.
13 :param addr: Address of the server to connect to. For TCP sockets, this is a (host, port) tuple.
14 :param family: Socket family, optional. See :mod:`socket` documentation for available families.
15 :param bind: Local address to bind to, optional.
16 :return: The connected green socket object.
18 sock = socket.socket(family, socket.SOCK_STREAM)
25 def listen(addr, family=socket.AF_INET, backlog=50):
26 """Convenience function for opening server sockets. This
27 socket can be used in :func:`~eventlet.serve` or a custom ``accept()`` loop.
29 Sets SO_REUSEADDR on the socket to save on annoyance.
31 :param addr: Address to listen on. For TCP sockets, this is a (host, port) tuple.
32 :param family: Socket family, optional. See :mod:`socket` documentation for available families.
33 :param backlog: The maximum number of queued connections. Should be at least 1; the maximum value is system-dependent.
34 :return: The listening green socket object.
36 sock = socket.socket(family, socket.SOCK_STREAM)
37 if sys.platform[:3] != "win":
38 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
44 class StopServe(Exception):
45 """Exception class used for quitting :func:`~eventlet.serve` gracefully."""
49 def _stop_checker(t, server_gt, conn):
55 except greenlet.GreenletExit:
58 greenthread.kill(server_gt, *sys.exc_info())
61 def serve(sock, handle, concurrency=1000):
62 """Runs a server on the supplied socket. Calls the function *handle* in a
63 separate greenthread for every incoming client connection. *handle* takes
64 two arguments: the client socket object, and the client address::
66 def myhandle(client_sock, client_addr):
67 print("client connected", client_addr)
69 eventlet.serve(eventlet.listen(('127.0.0.1', 9999)), myhandle)
71 Returning from *handle* closes the client socket.
73 :func:`serve` blocks the calling greenthread; it won't return until
74 the server completes. If you desire an immediate return,
75 spawn a new greenthread for :func:`serve`.
77 Any uncaught exceptions raised in *handle* are raised as exceptions
78 from :func:`serve`, terminating the server, so be sure to be aware of the
79 exceptions your application can raise. The return value of *handle* is
82 Raise a :class:`~eventlet.StopServe` exception to gracefully terminate the
83 server -- that's the only way to get the server() function to return rather
86 The value in *concurrency* controls the maximum number of
87 greenthreads that will be open at any time handling requests. When
88 the server hits the concurrency limit, it stops accepting new
89 connections until the existing ones complete.
91 pool = greenpool.GreenPool(concurrency)
92 server_gt = greenthread.getcurrent()
96 conn, addr = sock.accept()
97 gt = pool.spawn(handle, conn, addr)
98 gt.link(_stop_checker, server_gt, conn)
99 conn, addr, gt = None, None, None
104 def wrap_ssl(sock, *a, **kw):
105 """Convenience function for converting a regular socket into an
106 SSL socket. Has the same interface as :func:`ssl.wrap_socket`,
107 but can also use PyOpenSSL. Though, note that it ignores the
108 `cert_reqs`, `ssl_version`, `ca_certs`, `do_handshake_on_connect`,
109 and `suppress_ragged_eofs` arguments when using PyOpenSSL.
111 The preferred idiom is to call wrap_ssl directly on the creation
112 method, e.g., ``wrap_ssl(connect(addr))`` or
113 ``wrap_ssl(listen(addr), server_side=True)``. This way there is
114 no "naked" socket sitting around to accidentally corrupt the SSL
117 :return Green SSL object.
119 return wrap_ssl_impl(sock, *a, **kw)
122 from eventlet.green import ssl
123 wrap_ssl_impl = ssl.wrap_socket
127 from eventlet.green.OpenSSL import SSL
129 def wrap_ssl_impl(*a, **kw):
130 raise ImportError("To use SSL with Eventlet, you must install PyOpenSSL or use Python 2.6 or later.")
132 def wrap_ssl_impl(sock, keyfile=None, certfile=None, server_side=False,
133 cert_reqs=None, ssl_version=None, ca_certs=None,
134 do_handshake_on_connect=True,
135 suppress_ragged_eofs=True, ciphers=None):
136 # theoretically the ssl_version could be respected in this line
137 context = SSL.Context(SSL.SSLv23_METHOD)
138 if certfile is not None:
139 context.use_certificate_file(certfile)
140 if keyfile is not None:
141 context.use_privatekey_file(keyfile)
142 context.set_verify(SSL.VERIFY_NONE, lambda *x: True)
144 connection = SSL.Connection(context, sock)
146 connection.set_accept_state()
148 connection.set_connect_state()