~ubuntu-branches/ubuntu/vivid/python-gevent/vivid

« back to all changes in this revision

Viewing changes to gevent/socket.py

  • Committer: Bazaar Package Importer
  • Author(s): Örjan Persson
  • Date: 2011-05-17 16:43:20 UTC
  • mto: (14.1.1 sid)
  • mto: This revision was merged to the branch mainline in revision 7.
  • Revision ID: james.westby@ubuntu.com-20110517164320-jyr5vamkqi3jfeab
Tags: upstream-0.13.6
Import upstream version 0.13.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
as well as the constants from :mod:`socket` module are imported into this module.
32
32
"""
33
33
 
34
 
 
35
 
__all__ = ['create_connection',
36
 
           'error',
37
 
           'fromfd',
38
 
           'gaierror',
39
 
           'getaddrinfo',
40
 
           'gethostbyname',
41
 
           'inet_aton',
42
 
           'inet_ntoa',
43
 
           'inet_pton',
44
 
           'inet_ntop',
45
 
           'socket',
46
 
           'socketpair',
47
 
           'timeout',
48
 
           'ssl',
49
 
           'sslerror',
50
 
           'SocketType',
51
 
           'wait_read',
52
 
           'wait_write',
53
 
           'wait_readwrite']
 
34
# standard functions and classes that this module re-implements in a gevent-aware way:
 
35
__implements__ = ['create_connection',
 
36
                  'getaddrinfo',
 
37
                  'gethostbyname',
 
38
                  'socket',
 
39
                  'SocketType',
 
40
                  'fromfd',
 
41
                  'socketpair']
 
42
 
 
43
# non-standard functions that this module provides:
 
44
__extensions__ = ['wait_read',
 
45
                  'wait_write',
 
46
                  'wait_readwrite']
 
47
 
 
48
# standard functions and classes that this module re-imports
 
49
__imports__ = ['error',
 
50
               'gaierror',
 
51
               'getfqdn',
 
52
               'herror',
 
53
               'htonl',
 
54
               'htons',
 
55
               'ntohl',
 
56
               'ntohs',
 
57
               'inet_aton',
 
58
               'inet_ntoa',
 
59
               'inet_pton',
 
60
               'inet_ntop',
 
61
               'timeout',
 
62
               'gethostname',
 
63
               'getprotobyname',
 
64
               'getservbyname',
 
65
               'getservbyport',
 
66
               'getdefaulttimeout',
 
67
               'setdefaulttimeout',
 
68
               # Python 2.5 and older:
 
69
               'RAND_add',
 
70
               'RAND_egd',
 
71
               'RAND_status',
 
72
               # Windows:
 
73
               'errorTab']
 
74
 
54
75
 
55
76
import sys
56
 
import errno
57
77
import time
58
78
import random
59
79
import re
68
88
    from errno import WSAEALREADY as EALREADY
69
89
    from errno import WSAEISCONN as EISCONN
70
90
    from gevent.win32util import formatError as strerror
71
 
    EGAIN = EWOULDBLOCK
 
91
    EAGAIN = EWOULDBLOCK
72
92
else:
73
93
    from errno import EINVAL
74
94
    from errno import EWOULDBLOCK
78
98
    from errno import EISCONN
79
99
    from os import strerror
80
100
 
 
101
try:
 
102
    from errno import EBADF
 
103
except ImportError:
 
104
    EBADF = 9
81
105
 
82
106
import _socket
83
 
error = _socket.error
84
 
timeout = _socket.timeout
85
107
_realsocket = _socket.socket
86
108
__socket__ = __import__('socket')
87
109
_fileobject = __socket__._fileobject
88
 
gaierror = _socket.gaierror
89
110
 
90
 
# Import public constants from the standard socket (called __socket__ here) into this module.
 
111
for name in __imports__[:]:
 
112
    try:
 
113
        value = getattr(__socket__, name)
 
114
        globals()[name] = value
 
115
    except AttributeError:
 
116
        __imports__.remove(name)
91
117
 
92
118
for name in __socket__.__all__:
93
 
    if name[:1].isupper():
94
 
        value = getattr(__socket__, name)
95
 
        if isinstance(value, (int, basestring)):
96
 
            globals()[name] = value
97
 
            __all__.append(name)
98
 
    elif name == 'getfqdn':
99
 
        globals()[name] = getattr(__socket__, name)
100
 
        __all__.append(name)
 
119
    value = getattr(__socket__, name)
 
120
    if isinstance(value, (int, long, basestring)):
 
121
        globals()[name] = value
 
122
        __imports__.append(name)
101
123
 
102
124
del name, value
103
125
 
104
 
inet_ntoa = _socket.inet_ntoa
105
 
inet_aton = _socket.inet_aton
106
 
try:
107
 
    inet_ntop = _socket.inet_ntop
108
 
except AttributeError:
 
126
if 'inet_ntop' not in globals():
 
127
    # inet_ntop is required by our implementation of getaddrinfo
 
128
 
109
129
    def inet_ntop(address_family, packed_ip):
110
130
        if address_family == AF_INET:
111
131
            return inet_ntoa(packed_ip)
112
132
        # XXX: ipv6 won't work on windows
113
133
        raise NotImplementedError('inet_ntop() is not available on this platform')
114
 
try:
115
 
    inet_pton = _socket.inet_pton
116
 
except AttributeError:
117
 
    def inet_pton(address_family, ip_string):
118
 
        if address_family == AF_INET:
119
 
            return inet_aton(ip_string)
120
 
        # XXX: ipv6 won't work on windows
121
 
        raise NotImplementedError('inet_ntop() is not available on this platform')
122
134
 
123
 
# XXX: import other non-blocking stuff, like ntohl
124
135
# XXX: implement blocking functions that are not yet implemented
125
 
# XXX: add test that checks that socket.__all__ matches gevent.socket.__all__ on all supported platforms
126
136
 
127
137
from gevent.hub import getcurrent, get_hub
128
138
from gevent import core
 
139
from gevent import spawn
 
140
from gevent.util import wrap_errors
129
141
 
130
142
_ip4_re = re.compile('^[\d\.]+$')
131
143
 
211
223
    if event.pending:
212
224
        arg = event.arg
213
225
        if arg is not None:
214
 
            arg[0].throw(error(errno.EBADF, 'File descriptor was closed in another greenlet'))
 
226
            arg[0].throw(error(EBADF, 'File descriptor was closed in another greenlet'))
215
227
 
216
228
 
217
229
def cancel_wait(event):
244
256
if sys.version_info[:2] < (2, 7):
245
257
    _get_memory = buffer
246
258
else:
 
259
 
247
260
    def _get_memory(string, offset):
248
261
        return memoryview(string)[offset:]
249
262
 
250
263
 
251
264
class _closedsocket(object):
252
265
    __slots__ = []
 
266
 
253
267
    def _dummy(*args):
254
 
        raise error(errno.EBADF, 'Bad file descriptor')
 
268
        raise error(EBADF, 'Bad file descriptor')
255
269
    # All _delegate_methods must also be initialized here.
256
270
    send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy
257
271
    __getattr__ = _dummy
261
275
 
262
276
timeout_default = object()
263
277
 
 
278
 
264
279
class socket(object):
265
280
 
266
281
    def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
279
294
        self._sock.setblocking(0)
280
295
        self._read_event = core.event(core.EV_READ, self.fileno(), _wait_helper)
281
296
        self._write_event = core.event(core.EV_WRITE, self.fileno(), _wait_helper)
282
 
        self._rw_event = core.event(core.EV_READ|core.EV_WRITE, self.fileno(), _wait_helper)
 
297
        # regarding the following, see issue #31
 
298
        # (http://code.google.com/p/gevent/issues/detail?id=31#c19)
 
299
        if is_windows:
 
300
            self._rw_event = core.event(core.EV_READ | core.EV_WRITE, self.fileno(), _wait_helper)
 
301
        else:
 
302
            self._rw_event = core.event(core.EV_WRITE, self.fileno(), _wait_helper)
283
303
 
284
304
    def __repr__(self):
285
305
        return '<%s at %s %s>' % (type(self).__name__, hex(id(self)), self._formatinfo())
307
327
            result += ' sock=' + str(sockname)
308
328
        if peername is not None:
309
329
            result += ' peer=' + str(peername)
310
 
        if self.timeout is not None:
 
330
        if getattr(self, 'timeout', None) is not None:
311
331
            result += ' timeout=' + str(self.timeout)
312
332
        return result
313
333
 
318
338
                client_socket, address = sock.accept()
319
339
                break
320
340
            except error, ex:
321
 
                if ex[0] != errno.EWOULDBLOCK or self.timeout == 0.0:
 
341
                if ex[0] != EWOULDBLOCK or self.timeout == 0.0:
322
342
                    raise
323
343
                sys.exc_clear()
324
344
            wait_read(sock.fileno(), timeout=self.timeout, event=self._read_event)
334
354
            setattr(self, method, dummy)
335
355
 
336
356
    def connect(self, address):
337
 
        if isinstance(address, tuple) and len(address)==2:
 
357
        if isinstance(address, tuple) and len(address) == 2:
338
358
            address = gethostbyname(address[0]), address[1]
339
359
        if self.timeout == 0.0:
340
360
            return self._sock.connect(address)
377
397
            if type(ex) is error:
378
398
                return ex[0]
379
399
            else:
380
 
                raise # gaierror is not silented by connect_ex
 
400
                raise  # gaierror is not silented by connect_ex
381
401
 
382
402
    def dup(self):
383
403
        """dup() -> socket object
392
412
        return _fileobject(self.dup(), mode, bufsize)
393
413
 
394
414
    def recv(self, *args):
395
 
        sock = self._sock # keeping the reference so that fd is not closed during waiting
 
415
        sock = self._sock  # keeping the reference so that fd is not closed during waiting
396
416
        while True:
397
417
            try:
398
418
                return sock.recv(*args)
399
419
            except error, ex:
400
 
                if ex[0] == errno.EBADF:
 
420
                if ex[0] == EBADF:
401
421
                    return ''
402
422
                if ex[0] != EWOULDBLOCK or self.timeout == 0.0:
403
423
                    raise
406
426
            try:
407
427
                wait_read(sock.fileno(), timeout=self.timeout, event=self._read_event)
408
428
            except error, ex:
409
 
                if ex[0] == errno.EBADF:
 
429
                if ex[0] == EBADF:
410
430
                    return ''
411
431
                raise
412
432
 
438
458
            try:
439
459
                return sock.recv_into(*args)
440
460
            except error, ex:
441
 
                if ex[0] == errno.EBADF:
 
461
                if ex[0] == EBADF:
442
462
                    return 0
443
463
                if ex[0] != EWOULDBLOCK or self.timeout == 0.0:
444
464
                    raise
446
466
            try:
447
467
                wait_read(sock.fileno(), timeout=self.timeout, event=self._read_event)
448
468
            except error, ex:
449
 
                if ex[0] == errno.EBADF:
 
469
                if ex[0] == EBADF:
450
470
                    return 0
451
471
                raise
452
472
 
463
483
            try:
464
484
                wait_write(sock.fileno(), timeout=timeout, event=self._write_event)
465
485
            except error, ex:
466
 
                if ex[0] == errno.EBADF:
 
486
                if ex[0] == EBADF:
467
487
                    return 0
468
488
                raise
469
489
            try:
530
550
    def gettimeout(self):
531
551
        return self.timeout
532
552
 
 
553
    def shutdown(self, how):
 
554
        cancel_wait(self._rw_event)
 
555
        if how == 0:  # SHUT_RD
 
556
            cancel_wait(self._read_event)
 
557
        elif how == 1:  # SHUT_RW
 
558
            cancel_wait(self._write_event)
 
559
        else:
 
560
            cancel_wait(self._read_event)
 
561
            cancel_wait(self._write_event)
 
562
        self._sock.shutdown(how)
 
563
 
533
564
    family = property(lambda self: self._sock.family, doc="the socket family")
534
565
    type = property(lambda self: self._sock.type, doc="the socket type")
535
566
    proto = property(lambda self: self._sock.proto, doc="the socket protocol")
545
576
SocketType = socket
546
577
 
547
578
if hasattr(_socket, 'socketpair'):
 
579
 
548
580
    def socketpair(*args):
549
581
        one, two = _socket.socketpair(*args)
550
582
        return socket(_sock=one), socket(_sock=two)
551
583
else:
552
 
    __all__.remove('socketpair')
 
584
    __implements__.remove('socketpair')
553
585
 
554
586
if hasattr(_socket, 'fromfd'):
 
587
 
555
588
    def fromfd(*args):
556
589
        return socket(_sock=_socket.fromfd(*args))
557
590
else:
558
 
    __all__.remove('fromfd')
 
591
    __implements__.remove('fromfd')
559
592
 
560
593
 
561
594
def bind_and_listen(descriptor, address=('', 0), backlog=50, reuse_addr=True):
580
613
except AttributeError:
581
614
    _GLOBAL_DEFAULT_TIMEOUT = object()
582
615
 
 
616
 
583
617
def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT, source_address=None):
584
618
    """Connect to *address* and return the socket object.
585
619
 
593
627
    An host of '' or port 0 tells the OS to use the default.
594
628
    """
595
629
 
596
 
    msg = "getaddrinfo returns an empty list"
597
630
    host, port = address
 
631
    err = None
598
632
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
599
633
        af, socktype, proto, _canonname, sa = res
600
634
        sock = None
606
640
                sock.bind(source_address)
607
641
            sock.connect(sa)
608
642
            return sock
609
 
        except error, msg:
 
643
        except error, ex:
 
644
            err = ex
 
645
            sys.exc_clear()
610
646
            if sock is not None:
611
647
                sock.close()
612
 
    raise error, msg
 
648
    if err is not None:
 
649
        raise err
 
650
    else:
 
651
        raise error("getaddrinfo returns an empty list")
613
652
 
614
653
 
615
654
try:
617
656
except Exception:
618
657
    import traceback
619
658
    traceback.print_exc()
620
 
    __all__.remove('gethostbyname')
621
 
    __all__.remove('getaddrinfo')
 
659
    __implements__.remove('gethostbyname')
 
660
    __implements__.remove('getaddrinfo')
622
661
else:
623
662
 
624
663
    def gethostbyname(hostname):
644
683
        _ttl, addrs = resolve_ipv4(hostname)
645
684
        return inet_ntoa(random.choice(addrs))
646
685
 
647
 
 
648
 
    def getaddrinfo(host, port, *args, **kwargs):
 
686
    def getaddrinfo(host, port, family=0, socktype=0, proto=0, flags=0, evdns_flags=0):
649
687
        """*Some* approximation of :func:`socket.getaddrinfo` implemented using :mod:`gevent.dns`.
650
688
 
651
689
        If *host* is not a string, does not has any dots or is a numeric IP address, then
652
690
        the standard :func:`socket.getaddrinfo` is called.
653
691
 
654
 
        Otherwise, calls either :func:`resolve_ipv4` or :func:`resolve_ipv6` and
655
 
        formats the result the way :func:`socket.getaddrinfo` does it.
 
692
        Otherwise, calls :func:`resolve_ipv4` (for ``AF_INET``) or :func:`resolve_ipv6` (for ``AF_INET6``) or
 
693
        both (for ``AF_UNSPEC``) and formats the result the way :func:`socket.getaddrinfo` does it.
656
694
 
657
695
        Differs in the following ways:
658
696
 
659
697
        * raises :class:`DNSError` (a subclass of :class:`gaierror`) with libevent-dns error
660
698
          codes instead of standard socket error codes
661
 
        * IPv6 support is untested.
662
 
        * AF_UNSPEC only tries IPv4
663
 
        * only supports TCP, UDP, IP protocols
664
 
        * port must be numeric, does not support string service names. see socket.getservbyname
665
699
        * *flags* argument is ignored
 
700
        * for IPv6, flow info and scope id are always 0
666
701
 
667
702
        Additionally, supports *evdns_flags* keyword arguments (default ``0``) that is passed
668
703
        to :mod:`dns` functions.
669
704
        """
670
 
        family, socktype, proto, _flags = args + (None, ) * (4 - len(args))
671
 
        if not isinstance(host, str) or '.' not in host or _ip4_re.match(host):
672
 
            return _socket.getaddrinfo(host, port, *args)
673
 
 
674
 
        evdns_flags = kwargs.pop('evdns_flags', 0)
675
 
        if kwargs:
676
 
            raise TypeError('Unsupported keyword arguments: %s' % (kwargs.keys(), ))
677
 
 
678
 
        if family in (None, AF_INET, AF_UNSPEC):
679
 
            family = AF_INET
680
 
            # TODO: AF_UNSPEC means try both AF_INET and AF_INET6
681
 
            _ttl, addrs = resolve_ipv4(host, evdns_flags)
682
 
        elif family == AF_INET6:
683
 
            _ttl, addrs = resolve_ipv6(host, evdns_flags)
684
 
        else:
685
 
            raise NotImplementedError('family is not among AF_UNSPEC/AF_INET/AF_INET6: %r' % (family, ))
 
705
        if isinstance(host, unicode):
 
706
            host = host.encode('idna')
 
707
        if not isinstance(host, str) or \
 
708
           '.' not in host or \
 
709
           _ip4_re.match(host) is not None or \
 
710
           family not in (AF_UNSPEC, AF_INET, AF_INET6):
 
711
            return _socket.getaddrinfo(host, port, family, socktype, proto, flags)
 
712
 
 
713
        if isinstance(port, basestring):
 
714
            try:
 
715
                if socktype == 0:
 
716
                    try:
 
717
                        port = getservbyname(port, 'tcp')
 
718
                        socktype = SOCK_STREAM
 
719
                    except socket.error:
 
720
                        port = getservbyname(port, 'udp')
 
721
                        socktype = SOCK_DGRAM
 
722
                elif socktype == SOCK_STREAM:
 
723
                    port = getservbyname(port, 'tcp')
 
724
                elif socktype == SOCK_DGRAM:
 
725
                    port = getservbyname(port, 'udp')
 
726
                else:
 
727
                    raise gaierror(EAI_SERVICE, 'Servname not supported for ai_socktype')
 
728
            except error, ex:
 
729
                if 'not found' in str(ex):
 
730
                    raise gaierror(EAI_SERVICE, 'Servname not supported for ai_socktype')
 
731
                else:
 
732
                    raise gaierror(str(ex))
686
733
 
687
734
        socktype_proto = [(SOCK_STREAM, 6), (SOCK_DGRAM, 17), (SOCK_RAW, 0)]
688
735
        if socktype:
691
738
            socktype_proto = [(x, y) for (x, y) in socktype_proto if proto == y]
692
739
 
693
740
        result = []
694
 
        for addr in addrs:
695
 
            for socktype, proto in socktype_proto:
696
 
                result.append((family, socktype, proto, '', (inet_ntop(family, addr), port)))
 
741
 
 
742
        if family == AF_INET:
 
743
            for res in resolve_ipv4(host, evdns_flags)[1]:
 
744
                sockaddr = (inet_ntop(family, res), port)
 
745
                for socktype, proto in socktype_proto:
 
746
                    result.append((family, socktype, proto, '', sockaddr))
 
747
        elif family == AF_INET6:
 
748
            for res in resolve_ipv6(host, evdns_flags)[1]:
 
749
                sockaddr = (inet_ntop(family, res), port, 0, 0)
 
750
                for socktype, proto in socktype_proto:
 
751
                    result.append((family, socktype, proto, '', sockaddr))
 
752
        else:
 
753
            failure = None
 
754
            job = spawn(wrap_errors(gaierror, resolve_ipv6), host, evdns_flags)
 
755
            try:
 
756
                try:
 
757
                    ipv4_res = resolve_ipv4(host, evdns_flags)[1]
 
758
                except gaierror, failure:
 
759
                    ipv4_res = None
 
760
                ipv6_res = job.get()
 
761
                if isinstance(ipv6_res, gaierror):
 
762
                    ipv6_res = None
 
763
                    if failure is not None:
 
764
                        raise
 
765
                if ipv4_res is not None:
 
766
                    for res in ipv4_res:
 
767
                        sockaddr = (inet_ntop(AF_INET, res), port)
 
768
                        for socktype, proto in socktype_proto:
 
769
                            result.append((AF_INET, socktype, proto, '', sockaddr))
 
770
                if ipv6_res is not None:
 
771
                    for res in ipv6_res[1]:
 
772
                        sockaddr = (inet_ntop(AF_INET6, res), port, 0, 0)
 
773
                        for socktype, proto in socktype_proto:
 
774
                            result.append((AF_INET6, socktype, proto, '', sockaddr))
 
775
            finally:
 
776
                job.kill()
697
777
        return result
698
778
        # TODO libevent2 has getaddrinfo that is probably better than the hack above; should wrap that.
699
779
 
701
781
_have_ssl = False
702
782
 
703
783
try:
704
 
    from gevent.ssl import sslwrap_simple as ssl, SSLError as sslerror
 
784
    from gevent.ssl import sslwrap_simple as ssl, SSLError as sslerror, SSLSocket as SSLType
705
785
    _have_ssl = True
706
786
except ImportError:
707
787
    try:
708
 
        from gevent.sslold import ssl, sslerror
 
788
        from gevent.sslold import ssl, sslerror, SSLObject as SSLType
709
789
        _have_ssl = True
710
790
    except ImportError:
711
791
        pass
712
792
 
713
 
if not _have_ssl:
714
 
    __all__.remove('ssl')
715
 
    __all__.remove('sslerror')
716
 
 
 
793
if sys.version_info[:2] <= (2, 5) and _have_ssl:
 
794
    __implements__.extend(['ssl', 'sslerror', 'SSLType'])
 
795
 
 
796
 
 
797
__all__ = __implements__ + __extensions__ + __imports__