Code import
This commit is contained in:
157
venv/lib/python2.7/site-packages/eventlet/convenience.py
Normal file
157
venv/lib/python2.7/site-packages/eventlet/convenience.py
Normal file
@@ -0,0 +1,157 @@
|
||||
import sys
|
||||
|
||||
from eventlet import greenio
|
||||
from eventlet import greenpool
|
||||
from eventlet import greenthread
|
||||
from eventlet.green import socket
|
||||
from eventlet.support import greenlets as greenlet
|
||||
|
||||
|
||||
def connect(addr, family=socket.AF_INET, bind=None):
|
||||
"""Convenience function for opening client sockets.
|
||||
|
||||
:param addr: Address of the server to connect to. For TCP sockets, this is a (host, port) tuple.
|
||||
:param family: Socket family, optional. See :mod:`socket` documentation for available families.
|
||||
:param bind: Local address to bind to, optional.
|
||||
:return: The connected green socket object.
|
||||
"""
|
||||
sock = socket.socket(family, socket.SOCK_STREAM)
|
||||
if bind is not None:
|
||||
sock.bind(bind)
|
||||
sock.connect(addr)
|
||||
return sock
|
||||
|
||||
|
||||
def listen(addr, family=socket.AF_INET, backlog=50):
|
||||
"""Convenience function for opening server sockets. This
|
||||
socket can be used in :func:`~eventlet.serve` or a custom ``accept()`` loop.
|
||||
|
||||
Sets SO_REUSEADDR on the socket to save on annoyance.
|
||||
|
||||
:param addr: Address to listen on. For TCP sockets, this is a (host, port) tuple.
|
||||
:param family: Socket family, optional. See :mod:`socket` documentation for available families.
|
||||
:param backlog:
|
||||
|
||||
The maximum number of queued connections. Should be at least 1; the maximum
|
||||
value is system-dependent.
|
||||
|
||||
:return: The listening green socket object.
|
||||
"""
|
||||
sock = socket.socket(family, socket.SOCK_STREAM)
|
||||
if sys.platform[:3] != "win":
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
if hasattr(socket, 'SO_REUSEPORT'):
|
||||
# NOTE(zhengwei): linux kernel >= 3.9
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
|
||||
sock.bind(addr)
|
||||
sock.listen(backlog)
|
||||
return sock
|
||||
|
||||
|
||||
class StopServe(Exception):
|
||||
"""Exception class used for quitting :func:`~eventlet.serve` gracefully."""
|
||||
pass
|
||||
|
||||
|
||||
def _stop_checker(t, server_gt, conn):
|
||||
try:
|
||||
try:
|
||||
t.wait()
|
||||
finally:
|
||||
conn.close()
|
||||
except greenlet.GreenletExit:
|
||||
pass
|
||||
except Exception:
|
||||
greenthread.kill(server_gt, *sys.exc_info())
|
||||
|
||||
|
||||
def serve(sock, handle, concurrency=1000):
|
||||
"""Runs a server on the supplied socket. Calls the function *handle* in a
|
||||
separate greenthread for every incoming client connection. *handle* takes
|
||||
two arguments: the client socket object, and the client address::
|
||||
|
||||
def myhandle(client_sock, client_addr):
|
||||
print("client connected", client_addr)
|
||||
|
||||
eventlet.serve(eventlet.listen(('127.0.0.1', 9999)), myhandle)
|
||||
|
||||
Returning from *handle* closes the client socket.
|
||||
|
||||
:func:`serve` blocks the calling greenthread; it won't return until
|
||||
the server completes. If you desire an immediate return,
|
||||
spawn a new greenthread for :func:`serve`.
|
||||
|
||||
Any uncaught exceptions raised in *handle* are raised as exceptions
|
||||
from :func:`serve`, terminating the server, so be sure to be aware of the
|
||||
exceptions your application can raise. The return value of *handle* is
|
||||
ignored.
|
||||
|
||||
Raise a :class:`~eventlet.StopServe` exception to gracefully terminate the
|
||||
server -- that's the only way to get the server() function to return rather
|
||||
than raise.
|
||||
|
||||
The value in *concurrency* controls the maximum number of
|
||||
greenthreads that will be open at any time handling requests. When
|
||||
the server hits the concurrency limit, it stops accepting new
|
||||
connections until the existing ones complete.
|
||||
"""
|
||||
pool = greenpool.GreenPool(concurrency)
|
||||
server_gt = greenthread.getcurrent()
|
||||
|
||||
while True:
|
||||
try:
|
||||
conn, addr = sock.accept()
|
||||
gt = pool.spawn(handle, conn, addr)
|
||||
gt.link(_stop_checker, server_gt, conn)
|
||||
conn, addr, gt = None, None, None
|
||||
except StopServe:
|
||||
return
|
||||
|
||||
|
||||
def wrap_ssl(sock, *a, **kw):
|
||||
"""Convenience function for converting a regular socket into an
|
||||
SSL socket. Has the same interface as :func:`ssl.wrap_socket`,
|
||||
but can also use PyOpenSSL. Though, note that it ignores the
|
||||
`cert_reqs`, `ssl_version`, `ca_certs`, `do_handshake_on_connect`,
|
||||
and `suppress_ragged_eofs` arguments when using PyOpenSSL.
|
||||
|
||||
The preferred idiom is to call wrap_ssl directly on the creation
|
||||
method, e.g., ``wrap_ssl(connect(addr))`` or
|
||||
``wrap_ssl(listen(addr), server_side=True)``. This way there is
|
||||
no "naked" socket sitting around to accidentally corrupt the SSL
|
||||
session.
|
||||
|
||||
:return Green SSL object.
|
||||
"""
|
||||
return wrap_ssl_impl(sock, *a, **kw)
|
||||
|
||||
try:
|
||||
from eventlet.green import ssl
|
||||
wrap_ssl_impl = ssl.wrap_socket
|
||||
except ImportError:
|
||||
# trying PyOpenSSL
|
||||
try:
|
||||
from eventlet.green.OpenSSL import SSL
|
||||
except ImportError:
|
||||
def wrap_ssl_impl(*a, **kw):
|
||||
raise ImportError(
|
||||
"To use SSL with Eventlet, you must install PyOpenSSL or use Python 2.6 or later.")
|
||||
else:
|
||||
def wrap_ssl_impl(sock, keyfile=None, certfile=None, server_side=False,
|
||||
cert_reqs=None, ssl_version=None, ca_certs=None,
|
||||
do_handshake_on_connect=True,
|
||||
suppress_ragged_eofs=True, ciphers=None):
|
||||
# theoretically the ssl_version could be respected in this line
|
||||
context = SSL.Context(SSL.SSLv23_METHOD)
|
||||
if certfile is not None:
|
||||
context.use_certificate_file(certfile)
|
||||
if keyfile is not None:
|
||||
context.use_privatekey_file(keyfile)
|
||||
context.set_verify(SSL.VERIFY_NONE, lambda *x: True)
|
||||
|
||||
connection = SSL.Connection(context, sock)
|
||||
if server_side:
|
||||
connection.set_accept_state()
|
||||
else:
|
||||
connection.set_connect_state()
|
||||
return connection
|
||||
Reference in New Issue
Block a user