Windows: Use 32-bit distribution of python
This commit is contained in:
@@ -1,9 +1,19 @@
|
||||
# Copyright (c) 2009-2012 Denis Bilenko. See LICENSE for details.
|
||||
"""TCP/SSL server"""
|
||||
|
||||
from contextlib import closing
|
||||
|
||||
import sys
|
||||
import _socket
|
||||
|
||||
from _socket import error as SocketError
|
||||
from _socket import SOL_SOCKET
|
||||
from _socket import SO_REUSEADDR
|
||||
from _socket import AF_INET
|
||||
from _socket import SOCK_DGRAM
|
||||
|
||||
from gevent.baseserver import BaseServer
|
||||
from gevent.socket import EWOULDBLOCK, socket
|
||||
from gevent.socket import EWOULDBLOCK
|
||||
from gevent.socket import socket as GeventSocket
|
||||
from gevent._compat import PYPY, PY3
|
||||
|
||||
__all__ = ['StreamServer', 'DatagramServer']
|
||||
@@ -16,6 +26,15 @@ else:
|
||||
DEFAULT_REUSE_ADDR = 1
|
||||
|
||||
|
||||
if PY3:
|
||||
# sockets and SSL sockets are context managers on Python 3
|
||||
def _closing_socket(sock):
|
||||
return sock
|
||||
else:
|
||||
# but they are not guaranteed to be so on Python 2
|
||||
_closing_socket = closing
|
||||
|
||||
|
||||
class StreamServer(BaseServer):
|
||||
"""
|
||||
A generic TCP server.
|
||||
@@ -66,7 +85,7 @@ class StreamServer(BaseServer):
|
||||
SSLContext, the resulting client sockets will not cooperate with gevent.
|
||||
|
||||
Otherwise, keyword arguments are assumed to apply to :func:`ssl.wrap_socket`.
|
||||
These keyword arguments bay include:
|
||||
These keyword arguments may include:
|
||||
|
||||
- keyfile
|
||||
- certfile
|
||||
@@ -147,7 +166,8 @@ class StreamServer(BaseServer):
|
||||
if not sock.timeout:
|
||||
return
|
||||
raise
|
||||
sock = socket(sock.family, sock.type, sock.proto, fileno=fd)
|
||||
|
||||
sock = GeventSocket(sock.family, sock.type, sock.proto, fileno=fd)
|
||||
# XXX Python issue #7995?
|
||||
return sock, address
|
||||
|
||||
@@ -156,13 +176,20 @@ class StreamServer(BaseServer):
|
||||
def do_read(self):
|
||||
try:
|
||||
client_socket, address = self.socket.accept()
|
||||
except _socket.error as err:
|
||||
except SocketError as err:
|
||||
if err.args[0] == EWOULDBLOCK:
|
||||
return
|
||||
raise
|
||||
sockobj = socket(_sock=client_socket)
|
||||
if PYPY:
|
||||
client_socket._drop()
|
||||
# XXX: When would this not be the case? In Python 3 it makes sense
|
||||
# because we're using the low-level _accept method,
|
||||
# but not in Python 2.
|
||||
if not isinstance(client_socket, GeventSocket):
|
||||
# This leads to a leak of the watchers in client_socket
|
||||
sockobj = GeventSocket(_sock=client_socket)
|
||||
if PYPY:
|
||||
client_socket._drop()
|
||||
else:
|
||||
sockobj = client_socket
|
||||
return sockobj, address
|
||||
|
||||
def do_close(self, sock, *args):
|
||||
@@ -171,8 +198,8 @@ class StreamServer(BaseServer):
|
||||
|
||||
def wrap_socket_and_handle(self, client_socket, address):
|
||||
# used in case of ssl sockets
|
||||
ssl_socket = self.wrap_socket(client_socket, **self.ssl_args)
|
||||
return self.handle(ssl_socket, address)
|
||||
with _closing_socket(self.wrap_socket(client_socket, **self.ssl_args)) as ssl_socket:
|
||||
return self.handle(ssl_socket, address)
|
||||
|
||||
|
||||
class DatagramServer(BaseServer):
|
||||
@@ -206,7 +233,7 @@ class DatagramServer(BaseServer):
|
||||
def do_read(self):
|
||||
try:
|
||||
data, address = self._socket.recvfrom(8192)
|
||||
except _socket.error as err:
|
||||
except SocketError as err:
|
||||
if err.args[0] == EWOULDBLOCK:
|
||||
return
|
||||
raise
|
||||
@@ -220,14 +247,14 @@ class DatagramServer(BaseServer):
|
||||
self._writelock.release()
|
||||
|
||||
|
||||
def _tcp_listener(address, backlog=50, reuse_addr=None, family=_socket.AF_INET):
|
||||
def _tcp_listener(address, backlog=50, reuse_addr=None, family=AF_INET):
|
||||
"""A shortcut to create a TCP socket, bind it and put it into listening state."""
|
||||
sock = socket(family=family)
|
||||
sock = GeventSocket(family=family)
|
||||
if reuse_addr is not None:
|
||||
sock.setsockopt(_socket.SOL_SOCKET, _socket.SO_REUSEADDR, reuse_addr)
|
||||
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, reuse_addr)
|
||||
try:
|
||||
sock.bind(address)
|
||||
except _socket.error as ex:
|
||||
except SocketError as ex:
|
||||
strerror = getattr(ex, 'strerror', None)
|
||||
if strerror is not None:
|
||||
ex.strerror = strerror + ': ' + repr(address)
|
||||
@@ -237,17 +264,17 @@ def _tcp_listener(address, backlog=50, reuse_addr=None, family=_socket.AF_INET):
|
||||
return sock
|
||||
|
||||
|
||||
def _udp_socket(address, backlog=50, reuse_addr=None, family=_socket.AF_INET):
|
||||
def _udp_socket(address, backlog=50, reuse_addr=None, family=AF_INET):
|
||||
# backlog argument for compat with tcp_listener
|
||||
# pylint:disable=unused-argument
|
||||
|
||||
# we want gevent.socket.socket here
|
||||
sock = socket(family=family, type=_socket.SOCK_DGRAM)
|
||||
sock = GeventSocket(family=family, type=SOCK_DGRAM)
|
||||
if reuse_addr is not None:
|
||||
sock.setsockopt(_socket.SOL_SOCKET, _socket.SO_REUSEADDR, reuse_addr)
|
||||
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, reuse_addr)
|
||||
try:
|
||||
sock.bind(address)
|
||||
except _socket.error as ex:
|
||||
except SocketError as ex:
|
||||
strerror = getattr(ex, 'strerror', None)
|
||||
if strerror is not None:
|
||||
ex.strerror = strerror + ': ' + repr(address)
|
||||
|
||||
Reference in New Issue
Block a user